1 //===- ELF.h - ELF object file implementation -------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file declares the ELFObjectFile template class.
12 //===----------------------------------------------------------------------===//
14 #ifndef LLVM_OBJECT_ELF_H
15 #define LLVM_OBJECT_ELF_H
17 #include "llvm/ADT/SmallVector.h"
18 #include "llvm/ADT/StringSwitch.h"
19 #include "llvm/ADT/Triple.h"
20 #include "llvm/ADT/DenseMap.h"
21 #include "llvm/Object/ObjectFile.h"
22 #include "llvm/Support/Casting.h"
23 #include "llvm/Support/ELF.h"
24 #include "llvm/Support/Endian.h"
25 #include "llvm/Support/ErrorHandling.h"
26 #include "llvm/Support/MemoryBuffer.h"
27 #include "llvm/Support/raw_ostream.h"
35 // Templates to choose Elf_Addr and Elf_Off depending on is64Bits.
36 template<support::endianness target_endianness>
37 struct ELFDataTypeTypedefHelperCommon {
38 typedef support::detail::packed_endian_specific_integral
39 <uint16_t, target_endianness, support::aligned> Elf_Half;
40 typedef support::detail::packed_endian_specific_integral
41 <uint32_t, target_endianness, support::aligned> Elf_Word;
42 typedef support::detail::packed_endian_specific_integral
43 <int32_t, target_endianness, support::aligned> Elf_Sword;
44 typedef support::detail::packed_endian_specific_integral
45 <uint64_t, target_endianness, support::aligned> Elf_Xword;
46 typedef support::detail::packed_endian_specific_integral
47 <int64_t, target_endianness, support::aligned> Elf_Sxword;
50 template<support::endianness target_endianness, bool is64Bits>
51 struct ELFDataTypeTypedefHelper;
54 template<support::endianness target_endianness>
55 struct ELFDataTypeTypedefHelper<target_endianness, false>
56 : ELFDataTypeTypedefHelperCommon<target_endianness> {
57 typedef uint32_t value_type;
58 typedef support::detail::packed_endian_specific_integral
59 <value_type, target_endianness, support::aligned> Elf_Addr;
60 typedef support::detail::packed_endian_specific_integral
61 <value_type, target_endianness, support::aligned> Elf_Off;
65 template<support::endianness target_endianness>
66 struct ELFDataTypeTypedefHelper<target_endianness, true>
67 : ELFDataTypeTypedefHelperCommon<target_endianness>{
68 typedef uint64_t value_type;
69 typedef support::detail::packed_endian_specific_integral
70 <value_type, target_endianness, support::aligned> Elf_Addr;
71 typedef support::detail::packed_endian_specific_integral
72 <value_type, target_endianness, support::aligned> Elf_Off;
75 // I really don't like doing this, but the alternative is copypasta.
76 #define LLVM_ELF_IMPORT_TYPES(target_endianness, is64Bits) \
78 ELFDataTypeTypedefHelper<target_endianness, is64Bits>::Elf_Addr Elf_Addr; \
80 ELFDataTypeTypedefHelper<target_endianness, is64Bits>::Elf_Off Elf_Off; \
82 ELFDataTypeTypedefHelper<target_endianness, is64Bits>::Elf_Half Elf_Half; \
84 ELFDataTypeTypedefHelper<target_endianness, is64Bits>::Elf_Word Elf_Word; \
86 ELFDataTypeTypedefHelper<target_endianness, is64Bits>::Elf_Sword Elf_Sword; \
88 ELFDataTypeTypedefHelper<target_endianness, is64Bits>::Elf_Xword Elf_Xword; \
90 ELFDataTypeTypedefHelper<target_endianness, is64Bits>::Elf_Sxword Elf_Sxword;
93 template<support::endianness target_endianness, bool is64Bits>
96 template<support::endianness target_endianness>
97 struct Elf_Shdr_Base<target_endianness, false> {
98 LLVM_ELF_IMPORT_TYPES(target_endianness, false)
99 Elf_Word sh_name; // Section name (index into string table)
100 Elf_Word sh_type; // Section type (SHT_*)
101 Elf_Word sh_flags; // Section flags (SHF_*)
102 Elf_Addr sh_addr; // Address where section is to be loaded
103 Elf_Off sh_offset; // File offset of section data, in bytes
104 Elf_Word sh_size; // Size of section, in bytes
105 Elf_Word sh_link; // Section type-specific header table index link
106 Elf_Word sh_info; // Section type-specific extra information
107 Elf_Word sh_addralign;// Section address alignment
108 Elf_Word sh_entsize; // Size of records contained within the section
111 template<support::endianness target_endianness>
112 struct Elf_Shdr_Base<target_endianness, true> {
113 LLVM_ELF_IMPORT_TYPES(target_endianness, true)
114 Elf_Word sh_name; // Section name (index into string table)
115 Elf_Word sh_type; // Section type (SHT_*)
116 Elf_Xword sh_flags; // Section flags (SHF_*)
117 Elf_Addr sh_addr; // Address where section is to be loaded
118 Elf_Off sh_offset; // File offset of section data, in bytes
119 Elf_Xword sh_size; // Size of section, in bytes
120 Elf_Word sh_link; // Section type-specific header table index link
121 Elf_Word sh_info; // Section type-specific extra information
122 Elf_Xword sh_addralign;// Section address alignment
123 Elf_Xword sh_entsize; // Size of records contained within the section
126 template<support::endianness target_endianness, bool is64Bits>
127 struct Elf_Shdr_Impl : Elf_Shdr_Base<target_endianness, is64Bits> {
128 using Elf_Shdr_Base<target_endianness, is64Bits>::sh_entsize;
129 using Elf_Shdr_Base<target_endianness, is64Bits>::sh_size;
131 /// @brief Get the number of entities this section contains if it has any.
132 unsigned getEntityCount() const {
135 return sh_size / sh_entsize;
139 template<support::endianness target_endianness, bool is64Bits>
142 template<support::endianness target_endianness>
143 struct Elf_Sym_Base<target_endianness, false> {
144 LLVM_ELF_IMPORT_TYPES(target_endianness, false)
145 Elf_Word st_name; // Symbol name (index into string table)
146 Elf_Addr st_value; // Value or address associated with the symbol
147 Elf_Word st_size; // Size of the symbol
148 unsigned char st_info; // Symbol's type and binding attributes
149 unsigned char st_other; // Must be zero; reserved
150 Elf_Half st_shndx; // Which section (header table index) it's defined in
153 template<support::endianness target_endianness>
154 struct Elf_Sym_Base<target_endianness, true> {
155 LLVM_ELF_IMPORT_TYPES(target_endianness, true)
156 Elf_Word st_name; // Symbol name (index into string table)
157 unsigned char st_info; // Symbol's type and binding attributes
158 unsigned char st_other; // Must be zero; reserved
159 Elf_Half st_shndx; // Which section (header table index) it's defined in
160 Elf_Addr st_value; // Value or address associated with the symbol
161 Elf_Xword st_size; // Size of the symbol
164 template<support::endianness target_endianness, bool is64Bits>
165 struct Elf_Sym_Impl : Elf_Sym_Base<target_endianness, is64Bits> {
166 using Elf_Sym_Base<target_endianness, is64Bits>::st_info;
168 // These accessors and mutators correspond to the ELF32_ST_BIND,
169 // ELF32_ST_TYPE, and ELF32_ST_INFO macros defined in the ELF specification:
170 unsigned char getBinding() const { return st_info >> 4; }
171 unsigned char getType() const { return st_info & 0x0f; }
172 void setBinding(unsigned char b) { setBindingAndType(b, getType()); }
173 void setType(unsigned char t) { setBindingAndType(getBinding(), t); }
174 void setBindingAndType(unsigned char b, unsigned char t) {
175 st_info = (b << 4) + (t & 0x0f);
179 template<support::endianness target_endianness, bool is64Bits, bool isRela>
182 template<support::endianness target_endianness>
183 struct Elf_Rel_Base<target_endianness, false, false> {
184 LLVM_ELF_IMPORT_TYPES(target_endianness, false)
185 Elf_Addr r_offset; // Location (file byte offset, or program virtual addr)
186 Elf_Word r_info; // Symbol table index and type of relocation to apply
189 template<support::endianness target_endianness>
190 struct Elf_Rel_Base<target_endianness, true, false> {
191 LLVM_ELF_IMPORT_TYPES(target_endianness, true)
192 Elf_Addr r_offset; // Location (file byte offset, or program virtual addr)
193 Elf_Xword r_info; // Symbol table index and type of relocation to apply
196 template<support::endianness target_endianness>
197 struct Elf_Rel_Base<target_endianness, false, true> {
198 LLVM_ELF_IMPORT_TYPES(target_endianness, false)
199 Elf_Addr r_offset; // Location (file byte offset, or program virtual addr)
200 Elf_Word r_info; // Symbol table index and type of relocation to apply
201 Elf_Sword r_addend; // Compute value for relocatable field by adding this
204 template<support::endianness target_endianness>
205 struct Elf_Rel_Base<target_endianness, true, true> {
206 LLVM_ELF_IMPORT_TYPES(target_endianness, true)
207 Elf_Addr r_offset; // Location (file byte offset, or program virtual addr)
208 Elf_Xword r_info; // Symbol table index and type of relocation to apply
209 Elf_Sxword r_addend; // Compute value for relocatable field by adding this.
212 template<support::endianness target_endianness, bool is64Bits, bool isRela>
215 template<support::endianness target_endianness, bool isRela>
216 struct Elf_Rel_Impl<target_endianness, true, isRela>
217 : Elf_Rel_Base<target_endianness, true, isRela> {
218 using Elf_Rel_Base<target_endianness, true, isRela>::r_info;
219 LLVM_ELF_IMPORT_TYPES(target_endianness, true)
221 // These accessors and mutators correspond to the ELF64_R_SYM, ELF64_R_TYPE,
222 // and ELF64_R_INFO macros defined in the ELF specification:
223 uint64_t getSymbol() const { return (r_info >> 32); }
224 unsigned char getType() const {
225 return (unsigned char) (r_info & 0xffffffffL);
227 void setSymbol(uint64_t s) { setSymbolAndType(s, getType()); }
228 void setType(unsigned char t) { setSymbolAndType(getSymbol(), t); }
229 void setSymbolAndType(uint64_t s, unsigned char t) {
230 r_info = (s << 32) + (t&0xffffffffL);
234 template<support::endianness target_endianness, bool isRela>
235 struct Elf_Rel_Impl<target_endianness, false, isRela>
236 : Elf_Rel_Base<target_endianness, false, isRela> {
237 using Elf_Rel_Base<target_endianness, false, isRela>::r_info;
238 LLVM_ELF_IMPORT_TYPES(target_endianness, false)
240 // These accessors and mutators correspond to the ELF32_R_SYM, ELF32_R_TYPE,
241 // and ELF32_R_INFO macros defined in the ELF specification:
242 uint32_t getSymbol() const { return (r_info >> 8); }
243 unsigned char getType() const { return (unsigned char) (r_info & 0x0ff); }
244 void setSymbol(uint32_t s) { setSymbolAndType(s, getType()); }
245 void setType(unsigned char t) { setSymbolAndType(getSymbol(), t); }
246 void setSymbolAndType(uint32_t s, unsigned char t) {
247 r_info = (s << 8) + t;
252 template<support::endianness target_endianness, bool is64Bits>
253 class ELFObjectFile : public ObjectFile {
254 LLVM_ELF_IMPORT_TYPES(target_endianness, is64Bits)
256 typedef Elf_Shdr_Impl<target_endianness, is64Bits> Elf_Shdr;
257 typedef Elf_Sym_Impl<target_endianness, is64Bits> Elf_Sym;
258 typedef Elf_Rel_Impl<target_endianness, is64Bits, false> Elf_Rel;
259 typedef Elf_Rel_Impl<target_endianness, is64Bits, true> Elf_Rela;
263 unsigned char e_ident[ELF::EI_NIDENT]; // ELF Identification bytes
264 Elf_Half e_type; // Type of file (see ET_*)
265 Elf_Half e_machine; // Required architecture for this file (see EM_*)
266 Elf_Word e_version; // Must be equal to 1
267 Elf_Addr e_entry; // Address to jump to in order to start program
268 Elf_Off e_phoff; // Program header table's file offset, in bytes
269 Elf_Off e_shoff; // Section header table's file offset, in bytes
270 Elf_Word e_flags; // Processor-specific flags
271 Elf_Half e_ehsize; // Size of ELF header, in bytes
272 Elf_Half e_phentsize;// Size of an entry in the program header table
273 Elf_Half e_phnum; // Number of entries in the program header table
274 Elf_Half e_shentsize;// Size of an entry in the section header table
275 Elf_Half e_shnum; // Number of entries in the section header table
276 Elf_Half e_shstrndx; // Section header table index of section name
278 bool checkMagic() const {
279 return (memcmp(e_ident, ELF::ElfMagic, strlen(ELF::ElfMagic))) == 0;
281 unsigned char getFileClass() const { return e_ident[ELF::EI_CLASS]; }
282 unsigned char getDataEncoding() const { return e_ident[ELF::EI_DATA]; }
284 // This flag is used for classof, to distinguish ELFObjectFile from
285 // its subclass. If more subclasses will be created, this flag will
286 // have to become an enum.
287 bool isDyldELFObject;
290 typedef SmallVector<const Elf_Shdr*, 1> Sections_t;
291 typedef DenseMap<unsigned, unsigned> IndexMap_t;
292 typedef DenseMap<const Elf_Shdr*, SmallVector<uint32_t, 1> > RelocMap_t;
294 const Elf_Ehdr *Header;
295 const Elf_Shdr *SectionHeaderTable;
296 const Elf_Shdr *dot_shstrtab_sec; // Section header string table.
297 const Elf_Shdr *dot_strtab_sec; // Symbol header string table.
298 const Elf_Shdr *dot_dynstr_sec; // Dynamic symbol string table.
299 Sections_t SymbolTableSections;
300 IndexMap_t SymbolTableSectionsIndexMap;
301 DenseMap<const Elf_Sym*, ELF::Elf64_Word> ExtendedSymbolTable;
303 /// @brief Map sections to an array of relocation sections that reference
304 /// them sorted by section index.
305 RelocMap_t SectionRelocMap;
307 /// @brief Get the relocation section that contains \a Rel.
308 const Elf_Shdr *getRelSection(DataRefImpl Rel) const {
309 return getSection(Rel.w.b);
312 bool isRelocationHasAddend(DataRefImpl Rel) const;
314 const T *getEntry(uint16_t Section, uint32_t Entry) const;
316 const T *getEntry(const Elf_Shdr *Section, uint32_t Entry) const;
317 const Elf_Shdr *getSection(DataRefImpl index) const;
318 const Elf_Shdr *getSection(uint32_t index) const;
319 const Elf_Rel *getRel(DataRefImpl Rel) const;
320 const Elf_Rela *getRela(DataRefImpl Rela) const;
321 const char *getString(uint32_t section, uint32_t offset) const;
322 const char *getString(const Elf_Shdr *section, uint32_t offset) const;
323 error_code getSymbolName(const Elf_Shdr *section,
325 StringRef &Res) const;
326 void VerifyStrTab(const Elf_Shdr *sh) const;
329 const Elf_Sym *getSymbol(DataRefImpl Symb) const; // FIXME: Should be private?
330 void validateSymbol(DataRefImpl Symb) const;
333 virtual error_code getSymbolNext(DataRefImpl Symb, SymbolRef &Res) const;
334 virtual error_code getSymbolName(DataRefImpl Symb, StringRef &Res) const;
335 virtual error_code getSymbolFileOffset(DataRefImpl Symb, uint64_t &Res) const;
336 virtual error_code getSymbolAddress(DataRefImpl Symb, uint64_t &Res) const;
337 virtual error_code getSymbolSize(DataRefImpl Symb, uint64_t &Res) const;
338 virtual error_code getSymbolNMTypeChar(DataRefImpl Symb, char &Res) const;
339 virtual error_code getSymbolFlags(DataRefImpl Symb, uint32_t &Res) const;
340 virtual error_code getSymbolType(DataRefImpl Symb, SymbolRef::Type &Res) const;
341 virtual error_code getSymbolSection(DataRefImpl Symb,
342 section_iterator &Res) const;
344 virtual error_code getSectionNext(DataRefImpl Sec, SectionRef &Res) const;
345 virtual error_code getSectionName(DataRefImpl Sec, StringRef &Res) const;
346 virtual error_code getSectionAddress(DataRefImpl Sec, uint64_t &Res) const;
347 virtual error_code getSectionSize(DataRefImpl Sec, uint64_t &Res) const;
348 virtual error_code getSectionContents(DataRefImpl Sec, StringRef &Res) const;
349 virtual error_code getSectionAlignment(DataRefImpl Sec, uint64_t &Res) const;
350 virtual error_code isSectionText(DataRefImpl Sec, bool &Res) const;
351 virtual error_code isSectionData(DataRefImpl Sec, bool &Res) const;
352 virtual error_code isSectionBSS(DataRefImpl Sec, bool &Res) const;
353 virtual error_code sectionContainsSymbol(DataRefImpl Sec, DataRefImpl Symb,
355 virtual relocation_iterator getSectionRelBegin(DataRefImpl Sec) const;
356 virtual relocation_iterator getSectionRelEnd(DataRefImpl Sec) const;
358 virtual error_code getRelocationNext(DataRefImpl Rel,
359 RelocationRef &Res) const;
360 virtual error_code getRelocationAddress(DataRefImpl Rel,
361 uint64_t &Res) const;
362 virtual error_code getRelocationOffset(DataRefImpl Rel,
363 uint64_t &Res) const;
364 virtual error_code getRelocationSymbol(DataRefImpl Rel,
365 SymbolRef &Res) const;
366 virtual error_code getRelocationType(DataRefImpl Rel,
367 uint64_t &Res) const;
368 virtual error_code getRelocationTypeName(DataRefImpl Rel,
369 SmallVectorImpl<char> &Result) const;
370 virtual error_code getRelocationAdditionalInfo(DataRefImpl Rel,
372 virtual error_code getRelocationValueString(DataRefImpl Rel,
373 SmallVectorImpl<char> &Result) const;
376 ELFObjectFile(MemoryBuffer *Object, error_code &ec);
377 virtual symbol_iterator begin_symbols() const;
378 virtual symbol_iterator end_symbols() const;
379 virtual symbol_iterator begin_dynamic_symbols() const;
380 virtual symbol_iterator end_dynamic_symbols() const;
381 virtual section_iterator begin_sections() const;
382 virtual section_iterator end_sections() const;
384 virtual uint8_t getBytesInAddress() const;
385 virtual StringRef getFileFormatName() const;
386 virtual unsigned getArch() const;
388 uint64_t getNumSections() const;
389 uint64_t getStringTableIndex() const;
390 ELF::Elf64_Word getSymbolTableIndex(const Elf_Sym *symb) const;
391 const Elf_Shdr *getSection(const Elf_Sym *symb) const;
393 // Methods for type inquiry through isa, cast, and dyn_cast
394 bool isDyldType() const { return isDyldELFObject; }
395 static inline bool classof(const Binary *v) {
396 return v->getType() == Binary::isELF;
398 static inline bool classof(const ELFObjectFile *v) { return true; }
401 template<support::endianness target_endianness, bool is64Bits>
402 void ELFObjectFile<target_endianness, is64Bits>
403 ::validateSymbol(DataRefImpl Symb) const {
404 const Elf_Sym *symb = getSymbol(Symb);
405 const Elf_Shdr *SymbolTableSection = SymbolTableSections[Symb.d.b];
406 // FIXME: We really need to do proper error handling in the case of an invalid
407 // input file. Because we don't use exceptions, I think we'll just pass
408 // an error object around.
410 && SymbolTableSection
411 && symb >= (const Elf_Sym*)(base()
412 + SymbolTableSection->sh_offset)
413 && symb < (const Elf_Sym*)(base()
414 + SymbolTableSection->sh_offset
415 + SymbolTableSection->sh_size)))
416 // FIXME: Proper error handling.
417 report_fatal_error("Symb must point to a valid symbol!");
420 template<support::endianness target_endianness, bool is64Bits>
421 error_code ELFObjectFile<target_endianness, is64Bits>
422 ::getSymbolNext(DataRefImpl Symb,
423 SymbolRef &Result) const {
424 validateSymbol(Symb);
425 const Elf_Shdr *SymbolTableSection = SymbolTableSections[Symb.d.b];
428 // Check to see if we are at the end of this symbol table.
429 if (Symb.d.a >= SymbolTableSection->getEntityCount()) {
430 // We are at the end. If there are other symbol tables, jump to them.
431 // If the symbol table is .dynsym, we are iterating dynamic symbols,
432 // and there is only one table of these.
435 Symb.d.a = 1; // The 0th symbol in ELF is fake.
437 // Otherwise return the terminator.
438 if (Symb.d.b == 0 || Symb.d.b >= SymbolTableSections.size()) {
439 Symb.d.a = std::numeric_limits<uint32_t>::max();
440 Symb.d.b = std::numeric_limits<uint32_t>::max();
444 Result = SymbolRef(Symb, this);
445 return object_error::success;
448 template<support::endianness target_endianness, bool is64Bits>
449 error_code ELFObjectFile<target_endianness, is64Bits>
450 ::getSymbolName(DataRefImpl Symb,
451 StringRef &Result) const {
452 validateSymbol(Symb);
453 const Elf_Sym *symb = getSymbol(Symb);
454 return getSymbolName(SymbolTableSections[Symb.d.b], symb, Result);
457 template<support::endianness target_endianness, bool is64Bits>
458 ELF::Elf64_Word ELFObjectFile<target_endianness, is64Bits>
459 ::getSymbolTableIndex(const Elf_Sym *symb) const {
460 if (symb->st_shndx == ELF::SHN_XINDEX)
461 return ExtendedSymbolTable.lookup(symb);
462 return symb->st_shndx;
465 template<support::endianness target_endianness, bool is64Bits>
466 const typename ELFObjectFile<target_endianness, is64Bits>::Elf_Shdr *
467 ELFObjectFile<target_endianness, is64Bits>
468 ::getSection(const Elf_Sym *symb) const {
469 if (symb->st_shndx == ELF::SHN_XINDEX)
470 return getSection(ExtendedSymbolTable.lookup(symb));
471 if (symb->st_shndx >= ELF::SHN_LORESERVE)
473 return getSection(symb->st_shndx);
476 template<support::endianness target_endianness, bool is64Bits>
477 error_code ELFObjectFile<target_endianness, is64Bits>
478 ::getSymbolFileOffset(DataRefImpl Symb,
479 uint64_t &Result) const {
480 validateSymbol(Symb);
481 const Elf_Sym *symb = getSymbol(Symb);
482 const Elf_Shdr *Section;
483 switch (getSymbolTableIndex(symb)) {
484 case ELF::SHN_COMMON:
485 // Unintialized symbols have no offset in the object file
487 Result = UnknownAddressOrSize;
488 return object_error::success;
490 Result = symb->st_value;
491 return object_error::success;
492 default: Section = getSection(symb);
495 switch (symb->getType()) {
496 case ELF::STT_SECTION:
497 Result = Section ? Section->sh_addr : UnknownAddressOrSize;
498 return object_error::success;
500 case ELF::STT_OBJECT:
501 case ELF::STT_NOTYPE:
502 Result = symb->st_value +
503 (Section ? Section->sh_offset : 0);
504 return object_error::success;
506 Result = UnknownAddressOrSize;
507 return object_error::success;
511 template<support::endianness target_endianness, bool is64Bits>
512 error_code ELFObjectFile<target_endianness, is64Bits>
513 ::getSymbolAddress(DataRefImpl Symb,
514 uint64_t &Result) const {
515 validateSymbol(Symb);
516 const Elf_Sym *symb = getSymbol(Symb);
517 const Elf_Shdr *Section;
518 switch (getSymbolTableIndex(symb)) {
519 case ELF::SHN_COMMON:
521 Result = UnknownAddressOrSize;
522 return object_error::success;
524 Result = symb->st_value;
525 return object_error::success;
526 default: Section = getSection(symb);
529 switch (symb->getType()) {
530 case ELF::STT_SECTION:
531 Result = Section ? Section->sh_addr : UnknownAddressOrSize;
532 return object_error::success;
534 case ELF::STT_OBJECT:
535 case ELF::STT_NOTYPE:
536 Result = symb->st_value + (Section ? Section->sh_addr : 0);
537 return object_error::success;
539 Result = UnknownAddressOrSize;
540 return object_error::success;
544 template<support::endianness target_endianness, bool is64Bits>
545 error_code ELFObjectFile<target_endianness, is64Bits>
546 ::getSymbolSize(DataRefImpl Symb,
547 uint64_t &Result) const {
548 validateSymbol(Symb);
549 const Elf_Sym *symb = getSymbol(Symb);
550 if (symb->st_size == 0)
551 Result = UnknownAddressOrSize;
552 Result = symb->st_size;
553 return object_error::success;
556 template<support::endianness target_endianness, bool is64Bits>
557 error_code ELFObjectFile<target_endianness, is64Bits>
558 ::getSymbolNMTypeChar(DataRefImpl Symb,
559 char &Result) const {
560 validateSymbol(Symb);
561 const Elf_Sym *symb = getSymbol(Symb);
562 const Elf_Shdr *Section = getSection(symb);
567 switch (Section->sh_type) {
568 case ELF::SHT_PROGBITS:
569 case ELF::SHT_DYNAMIC:
570 switch (Section->sh_flags) {
571 case (ELF::SHF_ALLOC | ELF::SHF_EXECINSTR):
573 case (ELF::SHF_ALLOC | ELF::SHF_WRITE):
576 case (ELF::SHF_ALLOC | ELF::SHF_MERGE):
577 case (ELF::SHF_ALLOC | ELF::SHF_MERGE | ELF::SHF_STRINGS):
581 case ELF::SHT_NOBITS: ret = 'b';
585 switch (getSymbolTableIndex(symb)) {
590 case ELF::SHN_ABS: ret = 'a'; break;
591 case ELF::SHN_COMMON: ret = 'c'; break;
594 switch (symb->getBinding()) {
595 case ELF::STB_GLOBAL: ret = ::toupper(ret); break;
597 if (getSymbolTableIndex(symb) == ELF::SHN_UNDEF)
600 if (symb->getType() == ELF::STT_OBJECT)
606 if (ret == '?' && symb->getType() == ELF::STT_SECTION) {
608 if (error_code ec = getSymbolName(Symb, name))
610 Result = StringSwitch<char>(name)
611 .StartsWith(".debug", 'N')
612 .StartsWith(".note", 'n')
614 return object_error::success;
618 return object_error::success;
621 template<support::endianness target_endianness, bool is64Bits>
622 error_code ELFObjectFile<target_endianness, is64Bits>
623 ::getSymbolType(DataRefImpl Symb,
624 SymbolRef::Type &Result) const {
625 validateSymbol(Symb);
626 const Elf_Sym *symb = getSymbol(Symb);
628 if (getSymbolTableIndex(symb) == ELF::SHN_UNDEF) {
629 Result = SymbolRef::ST_External;
630 return object_error::success;
633 switch (symb->getType()) {
634 case ELF::STT_SECTION:
635 Result = SymbolRef::ST_Debug;
638 Result = SymbolRef::ST_File;
641 Result = SymbolRef::ST_Function;
643 case ELF::STT_OBJECT:
644 Result = SymbolRef::ST_Data;
647 Result = SymbolRef::ST_Other;
650 return object_error::success;
653 template<support::endianness target_endianness, bool is64Bits>
654 error_code ELFObjectFile<target_endianness, is64Bits>
655 ::getSymbolFlags(DataRefImpl Symb,
656 uint32_t &Result) const {
657 validateSymbol(Symb);
658 const Elf_Sym *symb = getSymbol(Symb);
660 Result = SymbolRef::SF_None;
662 if (symb->getBinding() != ELF::STB_LOCAL)
663 Result |= SymbolRef::SF_Global;
665 if (symb->getBinding() == ELF::STB_WEAK)
666 Result |= SymbolRef::SF_Weak;
668 if (symb->st_shndx == ELF::SHN_ABS)
669 Result |= SymbolRef::SF_Absolute;
671 if (symb->getType() == ELF::STT_FILE ||
672 symb->getType() == ELF::STT_SECTION)
673 Result |= SymbolRef::SF_FormatSpecific;
675 return object_error::success;
678 template<support::endianness target_endianness, bool is64Bits>
679 error_code ELFObjectFile<target_endianness, is64Bits>
680 ::getSymbolSection(DataRefImpl Symb,
681 section_iterator &Res) const {
682 validateSymbol(Symb);
683 const Elf_Sym *symb = getSymbol(Symb);
684 const Elf_Shdr *sec = getSection(symb);
686 Res = end_sections();
689 Sec.p = reinterpret_cast<intptr_t>(sec);
690 Res = section_iterator(SectionRef(Sec, this));
692 return object_error::success;
695 template<support::endianness target_endianness, bool is64Bits>
696 error_code ELFObjectFile<target_endianness, is64Bits>
697 ::getSectionNext(DataRefImpl Sec, SectionRef &Result) const {
698 const uint8_t *sec = reinterpret_cast<const uint8_t *>(Sec.p);
699 sec += Header->e_shentsize;
700 Sec.p = reinterpret_cast<intptr_t>(sec);
701 Result = SectionRef(Sec, this);
702 return object_error::success;
705 template<support::endianness target_endianness, bool is64Bits>
706 error_code ELFObjectFile<target_endianness, is64Bits>
707 ::getSectionName(DataRefImpl Sec,
708 StringRef &Result) const {
709 const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p);
710 Result = StringRef(getString(dot_shstrtab_sec, sec->sh_name));
711 return object_error::success;
714 template<support::endianness target_endianness, bool is64Bits>
715 error_code ELFObjectFile<target_endianness, is64Bits>
716 ::getSectionAddress(DataRefImpl Sec,
717 uint64_t &Result) const {
718 const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p);
719 Result = sec->sh_addr;
720 return object_error::success;
723 template<support::endianness target_endianness, bool is64Bits>
724 error_code ELFObjectFile<target_endianness, is64Bits>
725 ::getSectionSize(DataRefImpl Sec,
726 uint64_t &Result) const {
727 const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p);
728 Result = sec->sh_size;
729 return object_error::success;
732 template<support::endianness target_endianness, bool is64Bits>
733 error_code ELFObjectFile<target_endianness, is64Bits>
734 ::getSectionContents(DataRefImpl Sec,
735 StringRef &Result) const {
736 const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p);
737 const char *start = (const char*)base() + sec->sh_offset;
738 Result = StringRef(start, sec->sh_size);
739 return object_error::success;
742 template<support::endianness target_endianness, bool is64Bits>
743 error_code ELFObjectFile<target_endianness, is64Bits>
744 ::getSectionAlignment(DataRefImpl Sec,
745 uint64_t &Result) const {
746 const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p);
747 Result = sec->sh_addralign;
748 return object_error::success;
751 template<support::endianness target_endianness, bool is64Bits>
752 error_code ELFObjectFile<target_endianness, is64Bits>
753 ::isSectionText(DataRefImpl Sec,
754 bool &Result) const {
755 const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p);
756 if (sec->sh_flags & ELF::SHF_EXECINSTR)
760 return object_error::success;
763 template<support::endianness target_endianness, bool is64Bits>
764 error_code ELFObjectFile<target_endianness, is64Bits>
765 ::isSectionData(DataRefImpl Sec,
766 bool &Result) const {
767 const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p);
768 if (sec->sh_flags & (ELF::SHF_ALLOC | ELF::SHF_WRITE)
769 && sec->sh_type == ELF::SHT_PROGBITS)
773 return object_error::success;
776 template<support::endianness target_endianness, bool is64Bits>
777 error_code ELFObjectFile<target_endianness, is64Bits>
778 ::isSectionBSS(DataRefImpl Sec,
779 bool &Result) const {
780 const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p);
781 if (sec->sh_flags & (ELF::SHF_ALLOC | ELF::SHF_WRITE)
782 && sec->sh_type == ELF::SHT_NOBITS)
786 return object_error::success;
789 template<support::endianness target_endianness, bool is64Bits>
790 error_code ELFObjectFile<target_endianness, is64Bits>
791 ::sectionContainsSymbol(DataRefImpl Sec,
793 bool &Result) const {
794 // FIXME: Unimplemented.
796 return object_error::success;
799 template<support::endianness target_endianness, bool is64Bits>
800 relocation_iterator ELFObjectFile<target_endianness, is64Bits>
801 ::getSectionRelBegin(DataRefImpl Sec) const {
803 memset(&RelData, 0, sizeof(RelData));
804 const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p);
805 typename RelocMap_t::const_iterator ittr = SectionRelocMap.find(sec);
806 if (sec != 0 && ittr != SectionRelocMap.end()) {
807 RelData.w.a = getSection(ittr->second[0])->sh_info;
808 RelData.w.b = ittr->second[0];
811 return relocation_iterator(RelocationRef(RelData, this));
814 template<support::endianness target_endianness, bool is64Bits>
815 relocation_iterator ELFObjectFile<target_endianness, is64Bits>
816 ::getSectionRelEnd(DataRefImpl Sec) const {
818 memset(&RelData, 0, sizeof(RelData));
819 const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p);
820 typename RelocMap_t::const_iterator ittr = SectionRelocMap.find(sec);
821 if (sec != 0 && ittr != SectionRelocMap.end()) {
822 // Get the index of the last relocation section for this section.
823 std::size_t relocsecindex = ittr->second[ittr->second.size() - 1];
824 const Elf_Shdr *relocsec = getSection(relocsecindex);
825 RelData.w.a = relocsec->sh_info;
826 RelData.w.b = relocsecindex;
827 RelData.w.c = relocsec->sh_size / relocsec->sh_entsize;
829 return relocation_iterator(RelocationRef(RelData, this));
833 template<support::endianness target_endianness, bool is64Bits>
834 error_code ELFObjectFile<target_endianness, is64Bits>
835 ::getRelocationNext(DataRefImpl Rel,
836 RelocationRef &Result) const {
838 const Elf_Shdr *relocsec = getSection(Rel.w.b);
839 if (Rel.w.c >= (relocsec->sh_size / relocsec->sh_entsize)) {
840 // We have reached the end of the relocations for this section. See if there
841 // is another relocation section.
842 typename RelocMap_t::mapped_type relocseclist =
843 SectionRelocMap.lookup(getSection(Rel.w.a));
845 // Do a binary search for the current reloc section index (which must be
846 // present). Then get the next one.
847 typename RelocMap_t::mapped_type::const_iterator loc =
848 std::lower_bound(relocseclist.begin(), relocseclist.end(), Rel.w.b);
851 // If there is no next one, don't do anything. The ++Rel.w.c above sets Rel
852 // to the end iterator.
853 if (loc != relocseclist.end()) {
858 Result = RelocationRef(Rel, this);
859 return object_error::success;
862 template<support::endianness target_endianness, bool is64Bits>
863 error_code ELFObjectFile<target_endianness, is64Bits>
864 ::getRelocationSymbol(DataRefImpl Rel,
865 SymbolRef &Result) const {
867 const Elf_Shdr *sec = getSection(Rel.w.b);
868 switch (sec->sh_type) {
870 report_fatal_error("Invalid section type in Rel!");
871 case ELF::SHT_REL : {
872 symbolIdx = getRel(Rel)->getSymbol();
875 case ELF::SHT_RELA : {
876 symbolIdx = getRela(Rel)->getSymbol();
880 DataRefImpl SymbolData;
881 IndexMap_t::const_iterator it = SymbolTableSectionsIndexMap.find(sec->sh_link);
882 if (it == SymbolTableSectionsIndexMap.end())
883 report_fatal_error("Relocation symbol table not found!");
884 SymbolData.d.a = symbolIdx;
885 SymbolData.d.b = it->second;
886 Result = SymbolRef(SymbolData, this);
887 return object_error::success;
890 template<support::endianness target_endianness, bool is64Bits>
891 error_code ELFObjectFile<target_endianness, is64Bits>
892 ::getRelocationAddress(DataRefImpl Rel,
893 uint64_t &Result) const {
895 const Elf_Shdr *sec = getSection(Rel.w.b);
896 switch (sec->sh_type) {
898 report_fatal_error("Invalid section type in Rel!");
899 case ELF::SHT_REL : {
900 offset = getRel(Rel)->r_offset;
903 case ELF::SHT_RELA : {
904 offset = getRela(Rel)->r_offset;
910 return object_error::success;
913 template<support::endianness target_endianness, bool is64Bits>
914 error_code ELFObjectFile<target_endianness, is64Bits>
915 ::getRelocationOffset(DataRefImpl Rel,
916 uint64_t &Result) const {
918 const Elf_Shdr *sec = getSection(Rel.w.b);
919 switch (sec->sh_type) {
921 report_fatal_error("Invalid section type in Rel!");
922 case ELF::SHT_REL : {
923 offset = getRel(Rel)->r_offset;
926 case ELF::SHT_RELA : {
927 offset = getRela(Rel)->r_offset;
932 Result = offset - sec->sh_addr;
933 return object_error::success;
936 template<support::endianness target_endianness, bool is64Bits>
937 error_code ELFObjectFile<target_endianness, is64Bits>
938 ::getRelocationType(DataRefImpl Rel,
939 uint64_t &Result) const {
940 const Elf_Shdr *sec = getSection(Rel.w.b);
941 switch (sec->sh_type) {
943 report_fatal_error("Invalid section type in Rel!");
944 case ELF::SHT_REL : {
945 Result = getRel(Rel)->getType();
948 case ELF::SHT_RELA : {
949 Result = getRela(Rel)->getType();
953 return object_error::success;
956 #define LLVM_ELF_SWITCH_RELOC_TYPE_NAME(enum) \
957 case ELF::enum: res = #enum; break;
959 template<support::endianness target_endianness, bool is64Bits>
960 error_code ELFObjectFile<target_endianness, is64Bits>
961 ::getRelocationTypeName(DataRefImpl Rel,
962 SmallVectorImpl<char> &Result) const {
963 const Elf_Shdr *sec = getSection(Rel.w.b);
966 switch (sec->sh_type) {
968 return object_error::parse_failed;
969 case ELF::SHT_REL : {
970 type = getRel(Rel)->getType();
973 case ELF::SHT_RELA : {
974 type = getRela(Rel)->getType();
978 switch (Header->e_machine) {
981 LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_NONE);
982 LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_64);
983 LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_PC32);
984 LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_GOT32);
985 LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_PLT32);
986 LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_COPY);
987 LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_GLOB_DAT);
988 LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_JUMP_SLOT);
989 LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_RELATIVE);
990 LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_GOTPCREL);
991 LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_32);
992 LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_32S);
993 LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_16);
994 LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_PC16);
995 LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_8);
996 LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_PC8);
997 LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_DTPMOD64);
998 LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_DTPOFF64);
999 LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_TPOFF64);
1000 LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_TLSGD);
1001 LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_TLSLD);
1002 LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_DTPOFF32);
1003 LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_GOTTPOFF);
1004 LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_TPOFF32);
1005 LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_PC64);
1006 LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_GOTOFF64);
1007 LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_GOTPC32);
1008 LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_SIZE32);
1009 LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_SIZE64);
1010 LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_GOTPC32_TLSDESC);
1011 LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_TLSDESC_CALL);
1012 LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_TLSDESC);
1019 LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_NONE);
1020 LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_32);
1021 LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_PC32);
1022 LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_GOT32);
1023 LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_PLT32);
1024 LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_COPY);
1025 LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_GLOB_DAT);
1026 LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_JUMP_SLOT);
1027 LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_RELATIVE);
1028 LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_GOTOFF);
1029 LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_GOTPC);
1030 LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_32PLT);
1031 LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_TPOFF);
1032 LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_IE);
1033 LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_GOTIE);
1034 LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_LE);
1035 LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_GD);
1036 LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_LDM);
1037 LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_16);
1038 LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_PC16);
1039 LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_8);
1040 LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_PC8);
1041 LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_GD_32);
1042 LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_GD_PUSH);
1043 LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_GD_CALL);
1044 LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_GD_POP);
1045 LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_LDM_32);
1046 LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_LDM_PUSH);
1047 LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_LDM_CALL);
1048 LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_LDM_POP);
1049 LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_LDO_32);
1050 LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_IE_32);
1051 LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_LE_32);
1052 LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_DTPMOD32);
1053 LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_DTPOFF32);
1054 LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_TPOFF32);
1055 LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_GOTDESC);
1056 LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_DESC_CALL);
1057 LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_DESC);
1058 LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_IRELATIVE);
1066 Result.append(res.begin(), res.end());
1067 return object_error::success;
1070 #undef LLVM_ELF_SWITCH_RELOC_TYPE_NAME
1072 template<support::endianness target_endianness, bool is64Bits>
1073 error_code ELFObjectFile<target_endianness, is64Bits>
1074 ::getRelocationAdditionalInfo(DataRefImpl Rel,
1075 int64_t &Result) const {
1076 const Elf_Shdr *sec = getSection(Rel.w.b);
1077 switch (sec->sh_type) {
1079 report_fatal_error("Invalid section type in Rel!");
1080 case ELF::SHT_REL : {
1082 return object_error::success;
1084 case ELF::SHT_RELA : {
1085 Result = getRela(Rel)->r_addend;
1086 return object_error::success;
1091 template<support::endianness target_endianness, bool is64Bits>
1092 error_code ELFObjectFile<target_endianness, is64Bits>
1093 ::getRelocationValueString(DataRefImpl Rel,
1094 SmallVectorImpl<char> &Result) const {
1095 const Elf_Shdr *sec = getSection(Rel.w.b);
1099 uint16_t symbol_index = 0;
1100 switch (sec->sh_type) {
1102 return object_error::parse_failed;
1103 case ELF::SHT_REL : {
1104 type = getRel(Rel)->getType();
1105 symbol_index = getRel(Rel)->getSymbol();
1106 // TODO: Read implicit addend from section data.
1109 case ELF::SHT_RELA : {
1110 type = getRela(Rel)->getType();
1111 symbol_index = getRela(Rel)->getSymbol();
1112 addend = getRela(Rel)->r_addend;
1116 const Elf_Sym *symb = getEntry<Elf_Sym>(sec->sh_link, symbol_index);
1118 if (error_code ec = getSymbolName(getSection(sec->sh_link), symb, symname))
1120 switch (Header->e_machine) {
1121 case ELF::EM_X86_64:
1123 case ELF::R_X86_64_32S:
1126 case ELF::R_X86_64_PC32: {
1128 raw_string_ostream fmt(fmtbuf);
1129 fmt << symname << (addend < 0 ? "" : "+") << addend << "-P";
1131 Result.append(fmtbuf.begin(), fmtbuf.end());
1142 Result.append(res.begin(), res.end());
1143 return object_error::success;
1146 // Verify that the last byte in the string table in a null.
1147 template<support::endianness target_endianness, bool is64Bits>
1148 void ELFObjectFile<target_endianness, is64Bits>
1149 ::VerifyStrTab(const Elf_Shdr *sh) const {
1150 const char *strtab = (const char*)base() + sh->sh_offset;
1151 if (strtab[sh->sh_size - 1] != 0)
1152 // FIXME: Proper error handling.
1153 report_fatal_error("String table must end with a null terminator!");
1156 template<support::endianness target_endianness, bool is64Bits>
1157 ELFObjectFile<target_endianness, is64Bits>::ELFObjectFile(MemoryBuffer *Object
1159 : ObjectFile(Binary::isELF, Object, ec)
1160 , isDyldELFObject(false)
1161 , SectionHeaderTable(0)
1162 , dot_shstrtab_sec(0)
1164 , dot_dynstr_sec(0) {
1166 const uint64_t FileSize = Data->getBufferSize();
1168 if (sizeof(Elf_Ehdr) > FileSize)
1169 // FIXME: Proper error handling.
1170 report_fatal_error("File too short!");
1172 Header = reinterpret_cast<const Elf_Ehdr *>(base());
1174 if (Header->e_shoff == 0)
1177 const uint64_t SectionTableOffset = Header->e_shoff;
1179 if (SectionTableOffset + sizeof(Elf_Shdr) > FileSize)
1180 // FIXME: Proper error handling.
1181 report_fatal_error("Section header table goes past end of file!");
1183 // The getNumSections() call below depends on SectionHeaderTable being set.
1184 SectionHeaderTable =
1185 reinterpret_cast<const Elf_Shdr *>(base() + SectionTableOffset);
1186 const uint64_t SectionTableSize = getNumSections() * Header->e_shentsize;
1188 if (SectionTableOffset + SectionTableSize > FileSize)
1189 // FIXME: Proper error handling.
1190 report_fatal_error("Section table goes past end of file!");
1192 // To find the symbol tables we walk the section table to find SHT_SYMTAB.
1193 const Elf_Shdr* SymbolTableSectionHeaderIndex = 0;
1194 const Elf_Shdr* sh = SectionHeaderTable;
1196 // Reserve SymbolTableSections[0] for .dynsym
1197 SymbolTableSections.push_back(NULL);
1199 for (uint64_t i = 0, e = getNumSections(); i != e; ++i) {
1200 if (sh->sh_type == ELF::SHT_SYMTAB_SHNDX) {
1201 if (SymbolTableSectionHeaderIndex)
1202 // FIXME: Proper error handling.
1203 report_fatal_error("More than one .symtab_shndx!");
1204 SymbolTableSectionHeaderIndex = sh;
1206 if (sh->sh_type == ELF::SHT_SYMTAB) {
1207 SymbolTableSectionsIndexMap[i] = SymbolTableSections.size();
1208 SymbolTableSections.push_back(sh);
1210 if (sh->sh_type == ELF::SHT_DYNSYM) {
1211 if (SymbolTableSections[0] != NULL)
1212 // FIXME: Proper error handling.
1213 report_fatal_error("More than one .dynsym!");
1214 SymbolTableSectionsIndexMap[i] = 0;
1215 SymbolTableSections[0] = sh;
1217 if (sh->sh_type == ELF::SHT_REL || sh->sh_type == ELF::SHT_RELA) {
1218 SectionRelocMap[getSection(sh->sh_info)].push_back(i);
1223 // Sort section relocation lists by index.
1224 for (typename RelocMap_t::iterator i = SectionRelocMap.begin(),
1225 e = SectionRelocMap.end(); i != e; ++i) {
1226 std::sort(i->second.begin(), i->second.end());
1229 // Get string table sections.
1230 dot_shstrtab_sec = getSection(getStringTableIndex());
1231 if (dot_shstrtab_sec) {
1232 // Verify that the last byte in the string table in a null.
1233 VerifyStrTab(dot_shstrtab_sec);
1236 // Merge this into the above loop.
1237 for (const char *i = reinterpret_cast<const char *>(SectionHeaderTable),
1238 *e = i + getNumSections() * Header->e_shentsize;
1239 i != e; i += Header->e_shentsize) {
1240 const Elf_Shdr *sh = reinterpret_cast<const Elf_Shdr*>(i);
1241 if (sh->sh_type == ELF::SHT_STRTAB) {
1242 StringRef SectionName(getString(dot_shstrtab_sec, sh->sh_name));
1243 if (SectionName == ".strtab") {
1244 if (dot_strtab_sec != 0)
1245 // FIXME: Proper error handling.
1246 report_fatal_error("Already found section named .strtab!");
1247 dot_strtab_sec = sh;
1248 VerifyStrTab(dot_strtab_sec);
1249 } else if (SectionName == ".dynstr") {
1250 if (dot_dynstr_sec != 0)
1251 // FIXME: Proper error handling.
1252 report_fatal_error("Already found section named .dynstr!");
1253 dot_dynstr_sec = sh;
1254 VerifyStrTab(dot_dynstr_sec);
1259 // Build symbol name side-mapping if there is one.
1260 if (SymbolTableSectionHeaderIndex) {
1261 const Elf_Word *ShndxTable = reinterpret_cast<const Elf_Word*>(base() +
1262 SymbolTableSectionHeaderIndex->sh_offset);
1264 for (symbol_iterator si = begin_symbols(),
1265 se = end_symbols(); si != se; si.increment(ec)) {
1267 report_fatal_error("Fewer extended symbol table entries than symbols!");
1268 if (*ShndxTable != ELF::SHN_UNDEF)
1269 ExtendedSymbolTable[getSymbol(si->getRawDataRefImpl())] = *ShndxTable;
1275 template<support::endianness target_endianness, bool is64Bits>
1276 symbol_iterator ELFObjectFile<target_endianness, is64Bits>
1277 ::begin_symbols() const {
1278 DataRefImpl SymbolData;
1279 memset(&SymbolData, 0, sizeof(SymbolData));
1280 if (SymbolTableSections.size() <= 1) {
1281 SymbolData.d.a = std::numeric_limits<uint32_t>::max();
1282 SymbolData.d.b = std::numeric_limits<uint32_t>::max();
1284 SymbolData.d.a = 1; // The 0th symbol in ELF is fake.
1285 SymbolData.d.b = 1; // The 0th table is .dynsym
1287 return symbol_iterator(SymbolRef(SymbolData, this));
1290 template<support::endianness target_endianness, bool is64Bits>
1291 symbol_iterator ELFObjectFile<target_endianness, is64Bits>
1292 ::end_symbols() const {
1293 DataRefImpl SymbolData;
1294 memset(&SymbolData, 0, sizeof(SymbolData));
1295 SymbolData.d.a = std::numeric_limits<uint32_t>::max();
1296 SymbolData.d.b = std::numeric_limits<uint32_t>::max();
1297 return symbol_iterator(SymbolRef(SymbolData, this));
1300 template<support::endianness target_endianness, bool is64Bits>
1301 symbol_iterator ELFObjectFile<target_endianness, is64Bits>
1302 ::begin_dynamic_symbols() const {
1303 DataRefImpl SymbolData;
1304 memset(&SymbolData, 0, sizeof(SymbolData));
1305 if (SymbolTableSections[0] == NULL) {
1306 SymbolData.d.a = std::numeric_limits<uint32_t>::max();
1307 SymbolData.d.b = std::numeric_limits<uint32_t>::max();
1309 SymbolData.d.a = 1; // The 0th symbol in ELF is fake.
1310 SymbolData.d.b = 0; // The 0th table is .dynsym
1312 return symbol_iterator(SymbolRef(SymbolData, this));
1315 template<support::endianness target_endianness, bool is64Bits>
1316 symbol_iterator ELFObjectFile<target_endianness, is64Bits>
1317 ::end_dynamic_symbols() const {
1318 DataRefImpl SymbolData;
1319 memset(&SymbolData, 0, sizeof(SymbolData));
1320 SymbolData.d.a = std::numeric_limits<uint32_t>::max();
1321 SymbolData.d.b = std::numeric_limits<uint32_t>::max();
1322 return symbol_iterator(SymbolRef(SymbolData, this));
1325 template<support::endianness target_endianness, bool is64Bits>
1326 section_iterator ELFObjectFile<target_endianness, is64Bits>
1327 ::begin_sections() const {
1329 memset(&ret, 0, sizeof(DataRefImpl));
1330 ret.p = reinterpret_cast<intptr_t>(base() + Header->e_shoff);
1331 return section_iterator(SectionRef(ret, this));
1334 template<support::endianness target_endianness, bool is64Bits>
1335 section_iterator ELFObjectFile<target_endianness, is64Bits>
1336 ::end_sections() const {
1338 memset(&ret, 0, sizeof(DataRefImpl));
1339 ret.p = reinterpret_cast<intptr_t>(base()
1341 + (Header->e_shentsize*getNumSections()));
1342 return section_iterator(SectionRef(ret, this));
1345 template<support::endianness target_endianness, bool is64Bits>
1346 uint8_t ELFObjectFile<target_endianness, is64Bits>::getBytesInAddress() const {
1347 return is64Bits ? 8 : 4;
1350 template<support::endianness target_endianness, bool is64Bits>
1351 StringRef ELFObjectFile<target_endianness, is64Bits>
1352 ::getFileFormatName() const {
1353 switch(Header->e_ident[ELF::EI_CLASS]) {
1354 case ELF::ELFCLASS32:
1355 switch(Header->e_machine) {
1357 return "ELF32-i386";
1358 case ELF::EM_X86_64:
1359 return "ELF32-x86-64";
1363 return "ELF32-unknown";
1365 case ELF::ELFCLASS64:
1366 switch(Header->e_machine) {
1368 return "ELF64-i386";
1369 case ELF::EM_X86_64:
1370 return "ELF64-x86-64";
1372 return "ELF64-unknown";
1375 // FIXME: Proper error handling.
1376 report_fatal_error("Invalid ELFCLASS!");
1380 template<support::endianness target_endianness, bool is64Bits>
1381 unsigned ELFObjectFile<target_endianness, is64Bits>::getArch() const {
1382 switch(Header->e_machine) {
1385 case ELF::EM_X86_64:
1386 return Triple::x86_64;
1390 return Triple::UnknownArch;
1394 template<support::endianness target_endianness, bool is64Bits>
1395 uint64_t ELFObjectFile<target_endianness, is64Bits>::getNumSections() const {
1396 assert(Header && "Header not initialized!");
1397 if (Header->e_shnum == ELF::SHN_UNDEF) {
1398 assert(SectionHeaderTable && "SectionHeaderTable not initialized!");
1399 return SectionHeaderTable->sh_size;
1401 return Header->e_shnum;
1404 template<support::endianness target_endianness, bool is64Bits>
1406 ELFObjectFile<target_endianness, is64Bits>::getStringTableIndex() const {
1407 if (Header->e_shnum == ELF::SHN_UNDEF) {
1408 if (Header->e_shstrndx == ELF::SHN_HIRESERVE)
1409 return SectionHeaderTable->sh_link;
1410 if (Header->e_shstrndx >= getNumSections())
1413 return Header->e_shstrndx;
1417 template<support::endianness target_endianness, bool is64Bits>
1418 template<typename T>
1420 ELFObjectFile<target_endianness, is64Bits>::getEntry(uint16_t Section,
1421 uint32_t Entry) const {
1422 return getEntry<T>(getSection(Section), Entry);
1425 template<support::endianness target_endianness, bool is64Bits>
1426 template<typename T>
1428 ELFObjectFile<target_endianness, is64Bits>::getEntry(const Elf_Shdr * Section,
1429 uint32_t Entry) const {
1430 return reinterpret_cast<const T *>(
1432 + Section->sh_offset
1433 + (Entry * Section->sh_entsize));
1436 template<support::endianness target_endianness, bool is64Bits>
1437 const typename ELFObjectFile<target_endianness, is64Bits>::Elf_Sym *
1438 ELFObjectFile<target_endianness, is64Bits>::getSymbol(DataRefImpl Symb) const {
1439 return getEntry<Elf_Sym>(SymbolTableSections[Symb.d.b], Symb.d.a);
1442 template<support::endianness target_endianness, bool is64Bits>
1443 const typename ELFObjectFile<target_endianness, is64Bits>::Elf_Rel *
1444 ELFObjectFile<target_endianness, is64Bits>::getRel(DataRefImpl Rel) const {
1445 return getEntry<Elf_Rel>(Rel.w.b, Rel.w.c);
1448 template<support::endianness target_endianness, bool is64Bits>
1449 const typename ELFObjectFile<target_endianness, is64Bits>::Elf_Rela *
1450 ELFObjectFile<target_endianness, is64Bits>::getRela(DataRefImpl Rela) const {
1451 return getEntry<Elf_Rela>(Rela.w.b, Rela.w.c);
1454 template<support::endianness target_endianness, bool is64Bits>
1455 const typename ELFObjectFile<target_endianness, is64Bits>::Elf_Shdr *
1456 ELFObjectFile<target_endianness, is64Bits>::getSection(DataRefImpl Symb) const {
1457 const Elf_Shdr *sec = getSection(Symb.d.b);
1458 if (sec->sh_type != ELF::SHT_SYMTAB || sec->sh_type != ELF::SHT_DYNSYM)
1459 // FIXME: Proper error handling.
1460 report_fatal_error("Invalid symbol table section!");
1464 template<support::endianness target_endianness, bool is64Bits>
1465 const typename ELFObjectFile<target_endianness, is64Bits>::Elf_Shdr *
1466 ELFObjectFile<target_endianness, is64Bits>::getSection(uint32_t index) const {
1469 if (!SectionHeaderTable || index >= getNumSections())
1470 // FIXME: Proper error handling.
1471 report_fatal_error("Invalid section index!");
1473 return reinterpret_cast<const Elf_Shdr *>(
1474 reinterpret_cast<const char *>(SectionHeaderTable)
1475 + (index * Header->e_shentsize));
1478 template<support::endianness target_endianness, bool is64Bits>
1479 const char *ELFObjectFile<target_endianness, is64Bits>
1480 ::getString(uint32_t section,
1481 ELF::Elf32_Word offset) const {
1482 return getString(getSection(section), offset);
1485 template<support::endianness target_endianness, bool is64Bits>
1486 const char *ELFObjectFile<target_endianness, is64Bits>
1487 ::getString(const Elf_Shdr *section,
1488 ELF::Elf32_Word offset) const {
1489 assert(section && section->sh_type == ELF::SHT_STRTAB && "Invalid section!");
1490 if (offset >= section->sh_size)
1491 // FIXME: Proper error handling.
1492 report_fatal_error("Symbol name offset outside of string table!");
1493 return (const char *)base() + section->sh_offset + offset;
1496 template<support::endianness target_endianness, bool is64Bits>
1497 error_code ELFObjectFile<target_endianness, is64Bits>
1498 ::getSymbolName(const Elf_Shdr *section,
1499 const Elf_Sym *symb,
1500 StringRef &Result) const {
1501 if (symb->st_name == 0) {
1502 const Elf_Shdr *section = getSection(symb);
1506 Result = getString(dot_shstrtab_sec, section->sh_name);
1507 return object_error::success;
1510 if (section == SymbolTableSections[0]) {
1511 // Symbol is in .dynsym, use .dynstr string table
1512 Result = getString(dot_dynstr_sec, symb->st_name);
1514 // Use the default symbol table name section.
1515 Result = getString(dot_strtab_sec, symb->st_name);
1517 return object_error::success;