ELFObjectFile.cpp revision 221345
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 SymbolRef getSymbolNext(DataRefImpl Symb) const;
226  virtual StringRef getSymbolName(DataRefImpl Symb) const;
227  virtual uint64_t  getSymbolAddress(DataRefImpl Symb) const;
228  virtual uint64_t  getSymbolSize(DataRefImpl Symb) const;
229  virtual char      getSymbolNMTypeChar(DataRefImpl Symb) const;
230  virtual bool      isSymbolInternal(DataRefImpl Symb) const;
231
232  virtual SectionRef getSectionNext(DataRefImpl Sec) const;
233  virtual StringRef  getSectionName(DataRefImpl Sec) const;
234  virtual uint64_t   getSectionAddress(DataRefImpl Sec) const;
235  virtual uint64_t   getSectionSize(DataRefImpl Sec) const;
236  virtual StringRef  getSectionContents(DataRefImpl Sec) const;
237  virtual bool       isSectionText(DataRefImpl Sec) const;
238
239public:
240  ELFObjectFile(MemoryBuffer *Object);
241  virtual symbol_iterator begin_symbols() const;
242  virtual symbol_iterator end_symbols() const;
243  virtual section_iterator begin_sections() const;
244  virtual section_iterator end_sections() const;
245
246  virtual uint8_t getBytesInAddress() const;
247  virtual StringRef getFileFormatName() const;
248  virtual unsigned getArch() const;
249};
250} // end namespace
251
252template<support::endianness target_endianness, bool is64Bits>
253void ELFObjectFile<target_endianness, is64Bits>
254                  ::validateSymbol(DataRefImpl Symb) const {
255  const Elf_Sym  *symb = getSymbol(Symb);
256  const Elf_Shdr *SymbolTableSection = SymbolTableSections[Symb.d.b];
257  // FIXME: We really need to do proper error handling in the case of an invalid
258  //        input file. Because we don't use exceptions, I think we'll just pass
259  //        an error object around.
260  if (!(  symb
261        && SymbolTableSection
262        && symb >= (const Elf_Sym*)(base
263                   + SymbolTableSection->sh_offset)
264        && symb <  (const Elf_Sym*)(base
265                   + SymbolTableSection->sh_offset
266                   + SymbolTableSection->sh_size)))
267    // FIXME: Proper error handling.
268    report_fatal_error("Symb must point to a valid symbol!");
269}
270
271template<support::endianness target_endianness, bool is64Bits>
272SymbolRef ELFObjectFile<target_endianness, is64Bits>
273                       ::getSymbolNext(DataRefImpl Symb) const {
274  validateSymbol(Symb);
275  const Elf_Shdr *SymbolTableSection = SymbolTableSections[Symb.d.b];
276
277  ++Symb.d.a;
278  // Check to see if we are at the end of this symbol table.
279  if (Symb.d.a >= SymbolTableSection->getEntityCount()) {
280    // We are at the end. If there are other symbol tables, jump to them.
281    ++Symb.d.b;
282    Symb.d.a = 1; // The 0th symbol in ELF is fake.
283    // Otherwise return the terminator.
284    if (Symb.d.b >= SymbolTableSections.size()) {
285      Symb.d.a = std::numeric_limits<uint32_t>::max();
286      Symb.d.b = std::numeric_limits<uint32_t>::max();
287    }
288  }
289
290  return SymbolRef(Symb, this);
291}
292
293template<support::endianness target_endianness, bool is64Bits>
294StringRef ELFObjectFile<target_endianness, is64Bits>
295                       ::getSymbolName(DataRefImpl Symb) const {
296  validateSymbol(Symb);
297  const Elf_Sym  *symb = getSymbol(Symb);
298  if (symb->st_name == 0) {
299    const Elf_Shdr *section = getSection(symb->st_shndx);
300    if (!section)
301      return "";
302    return getString(dot_shstrtab_sec, section->sh_name);
303  }
304
305  // Use the default symbol table name section.
306  return getString(dot_strtab_sec, symb->st_name);
307}
308
309template<support::endianness target_endianness, bool is64Bits>
310uint64_t ELFObjectFile<target_endianness, is64Bits>
311                      ::getSymbolAddress(DataRefImpl Symb) const {
312  validateSymbol(Symb);
313  const Elf_Sym  *symb = getSymbol(Symb);
314  const Elf_Shdr *Section;
315  switch (symb->st_shndx) {
316  case ELF::SHN_COMMON:
317   // Undefined symbols have no address yet.
318  case ELF::SHN_UNDEF: return UnknownAddressOrSize;
319  case ELF::SHN_ABS: return symb->st_value;
320  default: Section = getSection(symb->st_shndx);
321  }
322
323  switch (symb->getType()) {
324  case ELF::STT_SECTION: return Section ? Section->sh_addr
325                                        : UnknownAddressOrSize;
326  case ELF::STT_FUNC:
327  case ELF::STT_OBJECT:
328  case ELF::STT_NOTYPE:
329    return symb->st_value;
330  default: return UnknownAddressOrSize;
331  }
332}
333
334template<support::endianness target_endianness, bool is64Bits>
335uint64_t ELFObjectFile<target_endianness, is64Bits>
336                      ::getSymbolSize(DataRefImpl Symb) const {
337  validateSymbol(Symb);
338  const Elf_Sym  *symb = getSymbol(Symb);
339  if (symb->st_size == 0)
340    return UnknownAddressOrSize;
341  return symb->st_size;
342}
343
344template<support::endianness target_endianness, bool is64Bits>
345char ELFObjectFile<target_endianness, is64Bits>
346                  ::getSymbolNMTypeChar(DataRefImpl Symb) const {
347  validateSymbol(Symb);
348  const Elf_Sym  *symb = getSymbol(Symb);
349  const Elf_Shdr *Section = getSection(symb->st_shndx);
350
351  char ret = '?';
352
353  if (Section) {
354    switch (Section->sh_type) {
355    case ELF::SHT_PROGBITS:
356    case ELF::SHT_DYNAMIC:
357      switch (Section->sh_flags) {
358      case (ELF::SHF_ALLOC | ELF::SHF_EXECINSTR):
359        ret = 't'; break;
360      case (ELF::SHF_ALLOC | ELF::SHF_WRITE):
361        ret = 'd'; break;
362      case ELF::SHF_ALLOC:
363      case (ELF::SHF_ALLOC | ELF::SHF_MERGE):
364      case (ELF::SHF_ALLOC | ELF::SHF_MERGE | ELF::SHF_STRINGS):
365        ret = 'r'; break;
366      }
367      break;
368    case ELF::SHT_NOBITS: ret = 'b';
369    }
370  }
371
372  switch (symb->st_shndx) {
373  case ELF::SHN_UNDEF:
374    if (ret == '?')
375      ret = 'U';
376    break;
377  case ELF::SHN_ABS: ret = 'a'; break;
378  case ELF::SHN_COMMON: ret = 'c'; break;
379  }
380
381  switch (symb->getBinding()) {
382  case ELF::STB_GLOBAL: ret = ::toupper(ret); break;
383  case ELF::STB_WEAK:
384    if (symb->st_shndx == ELF::SHN_UNDEF)
385      ret = 'w';
386    else
387      if (symb->getType() == ELF::STT_OBJECT)
388        ret = 'V';
389      else
390        ret = 'W';
391  }
392
393  if (ret == '?' && symb->getType() == ELF::STT_SECTION)
394    return StringSwitch<char>(getSymbolName(Symb))
395      .StartsWith(".debug", 'N')
396      .StartsWith(".note", 'n');
397
398  return ret;
399}
400
401template<support::endianness target_endianness, bool is64Bits>
402bool ELFObjectFile<target_endianness, is64Bits>
403                  ::isSymbolInternal(DataRefImpl Symb) const {
404  validateSymbol(Symb);
405  const Elf_Sym  *symb = getSymbol(Symb);
406
407  if (  symb->getType() == ELF::STT_FILE
408     || symb->getType() == ELF::STT_SECTION)
409    return true;
410  return false;
411}
412
413template<support::endianness target_endianness, bool is64Bits>
414SectionRef ELFObjectFile<target_endianness, is64Bits>
415                        ::getSectionNext(DataRefImpl Sec) const {
416  const uint8_t *sec = reinterpret_cast<const uint8_t *>(Sec.p);
417  sec += Header->e_shentsize;
418  Sec.p = reinterpret_cast<intptr_t>(sec);
419  return SectionRef(Sec, this);
420}
421
422template<support::endianness target_endianness, bool is64Bits>
423StringRef ELFObjectFile<target_endianness, is64Bits>
424                       ::getSectionName(DataRefImpl Sec) const {
425  const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p);
426  return StringRef(getString(dot_shstrtab_sec, sec->sh_name));
427}
428
429template<support::endianness target_endianness, bool is64Bits>
430uint64_t ELFObjectFile<target_endianness, is64Bits>
431                      ::getSectionAddress(DataRefImpl Sec) const {
432  const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p);
433  return sec->sh_addr;
434}
435
436template<support::endianness target_endianness, bool is64Bits>
437uint64_t ELFObjectFile<target_endianness, is64Bits>
438                      ::getSectionSize(DataRefImpl Sec) const {
439  const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p);
440  return sec->sh_size;
441}
442
443template<support::endianness target_endianness, bool is64Bits>
444StringRef ELFObjectFile<target_endianness, is64Bits>
445                       ::getSectionContents(DataRefImpl Sec) const {
446  const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p);
447  const char *start = (char*)base + sec->sh_offset;
448  return StringRef(start, sec->sh_size);
449}
450
451template<support::endianness target_endianness, bool is64Bits>
452bool ELFObjectFile<target_endianness, is64Bits>
453                  ::isSectionText(DataRefImpl Sec) const {
454  const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p);
455  if (sec->sh_flags & ELF::SHF_EXECINSTR)
456    return true;
457  return false;
458}
459
460template<support::endianness target_endianness, bool is64Bits>
461ELFObjectFile<target_endianness, is64Bits>::ELFObjectFile(MemoryBuffer *Object)
462  : ObjectFile(Object)
463  , SectionHeaderTable(0)
464  , dot_shstrtab_sec(0)
465  , dot_strtab_sec(0) {
466  Header = reinterpret_cast<const Elf_Ehdr *>(base);
467
468  if (Header->e_shoff == 0)
469    return;
470
471  SectionHeaderTable =
472    reinterpret_cast<const Elf_Shdr *>(base + Header->e_shoff);
473  uint32_t SectionTableSize = Header->e_shnum * Header->e_shentsize;
474  if (!(  (const uint8_t *)SectionHeaderTable + SectionTableSize
475         <= base + MapFile->getBufferSize()))
476    // FIXME: Proper error handling.
477    report_fatal_error("Section table goes past end of file!");
478
479
480  // To find the symbol tables we walk the section table to find SHT_STMTAB.
481  for (const char *i = reinterpret_cast<const char *>(SectionHeaderTable),
482                  *e = i + Header->e_shnum * Header->e_shentsize;
483                   i != e; i += Header->e_shentsize) {
484    const Elf_Shdr *sh = reinterpret_cast<const Elf_Shdr*>(i);
485    if (sh->sh_type == ELF::SHT_SYMTAB) {
486      SymbolTableSections.push_back(sh);
487    }
488  }
489
490  // Get string table sections.
491  dot_shstrtab_sec = getSection(Header->e_shstrndx);
492  if (dot_shstrtab_sec) {
493    // Verify that the last byte in the string table in a null.
494    if (((const char*)base + dot_shstrtab_sec->sh_offset)
495        [dot_shstrtab_sec->sh_size - 1] != 0)
496      // FIXME: Proper error handling.
497      report_fatal_error("String table must end with a null terminator!");
498  }
499
500  // Merge this into the above loop.
501  for (const char *i = reinterpret_cast<const char *>(SectionHeaderTable),
502                  *e = i + Header->e_shnum * Header->e_shentsize;
503                   i != e; i += Header->e_shentsize) {
504    const Elf_Shdr *sh = reinterpret_cast<const Elf_Shdr*>(i);
505    if (sh->sh_type == ELF::SHT_STRTAB) {
506      StringRef SectionName(getString(dot_shstrtab_sec, sh->sh_name));
507      if (SectionName == ".strtab") {
508        if (dot_strtab_sec != 0)
509          // FIXME: Proper error handling.
510          report_fatal_error("Already found section named .strtab!");
511        dot_strtab_sec = sh;
512        const char *dot_strtab = (const char*)base + sh->sh_offset;
513          if (dot_strtab[sh->sh_size - 1] != 0)
514            // FIXME: Proper error handling.
515            report_fatal_error("String table must end with a null terminator!");
516      }
517    }
518  }
519}
520
521template<support::endianness target_endianness, bool is64Bits>
522ObjectFile::symbol_iterator ELFObjectFile<target_endianness, is64Bits>
523                                         ::begin_symbols() const {
524  DataRefImpl SymbolData;
525  memset(&SymbolData, 0, sizeof(SymbolData));
526  if (SymbolTableSections.size() == 0) {
527    SymbolData.d.a = std::numeric_limits<uint32_t>::max();
528    SymbolData.d.b = std::numeric_limits<uint32_t>::max();
529  } else {
530    SymbolData.d.a = 1; // The 0th symbol in ELF is fake.
531    SymbolData.d.b = 0;
532  }
533  return symbol_iterator(SymbolRef(SymbolData, this));
534}
535
536template<support::endianness target_endianness, bool is64Bits>
537ObjectFile::symbol_iterator ELFObjectFile<target_endianness, is64Bits>
538                                         ::end_symbols() const {
539  DataRefImpl SymbolData;
540  memset(&SymbolData, 0, sizeof(SymbolData));
541  SymbolData.d.a = std::numeric_limits<uint32_t>::max();
542  SymbolData.d.b = std::numeric_limits<uint32_t>::max();
543  return symbol_iterator(SymbolRef(SymbolData, this));
544}
545
546template<support::endianness target_endianness, bool is64Bits>
547ObjectFile::section_iterator ELFObjectFile<target_endianness, is64Bits>
548                                          ::begin_sections() const {
549  DataRefImpl ret;
550  memset(&ret, 0, sizeof(DataRefImpl));
551  ret.p = reinterpret_cast<intptr_t>(base + Header->e_shoff);
552  return section_iterator(SectionRef(ret, this));
553}
554
555template<support::endianness target_endianness, bool is64Bits>
556ObjectFile::section_iterator ELFObjectFile<target_endianness, is64Bits>
557                                          ::end_sections() const {
558  DataRefImpl ret;
559  memset(&ret, 0, sizeof(DataRefImpl));
560  ret.p = reinterpret_cast<intptr_t>(base
561                                     + Header->e_shoff
562                                     + (Header->e_shentsize * Header->e_shnum));
563  return section_iterator(SectionRef(ret, this));
564}
565
566template<support::endianness target_endianness, bool is64Bits>
567uint8_t ELFObjectFile<target_endianness, is64Bits>::getBytesInAddress() const {
568  return is64Bits ? 8 : 4;
569}
570
571template<support::endianness target_endianness, bool is64Bits>
572StringRef ELFObjectFile<target_endianness, is64Bits>
573                       ::getFileFormatName() const {
574  switch(Header->e_ident[ELF::EI_CLASS]) {
575  case ELF::ELFCLASS32:
576    switch(Header->e_machine) {
577    case ELF::EM_386:
578      return "ELF32-i386";
579    case ELF::EM_X86_64:
580      return "ELF32-x86-64";
581    default:
582      return "ELF32-unknown";
583    }
584  case ELF::ELFCLASS64:
585    switch(Header->e_machine) {
586    case ELF::EM_386:
587      return "ELF64-i386";
588    case ELF::EM_X86_64:
589      return "ELF64-x86-64";
590    default:
591      return "ELF64-unknown";
592    }
593  default:
594    // FIXME: Proper error handling.
595    report_fatal_error("Invalid ELFCLASS!");
596  }
597}
598
599template<support::endianness target_endianness, bool is64Bits>
600unsigned ELFObjectFile<target_endianness, is64Bits>::getArch() const {
601  switch(Header->e_machine) {
602  case ELF::EM_386:
603    return Triple::x86;
604  case ELF::EM_X86_64:
605    return Triple::x86_64;
606  default:
607    return Triple::UnknownArch;
608  }
609}
610
611template<support::endianness target_endianness, bool is64Bits>
612const typename ELFObjectFile<target_endianness, is64Bits>::Elf_Sym *
613ELFObjectFile<target_endianness, is64Bits>::getSymbol(DataRefImpl Symb) const {
614  const Elf_Shdr *sec = SymbolTableSections[Symb.d.b];
615  return reinterpret_cast<const Elf_Sym *>(
616           base
617           + sec->sh_offset
618           + (Symb.d.a * sec->sh_entsize));
619}
620
621template<support::endianness target_endianness, bool is64Bits>
622const typename ELFObjectFile<target_endianness, is64Bits>::Elf_Shdr *
623ELFObjectFile<target_endianness, is64Bits>::getSection(DataRefImpl Symb) const {
624  const Elf_Shdr *sec = getSection(Symb.d.b);
625  if (sec->sh_type != ELF::SHT_SYMTAB)
626    // FIXME: Proper error handling.
627    report_fatal_error("Invalid symbol table section!");
628  return sec;
629}
630
631template<support::endianness target_endianness, bool is64Bits>
632const typename ELFObjectFile<target_endianness, is64Bits>::Elf_Shdr *
633ELFObjectFile<target_endianness, is64Bits>::getSection(uint16_t index) const {
634  if (index == 0 || index >= ELF::SHN_LORESERVE)
635    return 0;
636  if (!SectionHeaderTable || index >= Header->e_shnum)
637    // FIXME: Proper error handling.
638    report_fatal_error("Invalid section index!");
639
640  return reinterpret_cast<const Elf_Shdr *>(
641         reinterpret_cast<const char *>(SectionHeaderTable)
642         + (index * Header->e_shentsize));
643}
644
645template<support::endianness target_endianness, bool is64Bits>
646const char *ELFObjectFile<target_endianness, is64Bits>
647                         ::getString(uint16_t section,
648                                     ELF::Elf32_Word offset) const {
649  return getString(getSection(section), offset);
650}
651
652template<support::endianness target_endianness, bool is64Bits>
653const char *ELFObjectFile<target_endianness, is64Bits>
654                         ::getString(const Elf_Shdr *section,
655                                     ELF::Elf32_Word offset) const {
656  assert(section && section->sh_type == ELF::SHT_STRTAB && "Invalid section!");
657  if (offset >= section->sh_size)
658    // FIXME: Proper error handling.
659    report_fatal_error("Sybol name offset outside of string table!");
660  return (const char *)base + section->sh_offset + offset;
661}
662
663// EI_CLASS, EI_DATA.
664static std::pair<unsigned char, unsigned char>
665getElfArchType(MemoryBuffer *Object) {
666  if (Object->getBufferSize() < ELF::EI_NIDENT)
667    return std::make_pair((uint8_t)ELF::ELFCLASSNONE,(uint8_t)ELF::ELFDATANONE);
668  return std::make_pair( (uint8_t)Object->getBufferStart()[ELF::EI_CLASS]
669                       , (uint8_t)Object->getBufferStart()[ELF::EI_DATA]);
670}
671
672namespace llvm {
673
674  ObjectFile *ObjectFile::createELFObjectFile(MemoryBuffer *Object) {
675    std::pair<unsigned char, unsigned char> Ident = getElfArchType(Object);
676    if (Ident.first == ELF::ELFCLASS32 && Ident.second == ELF::ELFDATA2LSB)
677      return new ELFObjectFile<support::little, false>(Object);
678    else if (Ident.first == ELF::ELFCLASS32 && Ident.second == ELF::ELFDATA2MSB)
679      return new ELFObjectFile<support::big, false>(Object);
680    else if (Ident.first == ELF::ELFCLASS64 && Ident.second == ELF::ELFDATA2LSB)
681      return new ELFObjectFile<support::little, true>(Object);
682    else if (Ident.first == ELF::ELFCLASS64 && Ident.second == ELF::ELFDATA2MSB)
683      return new ELFObjectFile<support::big, true>(Object);
684    // FIXME: Proper error handling.
685    report_fatal_error("Not an ELF object file!");
686  }
687
688} // end namespace llvm
689