1
2
3
4 package joeq.Linker.ELF;
5
6 import java.util.ArrayList;
7 import java.util.List;
8 import java.io.IOException;
9 import java.io.RandomAccessFile;
10
11 /***
12 *
13 * @author John Whaley <jwhaley@alum.mit.edu>
14 * @version $Id: ELFRandomAccessFile.java 2474 2006-12-24 07:54:24Z joewhaley $
15 */
16 public class ELFRandomAccessFile extends ELFImpl {
17
18 protected RandomAccessFile file;
19 protected List section_headers;
20 public ELFRandomAccessFile(RandomAccessFile file) throws IOException {
21 this.file = file;
22 this.readHeader();
23 }
24 public ELFRandomAccessFile(byte data, int type, int machine, int entry, RandomAccessFile file) {
25 super(data, type, machine, entry);
26 this.file = file;
27 }
28
29 void readHeader() throws IOException {
30
31 byte mag0 = read_byte();
32 if (mag0 != ELFMAG0) throw new IOException();
33 byte mag1 = read_byte();
34 if (mag1 != ELFMAG1) throw new IOException();
35 byte mag2 = read_byte();
36 if (mag2 != ELFMAG2) throw new IOException();
37 byte mag3 = read_byte();
38 if (mag3 != ELFMAG3) throw new IOException();
39 this.ei_class = read_byte();
40 this.ei_data = read_byte();
41 byte e_version2 = read_byte();
42 for (int i=7; i<16; ++i) {
43 byte b = read_byte();
44 if (b != 0) throw new IOException();
45 }
46 this.e_type = read_half();
47 this.e_machine = read_half();
48 this.e_version = read_word();
49 if (e_version2 != (byte)e_version) throw new IOException();
50 this.e_entry = read_addr();
51 int e_phoff = read_off();
52 int e_shoff = read_off();
53 this.e_flags = read_word();
54 int headersize = read_half();
55 if (headersize != ELFImpl.getHeaderSize()) throw new IOException();
56 int programheadersize = read_half();
57 int n_programheaders = read_half();
58 if (n_programheaders > 0 && programheadersize != ProgramHeader.getSize()) throw new IOException();
59 int sectionheadersize = read_half();
60 int n_sectionheaders = read_half();
61 if (n_sectionheaders > 0 && sectionheadersize != Section.getHeaderSize()) throw new IOException();
62 int section_header_string_table_index = read_half();
63
64
65 this.set_position(e_shoff);
66 section_headers = new ArrayList(n_sectionheaders);
67 for (int i=0; i<n_sectionheaders; ++i) {
68 Section.UnloadedSection us = new Section.UnloadedSection(this);
69 section_headers.add(us);
70 Section ss = us.parseHeader();
71 sections.add(ss);
72 }
73
74
75 if (section_header_string_table_index != 0) {
76 this.section_header_string_table = (Section.StrTabSection)sections.get(section_header_string_table_index);
77 Section.UnloadedSection us = (Section.UnloadedSection)section_headers.get(section_header_string_table_index);
78 section_headers.set(section_header_string_table_index, null);
79 this.section_header_string_table.load(us, this);
80 }
81 }
82
83 public Section getSection(int i) {
84 if (i == SHN_ABS) return Section.AbsSection.INSTANCE;
85 Section s = (Section)sections.get(i);
86 Section.UnloadedSection us = (Section.UnloadedSection)section_headers.get(i);
87 if (us != null) {
88 section_headers.set(i, null);
89 try {
90 s.load(us, this);
91 } catch (IOException x) {
92 x.printStackTrace();
93 }
94 }
95 return s;
96 }
97
98 public void write_byte(byte v) throws IOException {
99 file.writeByte(v);
100 }
101
102 public void write_bytes(byte[] v) throws IOException {
103 file.write(v);
104 }
105
106 public void write_half(int v) throws IOException {
107 if (isLittleEndian()) {
108 file.writeByte((byte)v);
109 file.writeByte((byte)(v>>8));
110 } else {
111 file.writeByte((byte)(v>>8));
112 file.writeByte((byte)v);
113 }
114 }
115
116 public void write_word(int v) throws IOException {
117 if (isLittleEndian()) {
118 file.writeByte((byte)v);
119 file.writeByte((byte)(v>>8));
120 file.writeByte((byte)(v>>16));
121 file.writeByte((byte)(v>>24));
122 } else {
123 file.writeByte((byte)(v>>24));
124 file.writeByte((byte)(v>>16));
125 file.writeByte((byte)(v>>8));
126 file.writeByte((byte)v);
127 }
128 }
129
130 public void write_sword(int v) throws IOException {
131 write_word(v);
132 }
133
134 public void write_off(int v) throws IOException {
135 write_word(v);
136 }
137
138 public void write_addr(int v) throws IOException {
139 write_word(v);
140 }
141
142 public void write_sectionname(String s) throws IOException {
143 int value;
144 if (section_header_string_table == null)
145 value = 0;
146 else
147 value = section_header_string_table.getStringIndex(s);
148 write_word(value);
149 }
150
151 public void set_position(int offset) throws IOException {
152 file.seek(offset);
153 }
154
155 public byte read_byte() throws IOException {
156 return file.readByte();
157 }
158
159 public void read_bytes(byte[] b) throws IOException {
160 file.readFully(b);
161 }
162
163 public int read_half() throws IOException {
164 int b1 = file.readByte() & 0xFF;
165 int b2 = file.readByte() & 0xFF;
166 int r;
167 if (isLittleEndian()) {
168 r = (b2 << 8) | b1;
169 } else {
170 r = (b1 << 8) | b2;
171 }
172 return r;
173 }
174
175 public int read_word() throws IOException {
176 int b1 = file.readByte() & 0xFF;
177 int b2 = file.readByte() & 0xFF;
178 int b3 = file.readByte() & 0xFF;
179 int b4 = file.readByte() & 0xFF;
180 int r;
181 if (isLittleEndian()) {
182 r = (b4 << 24) | (b3 << 16) | (b2 << 8) | b1;
183 } else {
184 r = (b1 << 24) | (b2 << 16) | (b3 << 8) | b4;
185 }
186 return r;
187 }
188
189 public int read_sword() throws IOException {
190 return read_word();
191 }
192
193 public int read_off() throws IOException {
194 return read_word();
195 }
196
197 public int read_addr() throws IOException {
198 return read_word();
199 }
200 }