]> sigrok.org Git - sigrok-androidutils.git/blame - ant/src/org/sigrok/androidutils/ant/ElfFile.java
Add some missing license headers.
[sigrok-androidutils.git] / ant / src / org / sigrok / androidutils / ant / ElfFile.java
CommitLineData
ea3ce762 1/*
5de7ce63 2 * This file is part of the sigrok-androidutils project.
ea3ce762
MC
3 *
4 * Copyright (C) 2014 Marcus Comstedt <marcus@mc.pp.se>
5 *
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.
10 *
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.
15 *
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/>.
18 */
19
20package org.sigrok.androidutils.ant;
21
22import java.io.File;
23import java.io.IOException;
24import java.io.RandomAccessFile;
25
26class ElfFile
27{
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;
45
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;
80
81 protected final RandomAccessFile file;
82 protected final boolean bit64, little;
83 public final Header header;
84 public final SectionHeader[] secHeaders;
85
86 protected short swap(short s)
87 {
88 return (little? (short)(((s&0xff)<<8)|((s>>8)&0xff)) : s);
89 }
90
91 protected int swap(int i)
92 {
93 return (little? (((i&0xff)<<24)|((i&0xff00)<<8)|
94 ((i>>8)&0xff00)|((i>>24)&0xff)) : i);
95 }
96
97 protected long swap(long l)
98 {
99 return (little? ((((long)swap((int)(l&0xffffffffL)))<<32) |
100 (((long)swap((int)((l>>32)&0xffffffffL)))&0xffffffffL))
101 : l);
102 }
103
104 protected short getHalf() throws IOException
105 {
106 return swap(file.readShort());
107 }
108
109 protected int getWord() throws IOException
110 {
111 return swap(file.readInt());
112 }
113
114 protected long getXword() throws IOException
115 {
116 return swap(file.readLong());
117 }
118
119 protected long getAddr() throws IOException
120 {
121 return (bit64? getXword() : getWord());
122 }
123
124 protected long getOff() throws IOException
125 {
126 return (bit64? getXword() : getWord());
127 }
128
129 public class Header
130 {
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;
138
139 private Header(byte[] ident) throws IOException
140 {
141 e_ident = ident;
142 e_type = getHalf();
143 e_machine = getHalf();
144 e_version = getWord();
145 e_entry = getAddr();
146 e_phoff = getOff();
147 e_shoff = getOff();
148 e_flags = getWord();
149 e_ehsize = getHalf();
150 e_phentsize = getHalf();
151 e_phnum = getHalf();
152 e_shentsize = getHalf();
153 e_shnum = getHalf();
154 e_shstrndx = getHalf();
155 }
156 }
157
158 public class SectionHeader
159 {
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;
164
165 private SectionHeader() throws IOException
166 {
167 sh_name = getWord();
168 sh_type = getWord();
169 sh_flags = (bit64? getXword() : getWord());
170 sh_addr = getAddr();
171 sh_offset = getOff();
172 sh_size = (bit64? getXword() : getWord());
173 sh_link = getWord();
174 sh_info = getWord();
175 if (bit64) {
176 sh_addralign = getXword();
177 sh_entsize = getXword();
178 } else {
179 sh_addralign = getWord();
180 sh_entsize = getWord();
181 }
182 }
183 }
184
185 public class Dynamic
186 {
187 public final long d_tag, d_val;
188
189 private Dynamic() throws IOException
190 {
191 if (bit64) {
192 d_tag = getXword();
193 d_val = getXword();
194 } else {
195 d_tag = getWord();
196 d_val = getWord();
197 }
198 }
199 }
200
201 public Dynamic[] readDynamic(SectionHeader sh) throws IOException
202 {
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();
207 return dyn;
208 }
209
210 public void read(SectionHeader sh, byte[] buf) throws Exception
211 {
212 if (sh.sh_type == SHT_NOBITS || buf.length > sh.sh_size)
213 throw new Exception("Illegal read");
214 file.seek(sh.sh_offset);
215 file.readFully(buf);
216 }
217
218 public ElfFile(File f) throws Exception
219 {
220 file = new RandomAccessFile(f, "r");
221 file.seek(0);
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");
227 if (ident[4] == 1)
228 bit64 = false;
229 else if (ident[4] == 2)
230 bit64 = true;
231 else
232 throw new Exception("Invalid ELF file class");
233 if (ident[5] == 1)
234 little = true;
235 else if (ident[5] == 2)
236 little = false;
237 else
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();
244 }
245}