├── .classpath
├── .project
├── .settings
└── org.eclipse.jdt.core.prefs
├── README.md
├── bin
└── com
│ └── bluth
│ ├── parse
│ ├── ParseSO.class
│ ├── ReadElf$Symbol.class
│ └── ReadElf.class
│ └── readelf
│ ├── DataSource.class
│ ├── ELFException.class
│ ├── ELFFile.class
│ ├── ELFFileParser$ELFFileImpl$ELFHashTableImpl.class
│ ├── ELFFileParser$ELFFileImpl$ELFHeaderImpl$1.class
│ ├── ELFFileParser$ELFFileImpl$ELFHeaderImpl.class
│ ├── ELFFileParser$ELFFileImpl$ELFSectionHeaderImpl$1.class
│ ├── ELFFileParser$ELFFileImpl$ELFSectionHeaderImpl$2.class
│ ├── ELFFileParser$ELFFileImpl$ELFSectionHeaderImpl$3.class
│ ├── ELFFileParser$ELFFileImpl$ELFSectionHeaderImpl.class
│ ├── ELFFileParser$ELFFileImpl$ELFStringTableImpl.class
│ ├── ELFFileParser$ELFFileImpl$ELFSymbolImpl.class
│ ├── ELFFileParser$ELFFileImpl.class
│ ├── ELFFileParser.class
│ ├── ELFHashTable.class
│ ├── ELFHeader.class
│ ├── ELFProgramHeader.class
│ ├── ELFSectionHeader.class
│ ├── ELFStringTable.class
│ ├── ELFSymbol.class
│ ├── MemoizedObject.class
│ └── RandomAccessFileDataSource.class
├── libgetstr.so
└── src
└── com
└── bluth
├── parse
├── ParseSO.java
└── ReadElf.java
└── readelf
├── DataSource.java
├── ELFException.java
├── ELFFile.java
├── ELFFileParser.java
├── ELFHashTable.java
├── ELFHeader.java
├── ELFProgramHeader.java
├── ELFSectionHeader.java
├── ELFStringTable.java
├── ELFSymbol.java
├── MemoizedObject.java
└── RandomAccessFileDataSource.java
/.classpath:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | READELF
4 |
5 |
6 |
7 |
8 |
9 | org.eclipse.jdt.core.javabuilder
10 |
11 |
12 |
13 |
14 |
15 | org.eclipse.jdt.core.javanature
16 |
17 |
18 |
--------------------------------------------------------------------------------
/.settings/org.eclipse.jdt.core.prefs:
--------------------------------------------------------------------------------
1 | eclipse.preferences.version=1
2 | org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
3 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
4 | org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
5 | org.eclipse.jdt.core.compiler.compliance=1.6
6 | org.eclipse.jdt.core.compiler.debug.lineNumber=generate
7 | org.eclipse.jdt.core.compiler.debug.localVariable=generate
8 | org.eclipse.jdt.core.compiler.debug.sourceFile=generate
9 | org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
10 | org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
11 | org.eclipse.jdt.core.compiler.source=1.6
12 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bluthmatter/ReadElf/3c2cc08df8bda5854e761f7de190ee4a7f1054e2/README.md
--------------------------------------------------------------------------------
/bin/com/bluth/parse/ParseSO.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bluthmatter/ReadElf/3c2cc08df8bda5854e761f7de190ee4a7f1054e2/bin/com/bluth/parse/ParseSO.class
--------------------------------------------------------------------------------
/bin/com/bluth/parse/ReadElf$Symbol.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bluthmatter/ReadElf/3c2cc08df8bda5854e761f7de190ee4a7f1054e2/bin/com/bluth/parse/ReadElf$Symbol.class
--------------------------------------------------------------------------------
/bin/com/bluth/parse/ReadElf.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bluthmatter/ReadElf/3c2cc08df8bda5854e761f7de190ee4a7f1054e2/bin/com/bluth/parse/ReadElf.class
--------------------------------------------------------------------------------
/bin/com/bluth/readelf/DataSource.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bluthmatter/ReadElf/3c2cc08df8bda5854e761f7de190ee4a7f1054e2/bin/com/bluth/readelf/DataSource.class
--------------------------------------------------------------------------------
/bin/com/bluth/readelf/ELFException.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bluthmatter/ReadElf/3c2cc08df8bda5854e761f7de190ee4a7f1054e2/bin/com/bluth/readelf/ELFException.class
--------------------------------------------------------------------------------
/bin/com/bluth/readelf/ELFFile.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bluthmatter/ReadElf/3c2cc08df8bda5854e761f7de190ee4a7f1054e2/bin/com/bluth/readelf/ELFFile.class
--------------------------------------------------------------------------------
/bin/com/bluth/readelf/ELFFileParser$ELFFileImpl$ELFHashTableImpl.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bluthmatter/ReadElf/3c2cc08df8bda5854e761f7de190ee4a7f1054e2/bin/com/bluth/readelf/ELFFileParser$ELFFileImpl$ELFHashTableImpl.class
--------------------------------------------------------------------------------
/bin/com/bluth/readelf/ELFFileParser$ELFFileImpl$ELFHeaderImpl$1.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bluthmatter/ReadElf/3c2cc08df8bda5854e761f7de190ee4a7f1054e2/bin/com/bluth/readelf/ELFFileParser$ELFFileImpl$ELFHeaderImpl$1.class
--------------------------------------------------------------------------------
/bin/com/bluth/readelf/ELFFileParser$ELFFileImpl$ELFHeaderImpl.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bluthmatter/ReadElf/3c2cc08df8bda5854e761f7de190ee4a7f1054e2/bin/com/bluth/readelf/ELFFileParser$ELFFileImpl$ELFHeaderImpl.class
--------------------------------------------------------------------------------
/bin/com/bluth/readelf/ELFFileParser$ELFFileImpl$ELFSectionHeaderImpl$1.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bluthmatter/ReadElf/3c2cc08df8bda5854e761f7de190ee4a7f1054e2/bin/com/bluth/readelf/ELFFileParser$ELFFileImpl$ELFSectionHeaderImpl$1.class
--------------------------------------------------------------------------------
/bin/com/bluth/readelf/ELFFileParser$ELFFileImpl$ELFSectionHeaderImpl$2.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bluthmatter/ReadElf/3c2cc08df8bda5854e761f7de190ee4a7f1054e2/bin/com/bluth/readelf/ELFFileParser$ELFFileImpl$ELFSectionHeaderImpl$2.class
--------------------------------------------------------------------------------
/bin/com/bluth/readelf/ELFFileParser$ELFFileImpl$ELFSectionHeaderImpl$3.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bluthmatter/ReadElf/3c2cc08df8bda5854e761f7de190ee4a7f1054e2/bin/com/bluth/readelf/ELFFileParser$ELFFileImpl$ELFSectionHeaderImpl$3.class
--------------------------------------------------------------------------------
/bin/com/bluth/readelf/ELFFileParser$ELFFileImpl$ELFSectionHeaderImpl.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bluthmatter/ReadElf/3c2cc08df8bda5854e761f7de190ee4a7f1054e2/bin/com/bluth/readelf/ELFFileParser$ELFFileImpl$ELFSectionHeaderImpl.class
--------------------------------------------------------------------------------
/bin/com/bluth/readelf/ELFFileParser$ELFFileImpl$ELFStringTableImpl.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bluthmatter/ReadElf/3c2cc08df8bda5854e761f7de190ee4a7f1054e2/bin/com/bluth/readelf/ELFFileParser$ELFFileImpl$ELFStringTableImpl.class
--------------------------------------------------------------------------------
/bin/com/bluth/readelf/ELFFileParser$ELFFileImpl$ELFSymbolImpl.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bluthmatter/ReadElf/3c2cc08df8bda5854e761f7de190ee4a7f1054e2/bin/com/bluth/readelf/ELFFileParser$ELFFileImpl$ELFSymbolImpl.class
--------------------------------------------------------------------------------
/bin/com/bluth/readelf/ELFFileParser$ELFFileImpl.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bluthmatter/ReadElf/3c2cc08df8bda5854e761f7de190ee4a7f1054e2/bin/com/bluth/readelf/ELFFileParser$ELFFileImpl.class
--------------------------------------------------------------------------------
/bin/com/bluth/readelf/ELFFileParser.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bluthmatter/ReadElf/3c2cc08df8bda5854e761f7de190ee4a7f1054e2/bin/com/bluth/readelf/ELFFileParser.class
--------------------------------------------------------------------------------
/bin/com/bluth/readelf/ELFHashTable.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bluthmatter/ReadElf/3c2cc08df8bda5854e761f7de190ee4a7f1054e2/bin/com/bluth/readelf/ELFHashTable.class
--------------------------------------------------------------------------------
/bin/com/bluth/readelf/ELFHeader.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bluthmatter/ReadElf/3c2cc08df8bda5854e761f7de190ee4a7f1054e2/bin/com/bluth/readelf/ELFHeader.class
--------------------------------------------------------------------------------
/bin/com/bluth/readelf/ELFProgramHeader.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bluthmatter/ReadElf/3c2cc08df8bda5854e761f7de190ee4a7f1054e2/bin/com/bluth/readelf/ELFProgramHeader.class
--------------------------------------------------------------------------------
/bin/com/bluth/readelf/ELFSectionHeader.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bluthmatter/ReadElf/3c2cc08df8bda5854e761f7de190ee4a7f1054e2/bin/com/bluth/readelf/ELFSectionHeader.class
--------------------------------------------------------------------------------
/bin/com/bluth/readelf/ELFStringTable.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bluthmatter/ReadElf/3c2cc08df8bda5854e761f7de190ee4a7f1054e2/bin/com/bluth/readelf/ELFStringTable.class
--------------------------------------------------------------------------------
/bin/com/bluth/readelf/ELFSymbol.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bluthmatter/ReadElf/3c2cc08df8bda5854e761f7de190ee4a7f1054e2/bin/com/bluth/readelf/ELFSymbol.class
--------------------------------------------------------------------------------
/bin/com/bluth/readelf/MemoizedObject.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bluthmatter/ReadElf/3c2cc08df8bda5854e761f7de190ee4a7f1054e2/bin/com/bluth/readelf/MemoizedObject.class
--------------------------------------------------------------------------------
/bin/com/bluth/readelf/RandomAccessFileDataSource.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bluthmatter/ReadElf/3c2cc08df8bda5854e761f7de190ee4a7f1054e2/bin/com/bluth/readelf/RandomAccessFileDataSource.class
--------------------------------------------------------------------------------
/libgetstr.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bluthmatter/ReadElf/3c2cc08df8bda5854e761f7de190ee4a7f1054e2/libgetstr.so
--------------------------------------------------------------------------------
/src/com/bluth/parse/ParseSO.java:
--------------------------------------------------------------------------------
1 | package com.bluth.parse;
2 |
3 | import java.io.File;
4 | import java.io.IOException;
5 | import java.util.HashMap;
6 | import java.util.Iterator;
7 | import java.util.Map;
8 | import java.util.Map.Entry;
9 |
10 | import com.bluth.parse.ReadElf.Symbol;
11 | import com.bluth.readelf.ELFFileParser;
12 |
13 | public class ParseSO {
14 |
15 | public static void main(String[] args) throws Exception {
16 | parseSO();
17 | }
18 |
19 | private static void parseSO() throws Exception {
20 | ELFFileParser.main(new String[]{"libgetstr.so" });
21 | }
22 |
23 | static void outMap(Map map) {
24 | Iterator> i = map.entrySet().iterator();
25 | while (i.hasNext()) {
26 | Map.Entry entry = (Entry) i.next();
27 | String key = entry.getKey();
28 | String value = entry.getValue();
29 | System.out.println(key + "===" + value);
30 | }
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/src/com/bluth/parse/ReadElf.java:
--------------------------------------------------------------------------------
1 | package com.bluth.parse;
2 |
3 | import java.io.File;
4 | import java.io.IOException;
5 | import java.io.RandomAccessFile;
6 | import java.util.HashMap;
7 | import java.util.Iterator;
8 | import java.util.Map;
9 | import java.util.Map.Entry;
10 |
11 | /**
12 | * A poor man's implementation of the readelf command. This program is
13 | * designed to parse ELF (Executable and Linkable Format) files.
14 | */
15 | public class ReadElf {
16 | /** The magic values for the ELF identification. */
17 | private static final byte[] ELF_IDENT = {
18 | (byte) 0x7F, (byte) 'E', (byte) 'L', (byte) 'F',
19 | };
20 |
21 | /** Size of the e_ident[] structure in the ELF header. */
22 | private static final int EI_NIDENT = 16;
23 |
24 | /** Offset from end of ident structure in half-word sizes. */
25 | private static final int OFFSET_TYPE = 0;
26 |
27 | /** Machine type. */
28 | private static final int OFFSET_MACHINE = 1;
29 |
30 | /** ELF version. */
31 | private static final int OFFSET_VERSION = 2;
32 |
33 | /**
34 | * The offset to which the system transfers control. e.g., the first thing
35 | * executed.
36 | */
37 | private static final int OFFSET_ENTRY = 4;
38 |
39 | /** Program header offset in bytes. */
40 | private static final int OFFSET_PHOFF = 6;
41 |
42 | /** Segment header offset in bytes. */
43 | private static final int OFFSET_SHOFF = 8;
44 |
45 | /** Processor-specific flags for binary. */
46 | private static final int OFFSET_FLAGS = 10;
47 |
48 | /** ELF header size in bytes. */
49 | private static final int OFFSET_EHSIZE = 12;
50 |
51 | /** All program headers entry size in bytes. */
52 | private static final int OFFSET_PHENTSIZE = 13;
53 |
54 | /** Number of program headers in ELF. */
55 | private static final int OFFSET_PHNUM = 14;
56 |
57 | /** All segment headers entry size in bytes. */
58 | private static final int OFFSET_SHENTSIZE = 15;
59 |
60 | /** Number of segment headers in ELF. */
61 | private static final int OFFSET_SHNUM = 16;
62 |
63 | /** The section header index that refers to string table. */
64 | private static final int OFFSET_SHSTRNDX = 17;
65 |
66 | /** Program header offset for type of this program header. */
67 | private static final int PHOFF_TYPE = 0;
68 |
69 | /** Program header offset for absolute offset in file. */
70 | private static final int PHOFF_OFFSET = 2;
71 |
72 | /** Program header offset for virtual address. */
73 | private static final int PHOFF_VADDR = 4;
74 |
75 | /** Program header offset for physical address. */
76 | private static final int PHOFF_PADDR = 6;
77 |
78 | /** Program header offset for file size in bytes. */
79 | private static final int PHOFF_FILESZ = 8;
80 |
81 | /** Program header offset for memory size in bytes. */
82 | private static final int PHOFF_MEMSZ = 10;
83 |
84 | /** Program header offset for flags. */
85 | private static final int PHOFF_FLAGS = 12;
86 |
87 | /**
88 | * Program header offset for required alignment. 0 or 1 means no alignment
89 | * necessary.
90 | */
91 | private static final int PHOFF_ALIGN = 14;
92 |
93 | /** Index into string pool for segment name. */
94 | private static final long SHOFF_NAME = 0;
95 |
96 | /** Segment header offset for type (half-words) */
97 | private static final long SHOFF_TYPE = 2;
98 |
99 | /** Segment header offset for offset (meta!) (half-words) */
100 | private static final long SHOFF_OFFSET = 8;
101 |
102 | /** Segment header offset for size (half-words) */
103 | private static final long SHOFF_SIZE = 10;
104 |
105 | /** Data is presented in LSB format. */
106 | private static final int ELFDATA2LSB = 1;
107 |
108 | /** Date is presented in MSB format. */
109 | private static final int ELFDATA2MSB = 2;
110 |
111 | private static final int ELFCLASS32 = 1;
112 |
113 | private static final int ELFCLASS64 = 2;
114 |
115 | private static final long PT_LOAD = 1;
116 |
117 | /** Section Type: Symbol Table */
118 | private static final int SHT_SYMTAB = 2;
119 |
120 | /** Section Type: String Table */
121 | private static final int SHT_STRTAB = 3;
122 |
123 | /** Section Type: Dynamic **/
124 | private static final int SHT_DYNAMIC = 6;
125 |
126 | /** Section Type: Dynamic Symbol Table */
127 | private static final int SHT_DYNSYM = 11;
128 |
129 | /** Symbol Table Entry: Name offset */
130 | private static final int SYMTAB_NAME = 0;
131 |
132 | /** Symbol Table Entry: SymTab Info */
133 | private static final int SYMTAB_ST_INFO = 6;
134 |
135 | /** Symbol Table Entry size (half-words) */
136 | private static final int SYMTAB_ENTRY_HALFWORD_SIZE = 7;
137 |
138 | /**
139 | * Symbol Table Entry size (extra in bytes) to cover "st_info" and
140 | * "st_other"
141 | */
142 | private static final int SYMTAB_ENTRY_BYTE_EXTRA_SIZE = 2;
143 |
144 | public static class Symbol {
145 | public static final int STB_LOCAL = 0;
146 |
147 | public static final int STB_GLOBAL = 1;
148 |
149 | public static final int STB_WEAK = 2;
150 |
151 | public static final int STB_LOPROC = 13;
152 |
153 | public static final int STB_HIPROC = 15;
154 |
155 | public final String name;
156 |
157 | public final int bind;
158 |
159 | public final int type;
160 |
161 | Symbol(String name, int st_info) {
162 | this.name = name;
163 | this.bind = (st_info >> 4) & 0x0F;
164 | this.type = st_info & 0x0F;
165 | }
166 | };
167 |
168 | private final RandomAccessFile mFile;
169 | private final byte[] mBuffer = new byte[512];
170 | private int mClass;
171 | private int mEndian;
172 | private boolean mIsDynamic;
173 | private boolean mIsPIE;
174 | private int mType;
175 | private int mWordSize;
176 | private int mHalfWordSize;
177 |
178 | /** Symbol Table offset */
179 | private long mSymTabOffset;
180 |
181 | /** Symbol Table size */
182 | private long mSymTabSize;
183 |
184 | /** Dynamic Symbol Table offset */
185 | private long mDynSymOffset;
186 |
187 | /** Dynamic Symbol Table size */
188 | private long mDynSymSize;
189 |
190 | /** Section Header String Table offset */
191 | private long mShStrTabOffset;
192 |
193 | /** Section Header String Table size */
194 | private long mShStrTabSize;
195 |
196 | /** String Table offset */
197 | private long mStrTabOffset;
198 |
199 | /** String Table size */
200 | private long mStrTabSize;
201 |
202 | /** Dynamic String Table offset */
203 | private long mDynStrOffset;
204 |
205 | /** Dynamic String Table size */
206 | private long mDynStrSize;
207 |
208 | /** Symbol Table symbol names */
209 | private Map mSymbols;
210 |
211 | /** Dynamic Symbol Table symbol names */
212 | private Map mDynamicSymbols;
213 |
214 | static ReadElf read(File file) throws IOException {
215 | return new ReadElf(file);
216 | }
217 |
218 | boolean isDynamic() {
219 | return mIsDynamic;
220 | }
221 |
222 | int getType() {
223 | return mType;
224 | }
225 |
226 | boolean isPIE() {
227 | return mIsPIE;
228 | }
229 |
230 | private ReadElf(File file) throws IOException {
231 | mFile = new RandomAccessFile(file, "r");
232 |
233 | readIdent();
234 |
235 | readHeader();
236 | }
237 |
238 | protected void finalize() throws Throwable {
239 | try {
240 | mFile.close();
241 | } catch (IOException e) {
242 | // nothing
243 | } finally {
244 | super.finalize();
245 | }
246 | }
247 |
248 | private void readHeader() throws IOException {
249 | mType = readHalf(getHeaderOffset(OFFSET_TYPE));
250 |
251 | final long shOffset = readWord(getHeaderOffset(OFFSET_SHOFF));
252 | final int shNumber = readHalf(getHeaderOffset(OFFSET_SHNUM));
253 | final int shSize = readHalf(getHeaderOffset(OFFSET_SHENTSIZE));
254 | final int shStrIndex = readHalf(getHeaderOffset(OFFSET_SHSTRNDX));
255 |
256 | readSectionHeaders(shOffset, shNumber, shSize, shStrIndex);
257 |
258 | final long phOffset = readWord(getHeaderOffset(OFFSET_PHOFF));
259 | final int phNumber = readHalf(getHeaderOffset(OFFSET_PHNUM));
260 | final int phSize = readHalf(getHeaderOffset(OFFSET_PHENTSIZE));
261 |
262 | readProgramHeaders(phOffset, phNumber, phSize);
263 | }
264 |
265 | private void readSectionHeaders(long tableOffset, int shNumber, int shSize, int shStrIndex)
266 | throws IOException {
267 | // Read the Section Header String Table offset first.
268 | {
269 | final long shStrTabShOffset = tableOffset + shStrIndex * shSize;
270 | final long type = readWord(shStrTabShOffset + mHalfWordSize * SHOFF_TYPE);
271 |
272 | if (type == SHT_STRTAB) {
273 | mShStrTabOffset = readWord(shStrTabShOffset + mHalfWordSize * SHOFF_OFFSET);
274 | mShStrTabSize = readWord(shStrTabShOffset + mHalfWordSize * SHOFF_SIZE);
275 | }
276 | }
277 |
278 | for (int i = 0; i < shNumber; i++) {
279 | // Don't bother to re-read the Section Header StrTab.
280 | if (i == shStrIndex) {
281 | continue;
282 | }
283 |
284 | final long shOffset = tableOffset + i * shSize;
285 |
286 | final long type = readWord(shOffset + mHalfWordSize * SHOFF_TYPE);
287 | if ((type == SHT_SYMTAB) || (type == SHT_DYNSYM)) {
288 | final long nameOffset = readWord(shOffset + mHalfWordSize * SHOFF_NAME);
289 | final long offset = readWord(shOffset + mHalfWordSize * SHOFF_OFFSET);
290 | final long size = readWord(shOffset + mHalfWordSize * SHOFF_SIZE);
291 |
292 | final String symTabName = readShStrTabEntry(nameOffset);
293 |
294 | if (".symtab".equals(symTabName)) {
295 | mSymTabOffset = offset;
296 | mSymTabSize = size;
297 | } else if (".dynsym".equals(symTabName)) {
298 | mDynSymOffset = offset;
299 | mDynSymSize = size;
300 | }
301 | } else if (type == SHT_STRTAB) {
302 | final long nameOffset = readWord(shOffset + mHalfWordSize * SHOFF_NAME);
303 | final long offset = readWord(shOffset + mHalfWordSize * SHOFF_OFFSET);
304 | final long size = readWord(shOffset + mHalfWordSize * SHOFF_SIZE);
305 |
306 | final String strTabName = readShStrTabEntry(nameOffset);
307 | System.out.println(strTabName);
308 | if (".strtab".equals(strTabName)) {
309 | mStrTabOffset = offset;
310 | mStrTabSize = size;
311 | } else if (".dynstr".equals(strTabName)) {
312 | mDynStrOffset = offset;
313 | mDynStrSize = size;
314 | }
315 | } else if (type == SHT_DYNAMIC) {
316 | mIsDynamic = true;
317 | }
318 | }
319 | }
320 |
321 | private void readProgramHeaders(long phOffset, int phNumber, int phSize) throws IOException {
322 | for (int i = 0; i < phNumber; i++) {
323 | final long baseOffset = phOffset + i * phSize;
324 | final long type = readWord(baseOffset);
325 | if (type == PT_LOAD) {
326 | final long virtAddress = readWord(baseOffset + mHalfWordSize * PHOFF_VADDR);
327 | System.out.println(String.format("%h", virtAddress));
328 | if (virtAddress == 0) {
329 | mIsPIE = true;
330 | }
331 | }
332 | }
333 | }
334 |
335 | private void readSymbolTable(Map symbolMap, long symStrOffset, long symStrSize,
336 | long symOffset, long symSize) throws IOException {
337 | final long symEnd = symOffset + symSize;
338 | for (long off = symOffset; off < symEnd; off += SYMTAB_ENTRY_HALFWORD_SIZE * mHalfWordSize
339 | + SYMTAB_ENTRY_BYTE_EXTRA_SIZE) {
340 | long strOffset = readWord(off + SYMTAB_NAME);
341 | if (strOffset == 0) {
342 | continue;
343 | }
344 |
345 | final String symName = readStrTabEntry(symStrOffset, symStrSize, strOffset);
346 | System.out.println(symName);
347 | if (symName != null) {
348 | final int st_info = readByte(off + SYMTAB_ST_INFO);
349 | symbolMap.put(symName, new Symbol(symName, st_info));
350 | }
351 | }
352 | outMap(symbolMap);
353 | }
354 |
355 | static void outMap(Map map) {
356 | Iterator> i = map.entrySet().iterator();
357 | while (i.hasNext()) {
358 | Map.Entry entry = (Entry) i.next();
359 | String key = entry.getKey();
360 | Symbol value = entry.getValue();
361 | System.out.println(key + "===" + value.name);
362 | }
363 | }
364 |
365 | private String readShStrTabEntry(long strOffset) throws IOException {
366 | if ((mShStrTabOffset == 0) || (strOffset < 0) || (strOffset >= mShStrTabSize)) {
367 | return null;
368 | }
369 |
370 | return readString(mShStrTabOffset + strOffset);
371 | }
372 |
373 | private String readStrTabEntry(long tableOffset, long tableSize, long strOffset)
374 | throws IOException {
375 | if ((tableOffset == 0) || (strOffset < 0) || (strOffset >= tableSize)) {
376 | return null;
377 | }
378 |
379 | return readString(tableOffset + strOffset);
380 | }
381 |
382 | private int getHeaderOffset(int halfWorldOffset) {
383 | return EI_NIDENT + halfWorldOffset * mHalfWordSize;
384 | }
385 |
386 | private int readByte(long offset) throws IOException {
387 | mFile.seek(offset);
388 | mFile.readFully(mBuffer, 0, 1);
389 |
390 | return mBuffer[0];
391 | }
392 |
393 | private int readHalf(long offset) throws IOException {
394 | mFile.seek(offset);
395 | mFile.readFully(mBuffer, 0, mWordSize);
396 |
397 | final int answer;
398 | if (mEndian == ELFDATA2LSB) {
399 | answer = mBuffer[1] << 8 | mBuffer[0];
400 | } else {
401 | answer = mBuffer[0] << 8 | mBuffer[1];
402 | }
403 |
404 | return answer;
405 | }
406 |
407 | private long readWord(long offset) throws IOException {
408 | mFile.seek(offset);
409 | mFile.readFully(mBuffer, 0, mWordSize);
410 |
411 | int answer = 0;
412 | if (mEndian == ELFDATA2LSB) {
413 | for (int i = mWordSize - 1; i >= 0; i--) {
414 | answer = (answer << 8) | (mBuffer[i] & 0xFF);
415 | }
416 | } else {
417 | final int N = mWordSize - 1;
418 | for (int i = 0; i <= N; i++) {
419 | answer = (answer << 8) | mBuffer[i];
420 | }
421 | }
422 |
423 | return answer;
424 | }
425 |
426 | private String readString(long offset) throws IOException {
427 | mFile.seek(offset);
428 | mFile.readFully(mBuffer, 0, (int) Math.min(mBuffer.length, mFile.length() - offset));
429 |
430 | for (int i = 0; i < mBuffer.length; i++) {
431 | if (mBuffer[i] == 0) {
432 | return new String(mBuffer, 0, i);
433 | }
434 | }
435 |
436 | return null;
437 | }
438 |
439 | private void readIdent() throws IOException {
440 | mFile.seek(0);
441 | mFile.readFully(mBuffer, 0, EI_NIDENT);
442 |
443 | if ((mBuffer[0] != ELF_IDENT[0]) || (mBuffer[1] != ELF_IDENT[1])
444 | || (mBuffer[2] != ELF_IDENT[2]) || (mBuffer[3] != ELF_IDENT[3])) {
445 | throw new IllegalArgumentException("Invalid ELF file");
446 | }
447 |
448 | mClass = mBuffer[4];
449 | if (mClass == ELFCLASS32) {
450 | mWordSize = 4;
451 | mHalfWordSize = 2;
452 | } else {
453 | throw new IOException("Invalid executable type " + mClass + ": not ELFCLASS32!");
454 | }
455 |
456 | mEndian = mBuffer[5];
457 | }
458 |
459 | public Symbol getSymbol(String name) {
460 | if ((mSymTabOffset == 0) && (mSymTabSize == 0)) {
461 | return null;
462 | }
463 |
464 | if (mSymbols == null) {
465 | mSymbols = new HashMap();
466 | try {
467 | readSymbolTable(mSymbols, mStrTabOffset, mStrTabSize, mSymTabOffset, mSymTabSize);
468 | } catch (IOException e) {
469 | return null;
470 | }
471 | }
472 |
473 | return mSymbols.get(name);
474 | }
475 |
476 | public Symbol getDynamicSymbol(String name) {
477 | if ((mDynSymOffset == 0) && (mDynSymSize == 0)) {
478 | return null;
479 | }
480 |
481 | if (mDynamicSymbols == null) {
482 | mDynamicSymbols = new HashMap();
483 | try {
484 | readSymbolTable(mDynamicSymbols, mDynStrOffset, mDynStrSize, mDynSymOffset,
485 | mDynSymSize);
486 | } catch (IOException e) {
487 | return null;
488 | }
489 | }
490 |
491 | return mDynamicSymbols.get(name);
492 | }
493 | }
--------------------------------------------------------------------------------
/src/com/bluth/readelf/DataSource.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2000, 2001, Oracle and/or its affiliates. All rights reserved.
3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 | *
5 | * This code is free software; you can redistribute it and/or modify it
6 | * under the terms of the GNU General Public License version 2 only, as
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,
20 | * CA 94065 USA or visit www.oracle.com if you need additional information or
21 | * have any questions.
22 | *
23 | */
24 |
25 | package com.bluth.readelf;
26 |
27 | import java.io.*;
28 |
29 | /** An abstraction which represents a seekable data source.
30 | RandomAccessFile can be trivially mapped to this; in addition, we
31 | can support an adapter for addresses, so we can parse DLLs
32 | directly out of the remote process's address space. This class is
33 | used by the Windows COFF and Posix ELF implementations. */
34 |
35 | public interface DataSource {
36 | public byte readByte() throws IOException;
37 | public short readShort() throws IOException;
38 | public int readInt() throws IOException;
39 | public long readLong() throws IOException;
40 | public int read(byte[] b) throws IOException;
41 | public void seek(long pos) throws IOException;
42 | public long getFilePointer() throws IOException;
43 | public void close() throws IOException;
44 | }
--------------------------------------------------------------------------------
/src/com/bluth/readelf/ELFException.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2001, 2004, Oracle and/or its affiliates. All rights reserved.
3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 | *
5 | * This code is free software; you can redistribute it and/or modify it
6 | * under the terms of the GNU General Public License version 2 only, as
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,
20 | * CA 94065 USA or visit www.oracle.com if you need additional information or
21 | * have any questions.
22 | *
23 | */
24 |
25 | package com.bluth.readelf;
26 |
27 | /** Generic exception class for all exceptions which occur in this
28 | package. Since there is no mechanism built into this library for
29 | recovering from errors, the best clients can do is display the
30 | error string. */
31 |
32 | public class ELFException extends RuntimeException {
33 | public ELFException() {
34 | super();
35 | }
36 |
37 | public ELFException(String message) {
38 | super(message);
39 | }
40 |
41 | public ELFException(Throwable cause) {
42 | super(cause);
43 | }
44 |
45 | public ELFException(String message, Throwable cause) {
46 | super(message, cause);
47 | }
48 | }
--------------------------------------------------------------------------------
/src/com/bluth/readelf/ELFFile.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2001, Oracle and/or its affiliates. All rights reserved.
3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 | *
5 | * This code is free software; you can redistribute it and/or modify it
6 | * under the terms of the GNU General Public License version 2 only, as
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,
20 | * CA 94065 USA or visit www.oracle.com if you need additional information or
21 | * have any questions.
22 | *
23 | */
24 |
25 | package com.bluth.readelf;
26 |
27 | public interface ELFFile {
28 | /** ELF magic number. */
29 | public static final byte ELF_MAGIC_NUMBER[] = { 0x7f, 'E', 'L', 'F' };
30 |
31 | public static final byte CLASS_INVALID = 0;
32 | /** 32-bit objects. */
33 | public static final byte CLASS_32 = 1;
34 | /** 64-bit objects. */
35 | public static final byte CLASS_64 = 2;
36 |
37 | /** No data encoding. */
38 | public static final byte DATA_INVALID = 0;
39 | /** LSB data encoding. */
40 | public static final byte DATA_LSB = 1;
41 | /** MSB data encoding. */
42 | public static final byte DATA_MSB = 2;
43 |
44 | /** No ELF header version. */
45 | public static final byte VERSION_INVALID = 0;
46 | /** Current ELF header version. */
47 | public static final byte VERSION_CURRENT = 1;
48 |
49 | public static final byte NDX_MAGIC_0 = 0;
50 | public static final byte NDX_MAGIC_1 = 1;
51 | public static final byte NDX_MAGIC_2 = 2;
52 | public static final byte NDX_MAGIC_3 = 3;
53 | public static final byte NDX_OBJECT_SIZE = 4;
54 | public static final byte NDX_ENCODING = 5;
55 | public static final byte NDX_VERSION = 6;
56 |
57 | public ELFHeader getHeader();
58 | public void close();
59 |
60 | /** Returns the 4 byte magic number for this file. This value should
61 | * match the values in ELF_MAGIC_NUMBER. */
62 | public byte[] getMagicNumber();
63 | /** Returns a byte identifying the size of objects used for this ELF
64 | * file. The byte will be either CLASS_INVALID, CLASS_32 or CLASS_64. */
65 | public byte getObjectSize();
66 | /** Returns a byte identifying the data encoding of the processor specific
67 | * data. This byte will be either DATA_INVALID, DATA_LSB or DATA_MSB. */
68 | public byte getEncoding();
69 | /** Returns one of the version constants. This should be VERSION_CURRENT. */
70 | public byte getVersion();
71 | }
--------------------------------------------------------------------------------
/src/com/bluth/readelf/ELFFileParser.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2001, 2004, Oracle and/or its affiliates. All rights reserved.
3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 | *
5 | * This code is free software; you can redistribute it and/or modify it
6 | * under the terms of the GNU General Public License version 2 only, as
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,
20 | * CA 94065 USA or visit www.oracle.com if you need additional information or
21 | * have any questions.
22 | *
23 | */
24 |
25 | package com.bluth.readelf;
26 |
27 | import java.io.*;
28 | import java.util.*;
29 |
30 | public class ELFFileParser {
31 | private static ELFFileParser elfParser;
32 | private static final String US_ASCII = "US-ASCII";
33 |
34 | public static ELFFileParser getParser() {
35 | if (elfParser == null) {
36 | elfParser = new ELFFileParser();
37 | }
38 | return elfParser;
39 | }
40 |
41 | /**
42 | * Parses the data in filename and returns the ELFFile representation.
43 | */
44 | public ELFFile parse(String filename) throws ELFException {
45 | try {
46 | RandomAccessFile file = new RandomAccessFile(filename, "r");
47 | return parse(new RandomAccessFileDataSource(file));
48 | } catch (FileNotFoundException e) {
49 | throw new ELFException(e);
50 | }
51 | }
52 |
53 | /**
54 | * Parses the data source and returns the ELFFile representation.
55 | */
56 | public ELFFile parse(DataSource source) throws ELFException {
57 | return new ELFFileImpl(source);
58 | }
59 |
60 | /**
61 | * Implementation of the ELFFile interface.
62 | */
63 | class ELFFileImpl implements ELFFile {
64 | private DataSource file;
65 | private ELFHeader header;
66 | private byte ident[] = new byte[16];
67 |
68 | ELFFileImpl(DataSource file) throws ELFException {
69 | this.file = file;
70 | int bytesRead = readBytes(ident);
71 | if (bytesRead != ident.length) {
72 | throw new ELFException("Error reading elf header (read " +
73 | bytesRead + "bytes, expected to " +
74 | "read " + ident.length + "bytes).");
75 | }
76 |
77 | // Check the magic number before we continue reading the file.
78 | if (!Arrays.equals(getMagicNumber(), ELF_MAGIC_NUMBER)) {
79 | throw new ELFException("Bad magic number for file.");
80 | }
81 |
82 | header = new ELFHeaderImpl();
83 | }
84 |
85 | public ELFHeader getHeader() { return header; }
86 |
87 | public byte[] getMagicNumber() {
88 | byte magicNumber[] = new byte[4];
89 | magicNumber[0] = ident[NDX_MAGIC_0];
90 | magicNumber[1] = ident[NDX_MAGIC_1];
91 | magicNumber[2] = ident[NDX_MAGIC_2];
92 | magicNumber[3] = ident[NDX_MAGIC_3];
93 | return magicNumber;
94 | }
95 |
96 | public byte getObjectSize() { return ident[NDX_OBJECT_SIZE]; }
97 | public byte getEncoding() { return ident[NDX_ENCODING]; }
98 | public byte getVersion() { return ident[NDX_VERSION]; }
99 |
100 |
101 | /**
102 | * Implementation of the ELFHeader interface.
103 | */
104 | class ELFHeaderImpl implements ELFHeader {
105 | /** Marks the file as an object file and provide machine-independent
106 | * data so the contents may be decoded and interpreted. */
107 | private byte ident[] = new byte[16]; // unsigned char
108 | /** Identifies the object file type. */
109 | private short file_type; // Elf32_Half
110 | /** The required architecture. */
111 | private short arch; // Elf32_Half
112 | /** Version */
113 | private int version; // Elf32_Word
114 | /** Virtual address to which the system first transfers control.
115 | * If there is no entry point for the file the value is 0. */
116 | private int entry_point; // Elf32_Addr
117 | /** Program header table offset in bytes. If there is no program
118 | * header table the value is 0. */
119 | private int ph_offset; // Elf32_Off
120 | /** Section header table offset in bytes. If there is no section
121 | * header table the value is 0. */
122 | private int sh_offset; // Elf32_Off
123 | /** Processor specific flags. */
124 | private int flags; // Elf32_Word
125 | /** ELF header size in bytes. */
126 | private short eh_size; // Elf32_Half
127 | /** Size of one entry in the file's program header table in bytes.
128 | * All entries are the same size. */
129 | private short ph_entry_size; // Elf32_Half
130 | /** Number of entries in the program header table, 0 if no
131 | * entries. */
132 | private short num_ph; // Elf32_Half
133 | /** Section header entry size in bytes. */
134 | private short sh_entry_size; // Elf32_Half
135 | /** Number of entries in the section header table, 0 if no
136 | * entries. */
137 | private short num_sh; // Elf32_Half
138 | /** Index into the section header table associated with the section
139 | * name string table. SH_UNDEF if there is no section name string
140 | * table. */
141 | private short sh_string_ndx; // Elf32_Half
142 |
143 | /** MemoizedObject array of section headers associated with this
144 | * ELF file. */
145 | private MemoizedObject[] sectionHeaders;
146 | /** MemoizedObject array of program headers associated with this
147 | * ELF file. */
148 | private MemoizedObject[] programHeaders;
149 |
150 | /** Used to cache symbol table lookup. */
151 | private ELFSectionHeader symbolTableSection;
152 | /** Used to cache dynamic symbol table lookup. */
153 | private ELFSectionHeader dynamicSymbolTableSection;
154 | /** Used to cache hash table lookup. */
155 | private ELFHashTable hashTable;
156 |
157 | /**
158 | * Reads the ELF header and sets up the section and program headers
159 | * in memoized arrays.
160 | */
161 | ELFHeaderImpl() throws ELFException {
162 | file_type = readShort();
163 | arch = readShort();
164 | version = readInt();
165 | entry_point = readInt();
166 | ph_offset = readInt();
167 | sh_offset = readInt();
168 | flags = readInt();
169 | eh_size = readShort();
170 | ph_entry_size = readShort();
171 | num_ph = readShort();
172 | sh_entry_size = readShort();
173 | num_sh = readShort();
174 | sh_string_ndx = readShort();
175 |
176 | // Set up the section headers
177 | sectionHeaders = new MemoizedObject[num_sh];
178 | for (int i = 0; i < num_sh; i++) {
179 | final long sectionHeaderOffset =
180 | (long)(sh_offset + (i * sh_entry_size));
181 | sectionHeaders[i] = new MemoizedObject() {
182 | public Object computeValue() {
183 | return new ELFSectionHeaderImpl(sectionHeaderOffset);
184 | }
185 | };
186 | }
187 |
188 | // // Set up the program headers
189 | // programHeaders = new MemoizedObject[num_sh];
190 | // for (int i = 0; i < num_sh; i++) {
191 | // final long programHeaderOffset =
192 | // (long)(ph_offset + (i * ph_entry_size));
193 | // programHeaders[i] = new MemoizedObject() {
194 | // public Object computeValue() {
195 | // return new ProgramHeaderImpl(programHeaderOffset);
196 | // }
197 | // };
198 | // }
199 | }
200 |
201 | public short getFileType() { return file_type; }
202 | public short getArch() { return arch; }
203 | public short getSectionHeaderSize() { return sh_entry_size; }
204 | public short getNumberOfSectionHeaders() { return num_sh; }
205 |
206 | // public short getProgramHeaderSize() { return ph_entry_size; }
207 | // public short getNumberOfProgramHeaders() { return num_ph; }
208 |
209 |
210 | /**
211 | * Returns the section header at the specified index. The section
212 | * header at index 0 is defined as being a undefined section. */
213 | public ELFSectionHeader getSectionHeader(int index) {
214 | return (ELFSectionHeader)sectionHeaders[index].getValue();
215 | }
216 |
217 | public ELFStringTable getSectionHeaderStringTable() {
218 | return getSectionHeader(sh_string_ndx).getStringTable();
219 | }
220 |
221 | public ELFStringTable getStringTable() {
222 | return findStringTableWithName(ELFSectionHeader.STRING_TABLE_NAME);
223 | }
224 |
225 | public ELFStringTable getDynamicStringTable() {
226 | return findStringTableWithName(
227 | ELFSectionHeader.DYNAMIC_STRING_TABLE_NAME);
228 | }
229 |
230 | private ELFStringTable findStringTableWithName(String tableName) {
231 | // Loop through the section header and look for a section
232 | // header with the name "tableName". We can ignore entry 0
233 | // since it is defined as being undefined.
234 | ELFSectionHeader sh = null;
235 | for (int i = 1; i < getNumberOfSectionHeaders(); i++) {
236 | sh = getSectionHeader(i);
237 | if (tableName.equals(sh.getName())) {
238 | return sh.getStringTable();
239 | }
240 | }
241 | return null;
242 | }
243 |
244 | /**
245 | * The ELFHashTable does not currently work. This method will
246 | * always return null. */
247 | public ELFHashTable getHashTable() {
248 | // if (hashTable != null) {
249 | // return hashTable;
250 | // }
251 | //
252 | // ELFHashTable ht = null;
253 | // for (int i = 1; i < getNumberOfSectionHeaders(); i++) {
254 | // if ((ht = getSectionHeader(i).getHashTable()) != null) {
255 | // hashTable = ht;
256 | // return hashTable;
257 | // }
258 | // }
259 | return null;
260 | }
261 |
262 | public ELFSectionHeader getSymbolTableSection() {
263 | if (symbolTableSection != null) {
264 | return symbolTableSection;
265 | }
266 |
267 | symbolTableSection =
268 | getSymbolTableSection(ELFSectionHeader.TYPE_SYMTBL);
269 | return symbolTableSection;
270 | }
271 |
272 | public ELFSectionHeader getDynamicSymbolTableSection() {
273 | if (dynamicSymbolTableSection != null) {
274 | return dynamicSymbolTableSection;
275 | }
276 |
277 | dynamicSymbolTableSection =
278 | getSymbolTableSection(ELFSectionHeader.TYPE_DYNSYM);
279 | return dynamicSymbolTableSection;
280 | }
281 |
282 | private ELFSectionHeader getSymbolTableSection(int type) {
283 | ELFSectionHeader sh = null;
284 | for (int i = 1; i < getNumberOfSectionHeaders(); i++) {
285 | sh = getSectionHeader(i);
286 | if (sh.getType() == type) {
287 | dynamicSymbolTableSection = sh;
288 | return sh;
289 | }
290 | }
291 | return null;
292 | }
293 |
294 | public ELFSymbol getELFSymbol(String symbolName) {
295 | if (symbolName == null) {
296 | return null;
297 | }
298 |
299 | // Check dynamic symbol table for symbol name.
300 | ELFSymbol symbol = null;
301 | int numSymbols = 0;
302 | ELFSectionHeader sh = getDynamicSymbolTableSection();
303 | if (sh != null) {
304 | numSymbols = sh.getNumberOfSymbols();
305 | for (int i = 0; i < Math.ceil(numSymbols / 2); i++) {
306 | if (symbolName.equals(
307 | (symbol = sh.getELFSymbol(i)).getName())) {
308 | return symbol;
309 | } else if (symbolName.equals(
310 | (symbol = sh.getELFSymbol(
311 | numSymbols - 1 - i)).getName())) {
312 | return symbol;
313 | }
314 | }
315 | }
316 |
317 | // Check symbol table for symbol name.
318 | sh = getSymbolTableSection();
319 | if (sh != null) {
320 | numSymbols = sh.getNumberOfSymbols();
321 | for (int i = 0; i < Math.ceil(numSymbols / 2); i++) {
322 | if (symbolName.equals(
323 | (symbol = sh.getELFSymbol(i)).getName())) {
324 | return symbol;
325 | } else if (symbolName.equals(
326 | (symbol = sh.getELFSymbol(
327 | numSymbols - 1 - i)).getName())) {
328 | return symbol;
329 | }
330 | }
331 | }
332 | return null;
333 | }
334 |
335 | public ELFSymbol getELFSymbol(long address) {
336 | // Check dynamic symbol table for address.
337 | ELFSymbol symbol = null;
338 | int numSymbols = 0;
339 | long value = 0L;
340 |
341 | ELFSectionHeader sh = getDynamicSymbolTableSection();
342 | if (sh != null) {
343 | numSymbols = sh.getNumberOfSymbols();
344 | for (int i = 0; i < numSymbols; i++) {
345 | symbol = sh.getELFSymbol(i);
346 | value = symbol.getValue();
347 | if (address >= value && address < value + symbol.getSize()) {
348 | return symbol;
349 | }
350 | }
351 | }
352 |
353 | // Check symbol table for symbol name.
354 | sh = getSymbolTableSection();
355 | if (sh != null) {
356 | numSymbols = sh.getNumberOfSymbols();
357 | for (int i = 0; i < numSymbols; i++) {
358 | symbol = sh.getELFSymbol(i);
359 | value = symbol.getValue();
360 | if (address >= value && address < value + symbol.getSize()) {
361 | return symbol;
362 | }
363 | }
364 | }
365 | return null;
366 | }
367 |
368 | // public ProgramHeader getProgramHeader(int index) {
369 | // return (ProgramHeader)programHeaders[index].getValue();
370 | // }
371 | }
372 |
373 |
374 | /**
375 | * Implementation of the ELFSectionHeader interface.
376 | */
377 | class ELFSectionHeaderImpl implements ELFSectionHeader {
378 | /** Index into the section header string table which gives the
379 | * name of the section. */
380 | private int name_ndx; // Elf32_Word
381 | /** Section content and semantics. */
382 | private int type; // Elf32_Word
383 | /** Flags. */
384 | private int flags; // Elf32_Word
385 | /** If the section will be in the memory image of a process this
386 | * will be the address at which the first byte of section will be
387 | * loaded. Otherwise, this value is 0. */
388 | private int address; // Elf32_Addr
389 | /** Offset from beginning of file to first byte of the section. */
390 | private int section_offset; // Elf32_Off
391 | /** Size in bytes of the section. TYPE_NOBITS is a special case. */
392 | private int size; // Elf32_Word
393 | /** Section header table index link. */
394 | private int link; // Elf32_Word
395 | /** Extra information determined by the section type. */
396 | private int info; // Elf32_Word
397 | /** Address alignment constraints for the section. */
398 | private int address_alignment; // Elf32_Word
399 | /** Size of a fixed-size entry, 0 if none. */
400 | private int entry_size; // Elf32_Word
401 |
402 | /** Memoized symbol table. */
403 | private MemoizedObject[] symbols;
404 | /** Memoized string table. */
405 | private MemoizedObject stringTable;
406 | /** Memoized hash table. */
407 | private MemoizedObject hashTable;
408 |
409 | /**
410 | * Reads the section header information located at offset.
411 | */
412 | ELFSectionHeaderImpl(long offset) throws ELFException {
413 | seek(offset);
414 | name_ndx = readInt();
415 | type = readInt();
416 | flags = readInt();
417 | address = readInt();
418 | section_offset = readInt();
419 | size = readInt();
420 | link = readInt();
421 | info = readInt();
422 | address_alignment = readInt();
423 | entry_size = readInt();
424 |
425 | switch (type) {
426 | case ELFSectionHeader.TYPE_NULL:
427 | break;
428 | case ELFSectionHeader.TYPE_PROGBITS:
429 | break;
430 | case ELFSectionHeader.TYPE_SYMTBL:
431 | case ELFSectionHeader.TYPE_DYNSYM:
432 | // Setup the symbol table.
433 | int num_entries = size / entry_size;
434 | symbols = new MemoizedObject[num_entries];
435 | for (int i = 0; i < num_entries; i++) {
436 | final int symbolOffset = section_offset +
437 | (i * entry_size);
438 | symbols[i] = new MemoizedObject() {
439 | public Object computeValue() {
440 | return new ELFSymbolImpl(symbolOffset,type);
441 | }
442 | };
443 | }
444 | break;
445 | case ELFSectionHeader.TYPE_STRTBL:
446 | // Setup the string table.
447 | final int strTableOffset = section_offset;
448 | final int strTableSize = size;
449 | stringTable = new MemoizedObject() {
450 | public Object computeValue() {
451 | return new ELFStringTableImpl(strTableOffset,
452 | strTableSize);
453 | }
454 | };
455 | break;
456 | case ELFSectionHeader.TYPE_RELO_EXPLICIT:
457 | break;
458 | case ELFSectionHeader.TYPE_HASH:
459 | final int hashTableOffset = section_offset;
460 | final int hashTableSize = size;
461 | hashTable = new MemoizedObject() {
462 | public Object computeValue() {
463 | return new ELFHashTableImpl(hashTableOffset,
464 | hashTableSize);
465 | }
466 | };
467 | break;
468 | case ELFSectionHeader.TYPE_DYNAMIC:
469 | break;
470 | case ELFSectionHeader.TYPE_NOTE:
471 | break;
472 | case ELFSectionHeader.TYPE_NOBITS:
473 | break;
474 | case ELFSectionHeader.TYPE_RELO:
475 | break;
476 | case ELFSectionHeader.TYPE_SHLIB:
477 | break;
478 | default:
479 | break;
480 | }
481 | }
482 |
483 | public int getType() {
484 | return type;
485 | }
486 |
487 | public int getNumberOfSymbols() {
488 | if (symbols != null) {
489 | return symbols.length;
490 | }
491 | return 0;
492 | }
493 |
494 | /**
495 | * Returns the ELFSymbol at the specified index. Index 0 is
496 | * reserved for the undefined ELF symbol. */
497 | public ELFSymbol getELFSymbol(int index) {
498 | return (ELFSymbol)symbols[index].getValue();
499 | }
500 |
501 | public ELFStringTable getStringTable() {
502 | if (stringTable != null) {
503 | return (ELFStringTable)stringTable.getValue();
504 | }
505 | return null;
506 | }
507 |
508 | /**
509 | * The ELFHashTable does not currently work. This method will
510 | * always return null. */
511 | public ELFHashTable getHashTable() {
512 | if (hashTable != null) {
513 | return (ELFHashTable)hashTable.getValue();
514 | }
515 | return null;
516 | }
517 |
518 | public String getName() {
519 | if (name_ndx == 0) {
520 | return null;
521 | }
522 |
523 | ELFStringTable tbl = getHeader().getSectionHeaderStringTable();
524 | return tbl.get(name_ndx);
525 | }
526 |
527 | public int getLink() {
528 | return link;
529 | }
530 |
531 | public int getOffset() {
532 | return section_offset;
533 | }
534 | }
535 |
536 |
537 | // class ProgramHeaderImpl implements ProgramHeader {
538 | // /** Defines the kind of segment this element describes. */
539 | // private int type; // Elf32_Word
540 | // /** Offset from the beginning of the file. */
541 | // private int offset; // Elf32_Off
542 | // /** Virtual address at which the first byte of the segment
543 | // * resides in memory. */
544 | // private int virtual_address; // Elf32_Addr
545 | // /** Reserved for the physical address of the segment on systems
546 | // * where physical addressinf is relevant. */
547 | // private int physical_address; // Elf32_addr
548 | // /** File image size of segment in bytes, may be 0. */
549 | // private int file_size; // Elf32_Word
550 | // /** Memory image size of segment in bytes, may be 0. */
551 | // private int mem_size; // Elf32_Word
552 | // /** Flags relevant to this segment. Values for flags are defined
553 | // * in ELFSectionHeader. */
554 | // private int flags; // Elf32_Word
555 | // private int alignment; // Elf32_Word
556 | //
557 | // private MemoizedObject[] symbols;
558 | //
559 | // ProgramHeaderImpl(long offset) throws ELFException {
560 | // seek(offset);
561 | // type = readInt();
562 | // this.offset = readInt();
563 | // virtual_address = readInt();
564 | // physical_address = readInt();
565 | // file_size = readInt();
566 | // mem_size = readInt();
567 | // flags = readInt();
568 | // alignment = readInt();
569 | //
570 | // switch (type) {
571 | // case ELFSectionHeader.TYPE_NULL:
572 | // break;
573 | // case ELFSectionHeader.TYPE_PROGBITS:
574 | // break;
575 | // case ELFSectionHeader.TYPE_SYMTBL:
576 | // case ELFSectionHeader.TYPE_DYNSYM:
577 | // break;
578 | // case ELFSectionHeader.TYPE_STRTBL:
579 | // // Setup the string table.
580 | // final int strTableOffset = section_offset;
581 | // final int strTableSize = size;
582 | // stringTable = new MemoizedObject() {
583 | // public Object computeValue() {
584 | // return new ELFStringTableImpl(strTableOffset,
585 | // strTableSize);
586 | // }
587 | // };
588 | // new ELFStringTableImpl(offset, file_size);
589 | // break;
590 | // case ELFSectionHeader.TYPE_RELO_EXPLICIT:
591 | // break;
592 | // case ELFSectionHeader.TYPE_HASH:
593 | // break;
594 | // case ELFSectionHeader.TYPE_DYNAMIC:
595 | // break;
596 | // case ELFSectionHeader.TYPE_NOTE:
597 | // break;
598 | // case ELFSectionHeader.TYPE_NOBITS:
599 | // break;
600 | // case ELFSectionHeader.TYPE_RELO:
601 | // break;
602 | // case ELFSectionHeader.TYPE_SHLIB:
603 | // break;
604 | // default:
605 | // break;
606 | // }
607 | // }
608 | //
609 | // public int getType() {
610 | // return type;
611 | // }
612 | // }
613 |
614 |
615 | /**
616 | * Implementation of the ELFSymbol interface.
617 | */
618 | class ELFSymbolImpl implements ELFSymbol {
619 | /** Index into the symbol string table that holds the character
620 | * representation of the symbols. 0 means the symbol has no
621 | * character name. */
622 | private int name_ndx; // Elf32_Word
623 | /** Value of the associated symbol. This may be an address or
624 | * an absolute value. */
625 | private int value; // Elf32_Addr
626 | /** Size of the symbol. 0 if the symbol has no size or the size
627 | * is unknown. */
628 | private int size; // Elf32_Word
629 | /** Specifies the symbol type and beinding attributes. */
630 | private byte info; // unsigned char
631 | /** Currently holds the value of 0 and has no meaning. */
632 | private byte other; // unsigned char
633 | /** Index to the associated section header. This value will need
634 | * to be read as an unsigned short if we compare it to
635 | * ELFSectionHeader.NDX_LORESERVE and ELFSectionHeader.NDX_HIRESERVE. */
636 | private short section_header_ndx; // Elf32_Half
637 |
638 | private int section_type;
639 |
640 | /** Offset from the beginning of the file to this symbol. */
641 | private long offset;
642 |
643 | ELFSymbolImpl(long offset, int section_type) throws ELFException {
644 | seek(offset);
645 | this.offset = offset;
646 | name_ndx = readInt();
647 | value = readInt();
648 | size = readInt();
649 | info = readByte();
650 | other = readByte();
651 | section_header_ndx = readShort();
652 |
653 | this.section_type = section_type;
654 |
655 | switch (getType()) {
656 | case TYPE_NOOBJECT:
657 | break;
658 | case TYPE_OBJECT:
659 | break;
660 | case TYPE_FUNCTION:
661 | break;
662 | case TYPE_SECTION:
663 | break;
664 | case TYPE_FILE:
665 | break;
666 | case TYPE_LOPROC:
667 | break;
668 | case TYPE_HIPROC:
669 | break;
670 | default:
671 | break;
672 | }
673 | }
674 |
675 | public int getBinding() { return info >> 4; }
676 | public int getType() { return info & 0x0F; }
677 | public long getOffset() { return offset; }
678 |
679 | public String getName() {
680 | // Check to make sure this symbol has a name.
681 | if (name_ndx == 0) {
682 | return null;
683 | }
684 |
685 | // Retrieve the name of the symbol from the correct string
686 | // table.
687 | String symbol_name = null;
688 | if (section_type == ELFSectionHeader.TYPE_SYMTBL) {
689 | symbol_name = getHeader().getStringTable().get(name_ndx);
690 | } else if (section_type == ELFSectionHeader.TYPE_DYNSYM) {
691 | symbol_name =
692 | getHeader().getDynamicStringTable().get(name_ndx);
693 | }
694 | return symbol_name;
695 | }
696 |
697 | public long getValue() {
698 | return value;
699 | }
700 |
701 | public int getSize() {
702 | return size;
703 | }
704 | }
705 |
706 | /**
707 | * Implementation of the ELFStringTable interface.
708 | */
709 | class ELFStringTableImpl implements ELFStringTable {
710 | /** The string table data. */
711 | private byte data[];
712 | private int numStrings;
713 |
714 | /**
715 | * Reads all the strings from [offset, length].
716 | */
717 | ELFStringTableImpl(long offset, int length) throws ELFException {
718 | seek(offset);
719 | data = new byte[length];
720 | int bytesRead = readBytes(data);
721 | if (bytesRead != length) {
722 | throw new ELFException("Error reading string table (read " +
723 | bytesRead + "bytes, expected to " +
724 | "read " + data.length + "bytes).");
725 | }
726 |
727 | // Count the strings.
728 | numStrings = 0;
729 | for (int ptr = 0; ptr < data.length; ptr++) {
730 | if (data[ptr] == '\0') {
731 | numStrings++;
732 | }
733 | }
734 | }
735 |
736 | public String get(int index) {
737 | int startPtr = index;
738 | int endPtr = index;
739 | while (data[endPtr] != '\0') {
740 | endPtr++;
741 | }
742 | return new String(data, startPtr, endPtr - startPtr);
743 | }
744 |
745 | public int getNumStrings() {
746 | return numStrings;
747 | }
748 | }
749 |
750 |
751 | /** Implementation of the ELFHashTable. */
752 | class ELFHashTableImpl implements ELFHashTable {
753 | private int num_buckets;
754 | private int num_chains;
755 |
756 | // These could probably be memoized.
757 | private int buckets[];
758 | private int chains[];
759 |
760 | ELFHashTableImpl(long offset, int length) throws ELFException {
761 | seek(offset);
762 | num_buckets = readInt();
763 | num_chains = readInt();
764 |
765 | buckets = new int[num_buckets];
766 | chains = new int[num_chains];
767 | // Read the bucket data.
768 | for (int i = 0; i < num_buckets; i++) {
769 | buckets[i] = readInt();
770 | }
771 |
772 | // Read the chain data.
773 | for (int i = 0; i < num_chains; i++) {
774 | chains[i] = readInt();
775 | }
776 |
777 | // Make sure that the amount of bytes we were supposed to read
778 | // was what we actually read.
779 | int actual = num_buckets * 4 + num_chains * 4 + 8;
780 | if (length != actual) {
781 | throw new ELFException("Error reading string table (read " +
782 | actual + "bytes, expected to " +
783 | "read " + length + "bytes).");
784 | }
785 | }
786 |
787 | /**
788 | * This method doesn't work every time and is unreliable. Use
789 | * ELFSection.getELFSymbol(String) to retrieve symbols by name.
790 | * NOTE: since this method is currently broken it will always
791 | * return null. */
792 | public ELFSymbol getSymbol(String symbolName) {
793 | // if (symbolName == null) {
794 | // return null;
795 | // }
796 | //
797 | // long hash = 0;
798 | // long g = 0;
799 | //
800 | // for (int i = 0; i < symbolName.length(); i++) {
801 | // hash = (hash << 4) + symbolName.charAt(i);
802 | // if ((g = hash & 0xf0000000) != 0) {
803 | // hash ^= g >>> 24;
804 | // }
805 | // hash &= ~g;
806 | // }
807 | //
808 | // ELFSymbol symbol = null;
809 | // ELFSectionHeader dyn_sh =
810 | // getHeader().getDynamicSymbolTableSection();
811 | // int index = (int)hash % num_buckets;
812 | // while(index != 0) {
813 | // symbol = dyn_sh.getELFSymbol(index);
814 | // if (symbolName.equals(symbol.getName())) {
815 | // break;
816 | // }
817 | // symbol = null;
818 | // index = chains[index];
819 | // }
820 | // return symbol;
821 | return null;
822 | }
823 | }
824 |
825 |
826 | public void close() throws ELFException {
827 | try {
828 | file.close();
829 | } catch (IOException e) {
830 | throw new ELFException(e);
831 | }
832 | }
833 |
834 | void seek(long offset) throws ELFException {
835 | try {
836 | file.seek(offset);
837 | } catch (IOException e) {
838 | throw new ELFException(e);
839 | }
840 | }
841 |
842 | long getFilePointer() throws ELFException {
843 | try {
844 | return file.getFilePointer();
845 | } catch (IOException e) {
846 | throw new ELFException(e);
847 | }
848 | }
849 |
850 | byte readByte() throws ELFException {
851 | try {
852 | return file.readByte();
853 | } catch (IOException e) {
854 | throw new ELFException(e);
855 | }
856 | }
857 |
858 | int readBytes(byte[] b) throws ELFException {
859 | try {
860 | return file.read(b);
861 | } catch (IOException e) {
862 | throw new ELFException(e);
863 | }
864 | }
865 |
866 | short readShort() throws ELFException {
867 | try {
868 | short val;
869 | switch (ident[NDX_ENCODING]) {
870 | case DATA_LSB:
871 | val = byteSwap(file.readShort());
872 | break;
873 | case DATA_MSB:
874 | val = file.readShort();
875 | break;
876 | default:
877 | throw new ELFException("Invalid encoding.");
878 | }
879 | return val;
880 | } catch (IOException e) {
881 | throw new ELFException(e);
882 | }
883 | }
884 |
885 | int readInt() throws ELFException {
886 | try {
887 | int val;
888 | switch (ident[NDX_ENCODING]) {
889 | case DATA_LSB:
890 | val = byteSwap(file.readInt());
891 | break;
892 | case DATA_MSB:
893 | val = file.readInt();
894 | break;
895 | default:
896 | throw new ELFException("Invalid encoding.");
897 | }
898 | return val;
899 | } catch (IOException e) {
900 | throw new ELFException(e);
901 | }
902 | }
903 |
904 | long readLong() throws ELFException {
905 | try {
906 | long val;
907 | switch (ident[NDX_ENCODING]) {
908 | case DATA_LSB:
909 | val = byteSwap(file.readLong());
910 | break;
911 | case DATA_MSB:
912 | val = file.readLong();
913 | break;
914 | default:
915 | throw new ELFException("Invalid encoding.");
916 | }
917 | return val;
918 | } catch (IOException e) {
919 | throw new ELFException(e);
920 | }
921 | }
922 |
923 | /** Signed byte utility functions used for converting from big-endian
924 | * (MSB) to little-endian (LSB). */
925 | short byteSwap(short arg) {
926 | return (short) ((arg << 8) | ((arg >>> 8) & 0xFF));
927 | }
928 |
929 | int byteSwap(int arg) {
930 | return (((int) byteSwap((short) arg)) << 16) |
931 | (((int) (byteSwap((short) (arg >>> 16)))) & 0xFFFF);
932 | }
933 |
934 | long byteSwap(long arg) {
935 | return ((((long) byteSwap((int) arg)) << 32) |
936 | (((long) byteSwap((int) (arg >>> 32))) & 0xFFFFFFFF));
937 | }
938 |
939 |
940 | /* Unsigned byte utility functions. Since java does not have unsigned
941 | * data types we must convert values manually and we must return
942 | * unsigned values in a larger data type. Therefore we can only have
943 | * unsigned values for byte, short, and int. */
944 | short readUnsignedByte() throws ELFException {
945 | try {
946 | return unsignedByte(file.readByte());
947 | } catch (IOException e) {
948 | throw new ELFException(e);
949 | }
950 | }
951 |
952 | int readUnsignedShort() throws ELFException {
953 | try {
954 | int val;
955 | switch (ident[NDX_ENCODING]) {
956 | case DATA_LSB:
957 | val = unsignedByteSwap(file.readShort());
958 | break;
959 | case DATA_MSB:
960 | val = unsignedByte(file.readShort());
961 | break;
962 | default:
963 | throw new ELFException("Invalid encoding.");
964 | }
965 | return val;
966 | } catch (IOException e) {
967 | throw new ELFException(e);
968 | }
969 | }
970 |
971 | long readUnsignedInt() throws ELFException {
972 | try {
973 | long val;
974 | switch (ident[NDX_ENCODING]) {
975 | case DATA_LSB:
976 | val = unsignedByteSwap(file.readInt());
977 | break;
978 | case DATA_MSB:
979 | val = unsignedByte(file.readInt());
980 | break;
981 | default:
982 | throw new ELFException("Invalid encoding.");
983 | }
984 | return val;
985 | } catch (IOException e) {
986 | throw new ELFException(e);
987 | }
988 | }
989 |
990 | /** Returns the unsigned value of the byte. */
991 | short unsignedByte(byte arg) {
992 | return (short)(arg & 0x00FF);
993 | }
994 |
995 | /** Returns a big-endian unsigned representation of the short. */
996 | int unsignedByte(short arg) {
997 | int val;
998 | if (arg >= 0) {
999 | val = arg;
1000 | } else {
1001 | val = (int)(((int)unsignedByte((byte)(arg >>> 8)) << 8) |
1002 | ((byte)arg));
1003 | }
1004 | return val;
1005 | }
1006 |
1007 | /** Returns a big-endian unsigned representation of the int. */
1008 | long unsignedByte(int arg) {
1009 | long val;
1010 | if (arg >= 0) {
1011 | val = arg;
1012 | } else {
1013 | val = (long)(((long)unsignedByte((short)(arg >>> 16)) << 16) |
1014 | ((short)arg));
1015 | }
1016 | return val;
1017 | }
1018 |
1019 | /** Unsigned byte utility functions used for converting from big-endian
1020 | * (MSB) to little-endian (LSB). */
1021 | int unsignedByteSwap(short arg) {
1022 | return (int)(((int)unsignedByte((byte)arg)) << 8) |
1023 | ((int)unsignedByte((byte)(arg >>> 8)));
1024 | }
1025 |
1026 | long unsignedByteSwap(int arg) {
1027 | return (long)(((long)unsignedByteSwap((short)arg)) << 16) |
1028 | ((long)unsignedByteSwap((short)(arg >>> 16)));
1029 | }
1030 | }
1031 |
1032 | public static void main(String args[]) {
1033 | if (args.length != 1) {
1034 | System.out.println("Usage: java ELFFileParser ");
1035 | System.exit(0);
1036 | }
1037 |
1038 | // Parse the file.
1039 | ELFFile elfFile = ELFFileParser.getParser().parse(args[0]);
1040 |
1041 | ELFHeader elfHeader = elfFile.getHeader();
1042 | System.out.println("ELF File: " + args[0]);
1043 |
1044 | System.out.println("ELF object size: " +
1045 | ((elfFile.getObjectSize() == 0) ? "Invalid Object Size" :
1046 | (elfFile.getObjectSize() == 1) ? "32-bit" : "64-bit"));
1047 | System.out.println("ELF data encoding: " +
1048 | ((elfFile.getEncoding() == 0) ? "Invalid Data Encoding" :
1049 | (elfFile.getEncoding() == 1) ? "LSB" : "MSB"));
1050 |
1051 | int h = elfHeader.getNumberOfSectionHeaders();
1052 | System.out.println("--> Start: reading " + h + " section headers.");
1053 | for (int i = 0; i < elfHeader.getNumberOfSectionHeaders(); i++) {
1054 | ELFSectionHeader sh = elfHeader.getSectionHeader(i);
1055 | String str = sh.getName();
1056 | System.out.println("----> Start: Section (" + i + ") " + str);
1057 |
1058 | int num = 0;
1059 | if ((num = sh.getNumberOfSymbols()) != 0) {
1060 | System.out.println("------> Start: reading " + num + " symbols.");
1061 | for (int j = 0; j < num ; j++) {
1062 | ELFSymbol sym = sh.getELFSymbol(j);
1063 | //String name = sym.getName();
1064 | //if (name != null) {
1065 | // System.out.println(name);
1066 | //}
1067 | }
1068 | System.out.println("<------ End: reading " + num + " symbols.");
1069 | }
1070 | ELFStringTable st;
1071 | if (sh.getType() == ELFSectionHeader.TYPE_STRTBL) {
1072 | System.out.println("------> Start: reading string table.");
1073 | st = sh.getStringTable();
1074 | System.out.println("<------ End: reading string table.");
1075 | }
1076 | if (sh.getType() == ELFSectionHeader.TYPE_HASH) {
1077 | System.out.println("------> Start: reading hash table.");
1078 | sh.getHashTable();
1079 | System.out.println("<------ End: reading hash table.");
1080 | }
1081 | System.out.println("<---- End: Section (" + i + ") " + str);
1082 | }
1083 | System.out.println("<-- End: reading " + h + " section headers.");
1084 | /*
1085 | h = elfHeader.getNumberOfProgramHeaders();
1086 | System.out.println("--> Start: reading " + h + " program headers.");
1087 | for (int i = 0; i < elfHeader.getNumberOfProgramHeaders(); i++) {
1088 | elfHeader.getProgramHeader(i);
1089 | }
1090 | System.out.println("<-- End: reading " + h + " program headers.");
1091 | */
1092 | elfFile.close();
1093 | }
1094 | }
--------------------------------------------------------------------------------
/src/com/bluth/readelf/ELFHashTable.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2001, Oracle and/or its affiliates. All rights reserved.
3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 | *
5 | * This code is free software; you can redistribute it and/or modify it
6 | * under the terms of the GNU General Public License version 2 only, as
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,
20 | * CA 94065 USA or visit www.oracle.com if you need additional information or
21 | * have any questions.
22 | *
23 | */
24 |
25 | package com.bluth.readelf;
26 |
27 | public interface ELFHashTable {
28 | /**
29 | * Returns the ELFSymbol that has the specified name or null if no symbol
30 | * with that name exists. NOTE: Currently this method does not work and
31 | * willl always return null.
32 | */
33 | public ELFSymbol getSymbol(String symbolName);
34 | }
--------------------------------------------------------------------------------
/src/com/bluth/readelf/ELFHeader.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2001, 2003, Oracle and/or its affiliates. All rights reserved.
3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 | *
5 | * This code is free software; you can redistribute it and/or modify it
6 | * under the terms of the GNU General Public License version 2 only, as
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,
20 | * CA 94065 USA or visit www.oracle.com if you need additional information or
21 | * have any questions.
22 | *
23 | */
24 |
25 | package com.bluth.readelf;
26 |
27 | import java.io.FileInputStream;
28 |
29 | /**
30 | * This is a Java class that represents a ELF file header.
31 | *
32 | * @author Joshua W. Outwater
33 | */
34 | public interface ELFHeader {
35 | /** No file type. */
36 | public static final int FT_NONE = 0;
37 | /** Relocatable file type. */
38 | public static final int FT_REL = 1;
39 | /** Executable file type. */
40 | public static final int FT_EXEC = 2;
41 | /** Shared object file type. */
42 | public static final int FT_DYN = 3;
43 | /** Core file file type. */
44 | public static final int FT_CORE = 4;
45 | /** Processor specific. */
46 | public static final int FT_LOCPROC = 0xff00;
47 | /** Processor specific. */
48 | public static final int FT_HICPROC = 0xffff;
49 |
50 | /** No architecture type. */
51 | public static final int ARCH_NONE = 0;
52 | /** AT&T architecture type. */
53 | public static final int ARCH_ATT = 1;
54 | /** SPARC architecture type. */
55 | public static final int ARCH_SPARC = 2;
56 | /** Intel 386 architecture type. */
57 | public static final int ARCH_i386 = 3;
58 | /** Motorolla 68000 architecture type. */
59 | public static final int ARCH_68k = 4;
60 | /** Motorolla 88000 architecture type. */
61 | public static final int ARCH_88k = 5;
62 | /** Intel 860 architecture type. */
63 | public static final int ARCH_i860 = 7;
64 | /** MIPS architecture type. */
65 | public static final int ARCH_MIPS = 8;
66 |
67 | /** Returns a file type which is defined by the file type constants. */
68 | public short getFileType();
69 | /** Returns one of the architecture constants. */
70 | public short getArch();
71 | /** Returns the size of a section header. */
72 | public short getSectionHeaderSize();
73 | /** Returns the number of section headers. */
74 | public short getNumberOfSectionHeaders();
75 | /** Returns the section header at the specified index. The section header
76 | * at index 0 is the undefined section header. */
77 | public ELFSectionHeader getSectionHeader(int index);
78 | /** Returns the section header string table associated with this ELF
79 | * file. */
80 | public ELFStringTable getSectionHeaderStringTable();
81 | /** Returns the string table associated with this ELF file. */
82 | public ELFStringTable getStringTable();
83 | /** Returns the dynamic string table associated with this ELF file, or null
84 | * if one does not exist. */
85 | public ELFStringTable getDynamicStringTable();
86 | /** Returns the hash table associated with this ELF file, or null if one
87 | * does not exist. NOTE: Currently the ELFHashTable does not work so this
88 | * method will always return null. */
89 | public ELFHashTable getHashTable();
90 | /** Returns the symbol table associated with this ELF file, or null if one
91 | * does not exist. */
92 | public ELFSectionHeader getSymbolTableSection();
93 | /** Returns the dynamic symbol table associated with this ELF file, or null
94 | * if one does not exist. */
95 | public ELFSectionHeader getDynamicSymbolTableSection();
96 | /** Returns the elf symbol with the specified name or null if one is not
97 | * found. */
98 | public ELFSymbol getELFSymbol(String name);
99 | /** Returns the elf symbol with the specified address or null if one is not
100 | * found. 'address' is relative to base of shared object for .so's. */
101 | public ELFSymbol getELFSymbol(long address);
102 | /** Returns the size of a program header. */
103 | //public short getProgramHeaderSize();
104 | /** Returns the number of program headers. */
105 | //public short getNumberOfProgramHeaders();
106 | /** Returns the program header at the specified index. */
107 | //public ProgramHeader getProgramHeader(int index);
108 | }
--------------------------------------------------------------------------------
/src/com/bluth/readelf/ELFProgramHeader.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2001, Oracle and/or its affiliates. All rights reserved.
3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 | *
5 | * This code is free software; you can redistribute it and/or modify it
6 | * under the terms of the GNU General Public License version 2 only, as
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,
20 | * CA 94065 USA or visit www.oracle.com if you need additional information or
21 | * have any questions.
22 | *
23 | */
24 |
25 | package com.bluth.readelf;
26 |
27 | /**
28 | * This is the interface definintion for a ProgramHeader in an ELF file.
29 | * Program headers contain system information necessary for preparing a program
30 | * for execution.
31 | */
32 | public interface ELFProgramHeader {
33 | /** Type defining that the array element is unused. Other member values
34 | * are undefined. */
35 | public static final int TYPE_NULL = 0;
36 | /** Type defining that the array element specifies a loadable segment. */
37 | public static final int TYPE_LOAD = 1;
38 | public static final int TYPE_DYNAMIC = 2;
39 | public static final int TYPE_INTERP = 3;
40 | public static final int TYPE_NOTE = 4;
41 | public static final int TYPE_SHLIB = 5;
42 | public static final int TYPE_PHDR = 6;
43 | public static final int TYPE_LOPROC = 0x70000000;
44 | public static final int TYPE_HIPROC = 0x7fffffff;
45 |
46 | public int getType();
47 | }
--------------------------------------------------------------------------------
/src/com/bluth/readelf/ELFSectionHeader.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2001, Oracle and/or its affiliates. All rights reserved.
3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 | *
5 | * This code is free software; you can redistribute it and/or modify it
6 | * under the terms of the GNU General Public License version 2 only, as
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,
20 | * CA 94065 USA or visit www.oracle.com if you need additional information or
21 | * have any questions.
22 | *
23 | */
24 |
25 | package com.bluth.readelf;
26 |
27 | public interface ELFSectionHeader {
28 | /** Undefined section header index. */
29 | public static final int NDX_UNDEFINED = 0;
30 | /** Lower bound section header index. */
31 | public static final int NDX_LORESERVE = 0xff00;
32 | /** Lower bound section header index reserved for processor specific
33 | * semantics. */
34 | public static final int NDX_LOPROC = 0xff00;
35 | /** Upper bound section header index reserved for processor specific
36 | * semantics. */
37 | public static final int NDX_HIPROC = 0xff1f;
38 | /** Absolute values for the corresponding reference. Symbols defined
39 | * relative to section number NDX_ABS have absolute values and are not
40 | * affected by relocation. */
41 | public static final int NDX_ABS = 0xfff1;
42 | /** Symbols defined relative to this section are common symbols, such
43 | * as FORTRAN, COMMON or unallocated C external variables. */
44 | public static final int NDX_COMMON = 0xfff2;
45 | /** Upper bound section header index. */
46 | public static final int NDX_HIRESERVE = 0xffff;
47 |
48 | /** Section is inactive. */
49 | public static final int TYPE_NULL = 0;
50 | /** Section holds information defined by the program. */
51 | public static final int TYPE_PROGBITS = 1;
52 | /** Section holds symbol table information for link editing. It may also
53 | * be used to store symbols for dynamic linking. */
54 | public static final int TYPE_SYMTBL = 2;
55 | /** Section holds string table information. */
56 | public static final int TYPE_STRTBL = 3;
57 | /** Section holds relocation entries with explicit addends. */
58 | public static final int TYPE_RELO_EXPLICIT = 4;
59 | /** Section holds symbol hash table. */
60 | public static final int TYPE_HASH = 5;
61 | /** Section holds information for dynamic linking. */
62 | public static final int TYPE_DYNAMIC = 6;
63 | /** Section holds information that marks the file. */
64 | public static final int TYPE_NOTE = 7;
65 | /** Section occupies no space but resembles TYPE_PROGBITS. */
66 | public static final int TYPE_NOBITS = 8;
67 | /** Section holds relocation entries without explicit addends. */
68 | public static final int TYPE_RELO = 9;
69 | /** Section is reserved but has unspecified semantics. */
70 | public static final int TYPE_SHLIB = 10;
71 | /** Section holds a minimum set of dynamic linking symbols. */
72 | public static final int TYPE_DYNSYM = 11;
73 | /** Lower bound section type that contains processor specific semantics. */
74 | public static final int TYPE_LOPROC = 0x70000000;
75 | /** Upper bound section type that contains processor specific semantics. */
76 | public static final int TYPE_HIPROC = 0x7fffffff;
77 | /** Lower bound of the range of indexes reserved for application
78 | * programs. */
79 | public static final int TYPE_LOUSER = 0x80000000;
80 | /** Upper bound of the range of indexes reserved for application
81 | * programs. */
82 | public static final int TYPE_HIUSER = 0xffffffff;
83 |
84 | /** Flag informing that this section contains data that should be writable
85 | * during process execution. */
86 | public static final int FLAG_WRITE = 0x1;
87 | /** Flag informing that section occupies memory during process
88 | * execution. */
89 | public static final int FLAG_ALLOC = 0x2;
90 | /** Flag informaing that section contains executable machine
91 | * instructions. */
92 | public static final int FLAG_EXEC_INSTR = 0x4;
93 | /** Flag informing that all the bits in the mask are reserved for processor
94 | * specific semantics. */
95 | public static final int FLAG_MASK = 0xf0000000;
96 |
97 | /** Section header name identifying the section as a string table. */
98 | public static final String STRING_TABLE_NAME = ".strtab";
99 | /** Section header name identifying the section as a dynamic string
100 | * table. */
101 | public static final String DYNAMIC_STRING_TABLE_NAME = ".dynstr";
102 | /** Returns the type of section header. */
103 | public int getType();
104 | /** Returns the number of symbols in this section or 0 if none. */
105 | public int getNumberOfSymbols();
106 | /** Returns the symbol at the specified index. The ELF symbol at index 0
107 | * is the undefined symbol. */
108 | public ELFSymbol getELFSymbol(int index);
109 | /** Returns the string table for this section or null if one does not
110 | * exist. */
111 | public ELFStringTable getStringTable();
112 | /** Returns the hash table for this section or null if one does not
113 | * exist. NOTE: currently the ELFHashTable does not work and this method
114 | * will always return null. */
115 | public ELFHashTable getHashTable();
116 | public int getLink();
117 | /** Returns the name of the section or null if the section has no name. */
118 | public String getName();
119 | /** Returns the offset in bytes to the beginning of the section. */
120 | public int getOffset();
121 | }
--------------------------------------------------------------------------------
/src/com/bluth/readelf/ELFStringTable.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2001, Oracle and/or its affiliates. All rights reserved.
3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 | *
5 | * This code is free software; you can redistribute it and/or modify it
6 | * under the terms of the GNU General Public License version 2 only, as
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,
20 | * CA 94065 USA or visit www.oracle.com if you need additional information or
21 | * have any questions.
22 | *
23 | */
24 |
25 | package com.bluth.readelf;
26 |
27 | public interface ELFStringTable {
28 | public String get(int index);
29 | public int getNumStrings();
30 | }
--------------------------------------------------------------------------------
/src/com/bluth/readelf/ELFSymbol.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2001, 2003, Oracle and/or its affiliates. All rights reserved.
3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 | *
5 | * This code is free software; you can redistribute it and/or modify it
6 | * under the terms of the GNU General Public License version 2 only, as
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,
20 | * CA 94065 USA or visit www.oracle.com if you need additional information or
21 | * have any questions.
22 | *
23 | */
24 |
25 | package com.bluth.readelf;
26 |
27 | public interface ELFSymbol {
28 | /** Binding specifying that local symbols are not visible outside the
29 | * object file that contains its definition. */
30 | public static final int BINDING_LOCAL = 0;
31 | /** Binding specifying that global symbols are visible to all object files
32 | * being combined. */
33 | public static final int BINDING_GLOBAL = 1;
34 | /** Binding secifying that the symbol resembles a global symbol, but has
35 | * a lower precedence. */
36 | public static final int BINDING_WEAK = 2;
37 | /** Lower bound binding values reserverd for processor specific
38 | * semantics. */
39 | public static final int BINDING_LOPROC = 13;
40 | /** Upper bound binding values reserverd for processor specific
41 | * semantics. */
42 | public static final int BINDING_HIPROC = 15;
43 |
44 | /** Type specifying that the symbol is unspecified. */
45 | public static final byte TYPE_NOOBJECT = 0;
46 | /** Type specifying that the symbol is associated with an object. */
47 | public static final byte TYPE_OBJECT = 1;
48 | /** Type specifying that the symbol is associated with a function. */
49 | public static final byte TYPE_FUNCTION = 2;
50 | /** Type specifying that the symbol is associated with a section. Symbol
51 | * table entries of this type exist for relocation and normally have the
52 | * binding BINDING_LOCAL. */
53 | public static final byte TYPE_SECTION = 3;
54 | /** Type defining that the symbol is associated with a file. */
55 | public static final byte TYPE_FILE = 4;
56 | /** Lower bound type reserved for processor specific semantics. */
57 | public static final byte TYPE_LOPROC = 13;
58 | /** Upper bound type reserved for processor specific semantics. */
59 | public static final byte TYPE_HIPROC = 15;
60 |
61 | /** Returns the location from the beginning of the file to the symbol. */
62 | public long getOffset();
63 | /** Returns the name of the symbol or null if the symbol has no name. */
64 | public String getName();
65 | /** Returns the binding for this symbol. */
66 | public int getBinding();
67 | /** Returns the symbol type. */
68 | public int getType();
69 |
70 | /** Value of the associated symbol. This may be a relativa address for .so
71 | * or absolute address for other ELFs. */
72 | public long getValue();
73 |
74 | /** Size of the symbol. 0 if the symbol has no size or the size
75 | * is unknown. */
76 | public int getSize();
77 | }
--------------------------------------------------------------------------------
/src/com/bluth/readelf/MemoizedObject.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2000, Oracle and/or its affiliates. All rights reserved.
3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 | *
5 | * This code is free software; you can redistribute it and/or modify it
6 | * under the terms of the GNU General Public License version 2 only, as
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 |
25 | package com.bluth.readelf;
26 |
27 | /** A memoized object. Override {@link #computeValue} in subclasses;
28 | call {@link #getValue} in using code. */
29 |
30 | public abstract class MemoizedObject {
31 | private boolean computed;
32 | private Object value;
33 |
34 | /** Should compute the value of this memoized object. This will only
35 | be called once, upon the first call to {@link #getValue}. */
36 | protected abstract Object computeValue();
37 |
38 | /** Public accessor for the memoized value. */
39 | public Object getValue() {
40 | if (!computed) {
41 | value = computeValue();
42 | computed = true;
43 | }
44 | return value;
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/src/com/bluth/readelf/RandomAccessFileDataSource.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2000, 2001, Oracle and/or its affiliates. All rights reserved.
3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 | *
5 | * This code is free software; you can redistribute it and/or modify it
6 | * under the terms of the GNU General Public License version 2 only, as
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,
20 | * CA 94065 USA or visit www.oracle.com if you need additional information or
21 | * have any questions.
22 | *
23 | */
24 |
25 | package com.bluth.readelf;
26 |
27 | import java.io.*;
28 |
29 | /* This class is used by the Windows COFF and Posix ELF implementations. */
30 | public class RandomAccessFileDataSource implements DataSource {
31 | public RandomAccessFileDataSource(RandomAccessFile file) {
32 | this.file = file;
33 | }
34 |
35 | public byte readByte() throws IOException { return file.readByte(); }
36 | public short readShort() throws IOException { return file.readShort(); }
37 | public int readInt() throws IOException { return file.readInt(); }
38 | public long readLong() throws IOException { return file.readLong(); }
39 | public int read(byte[] b) throws IOException { return file.read(b); }
40 | public void seek(long pos) throws IOException { file.seek(pos); }
41 | public long getFilePointer() throws IOException { return file.getFilePointer(); }
42 | public void close() throws IOException { file.close(); }
43 |
44 | private RandomAccessFile file;
45 | }
--------------------------------------------------------------------------------