View Javadoc

1   // ELFImpl.java, created Thu May  8 12:49:13 2003 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.Iterator;
7   import java.util.LinkedList;
8   import java.util.List;
9   import java.io.IOException;
10  import jwutil.util.Assert;
11  
12  /***
13   *
14   * @author  John Whaley <jwhaley@alum.mit.edu>
15   * @version $Id: ELFImpl.java 1941 2004-09-30 03:37:06Z joewhaley $
16   */
17  abstract class ELFImpl implements ELF, ELFConstants {
18  
19      protected byte ei_class;
20      protected byte ei_data;
21      protected int e_type;
22      protected int e_machine;
23      protected int e_version;
24      protected int e_entry;
25      //protected int e_phoff;
26      //protected int e_shoff;
27      protected int e_flags;
28      
29      protected List/*<ProgramHeader>*/ program_headers;
30      protected List/*<Section>*/ sections;
31      protected Section.StrTabSection section_header_string_table;
32      
33      /*** Creates new ELFImpl */
34      public ELFImpl(byte data, int type, int machine, int entry) {
35          ei_class = ELFCLASS32;
36          ei_data = data;
37          e_type = type;
38          e_machine = machine;
39          e_version = EV_CURRENT;
40          program_headers = new LinkedList();
41          sections = new LinkedList();
42      }
43      protected ELFImpl() {
44          ei_class = ELFCLASS32;
45          ei_data = ELFDATA2LSB;
46          e_type = ET_REL;
47          e_machine = EM_386;
48          e_version = EV_CURRENT;
49          program_headers = new LinkedList();
50          sections = new LinkedList();
51      }
52  
53      public Section.StrTabSection getSectionHeaderStringTable() {
54          return section_header_string_table;
55      }
56      
57      public void setSectionHeaderStringTable(Section.StrTabSection shstrtab) {
58          this.section_header_string_table = shstrtab;
59      }
60      
61      public int getSectionIndex(Section s) {
62          if (s == null)
63              return SHN_UNDEF;
64          return s.getIndex();
65      }
66      
67      public Section getSection(int i) {
68          if (i == SHN_ABS) return Section.AbsSection.INSTANCE;
69          return (Section)sections.get(i);
70      }
71      
72      public List/*<Section>*/ getSections() {
73          return sections;
74      }
75      
76      public void addSection(Section s) {
77          sections.add(s);
78      }
79      public void removeSection(Section s) {
80          sections.remove(s);
81      }
82      public void addProgramHeader(ProgramHeader p) {
83          program_headers.add(p);
84      }
85      public void removeProgramHeader(ProgramHeader p) {
86          program_headers.remove(p);
87      }
88      
89      public boolean isLittleEndian() { return ei_data == ELFDATA2LSB; }
90      public boolean isBigEndian() { return ei_data == ELFDATA2MSB; }
91      public void setLittleEndian() { ei_data = ELFDATA2LSB; }
92      public void setBigEndian() { ei_data = ELFDATA2MSB; }
93      
94      public void write() throws IOException {
95          // sanity check - sections should include the string tables.
96          if (section_header_string_table != null)
97              Assert._assert(sections.contains(section_header_string_table));
98          
99          // add section header names to the section header string table.
100         if (section_header_string_table != null) {
101             Iterator si = sections.iterator();
102             while (si.hasNext()) {
103                 Section s = (Section)si.next();
104                 section_header_string_table.addString(s.getName());
105             }
106         }
107         
108         // file offsets for the program header table and the section table.
109         int e_phoff, e_shoff, soff;
110         
111         // calculate program header table offset.
112         if (program_headers.isEmpty()) {
113             e_phoff = 0;
114             soff = e_shoff = ELFImpl.getHeaderSize();
115         } else {
116             e_phoff = ELFImpl.getHeaderSize();
117             soff = e_shoff = e_phoff + (program_headers.size() * ProgramHeader.getSize());
118         }
119         
120         // pack all sections and calculate section header offset.
121         Iterator si = sections.iterator();
122         Section s = (Section)si.next();
123         Assert._assert(s instanceof Section.NullSection);
124         int i = 0;
125         while (si.hasNext()) {
126             s = (Section)si.next();
127             if (s instanceof Section.StrTabSection) {
128                 Section.StrTabSection ss = (Section.StrTabSection)s;
129                 if (ss.getNumberOfEntries() < 10000)
130                     ss.super_pack();
131                 else
132                     ss.pack();
133             } else if (s instanceof Section.SymTabSection) {
134                 Section.SymTabSection ss = (Section.SymTabSection)s;
135                 ss.setIndices();
136             }
137             if (!(s instanceof Section.NoBitsSection))
138                 e_shoff += s.getSize();
139             s.setIndex(++i);
140         }
141         
142         // now, actually do the writing.
143         // write the header.
144         writeHeader(e_phoff, e_shoff);
145         
146         // write the program header table
147         Iterator pi = program_headers.iterator();
148         while (pi.hasNext()) {
149             ProgramHeader p = (ProgramHeader)pi.next();
150             p.writeHeader(this);
151         }
152         
153         // write the section data
154         si = sections.iterator();
155         while (si.hasNext()) {
156             s = (Section)si.next();
157             s.writeData(this);
158         }
159         
160         // write the section header table
161         si = sections.iterator();
162         while (si.hasNext()) {
163             s = (Section)si.next();
164             s.writeHeader(this, soff);
165             if (!(s instanceof Section.NoBitsSection))
166                 soff += s.getSize();
167         }
168     }
169 
170     void writeHeader(int e_phoff, int e_shoff) throws IOException {
171         writeIdent();
172         write_half(e_type);
173         write_half(e_machine);
174         write_word(e_version);
175         write_addr(e_entry);
176         write_off(e_phoff);
177         write_off(e_shoff);
178         write_word(e_flags);
179         write_half(getHeaderSize());
180         write_half(ProgramHeader.getSize());
181         write_half(program_headers.size());
182         write_half(Section.getHeaderSize());
183         write_half(sections.size());
184         write_half(getSectionIndex(section_header_string_table));
185     }
186     
187     void writeIdent() throws IOException {
188         writeMagicNumber();
189         write_byte(ei_class);
190         write_byte(ei_data);
191         write_byte((byte)e_version);
192         for (int i=7; i<16; ++i)
193             write_byte((byte)0);
194     }
195 
196     void writeMagicNumber() throws IOException {
197         write_byte(ELFMAG0);
198         write_byte(ELFMAG1);
199         write_byte(ELFMAG2);
200         write_byte(ELFMAG3);
201     }
202     
203     public static int getHeaderSize() { return 52; }
204     
205 }