View Javadoc

1   // ELFRandomAccessFile.java, created Sat May 25 12:46:16 2002 by joewhaley
2   // Copyright (C) 2001-3 John Whaley <jwhaley@alum.mit.edu>
3   // Licensed under the terms of the GNU LGPL; see COPYING for details.
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          // read and parse section headers
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          // read section header string table
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 }