7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 package jdk.tools.jaotc.binformat.elf; 25 26 import java.nio.ByteBuffer; 27 import java.nio.ByteOrder; 28 import java.util.ArrayList; 29 30 import jdk.tools.jaotc.binformat.elf.Elf; 31 import jdk.tools.jaotc.binformat.elf.Elf.Elf64_Sym; 32 import jdk.tools.jaotc.binformat.elf.ElfSymbol; 33 import jdk.tools.jaotc.binformat.elf.ElfByteBuffer; 34 35 public class ElfSymtab { 36 37 ArrayList<ElfSymbol>localSymbols = new ArrayList<ElfSymbol>(); 38 ArrayList<ElfSymbol>globalSymbols = new ArrayList<ElfSymbol>(); 39 40 /** 41 * number of symbols added 42 */ 43 int symbolCount; 44 45 /** 46 * String holding symbol table strings 47 */ 48 private StringBuilder strTabContent = new StringBuilder(); 49 50 /** 51 * Keeps track of bytes in string table since strTabContent.length() 52 * is number of chars, not bytes. 53 */ 54 private int strTabNrOfBytes = 0; 55 56 public ElfSymtab() { 57 symbolCount = 0; 58 } 59 60 public ElfSymbol addSymbolEntry(String name, byte type, byte bind, 61 byte secHdrIndex, long offset, long size) { 62 // Get the current symbol index and append symbol name to string table. 63 int index; 64 ElfSymbol sym; 65 66 if (name.isEmpty()) { 67 index = 0; 68 strTabContent.append('\0'); 69 strTabNrOfBytes += 1; 70 sym = new ElfSymbol(symbolCount, index, type, bind, secHdrIndex, offset, size); 71 localSymbols.add(sym); 72 } else { 73 // We can't trust strTabContent.length() since that is 74 // chars (UTF16), keep track of bytes on our own. 75 index = strTabNrOfBytes; 76 // strTabContent.append("_").append(name).append('\0'); 77 strTabContent.append(name).append('\0'); 78 // + 1 for null, + 1 for "_" 79 //strTabNrOfBytes += (name.getBytes().length + 1 + 1); 80 strTabNrOfBytes += (name.getBytes().length + 1); 81 82 sym = new ElfSymbol(symbolCount, index, type, bind, secHdrIndex, offset, size); 83 if ((bind & Elf64_Sym.STB_GLOBAL) != 0) 84 globalSymbols.add(sym); 85 else 86 localSymbols.add(sym); 87 } 88 symbolCount++; 89 return (sym); 90 } 91 92 // Update the symbol indexes once all symbols have been added. 93 // This is required since we'll be reordering the symbols in the 94 // file to be in the order of Local then global. 95 public void updateIndexes() { 96 int index = 0; 97 98 // Update the local symbol indexes 99 for (int i = 0; i < localSymbols.size(); i++ ) { 100 ElfSymbol sym = localSymbols.get(i); 101 sym.setIndex(index++); 102 } 103 104 // Update the global symbol indexes 105 for (int i = 0; i < globalSymbols.size(); i++ ) { 106 ElfSymbol sym = globalSymbols.get(i); 107 sym.setIndex(index++); 108 } 109 } 110 111 public int getNumLocalSyms() { return localSymbols.size(); } 112 public int getNumGlobalSyms() { return globalSymbols.size(); } 113 114 115 // Create a single byte array that contains the symbol table entries 116 public byte[] getSymtabArray() { 117 int index = 0; 118 ByteBuffer symtabData = ElfByteBuffer.allocate(symbolCount*Elf64_Sym.totalsize); 119 byte [] retarray; 120 121 updateIndexes(); 122 123 // Add the local symbols 124 for (int i = 0; i < localSymbols.size(); i++ ) { 125 ElfSymbol sym = localSymbols.get(i); 126 byte [] arr = sym.getArray(); 127 symtabData.put(arr); 128 } 129 // Add the global symbols 130 for (int i = 0; i < globalSymbols.size(); i++ ) { 131 ElfSymbol sym = globalSymbols.get(i); 132 byte [] arr = sym.getArray(); 133 symtabData.put(arr); 134 } 135 retarray = symtabData.array(); 136 137 return (retarray); 138 } 139 140 // Return the string table array 141 public byte[] getStrtabArray() { 142 byte [] strs = strTabContent.toString().getBytes(); 143 return (strs); 144 } 145 } 146 147 | 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 package jdk.tools.jaotc.binformat.elf; 25 26 import java.nio.ByteBuffer; 27 import java.util.ArrayList; 28 29 import jdk.tools.jaotc.binformat.elf.Elf.Elf64_Sym; 30 import jdk.tools.jaotc.binformat.elf.ElfSymbol; 31 import jdk.tools.jaotc.binformat.elf.ElfByteBuffer; 32 33 final class ElfSymtab { 34 35 private final ArrayList<ElfSymbol> localSymbols = new ArrayList<>(); 36 private final ArrayList<ElfSymbol> globalSymbols = new ArrayList<>(); 37 38 /** 39 * number of symbols added 40 */ 41 private int symbolCount; 42 43 /** 44 * String holding symbol table strings 45 */ 46 private final StringBuilder strTabContent = new StringBuilder(); 47 48 /** 49 * Keeps track of bytes in string table since strTabContent.length() is number of chars, not 50 * bytes. 51 */ 52 private int strTabNrOfBytes = 0; 53 54 ElfSymtab() { 55 symbolCount = 0; 56 } 57 58 ElfSymbol addSymbolEntry(String name, byte type, byte bind, byte secHdrIndex, long offset, long size) { 59 // Get the current symbol index and append symbol name to string table. 60 int index; 61 ElfSymbol sym; 62 63 if (name.isEmpty()) { 64 index = 0; 65 strTabContent.append('\0'); 66 strTabNrOfBytes += 1; 67 sym = new ElfSymbol(symbolCount, index, type, bind, secHdrIndex, offset, size); 68 localSymbols.add(sym); 69 } else { 70 // We can't trust strTabContent.length() since that is 71 // chars (UTF16), keep track of bytes on our own. 72 index = strTabNrOfBytes; 73 // strTabContent.append("_").append(name).append('\0'); 74 strTabContent.append(name).append('\0'); 75 // + 1 for null, + 1 for "_" 76 // strTabNrOfBytes += (name.getBytes().length + 1 + 1); 77 strTabNrOfBytes += (name.getBytes().length + 1); 78 79 sym = new ElfSymbol(symbolCount, index, type, bind, secHdrIndex, offset, size); 80 if ((bind & Elf64_Sym.STB_GLOBAL) != 0) 81 globalSymbols.add(sym); 82 else 83 localSymbols.add(sym); 84 } 85 symbolCount++; 86 return (sym); 87 } 88 89 // Update the symbol indexes once all symbols have been added. 90 // This is required since we'll be reordering the symbols in the 91 // file to be in the order of Local then global. 92 void updateIndexes() { 93 int index = 0; 94 95 // Update the local symbol indexes 96 for (int i = 0; i < localSymbols.size(); i++) { 97 ElfSymbol sym = localSymbols.get(i); 98 sym.setIndex(index++); 99 } 100 101 // Update the global symbol indexes 102 for (int i = 0; i < globalSymbols.size(); i++) { 103 ElfSymbol sym = globalSymbols.get(i); 104 sym.setIndex(index++); 105 } 106 } 107 108 int getNumLocalSyms() { 109 return localSymbols.size(); 110 } 111 112 int getNumGlobalSyms() { 113 return globalSymbols.size(); 114 } 115 116 // Create a single byte array that contains the symbol table entries 117 byte[] getSymtabArray() { 118 ByteBuffer symtabData = ElfByteBuffer.allocate(symbolCount * Elf64_Sym.totalsize); 119 byte[] retarray; 120 121 updateIndexes(); 122 123 // Add the local symbols 124 for (int i = 0; i < localSymbols.size(); i++) { 125 ElfSymbol sym = localSymbols.get(i); 126 byte[] arr = sym.getArray(); 127 symtabData.put(arr); 128 } 129 // Add the global symbols 130 for (int i = 0; i < globalSymbols.size(); i++) { 131 ElfSymbol sym = globalSymbols.get(i); 132 byte[] arr = sym.getArray(); 133 symtabData.put(arr); 134 } 135 retarray = symtabData.array(); 136 137 return (retarray); 138 } 139 140 // Return the string table array 141 byte[] getStrtabArray() { 142 byte[] strs = strTabContent.toString().getBytes(); 143 return (strs); 144 } 145 } |