]> sigrok.org Git - sigrok-androidutils.git/blame - ant/src/org/sigrok/androidutils/ant/ElfFile.java
Minor whitespace and cosmetic fixes.
[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{
6f1c3a93
UH
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)
ea3ce762 87 {
6f1c3a93 88 return (little ? (short)(((s & 0xff) << 8) | ((s >> 8) & 0xff)) : s);
ea3ce762 89 }
ea3ce762 90
6f1c3a93
UH
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)) : l);
101 }
102
103 protected short getHalf() throws IOException
104 {
105 return swap(file.readShort());
106 }
ea3ce762 107
6f1c3a93 108 protected int getWord() throws IOException
ea3ce762 109 {
6f1c3a93 110 return swap(file.readInt());
ea3ce762 111 }
ea3ce762 112
6f1c3a93
UH
113 protected long getXword() throws IOException
114 {
115 return swap(file.readLong());
116 }
117
118 protected long getAddr() throws IOException
119 {
120 return (bit64? getXword() : getWord());
121 }
122
123 protected long getOff() throws IOException
124 {
125 return (bit64 ? getXword() : getWord());
126 }
127
128 public class Header
129 {
130 public final byte[] e_ident;
131 public final short e_type, e_machine;
132 public final int e_version;
133 public final long e_entry, e_phoff, e_shoff;
134 public final int e_flags;
135 public final short e_ehsize, e_phentsize, e_phnum;
136 public final short e_shentsize, e_shnum, e_shstrndx;
137
138 private Header(byte[] ident) throws IOException
139 {
140 e_ident = ident;
141 e_type = getHalf();
142 e_machine = getHalf();
143 e_version = getWord();
144 e_entry = getAddr();
145 e_phoff = getOff();
146 e_shoff = getOff();
147 e_flags = getWord();
148 e_ehsize = getHalf();
149 e_phentsize = getHalf();
150 e_phnum = getHalf();
151 e_shentsize = getHalf();
152 e_shnum = getHalf();
153 e_shstrndx = getHalf();
154 }
155 }
156
157 public class SectionHeader
158 {
159 public final int sh_name, sh_type;
160 public final long sh_flags, sh_addr, sh_offset, sh_size;
161 public final int sh_link, sh_info;
162 public final long sh_addralign, sh_entsize;
163
164 private SectionHeader() throws IOException
165 {
166 sh_name = getWord();
167 sh_type = getWord();
168 sh_flags = (bit64 ? getXword() : getWord());
169 sh_addr = getAddr();
170 sh_offset = getOff();
171 sh_size = (bit64 ? getXword() : getWord());
172 sh_link = getWord();
173 sh_info = getWord();
174 if (bit64) {
175 sh_addralign = getXword();
176 sh_entsize = getXword();
177 } else {
178 sh_addralign = getWord();
179 sh_entsize = getWord();
180 }
181 }
182 }
183
184 public class Dynamic
185 {
186 public final long d_tag, d_val;
187
188 private Dynamic() throws IOException
189 {
190 if (bit64) {
191 d_tag = getXword();
192 d_val = getXword();
193 } else {
194 d_tag = getWord();
195 d_val = getWord();
196 }
197 }
198 }
199
200 public Dynamic[] readDynamic(SectionHeader sh) throws IOException
201 {
202 file.seek(sh.sh_offset);
203 Dynamic[] dyn = new Dynamic[(int)(sh.sh_size / sh.sh_entsize)];
204 for (int i = 0; i < dyn.length; i++)
205 dyn[i] = new Dynamic();
206 return dyn;
207 }
208
209 public void read(SectionHeader sh, byte[] buf) throws Exception
210 {
211 if (sh.sh_type == SHT_NOBITS || buf.length > sh.sh_size)
212 throw new Exception("Illegal read");
213 file.seek(sh.sh_offset);
214 file.readFully(buf);
215 }
ea3ce762 216
6f1c3a93 217 public ElfFile(File f) throws Exception
ea3ce762 218 {
6f1c3a93
UH
219 file = new RandomAccessFile(f, "r");
220 file.seek(0);
221 byte[] ident = new byte[16];
222 file.readFully(ident);
223 if (ident[0] != 0x7f || ident[1] != 'E' ||
224 ident[2] != 'L' || ident[3] != 'F')
225 throw new Exception("ELF signature not found");
226 if (ident[4] == 1)
227 bit64 = false;
228 else if (ident[4] == 2)
229 bit64 = true;
230 else
231 throw new Exception("Invalid ELF file class");
232 if (ident[5] == 1)
233 little = true;
234 else if (ident[5] == 2)
235 little = false;
236 else
237 throw new Exception("Invalid ELF data encoding");
238 header = new Header(ident);
239 file.seek(header.e_shoff);
240 secHeaders = new SectionHeader[header.e_shnum];
241 for (int i = 0; i < header.e_shnum; i++)
242 secHeaders[i] = new SectionHeader();
ea3ce762 243 }
ea3ce762 244}