]> CyberLeo.Net >> Repos - FreeBSD/stable/9.git/blob - contrib/llvm/lib/Object/ELFObjectFile.cpp
Copy head to stable/9 as part of 9.0-RELEASE release cycle.
[FreeBSD/stable/9.git] / contrib / llvm / lib / Object / ELFObjectFile.cpp
1 //===- ELFObjectFile.cpp - ELF object file implementation -------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file defines the ELFObjectFile class.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "llvm/ADT/SmallVector.h"
15 #include "llvm/ADT/StringSwitch.h"
16 #include "llvm/ADT/Triple.h"
17 #include "llvm/Object/ObjectFile.h"
18 #include "llvm/Support/ELF.h"
19 #include "llvm/Support/Endian.h"
20 #include "llvm/Support/ErrorHandling.h"
21 #include "llvm/Support/MemoryBuffer.h"
22 #include <limits>
23 #include <utility>
24
25 using namespace llvm;
26 using namespace object;
27
28 // Templates to choose Elf_Addr and Elf_Off depending on is64Bits.
29 namespace {
30 template<support::endianness target_endianness>
31 struct ELFDataTypeTypedefHelperCommon {
32   typedef support::detail::packed_endian_specific_integral
33     <uint16_t, target_endianness, support::aligned> Elf_Half;
34   typedef support::detail::packed_endian_specific_integral
35     <uint32_t, target_endianness, support::aligned> Elf_Word;
36   typedef support::detail::packed_endian_specific_integral
37     <int32_t, target_endianness, support::aligned> Elf_Sword;
38   typedef support::detail::packed_endian_specific_integral
39     <uint64_t, target_endianness, support::aligned> Elf_Xword;
40   typedef support::detail::packed_endian_specific_integral
41     <int64_t, target_endianness, support::aligned> Elf_Sxword;
42 };
43 }
44
45 namespace {
46 template<support::endianness target_endianness, bool is64Bits>
47 struct ELFDataTypeTypedefHelper;
48
49 /// ELF 32bit types.
50 template<support::endianness target_endianness>
51 struct ELFDataTypeTypedefHelper<target_endianness, false>
52   : ELFDataTypeTypedefHelperCommon<target_endianness> {
53   typedef support::detail::packed_endian_specific_integral
54     <uint32_t, target_endianness, support::aligned> Elf_Addr;
55   typedef support::detail::packed_endian_specific_integral
56     <uint32_t, target_endianness, support::aligned> Elf_Off;
57 };
58
59 /// ELF 64bit types.
60 template<support::endianness target_endianness>
61 struct ELFDataTypeTypedefHelper<target_endianness, true>
62   : ELFDataTypeTypedefHelperCommon<target_endianness>{
63   typedef support::detail::packed_endian_specific_integral
64     <uint64_t, target_endianness, support::aligned> Elf_Addr;
65   typedef support::detail::packed_endian_specific_integral
66     <uint64_t, target_endianness, support::aligned> Elf_Off;
67 };
68 }
69
70 // I really don't like doing this, but the alternative is copypasta.
71 #define LLVM_ELF_IMPORT_TYPES(target_endianness, is64Bits) \
72 typedef typename \
73   ELFDataTypeTypedefHelper<target_endianness, is64Bits>::Elf_Addr Elf_Addr; \
74 typedef typename \
75   ELFDataTypeTypedefHelper<target_endianness, is64Bits>::Elf_Off Elf_Off; \
76 typedef typename \
77   ELFDataTypeTypedefHelper<target_endianness, is64Bits>::Elf_Half Elf_Half; \
78 typedef typename \
79   ELFDataTypeTypedefHelper<target_endianness, is64Bits>::Elf_Word Elf_Word; \
80 typedef typename \
81   ELFDataTypeTypedefHelper<target_endianness, is64Bits>::Elf_Sword Elf_Sword; \
82 typedef typename \
83   ELFDataTypeTypedefHelper<target_endianness, is64Bits>::Elf_Xword Elf_Xword; \
84 typedef typename \
85   ELFDataTypeTypedefHelper<target_endianness, is64Bits>::Elf_Sxword Elf_Sxword;
86
87   // Section header.
88 namespace {
89 template<support::endianness target_endianness, bool is64Bits>
90 struct Elf_Shdr_Base;
91
92 template<support::endianness target_endianness>
93 struct Elf_Shdr_Base<target_endianness, false> {
94   LLVM_ELF_IMPORT_TYPES(target_endianness, false)
95   Elf_Word sh_name;     // Section name (index into string table)
96   Elf_Word sh_type;     // Section type (SHT_*)
97   Elf_Word sh_flags;    // Section flags (SHF_*)
98   Elf_Addr sh_addr;     // Address where section is to be loaded
99   Elf_Off  sh_offset;   // File offset of section data, in bytes
100   Elf_Word sh_size;     // Size of section, in bytes
101   Elf_Word sh_link;     // Section type-specific header table index link
102   Elf_Word sh_info;     // Section type-specific extra information
103   Elf_Word sh_addralign;// Section address alignment
104   Elf_Word sh_entsize;  // Size of records contained within the section
105 };
106
107 template<support::endianness target_endianness>
108 struct Elf_Shdr_Base<target_endianness, true> {
109   LLVM_ELF_IMPORT_TYPES(target_endianness, true)
110   Elf_Word  sh_name;     // Section name (index into string table)
111   Elf_Word  sh_type;     // Section type (SHT_*)
112   Elf_Xword sh_flags;    // Section flags (SHF_*)
113   Elf_Addr  sh_addr;     // Address where section is to be loaded
114   Elf_Off   sh_offset;   // File offset of section data, in bytes
115   Elf_Xword sh_size;     // Size of section, in bytes
116   Elf_Word  sh_link;     // Section type-specific header table index link
117   Elf_Word  sh_info;     // Section type-specific extra information
118   Elf_Xword sh_addralign;// Section address alignment
119   Elf_Xword sh_entsize;  // Size of records contained within the section
120 };
121
122 template<support::endianness target_endianness, bool is64Bits>
123 struct Elf_Shdr_Impl : Elf_Shdr_Base<target_endianness, is64Bits> {
124   using Elf_Shdr_Base<target_endianness, is64Bits>::sh_entsize;
125   using Elf_Shdr_Base<target_endianness, is64Bits>::sh_size;
126
127   /// @brief Get the number of entities this section contains if it has any.
128   unsigned getEntityCount() const {
129     if (sh_entsize == 0)
130       return 0;
131     return sh_size / sh_entsize;
132   }
133 };
134 }
135
136 namespace {
137 template<support::endianness target_endianness, bool is64Bits>
138 struct Elf_Sym_Base;
139
140 template<support::endianness target_endianness>
141 struct Elf_Sym_Base<target_endianness, false> {
142   LLVM_ELF_IMPORT_TYPES(target_endianness, false)
143   Elf_Word      st_name;  // Symbol name (index into string table)
144   Elf_Addr      st_value; // Value or address associated with the symbol
145   Elf_Word      st_size;  // Size of the symbol
146   unsigned char st_info;  // Symbol's type and binding attributes
147   unsigned char st_other; // Must be zero; reserved
148   Elf_Half      st_shndx; // Which section (header table index) it's defined in
149 };
150
151 template<support::endianness target_endianness>
152 struct Elf_Sym_Base<target_endianness, true> {
153   LLVM_ELF_IMPORT_TYPES(target_endianness, true)
154   Elf_Word      st_name;  // Symbol name (index into string table)
155   unsigned char st_info;  // Symbol's type and binding attributes
156   unsigned char st_other; // Must be zero; reserved
157   Elf_Half      st_shndx; // Which section (header table index) it's defined in
158   Elf_Addr      st_value; // Value or address associated with the symbol
159   Elf_Xword     st_size;  // Size of the symbol
160 };
161
162 template<support::endianness target_endianness, bool is64Bits>
163 struct Elf_Sym_Impl : Elf_Sym_Base<target_endianness, is64Bits> {
164   using Elf_Sym_Base<target_endianness, is64Bits>::st_info;
165
166   // These accessors and mutators correspond to the ELF32_ST_BIND,
167   // ELF32_ST_TYPE, and ELF32_ST_INFO macros defined in the ELF specification:
168   unsigned char getBinding() const { return st_info >> 4; }
169   unsigned char getType() const { return st_info & 0x0f; }
170   void setBinding(unsigned char b) { setBindingAndType(b, getType()); }
171   void setType(unsigned char t) { setBindingAndType(getBinding(), t); }
172   void setBindingAndType(unsigned char b, unsigned char t) {
173     st_info = (b << 4) + (t & 0x0f);
174   }
175 };
176 }
177
178 namespace {
179 template<support::endianness target_endianness, bool is64Bits>
180 class ELFObjectFile : public ObjectFile {
181   LLVM_ELF_IMPORT_TYPES(target_endianness, is64Bits)
182
183   typedef Elf_Shdr_Impl<target_endianness, is64Bits> Elf_Shdr;
184   typedef Elf_Sym_Impl<target_endianness, is64Bits> Elf_Sym;
185
186   struct Elf_Ehdr {
187     unsigned char e_ident[ELF::EI_NIDENT]; // ELF Identification bytes
188     Elf_Half e_type;     // Type of file (see ET_*)
189     Elf_Half e_machine;  // Required architecture for this file (see EM_*)
190     Elf_Word e_version;  // Must be equal to 1
191     Elf_Addr e_entry;    // Address to jump to in order to start program
192     Elf_Off  e_phoff;    // Program header table's file offset, in bytes
193     Elf_Off  e_shoff;    // Section header table's file offset, in bytes
194     Elf_Word e_flags;    // Processor-specific flags
195     Elf_Half e_ehsize;   // Size of ELF header, in bytes
196     Elf_Half e_phentsize;// Size of an entry in the program header table
197     Elf_Half e_phnum;    // Number of entries in the program header table
198     Elf_Half e_shentsize;// Size of an entry in the section header table
199     Elf_Half e_shnum;    // Number of entries in the section header table
200     Elf_Half e_shstrndx; // Section header table index of section name
201                                   // string table
202     bool checkMagic() const {
203       return (memcmp(e_ident, ELF::ElfMagic, strlen(ELF::ElfMagic))) == 0;
204     }
205     unsigned char getFileClass() const { return e_ident[ELF::EI_CLASS]; }
206     unsigned char getDataEncoding() const { return e_ident[ELF::EI_DATA]; }
207   };
208
209   typedef SmallVector<const Elf_Shdr*, 1> SymbolTableSections_t;
210
211   const Elf_Ehdr *Header;
212   const Elf_Shdr *SectionHeaderTable;
213   const Elf_Shdr *dot_shstrtab_sec; // Section header string table.
214   const Elf_Shdr *dot_strtab_sec;   // Symbol header string table.
215   SymbolTableSections_t SymbolTableSections;
216
217   void            validateSymbol(DataRefImpl Symb) const;
218   const Elf_Sym  *getSymbol(DataRefImpl Symb) const;
219   const Elf_Shdr *getSection(DataRefImpl index) const;
220   const Elf_Shdr *getSection(uint16_t index) const;
221   const char     *getString(uint16_t section, uint32_t offset) const;
222   const char     *getString(const Elf_Shdr *section, uint32_t offset) const;
223
224 protected:
225   virtual error_code getSymbolNext(DataRefImpl Symb, SymbolRef &Res) const;
226   virtual error_code getSymbolName(DataRefImpl Symb, StringRef &Res) const;
227   virtual error_code getSymbolAddress(DataRefImpl Symb, uint64_t &Res) const;
228   virtual error_code getSymbolSize(DataRefImpl Symb, uint64_t &Res) const;
229   virtual error_code getSymbolNMTypeChar(DataRefImpl Symb, char &Res) const;
230   virtual error_code isSymbolInternal(DataRefImpl Symb, bool &Res) const;
231
232   virtual error_code getSectionNext(DataRefImpl Sec, SectionRef &Res) const;
233   virtual error_code getSectionName(DataRefImpl Sec, StringRef &Res) const;
234   virtual error_code getSectionAddress(DataRefImpl Sec, uint64_t &Res) const;
235   virtual error_code getSectionSize(DataRefImpl Sec, uint64_t &Res) const;
236   virtual error_code getSectionContents(DataRefImpl Sec, StringRef &Res) const;
237   virtual error_code isSectionText(DataRefImpl Sec, bool &Res) const;
238   virtual error_code sectionContainsSymbol(DataRefImpl Sec, DataRefImpl Symb,
239                                            bool &Result) const;
240
241 public:
242   ELFObjectFile(MemoryBuffer *Object, error_code &ec);
243   virtual symbol_iterator begin_symbols() const;
244   virtual symbol_iterator end_symbols() const;
245   virtual section_iterator begin_sections() const;
246   virtual section_iterator end_sections() const;
247
248   virtual uint8_t getBytesInAddress() const;
249   virtual StringRef getFileFormatName() const;
250   virtual unsigned getArch() const;
251 };
252 } // end namespace
253
254 template<support::endianness target_endianness, bool is64Bits>
255 void ELFObjectFile<target_endianness, is64Bits>
256                   ::validateSymbol(DataRefImpl Symb) const {
257   const Elf_Sym  *symb = getSymbol(Symb);
258   const Elf_Shdr *SymbolTableSection = SymbolTableSections[Symb.d.b];
259   // FIXME: We really need to do proper error handling in the case of an invalid
260   //        input file. Because we don't use exceptions, I think we'll just pass
261   //        an error object around.
262   if (!(  symb
263         && SymbolTableSection
264         && symb >= (const Elf_Sym*)(base()
265                    + SymbolTableSection->sh_offset)
266         && symb <  (const Elf_Sym*)(base()
267                    + SymbolTableSection->sh_offset
268                    + SymbolTableSection->sh_size)))
269     // FIXME: Proper error handling.
270     report_fatal_error("Symb must point to a valid symbol!");
271 }
272
273 template<support::endianness target_endianness, bool is64Bits>
274 error_code ELFObjectFile<target_endianness, is64Bits>
275                         ::getSymbolNext(DataRefImpl Symb,
276                                         SymbolRef &Result) const {
277   validateSymbol(Symb);
278   const Elf_Shdr *SymbolTableSection = SymbolTableSections[Symb.d.b];
279
280   ++Symb.d.a;
281   // Check to see if we are at the end of this symbol table.
282   if (Symb.d.a >= SymbolTableSection->getEntityCount()) {
283     // We are at the end. If there are other symbol tables, jump to them.
284     ++Symb.d.b;
285     Symb.d.a = 1; // The 0th symbol in ELF is fake.
286     // Otherwise return the terminator.
287     if (Symb.d.b >= SymbolTableSections.size()) {
288       Symb.d.a = std::numeric_limits<uint32_t>::max();
289       Symb.d.b = std::numeric_limits<uint32_t>::max();
290     }
291   }
292
293   Result = SymbolRef(Symb, this);
294   return object_error::success;
295 }
296
297 template<support::endianness target_endianness, bool is64Bits>
298 error_code ELFObjectFile<target_endianness, is64Bits>
299                         ::getSymbolName(DataRefImpl Symb,
300                                         StringRef &Result) const {
301   validateSymbol(Symb);
302   const Elf_Sym  *symb = getSymbol(Symb);
303   if (symb->st_name == 0) {
304     const Elf_Shdr *section = getSection(symb->st_shndx);
305     if (!section)
306       Result = "";
307     else
308       Result = getString(dot_shstrtab_sec, section->sh_name);
309     return object_error::success;
310   }
311
312   // Use the default symbol table name section.
313   Result = getString(dot_strtab_sec, symb->st_name);
314   return object_error::success;
315 }
316
317 template<support::endianness target_endianness, bool is64Bits>
318 error_code ELFObjectFile<target_endianness, is64Bits>
319                         ::getSymbolAddress(DataRefImpl Symb,
320                                            uint64_t &Result) const {
321   validateSymbol(Symb);
322   const Elf_Sym  *symb = getSymbol(Symb);
323   const Elf_Shdr *Section;
324   switch (symb->st_shndx) {
325   case ELF::SHN_COMMON:
326    // Undefined symbols have no address yet.
327   case ELF::SHN_UNDEF:
328     Result = UnknownAddressOrSize;
329     return object_error::success;
330   case ELF::SHN_ABS:
331     Result = symb->st_value;
332     return object_error::success;
333   default: Section = getSection(symb->st_shndx);
334   }
335
336   switch (symb->getType()) {
337   case ELF::STT_SECTION:
338     Result = Section ? Section->sh_addr : UnknownAddressOrSize;
339     return object_error::success;
340   case ELF::STT_FUNC:
341   case ELF::STT_OBJECT:
342   case ELF::STT_NOTYPE:
343     Result = symb->st_value;
344     return object_error::success;
345   default:
346     Result = UnknownAddressOrSize;
347     return object_error::success;
348   }
349 }
350
351 template<support::endianness target_endianness, bool is64Bits>
352 error_code ELFObjectFile<target_endianness, is64Bits>
353                         ::getSymbolSize(DataRefImpl Symb,
354                                         uint64_t &Result) const {
355   validateSymbol(Symb);
356   const Elf_Sym  *symb = getSymbol(Symb);
357   if (symb->st_size == 0)
358     Result = UnknownAddressOrSize;
359   Result = symb->st_size;
360   return object_error::success;
361 }
362
363 template<support::endianness target_endianness, bool is64Bits>
364 error_code ELFObjectFile<target_endianness, is64Bits>
365                         ::getSymbolNMTypeChar(DataRefImpl Symb,
366                                               char &Result) const {
367   validateSymbol(Symb);
368   const Elf_Sym  *symb = getSymbol(Symb);
369   const Elf_Shdr *Section = getSection(symb->st_shndx);
370
371   char ret = '?';
372
373   if (Section) {
374     switch (Section->sh_type) {
375     case ELF::SHT_PROGBITS:
376     case ELF::SHT_DYNAMIC:
377       switch (Section->sh_flags) {
378       case (ELF::SHF_ALLOC | ELF::SHF_EXECINSTR):
379         ret = 't'; break;
380       case (ELF::SHF_ALLOC | ELF::SHF_WRITE):
381         ret = 'd'; break;
382       case ELF::SHF_ALLOC:
383       case (ELF::SHF_ALLOC | ELF::SHF_MERGE):
384       case (ELF::SHF_ALLOC | ELF::SHF_MERGE | ELF::SHF_STRINGS):
385         ret = 'r'; break;
386       }
387       break;
388     case ELF::SHT_NOBITS: ret = 'b';
389     }
390   }
391
392   switch (symb->st_shndx) {
393   case ELF::SHN_UNDEF:
394     if (ret == '?')
395       ret = 'U';
396     break;
397   case ELF::SHN_ABS: ret = 'a'; break;
398   case ELF::SHN_COMMON: ret = 'c'; break;
399   }
400
401   switch (symb->getBinding()) {
402   case ELF::STB_GLOBAL: ret = ::toupper(ret); break;
403   case ELF::STB_WEAK:
404     if (symb->st_shndx == ELF::SHN_UNDEF)
405       ret = 'w';
406     else
407       if (symb->getType() == ELF::STT_OBJECT)
408         ret = 'V';
409       else
410         ret = 'W';
411   }
412
413   if (ret == '?' && symb->getType() == ELF::STT_SECTION) {
414     StringRef name;
415     if (error_code ec = getSymbolName(Symb, name))
416       return ec;
417     Result = StringSwitch<char>(name)
418       .StartsWith(".debug", 'N')
419       .StartsWith(".note", 'n');
420     return object_error::success;
421   }
422
423   Result = ret;
424   return object_error::success;
425 }
426
427 template<support::endianness target_endianness, bool is64Bits>
428 error_code ELFObjectFile<target_endianness, is64Bits>
429                         ::isSymbolInternal(DataRefImpl Symb,
430                                            bool &Result) const {
431   validateSymbol(Symb);
432   const Elf_Sym  *symb = getSymbol(Symb);
433
434   if (  symb->getType() == ELF::STT_FILE
435      || symb->getType() == ELF::STT_SECTION)
436     Result = true;
437   Result = false;
438   return object_error::success;
439 }
440
441 template<support::endianness target_endianness, bool is64Bits>
442 error_code ELFObjectFile<target_endianness, is64Bits>
443                         ::getSectionNext(DataRefImpl Sec, SectionRef &Result) const {
444   const uint8_t *sec = reinterpret_cast<const uint8_t *>(Sec.p);
445   sec += Header->e_shentsize;
446   Sec.p = reinterpret_cast<intptr_t>(sec);
447   Result = SectionRef(Sec, this);
448   return object_error::success;
449 }
450
451 template<support::endianness target_endianness, bool is64Bits>
452 error_code ELFObjectFile<target_endianness, is64Bits>
453                         ::getSectionName(DataRefImpl Sec,
454                                          StringRef &Result) const {
455   const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p);
456   Result = StringRef(getString(dot_shstrtab_sec, sec->sh_name));
457   return object_error::success;
458 }
459
460 template<support::endianness target_endianness, bool is64Bits>
461 error_code ELFObjectFile<target_endianness, is64Bits>
462                         ::getSectionAddress(DataRefImpl Sec,
463                                             uint64_t &Result) const {
464   const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p);
465   Result = sec->sh_addr;
466   return object_error::success;
467 }
468
469 template<support::endianness target_endianness, bool is64Bits>
470 error_code ELFObjectFile<target_endianness, is64Bits>
471                         ::getSectionSize(DataRefImpl Sec,
472                                          uint64_t &Result) const {
473   const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p);
474   Result = sec->sh_size;
475   return object_error::success;
476 }
477
478 template<support::endianness target_endianness, bool is64Bits>
479 error_code ELFObjectFile<target_endianness, is64Bits>
480                         ::getSectionContents(DataRefImpl Sec,
481                                              StringRef &Result) const {
482   const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p);
483   const char *start = (const char*)base() + sec->sh_offset;
484   Result = StringRef(start, sec->sh_size);
485   return object_error::success;
486 }
487
488 template<support::endianness target_endianness, bool is64Bits>
489 error_code ELFObjectFile<target_endianness, is64Bits>
490                         ::isSectionText(DataRefImpl Sec,
491                                         bool &Result) const {
492   const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p);
493   if (sec->sh_flags & ELF::SHF_EXECINSTR)
494     Result = true;
495   else
496     Result = false;
497   return object_error::success;
498 }
499
500 template<support::endianness target_endianness, bool is64Bits>
501 error_code ELFObjectFile<target_endianness, is64Bits>
502                           ::sectionContainsSymbol(DataRefImpl Sec,
503                                                   DataRefImpl Symb,
504                                                   bool &Result) const {
505   // FIXME: Unimplemented.
506   Result = false;
507   return object_error::success;
508 }
509
510 template<support::endianness target_endianness, bool is64Bits>
511 ELFObjectFile<target_endianness, is64Bits>::ELFObjectFile(MemoryBuffer *Object
512                                                           , error_code &ec)
513   : ObjectFile(Binary::isELF, Object, ec)
514   , SectionHeaderTable(0)
515   , dot_shstrtab_sec(0)
516   , dot_strtab_sec(0) {
517   Header = reinterpret_cast<const Elf_Ehdr *>(base());
518
519   if (Header->e_shoff == 0)
520     return;
521
522   SectionHeaderTable =
523     reinterpret_cast<const Elf_Shdr *>(base() + Header->e_shoff);
524   uint32_t SectionTableSize = Header->e_shnum * Header->e_shentsize;
525   if (!(  (const uint8_t *)SectionHeaderTable + SectionTableSize
526          <= base() + Data->getBufferSize()))
527     // FIXME: Proper error handling.
528     report_fatal_error("Section table goes past end of file!");
529
530
531   // To find the symbol tables we walk the section table to find SHT_STMTAB.
532   for (const char *i = reinterpret_cast<const char *>(SectionHeaderTable),
533                   *e = i + Header->e_shnum * Header->e_shentsize;
534                    i != e; i += Header->e_shentsize) {
535     const Elf_Shdr *sh = reinterpret_cast<const Elf_Shdr*>(i);
536     if (sh->sh_type == ELF::SHT_SYMTAB) {
537       SymbolTableSections.push_back(sh);
538     }
539   }
540
541   // Get string table sections.
542   dot_shstrtab_sec = getSection(Header->e_shstrndx);
543   if (dot_shstrtab_sec) {
544     // Verify that the last byte in the string table in a null.
545     if (((const char*)base() + dot_shstrtab_sec->sh_offset)
546         [dot_shstrtab_sec->sh_size - 1] != 0)
547       // FIXME: Proper error handling.
548       report_fatal_error("String table must end with a null terminator!");
549   }
550
551   // Merge this into the above loop.
552   for (const char *i = reinterpret_cast<const char *>(SectionHeaderTable),
553                   *e = i + Header->e_shnum * Header->e_shentsize;
554                    i != e; i += Header->e_shentsize) {
555     const Elf_Shdr *sh = reinterpret_cast<const Elf_Shdr*>(i);
556     if (sh->sh_type == ELF::SHT_STRTAB) {
557       StringRef SectionName(getString(dot_shstrtab_sec, sh->sh_name));
558       if (SectionName == ".strtab") {
559         if (dot_strtab_sec != 0)
560           // FIXME: Proper error handling.
561           report_fatal_error("Already found section named .strtab!");
562         dot_strtab_sec = sh;
563         const char *dot_strtab = (const char*)base() + sh->sh_offset;
564           if (dot_strtab[sh->sh_size - 1] != 0)
565             // FIXME: Proper error handling.
566             report_fatal_error("String table must end with a null terminator!");
567       }
568     }
569   }
570 }
571
572 template<support::endianness target_endianness, bool is64Bits>
573 ObjectFile::symbol_iterator ELFObjectFile<target_endianness, is64Bits>
574                                          ::begin_symbols() const {
575   DataRefImpl SymbolData;
576   memset(&SymbolData, 0, sizeof(SymbolData));
577   if (SymbolTableSections.size() == 0) {
578     SymbolData.d.a = std::numeric_limits<uint32_t>::max();
579     SymbolData.d.b = std::numeric_limits<uint32_t>::max();
580   } else {
581     SymbolData.d.a = 1; // The 0th symbol in ELF is fake.
582     SymbolData.d.b = 0;
583   }
584   return symbol_iterator(SymbolRef(SymbolData, this));
585 }
586
587 template<support::endianness target_endianness, bool is64Bits>
588 ObjectFile::symbol_iterator ELFObjectFile<target_endianness, is64Bits>
589                                          ::end_symbols() const {
590   DataRefImpl SymbolData;
591   memset(&SymbolData, 0, sizeof(SymbolData));
592   SymbolData.d.a = std::numeric_limits<uint32_t>::max();
593   SymbolData.d.b = std::numeric_limits<uint32_t>::max();
594   return symbol_iterator(SymbolRef(SymbolData, this));
595 }
596
597 template<support::endianness target_endianness, bool is64Bits>
598 ObjectFile::section_iterator ELFObjectFile<target_endianness, is64Bits>
599                                           ::begin_sections() const {
600   DataRefImpl ret;
601   memset(&ret, 0, sizeof(DataRefImpl));
602   ret.p = reinterpret_cast<intptr_t>(base() + Header->e_shoff);
603   return section_iterator(SectionRef(ret, this));
604 }
605
606 template<support::endianness target_endianness, bool is64Bits>
607 ObjectFile::section_iterator ELFObjectFile<target_endianness, is64Bits>
608                                           ::end_sections() const {
609   DataRefImpl ret;
610   memset(&ret, 0, sizeof(DataRefImpl));
611   ret.p = reinterpret_cast<intptr_t>(base()
612                                      + Header->e_shoff
613                                      + (Header->e_shentsize * Header->e_shnum));
614   return section_iterator(SectionRef(ret, this));
615 }
616
617 template<support::endianness target_endianness, bool is64Bits>
618 uint8_t ELFObjectFile<target_endianness, is64Bits>::getBytesInAddress() const {
619   return is64Bits ? 8 : 4;
620 }
621
622 template<support::endianness target_endianness, bool is64Bits>
623 StringRef ELFObjectFile<target_endianness, is64Bits>
624                        ::getFileFormatName() const {
625   switch(Header->e_ident[ELF::EI_CLASS]) {
626   case ELF::ELFCLASS32:
627     switch(Header->e_machine) {
628     case ELF::EM_386:
629       return "ELF32-i386";
630     case ELF::EM_X86_64:
631       return "ELF32-x86-64";
632     default:
633       return "ELF32-unknown";
634     }
635   case ELF::ELFCLASS64:
636     switch(Header->e_machine) {
637     case ELF::EM_386:
638       return "ELF64-i386";
639     case ELF::EM_X86_64:
640       return "ELF64-x86-64";
641     default:
642       return "ELF64-unknown";
643     }
644   default:
645     // FIXME: Proper error handling.
646     report_fatal_error("Invalid ELFCLASS!");
647   }
648 }
649
650 template<support::endianness target_endianness, bool is64Bits>
651 unsigned ELFObjectFile<target_endianness, is64Bits>::getArch() const {
652   switch(Header->e_machine) {
653   case ELF::EM_386:
654     return Triple::x86;
655   case ELF::EM_X86_64:
656     return Triple::x86_64;
657   default:
658     return Triple::UnknownArch;
659   }
660 }
661
662 template<support::endianness target_endianness, bool is64Bits>
663 const typename ELFObjectFile<target_endianness, is64Bits>::Elf_Sym *
664 ELFObjectFile<target_endianness, is64Bits>::getSymbol(DataRefImpl Symb) const {
665   const Elf_Shdr *sec = SymbolTableSections[Symb.d.b];
666   return reinterpret_cast<const Elf_Sym *>(
667            base()
668            + sec->sh_offset
669            + (Symb.d.a * sec->sh_entsize));
670 }
671
672 template<support::endianness target_endianness, bool is64Bits>
673 const typename ELFObjectFile<target_endianness, is64Bits>::Elf_Shdr *
674 ELFObjectFile<target_endianness, is64Bits>::getSection(DataRefImpl Symb) const {
675   const Elf_Shdr *sec = getSection(Symb.d.b);
676   if (sec->sh_type != ELF::SHT_SYMTAB)
677     // FIXME: Proper error handling.
678     report_fatal_error("Invalid symbol table section!");
679   return sec;
680 }
681
682 template<support::endianness target_endianness, bool is64Bits>
683 const typename ELFObjectFile<target_endianness, is64Bits>::Elf_Shdr *
684 ELFObjectFile<target_endianness, is64Bits>::getSection(uint16_t index) const {
685   if (index == 0 || index >= ELF::SHN_LORESERVE)
686     return 0;
687   if (!SectionHeaderTable || index >= Header->e_shnum)
688     // FIXME: Proper error handling.
689     report_fatal_error("Invalid section index!");
690
691   return reinterpret_cast<const Elf_Shdr *>(
692          reinterpret_cast<const char *>(SectionHeaderTable)
693          + (index * Header->e_shentsize));
694 }
695
696 template<support::endianness target_endianness, bool is64Bits>
697 const char *ELFObjectFile<target_endianness, is64Bits>
698                          ::getString(uint16_t section,
699                                      ELF::Elf32_Word offset) const {
700   return getString(getSection(section), offset);
701 }
702
703 template<support::endianness target_endianness, bool is64Bits>
704 const char *ELFObjectFile<target_endianness, is64Bits>
705                          ::getString(const Elf_Shdr *section,
706                                      ELF::Elf32_Word offset) const {
707   assert(section && section->sh_type == ELF::SHT_STRTAB && "Invalid section!");
708   if (offset >= section->sh_size)
709     // FIXME: Proper error handling.
710     report_fatal_error("Symbol name offset outside of string table!");
711   return (const char *)base() + section->sh_offset + offset;
712 }
713
714 // EI_CLASS, EI_DATA.
715 static std::pair<unsigned char, unsigned char>
716 getElfArchType(MemoryBuffer *Object) {
717   if (Object->getBufferSize() < ELF::EI_NIDENT)
718     return std::make_pair((uint8_t)ELF::ELFCLASSNONE,(uint8_t)ELF::ELFDATANONE);
719   return std::make_pair( (uint8_t)Object->getBufferStart()[ELF::EI_CLASS]
720                        , (uint8_t)Object->getBufferStart()[ELF::EI_DATA]);
721 }
722
723 namespace llvm {
724
725   ObjectFile *ObjectFile::createELFObjectFile(MemoryBuffer *Object) {
726     std::pair<unsigned char, unsigned char> Ident = getElfArchType(Object);
727     error_code ec;
728     if (Ident.first == ELF::ELFCLASS32 && Ident.second == ELF::ELFDATA2LSB)
729       return new ELFObjectFile<support::little, false>(Object, ec);
730     else if (Ident.first == ELF::ELFCLASS32 && Ident.second == ELF::ELFDATA2MSB)
731       return new ELFObjectFile<support::big, false>(Object, ec);
732     else if (Ident.first == ELF::ELFCLASS64 && Ident.second == ELF::ELFDATA2LSB)
733       return new ELFObjectFile<support::little, true>(Object, ec);
734     else if (Ident.first == ELF::ELFCLASS64 && Ident.second == ELF::ELFDATA2MSB)
735       return new ELFObjectFile<support::big, true>(Object, ec);
736     // FIXME: Proper error handling.
737     report_fatal_error("Not an ELF object file!");
738   }
739
740 } // end namespace llvm