ELFObjectFile.cpp revision 224145
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
25using namespace llvm;
26using namespace object;
27
28// Templates to choose Elf_Addr and Elf_Off depending on is64Bits.
29namespace {
30template<support::endianness target_endianness>
31struct 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
45namespace {
46template<support::endianness target_endianness, bool is64Bits>
47struct ELFDataTypeTypedefHelper;
48
49/// ELF 32bit types.
50template<support::endianness target_endianness>
51struct 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.
60template<support::endianness target_endianness>
61struct 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) \
72typedef typename \
73  ELFDataTypeTypedefHelper<target_endianness, is64Bits>::Elf_Addr Elf_Addr; \
74typedef typename \
75  ELFDataTypeTypedefHelper<target_endianness, is64Bits>::Elf_Off Elf_Off; \
76typedef typename \
77  ELFDataTypeTypedefHelper<target_endianness, is64Bits>::Elf_Half Elf_Half; \
78typedef typename \
79  ELFDataTypeTypedefHelper<target_endianness, is64Bits>::Elf_Word Elf_Word; \
80typedef typename \
81  ELFDataTypeTypedefHelper<target_endianness, is64Bits>::Elf_Sword Elf_Sword; \
82typedef typename \
83  ELFDataTypeTypedefHelper<target_endianness, is64Bits>::Elf_Xword Elf_Xword; \
84typedef typename \
85  ELFDataTypeTypedefHelper<target_endianness, is64Bits>::Elf_Sxword Elf_Sxword;
86
87  // Section header.
88namespace {
89template<support::endianness target_endianness, bool is64Bits>
90struct Elf_Shdr_Base;
91
92template<support::endianness target_endianness>
93struct 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
107template<support::endianness target_endianness>
108struct 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
122template<support::endianness target_endianness, bool is64Bits>
123struct 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
136namespace {
137template<support::endianness target_endianness, bool is64Bits>
138struct Elf_Sym_Base;
139
140template<support::endianness target_endianness>
141struct 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
151template<support::endianness target_endianness>
152struct 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
162template<support::endianness target_endianness, bool is64Bits>
163struct 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
178namespace {
179template<support::endianness target_endianness, bool is64Bits>
180class 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
224protected:
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
241public:
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
254template<support::endianness target_endianness, bool is64Bits>
255void 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
273template<support::endianness target_endianness, bool is64Bits>
274error_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
297template<support::endianness target_endianness, bool is64Bits>
298error_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
317template<support::endianness target_endianness, bool is64Bits>
318error_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
351template<support::endianness target_endianness, bool is64Bits>
352error_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
363template<support::endianness target_endianness, bool is64Bits>
364error_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
427template<support::endianness target_endianness, bool is64Bits>
428error_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
441template<support::endianness target_endianness, bool is64Bits>
442error_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
451template<support::endianness target_endianness, bool is64Bits>
452error_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
460template<support::endianness target_endianness, bool is64Bits>
461error_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
469template<support::endianness target_endianness, bool is64Bits>
470error_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
478template<support::endianness target_endianness, bool is64Bits>
479error_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
488template<support::endianness target_endianness, bool is64Bits>
489error_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
500template<support::endianness target_endianness, bool is64Bits>
501error_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
510template<support::endianness target_endianness, bool is64Bits>
511ELFObjectFile<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
572template<support::endianness target_endianness, bool is64Bits>
573ObjectFile::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
587template<support::endianness target_endianness, bool is64Bits>
588ObjectFile::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
597template<support::endianness target_endianness, bool is64Bits>
598ObjectFile::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
606template<support::endianness target_endianness, bool is64Bits>
607ObjectFile::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
617template<support::endianness target_endianness, bool is64Bits>
618uint8_t ELFObjectFile<target_endianness, is64Bits>::getBytesInAddress() const {
619  return is64Bits ? 8 : 4;
620}
621
622template<support::endianness target_endianness, bool is64Bits>
623StringRef 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
650template<support::endianness target_endianness, bool is64Bits>
651unsigned 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
662template<support::endianness target_endianness, bool is64Bits>
663const typename ELFObjectFile<target_endianness, is64Bits>::Elf_Sym *
664ELFObjectFile<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
672template<support::endianness target_endianness, bool is64Bits>
673const typename ELFObjectFile<target_endianness, is64Bits>::Elf_Shdr *
674ELFObjectFile<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
682template<support::endianness target_endianness, bool is64Bits>
683const typename ELFObjectFile<target_endianness, is64Bits>::Elf_Shdr *
684ELFObjectFile<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
696template<support::endianness target_endianness, bool is64Bits>
697const char *ELFObjectFile<target_endianness, is64Bits>
698                         ::getString(uint16_t section,
699                                     ELF::Elf32_Word offset) const {
700  return getString(getSection(section), offset);
701}
702
703template<support::endianness target_endianness, bool is64Bits>
704const 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.
715static std::pair<unsigned char, unsigned char>
716getElfArchType(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
723namespace 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
741