2 * This file is part of the sigrok-androidutils project.
4 * Copyright (C) 2014 Marcus Comstedt <marcus@mc.pp.se>
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 package org.sigrok.androidutils.ant;
23 import java.io.IOException;
24 import java.io.RandomAccessFile;
28 public static final int SHT_NULL = 0;
29 public static final int SHT_PROGBITS = 1;
30 public static final int SHT_SYMTAB = 2;
31 public static final int SHT_STRTAB = 3;
32 public static final int SHT_RELA = 4;
33 public static final int SHT_HASH = 5;
34 public static final int SHT_DYNAMIC = 6;
35 public static final int SHT_NOTE = 7;
36 public static final int SHT_NOBITS = 8;
37 public static final int SHT_REL = 9;
38 public static final int SHT_SHLIB = 10;
39 public static final int SHT_DYNSYM = 11;
40 public static final int SHT_INIT_ARRAY = 14;
41 public static final int SHT_FINI_ARRAY = 15;
42 public static final int SHT_PREINIT_ARRAY = 16;
43 public static final int SHT_GROUP = 17;
44 public static final int SHT_SYMTAB_SHNDX = 18;
46 public static final int DT_NULL = 0;
47 public static final int DT_NEEDED = 1;
48 public static final int DT_PLTRELSZ = 2;
49 public static final int DT_PLTGOT = 3;
50 public static final int DT_HASH = 4;
51 public static final int DT_STRTAB = 5;
52 public static final int DT_SYMTAB = 6;
53 public static final int DT_RELA = 7;
54 public static final int DT_RELASZ = 8;
55 public static final int DT_RELAENT = 9;
56 public static final int DT_STRSZ = 10;
57 public static final int DT_SYMENT = 11;
58 public static final int DT_INIT = 12;
59 public static final int DT_FINI = 13;
60 public static final int DT_SONAME = 14;
61 public static final int DT_RPATH = 15;
62 public static final int DT_SYMBOLIC = 16;
63 public static final int DT_REL = 17;
64 public static final int DT_RELSZ = 18;
65 public static final int DT_RELENT = 19;
66 public static final int DT_PLTREL = 20;
67 public static final int DT_DEBUG = 21;
68 public static final int DT_TEXTREL = 22;
69 public static final int DT_JMPREL = 23;
70 public static final int DT_BIND_NOW = 24;
71 public static final int DT_INIT_ARRAY = 25;
72 public static final int DT_FINI_ARRAY = 26;
73 public static final int DT_INIT_ARRAYSZ = 27;
74 public static final int DT_FINI_ARRAYSZ = 28;
75 public static final int DT_RUNPATH = 29;
76 public static final int DT_FLAGS = 30;
77 public static final int DT_ENCODING = 32;
78 public static final int DT_PREINIT_ARRAY = 32;
79 public static final int DT_PREINIT_ARRAYSZ = 33;
81 protected final RandomAccessFile file;
82 protected final boolean bit64, little;
83 public final Header header;
84 public final SectionHeader[] secHeaders;
86 protected short swap(short s)
88 return (little? (short)(((s&0xff)<<8)|((s>>8)&0xff)) : s);
91 protected int swap(int i)
93 return (little? (((i&0xff)<<24)|((i&0xff00)<<8)|
94 ((i>>8)&0xff00)|((i>>24)&0xff)) : i);
97 protected long swap(long l)
99 return (little? ((((long)swap((int)(l&0xffffffffL)))<<32) |
100 (((long)swap((int)((l>>32)&0xffffffffL)))&0xffffffffL))
104 protected short getHalf() throws IOException
106 return swap(file.readShort());
109 protected int getWord() throws IOException
111 return swap(file.readInt());
114 protected long getXword() throws IOException
116 return swap(file.readLong());
119 protected long getAddr() throws IOException
121 return (bit64? getXword() : getWord());
124 protected long getOff() throws IOException
126 return (bit64? getXword() : getWord());
131 public final byte[] e_ident;
132 public final short e_type, e_machine;
133 public final int e_version;
134 public final long e_entry, e_phoff, e_shoff;
135 public final int e_flags;
136 public final short e_ehsize, e_phentsize, e_phnum;
137 public final short e_shentsize, e_shnum, e_shstrndx;
139 private Header(byte[] ident) throws IOException
143 e_machine = getHalf();
144 e_version = getWord();
149 e_ehsize = getHalf();
150 e_phentsize = getHalf();
152 e_shentsize = getHalf();
154 e_shstrndx = getHalf();
158 public class SectionHeader
160 public final int sh_name, sh_type;
161 public final long sh_flags, sh_addr, sh_offset, sh_size;
162 public final int sh_link, sh_info;
163 public final long sh_addralign, sh_entsize;
165 private SectionHeader() throws IOException
169 sh_flags = (bit64? getXword() : getWord());
171 sh_offset = getOff();
172 sh_size = (bit64? getXword() : getWord());
176 sh_addralign = getXword();
177 sh_entsize = getXword();
179 sh_addralign = getWord();
180 sh_entsize = getWord();
187 public final long d_tag, d_val;
189 private Dynamic() throws IOException
201 public Dynamic[] readDynamic(SectionHeader sh) throws IOException
203 file.seek(sh.sh_offset);
204 Dynamic[] dyn = new Dynamic[(int)(sh.sh_size/sh.sh_entsize)];
205 for (int i=0; i<dyn.length; i++)
206 dyn[i] = new Dynamic();
210 public void read(SectionHeader sh, byte[] buf) throws Exception
212 if (sh.sh_type == SHT_NOBITS || buf.length > sh.sh_size)
213 throw new Exception("Illegal read");
214 file.seek(sh.sh_offset);
218 public ElfFile(File f) throws Exception
220 file = new RandomAccessFile(f, "r");
222 byte[] ident = new byte[16];
223 file.readFully(ident);
224 if (ident[0] != 0x7f || ident[1] != 'E' ||
225 ident[2] != 'L' || ident[3] != 'F')
226 throw new Exception("ELF signature not found");
229 else if (ident[4] == 2)
232 throw new Exception("Invalid ELF file class");
235 else if (ident[5] == 2)
238 throw new Exception("Invalid ELF data encoding");
239 header = new Header(ident);
240 file.seek(header.e_shoff);
241 secHeaders = new SectionHeader[header.e_shnum];
242 for (int i=0; i<header.e_shnum; i++)
243 secHeaders[i] = new SectionHeader();