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 switch (symb->getType()) {
629 case ELF::STT_NOTYPE:
630 Result = SymbolRef::ST_Unknown;
632 case ELF::STT_SECTION:
633 Result = SymbolRef::ST_Debug;
636 Result = SymbolRef::ST_File;
639 Result = SymbolRef::ST_Function;
641 case ELF::STT_OBJECT:
642 case ELF::STT_COMMON:
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 if (getSymbolTableIndex(symb) == ELF::SHN_UNDEF)
676 Result |= SymbolRef::SF_Undefined;
678 if (symb->getType() == ELF::STT_COMMON ||
679 getSymbolTableIndex(symb) == ELF::SHN_COMMON)
680 Result |= SymbolRef::SF_Common;
682 if (symb->getType() == ELF::STT_TLS)
683 Result |= SymbolRef::SF_ThreadLocal;
685 return object_error::success;
688 template<support::endianness target_endianness, bool is64Bits>
689 error_code ELFObjectFile<target_endianness, is64Bits>
690 ::getSymbolSection(DataRefImpl Symb,
691 section_iterator &Res) const {
692 validateSymbol(Symb);
693 const Elf_Sym *symb = getSymbol(Symb);
694 const Elf_Shdr *sec = getSection(symb);
696 Res = end_sections();
699 Sec.p = reinterpret_cast<intptr_t>(sec);
700 Res = section_iterator(SectionRef(Sec, this));
702 return object_error::success;
705 template<support::endianness target_endianness, bool is64Bits>
706 error_code ELFObjectFile<target_endianness, is64Bits>
707 ::getSectionNext(DataRefImpl Sec, SectionRef &Result) const {
708 const uint8_t *sec = reinterpret_cast<const uint8_t *>(Sec.p);
709 sec += Header->e_shentsize;
710 Sec.p = reinterpret_cast<intptr_t>(sec);
711 Result = SectionRef(Sec, this);
712 return object_error::success;
715 template<support::endianness target_endianness, bool is64Bits>
716 error_code ELFObjectFile<target_endianness, is64Bits>
717 ::getSectionName(DataRefImpl Sec,
718 StringRef &Result) const {
719 const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p);
720 Result = StringRef(getString(dot_shstrtab_sec, sec->sh_name));
721 return object_error::success;
724 template<support::endianness target_endianness, bool is64Bits>
725 error_code ELFObjectFile<target_endianness, is64Bits>
726 ::getSectionAddress(DataRefImpl Sec,
727 uint64_t &Result) const {
728 const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p);
729 Result = sec->sh_addr;
730 return object_error::success;
733 template<support::endianness target_endianness, bool is64Bits>
734 error_code ELFObjectFile<target_endianness, is64Bits>
735 ::getSectionSize(DataRefImpl Sec,
736 uint64_t &Result) const {
737 const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p);
738 Result = sec->sh_size;
739 return object_error::success;
742 template<support::endianness target_endianness, bool is64Bits>
743 error_code ELFObjectFile<target_endianness, is64Bits>
744 ::getSectionContents(DataRefImpl Sec,
745 StringRef &Result) const {
746 const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p);
747 const char *start = (const char*)base() + sec->sh_offset;
748 Result = StringRef(start, sec->sh_size);
749 return object_error::success;
752 template<support::endianness target_endianness, bool is64Bits>
753 error_code ELFObjectFile<target_endianness, is64Bits>
754 ::getSectionAlignment(DataRefImpl Sec,
755 uint64_t &Result) const {
756 const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p);
757 Result = sec->sh_addralign;
758 return object_error::success;
761 template<support::endianness target_endianness, bool is64Bits>
762 error_code ELFObjectFile<target_endianness, is64Bits>
763 ::isSectionText(DataRefImpl Sec,
764 bool &Result) const {
765 const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p);
766 if (sec->sh_flags & ELF::SHF_EXECINSTR)
770 return object_error::success;
773 template<support::endianness target_endianness, bool is64Bits>
774 error_code ELFObjectFile<target_endianness, is64Bits>
775 ::isSectionData(DataRefImpl Sec,
776 bool &Result) const {
777 const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p);
778 if (sec->sh_flags & (ELF::SHF_ALLOC | ELF::SHF_WRITE)
779 && sec->sh_type == ELF::SHT_PROGBITS)
783 return object_error::success;
786 template<support::endianness target_endianness, bool is64Bits>
787 error_code ELFObjectFile<target_endianness, is64Bits>
788 ::isSectionBSS(DataRefImpl Sec,
789 bool &Result) const {
790 const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p);
791 if (sec->sh_flags & (ELF::SHF_ALLOC | ELF::SHF_WRITE)
792 && sec->sh_type == ELF::SHT_NOBITS)
796 return object_error::success;
799 template<support::endianness target_endianness, bool is64Bits>
800 error_code ELFObjectFile<target_endianness, is64Bits>
801 ::sectionContainsSymbol(DataRefImpl Sec,
803 bool &Result) const {
804 // FIXME: Unimplemented.
806 return object_error::success;
809 template<support::endianness target_endianness, bool is64Bits>
810 relocation_iterator ELFObjectFile<target_endianness, is64Bits>
811 ::getSectionRelBegin(DataRefImpl Sec) const {
813 memset(&RelData, 0, sizeof(RelData));
814 const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p);
815 typename RelocMap_t::const_iterator ittr = SectionRelocMap.find(sec);
816 if (sec != 0 && ittr != SectionRelocMap.end()) {
817 RelData.w.a = getSection(ittr->second[0])->sh_info;
818 RelData.w.b = ittr->second[0];
821 return relocation_iterator(RelocationRef(RelData, this));
824 template<support::endianness target_endianness, bool is64Bits>
825 relocation_iterator ELFObjectFile<target_endianness, is64Bits>
826 ::getSectionRelEnd(DataRefImpl Sec) const {
828 memset(&RelData, 0, sizeof(RelData));
829 const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p);
830 typename RelocMap_t::const_iterator ittr = SectionRelocMap.find(sec);
831 if (sec != 0 && ittr != SectionRelocMap.end()) {
832 // Get the index of the last relocation section for this section.
833 std::size_t relocsecindex = ittr->second[ittr->second.size() - 1];
834 const Elf_Shdr *relocsec = getSection(relocsecindex);
835 RelData.w.a = relocsec->sh_info;
836 RelData.w.b = relocsecindex;
837 RelData.w.c = relocsec->sh_size / relocsec->sh_entsize;
839 return relocation_iterator(RelocationRef(RelData, this));
843 template<support::endianness target_endianness, bool is64Bits>
844 error_code ELFObjectFile<target_endianness, is64Bits>
845 ::getRelocationNext(DataRefImpl Rel,
846 RelocationRef &Result) const {
848 const Elf_Shdr *relocsec = getSection(Rel.w.b);
849 if (Rel.w.c >= (relocsec->sh_size / relocsec->sh_entsize)) {
850 // We have reached the end of the relocations for this section. See if there
851 // is another relocation section.
852 typename RelocMap_t::mapped_type relocseclist =
853 SectionRelocMap.lookup(getSection(Rel.w.a));
855 // Do a binary search for the current reloc section index (which must be
856 // present). Then get the next one.
857 typename RelocMap_t::mapped_type::const_iterator loc =
858 std::lower_bound(relocseclist.begin(), relocseclist.end(), Rel.w.b);
861 // If there is no next one, don't do anything. The ++Rel.w.c above sets Rel
862 // to the end iterator.
863 if (loc != relocseclist.end()) {
868 Result = RelocationRef(Rel, this);
869 return object_error::success;
872 template<support::endianness target_endianness, bool is64Bits>
873 error_code ELFObjectFile<target_endianness, is64Bits>
874 ::getRelocationSymbol(DataRefImpl Rel,
875 SymbolRef &Result) const {
877 const Elf_Shdr *sec = getSection(Rel.w.b);
878 switch (sec->sh_type) {
880 report_fatal_error("Invalid section type in Rel!");
881 case ELF::SHT_REL : {
882 symbolIdx = getRel(Rel)->getSymbol();
885 case ELF::SHT_RELA : {
886 symbolIdx = getRela(Rel)->getSymbol();
890 DataRefImpl SymbolData;
891 IndexMap_t::const_iterator it = SymbolTableSectionsIndexMap.find(sec->sh_link);
892 if (it == SymbolTableSectionsIndexMap.end())
893 report_fatal_error("Relocation symbol table not found!");
894 SymbolData.d.a = symbolIdx;
895 SymbolData.d.b = it->second;
896 Result = SymbolRef(SymbolData, this);
897 return object_error::success;
900 template<support::endianness target_endianness, bool is64Bits>
901 error_code ELFObjectFile<target_endianness, is64Bits>
902 ::getRelocationAddress(DataRefImpl Rel,
903 uint64_t &Result) const {
905 const Elf_Shdr *sec = getSection(Rel.w.b);
906 switch (sec->sh_type) {
908 report_fatal_error("Invalid section type in Rel!");
909 case ELF::SHT_REL : {
910 offset = getRel(Rel)->r_offset;
913 case ELF::SHT_RELA : {
914 offset = getRela(Rel)->r_offset;
920 return object_error::success;
923 template<support::endianness target_endianness, bool is64Bits>
924 error_code ELFObjectFile<target_endianness, is64Bits>
925 ::getRelocationOffset(DataRefImpl Rel,
926 uint64_t &Result) const {
928 const Elf_Shdr *sec = getSection(Rel.w.b);
929 switch (sec->sh_type) {
931 report_fatal_error("Invalid section type in Rel!");
932 case ELF::SHT_REL : {
933 offset = getRel(Rel)->r_offset;
936 case ELF::SHT_RELA : {
937 offset = getRela(Rel)->r_offset;
942 Result = offset - sec->sh_addr;
943 return object_error::success;
946 template<support::endianness target_endianness, bool is64Bits>
947 error_code ELFObjectFile<target_endianness, is64Bits>
948 ::getRelocationType(DataRefImpl Rel,
949 uint64_t &Result) const {
950 const Elf_Shdr *sec = getSection(Rel.w.b);
951 switch (sec->sh_type) {
953 report_fatal_error("Invalid section type in Rel!");
954 case ELF::SHT_REL : {
955 Result = getRel(Rel)->getType();
958 case ELF::SHT_RELA : {
959 Result = getRela(Rel)->getType();
963 return object_error::success;
966 #define LLVM_ELF_SWITCH_RELOC_TYPE_NAME(enum) \
967 case ELF::enum: res = #enum; break;
969 template<support::endianness target_endianness, bool is64Bits>
970 error_code ELFObjectFile<target_endianness, is64Bits>
971 ::getRelocationTypeName(DataRefImpl Rel,
972 SmallVectorImpl<char> &Result) const {
973 const Elf_Shdr *sec = getSection(Rel.w.b);
976 switch (sec->sh_type) {
978 return object_error::parse_failed;
979 case ELF::SHT_REL : {
980 type = getRel(Rel)->getType();
983 case ELF::SHT_RELA : {
984 type = getRela(Rel)->getType();
988 switch (Header->e_machine) {
991 LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_NONE);
992 LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_64);
993 LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_PC32);
994 LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_GOT32);
995 LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_PLT32);
996 LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_COPY);
997 LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_GLOB_DAT);
998 LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_JUMP_SLOT);
999 LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_RELATIVE);
1000 LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_GOTPCREL);
1001 LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_32);
1002 LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_32S);
1003 LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_16);
1004 LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_PC16);
1005 LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_8);
1006 LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_PC8);
1007 LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_DTPMOD64);
1008 LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_DTPOFF64);
1009 LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_TPOFF64);
1010 LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_TLSGD);
1011 LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_TLSLD);
1012 LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_DTPOFF32);
1013 LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_GOTTPOFF);
1014 LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_TPOFF32);
1015 LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_PC64);
1016 LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_GOTOFF64);
1017 LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_GOTPC32);
1018 LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_SIZE32);
1019 LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_SIZE64);
1020 LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_GOTPC32_TLSDESC);
1021 LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_TLSDESC_CALL);
1022 LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_TLSDESC);
1029 LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_NONE);
1030 LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_32);
1031 LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_PC32);
1032 LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_GOT32);
1033 LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_PLT32);
1034 LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_COPY);
1035 LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_GLOB_DAT);
1036 LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_JUMP_SLOT);
1037 LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_RELATIVE);
1038 LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_GOTOFF);
1039 LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_GOTPC);
1040 LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_32PLT);
1041 LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_TPOFF);
1042 LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_IE);
1043 LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_GOTIE);
1044 LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_LE);
1045 LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_GD);
1046 LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_LDM);
1047 LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_16);
1048 LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_PC16);
1049 LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_8);
1050 LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_PC8);
1051 LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_GD_32);
1052 LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_GD_PUSH);
1053 LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_GD_CALL);
1054 LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_GD_POP);
1055 LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_LDM_32);
1056 LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_LDM_PUSH);
1057 LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_LDM_CALL);
1058 LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_LDM_POP);
1059 LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_LDO_32);
1060 LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_IE_32);
1061 LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_LE_32);
1062 LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_DTPMOD32);
1063 LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_DTPOFF32);
1064 LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_TPOFF32);
1065 LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_GOTDESC);
1066 LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_DESC_CALL);
1067 LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_DESC);
1068 LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_IRELATIVE);
1076 Result.append(res.begin(), res.end());
1077 return object_error::success;
1080 #undef LLVM_ELF_SWITCH_RELOC_TYPE_NAME
1082 template<support::endianness target_endianness, bool is64Bits>
1083 error_code ELFObjectFile<target_endianness, is64Bits>
1084 ::getRelocationAdditionalInfo(DataRefImpl Rel,
1085 int64_t &Result) const {
1086 const Elf_Shdr *sec = getSection(Rel.w.b);
1087 switch (sec->sh_type) {
1089 report_fatal_error("Invalid section type in Rel!");
1090 case ELF::SHT_REL : {
1092 return object_error::success;
1094 case ELF::SHT_RELA : {
1095 Result = getRela(Rel)->r_addend;
1096 return object_error::success;
1101 template<support::endianness target_endianness, bool is64Bits>
1102 error_code ELFObjectFile<target_endianness, is64Bits>
1103 ::getRelocationValueString(DataRefImpl Rel,
1104 SmallVectorImpl<char> &Result) const {
1105 const Elf_Shdr *sec = getSection(Rel.w.b);
1109 uint16_t symbol_index = 0;
1110 switch (sec->sh_type) {
1112 return object_error::parse_failed;
1113 case ELF::SHT_REL : {
1114 type = getRel(Rel)->getType();
1115 symbol_index = getRel(Rel)->getSymbol();
1116 // TODO: Read implicit addend from section data.
1119 case ELF::SHT_RELA : {
1120 type = getRela(Rel)->getType();
1121 symbol_index = getRela(Rel)->getSymbol();
1122 addend = getRela(Rel)->r_addend;
1126 const Elf_Sym *symb = getEntry<Elf_Sym>(sec->sh_link, symbol_index);
1128 if (error_code ec = getSymbolName(getSection(sec->sh_link), symb, symname))
1130 switch (Header->e_machine) {
1131 case ELF::EM_X86_64:
1133 case ELF::R_X86_64_32S:
1136 case ELF::R_X86_64_PC32: {
1138 raw_string_ostream fmt(fmtbuf);
1139 fmt << symname << (addend < 0 ? "" : "+") << addend << "-P";
1141 Result.append(fmtbuf.begin(), fmtbuf.end());
1152 Result.append(res.begin(), res.end());
1153 return object_error::success;
1156 // Verify that the last byte in the string table in a null.
1157 template<support::endianness target_endianness, bool is64Bits>
1158 void ELFObjectFile<target_endianness, is64Bits>
1159 ::VerifyStrTab(const Elf_Shdr *sh) const {
1160 const char *strtab = (const char*)base() + sh->sh_offset;
1161 if (strtab[sh->sh_size - 1] != 0)
1162 // FIXME: Proper error handling.
1163 report_fatal_error("String table must end with a null terminator!");
1166 template<support::endianness target_endianness, bool is64Bits>
1167 ELFObjectFile<target_endianness, is64Bits>::ELFObjectFile(MemoryBuffer *Object
1169 : ObjectFile(Binary::isELF, Object, ec)
1170 , isDyldELFObject(false)
1171 , SectionHeaderTable(0)
1172 , dot_shstrtab_sec(0)
1174 , dot_dynstr_sec(0) {
1176 const uint64_t FileSize = Data->getBufferSize();
1178 if (sizeof(Elf_Ehdr) > FileSize)
1179 // FIXME: Proper error handling.
1180 report_fatal_error("File too short!");
1182 Header = reinterpret_cast<const Elf_Ehdr *>(base());
1184 if (Header->e_shoff == 0)
1187 const uint64_t SectionTableOffset = Header->e_shoff;
1189 if (SectionTableOffset + sizeof(Elf_Shdr) > FileSize)
1190 // FIXME: Proper error handling.
1191 report_fatal_error("Section header table goes past end of file!");
1193 // The getNumSections() call below depends on SectionHeaderTable being set.
1194 SectionHeaderTable =
1195 reinterpret_cast<const Elf_Shdr *>(base() + SectionTableOffset);
1196 const uint64_t SectionTableSize = getNumSections() * Header->e_shentsize;
1198 if (SectionTableOffset + SectionTableSize > FileSize)
1199 // FIXME: Proper error handling.
1200 report_fatal_error("Section table goes past end of file!");
1202 // To find the symbol tables we walk the section table to find SHT_SYMTAB.
1203 const Elf_Shdr* SymbolTableSectionHeaderIndex = 0;
1204 const Elf_Shdr* sh = SectionHeaderTable;
1206 // Reserve SymbolTableSections[0] for .dynsym
1207 SymbolTableSections.push_back(NULL);
1209 for (uint64_t i = 0, e = getNumSections(); i != e; ++i) {
1210 if (sh->sh_type == ELF::SHT_SYMTAB_SHNDX) {
1211 if (SymbolTableSectionHeaderIndex)
1212 // FIXME: Proper error handling.
1213 report_fatal_error("More than one .symtab_shndx!");
1214 SymbolTableSectionHeaderIndex = sh;
1216 if (sh->sh_type == ELF::SHT_SYMTAB) {
1217 SymbolTableSectionsIndexMap[i] = SymbolTableSections.size();
1218 SymbolTableSections.push_back(sh);
1220 if (sh->sh_type == ELF::SHT_DYNSYM) {
1221 if (SymbolTableSections[0] != NULL)
1222 // FIXME: Proper error handling.
1223 report_fatal_error("More than one .dynsym!");
1224 SymbolTableSectionsIndexMap[i] = 0;
1225 SymbolTableSections[0] = sh;
1227 if (sh->sh_type == ELF::SHT_REL || sh->sh_type == ELF::SHT_RELA) {
1228 SectionRelocMap[getSection(sh->sh_info)].push_back(i);
1233 // Sort section relocation lists by index.
1234 for (typename RelocMap_t::iterator i = SectionRelocMap.begin(),
1235 e = SectionRelocMap.end(); i != e; ++i) {
1236 std::sort(i->second.begin(), i->second.end());
1239 // Get string table sections.
1240 dot_shstrtab_sec = getSection(getStringTableIndex());
1241 if (dot_shstrtab_sec) {
1242 // Verify that the last byte in the string table in a null.
1243 VerifyStrTab(dot_shstrtab_sec);
1246 // Merge this into the above loop.
1247 for (const char *i = reinterpret_cast<const char *>(SectionHeaderTable),
1248 *e = i + getNumSections() * Header->e_shentsize;
1249 i != e; i += Header->e_shentsize) {
1250 const Elf_Shdr *sh = reinterpret_cast<const Elf_Shdr*>(i);
1251 if (sh->sh_type == ELF::SHT_STRTAB) {
1252 StringRef SectionName(getString(dot_shstrtab_sec, sh->sh_name));
1253 if (SectionName == ".strtab") {
1254 if (dot_strtab_sec != 0)
1255 // FIXME: Proper error handling.
1256 report_fatal_error("Already found section named .strtab!");
1257 dot_strtab_sec = sh;
1258 VerifyStrTab(dot_strtab_sec);
1259 } else if (SectionName == ".dynstr") {
1260 if (dot_dynstr_sec != 0)
1261 // FIXME: Proper error handling.
1262 report_fatal_error("Already found section named .dynstr!");
1263 dot_dynstr_sec = sh;
1264 VerifyStrTab(dot_dynstr_sec);
1269 // Build symbol name side-mapping if there is one.
1270 if (SymbolTableSectionHeaderIndex) {
1271 const Elf_Word *ShndxTable = reinterpret_cast<const Elf_Word*>(base() +
1272 SymbolTableSectionHeaderIndex->sh_offset);
1274 for (symbol_iterator si = begin_symbols(),
1275 se = end_symbols(); si != se; si.increment(ec)) {
1277 report_fatal_error("Fewer extended symbol table entries than symbols!");
1278 if (*ShndxTable != ELF::SHN_UNDEF)
1279 ExtendedSymbolTable[getSymbol(si->getRawDataRefImpl())] = *ShndxTable;
1285 template<support::endianness target_endianness, bool is64Bits>
1286 symbol_iterator ELFObjectFile<target_endianness, is64Bits>
1287 ::begin_symbols() const {
1288 DataRefImpl SymbolData;
1289 memset(&SymbolData, 0, sizeof(SymbolData));
1290 if (SymbolTableSections.size() <= 1) {
1291 SymbolData.d.a = std::numeric_limits<uint32_t>::max();
1292 SymbolData.d.b = std::numeric_limits<uint32_t>::max();
1294 SymbolData.d.a = 1; // The 0th symbol in ELF is fake.
1295 SymbolData.d.b = 1; // The 0th table is .dynsym
1297 return symbol_iterator(SymbolRef(SymbolData, this));
1300 template<support::endianness target_endianness, bool is64Bits>
1301 symbol_iterator ELFObjectFile<target_endianness, is64Bits>
1302 ::end_symbols() const {
1303 DataRefImpl SymbolData;
1304 memset(&SymbolData, 0, sizeof(SymbolData));
1305 SymbolData.d.a = std::numeric_limits<uint32_t>::max();
1306 SymbolData.d.b = std::numeric_limits<uint32_t>::max();
1307 return symbol_iterator(SymbolRef(SymbolData, this));
1310 template<support::endianness target_endianness, bool is64Bits>
1311 symbol_iterator ELFObjectFile<target_endianness, is64Bits>
1312 ::begin_dynamic_symbols() const {
1313 DataRefImpl SymbolData;
1314 memset(&SymbolData, 0, sizeof(SymbolData));
1315 if (SymbolTableSections[0] == NULL) {
1316 SymbolData.d.a = std::numeric_limits<uint32_t>::max();
1317 SymbolData.d.b = std::numeric_limits<uint32_t>::max();
1319 SymbolData.d.a = 1; // The 0th symbol in ELF is fake.
1320 SymbolData.d.b = 0; // The 0th table is .dynsym
1322 return symbol_iterator(SymbolRef(SymbolData, this));
1325 template<support::endianness target_endianness, bool is64Bits>
1326 symbol_iterator ELFObjectFile<target_endianness, is64Bits>
1327 ::end_dynamic_symbols() const {
1328 DataRefImpl SymbolData;
1329 memset(&SymbolData, 0, sizeof(SymbolData));
1330 SymbolData.d.a = std::numeric_limits<uint32_t>::max();
1331 SymbolData.d.b = std::numeric_limits<uint32_t>::max();
1332 return symbol_iterator(SymbolRef(SymbolData, this));
1335 template<support::endianness target_endianness, bool is64Bits>
1336 section_iterator ELFObjectFile<target_endianness, is64Bits>
1337 ::begin_sections() const {
1339 memset(&ret, 0, sizeof(DataRefImpl));
1340 ret.p = reinterpret_cast<intptr_t>(base() + Header->e_shoff);
1341 return section_iterator(SectionRef(ret, this));
1344 template<support::endianness target_endianness, bool is64Bits>
1345 section_iterator ELFObjectFile<target_endianness, is64Bits>
1346 ::end_sections() const {
1348 memset(&ret, 0, sizeof(DataRefImpl));
1349 ret.p = reinterpret_cast<intptr_t>(base()
1351 + (Header->e_shentsize*getNumSections()));
1352 return section_iterator(SectionRef(ret, this));
1355 template<support::endianness target_endianness, bool is64Bits>
1356 uint8_t ELFObjectFile<target_endianness, is64Bits>::getBytesInAddress() const {
1357 return is64Bits ? 8 : 4;
1360 template<support::endianness target_endianness, bool is64Bits>
1361 StringRef ELFObjectFile<target_endianness, is64Bits>
1362 ::getFileFormatName() const {
1363 switch(Header->e_ident[ELF::EI_CLASS]) {
1364 case ELF::ELFCLASS32:
1365 switch(Header->e_machine) {
1367 return "ELF32-i386";
1368 case ELF::EM_X86_64:
1369 return "ELF32-x86-64";
1373 return "ELF32-unknown";
1375 case ELF::ELFCLASS64:
1376 switch(Header->e_machine) {
1378 return "ELF64-i386";
1379 case ELF::EM_X86_64:
1380 return "ELF64-x86-64";
1382 return "ELF64-unknown";
1385 // FIXME: Proper error handling.
1386 report_fatal_error("Invalid ELFCLASS!");
1390 template<support::endianness target_endianness, bool is64Bits>
1391 unsigned ELFObjectFile<target_endianness, is64Bits>::getArch() const {
1392 switch(Header->e_machine) {
1395 case ELF::EM_X86_64:
1396 return Triple::x86_64;
1400 return Triple::UnknownArch;
1404 template<support::endianness target_endianness, bool is64Bits>
1405 uint64_t ELFObjectFile<target_endianness, is64Bits>::getNumSections() const {
1406 assert(Header && "Header not initialized!");
1407 if (Header->e_shnum == ELF::SHN_UNDEF) {
1408 assert(SectionHeaderTable && "SectionHeaderTable not initialized!");
1409 return SectionHeaderTable->sh_size;
1411 return Header->e_shnum;
1414 template<support::endianness target_endianness, bool is64Bits>
1416 ELFObjectFile<target_endianness, is64Bits>::getStringTableIndex() const {
1417 if (Header->e_shnum == ELF::SHN_UNDEF) {
1418 if (Header->e_shstrndx == ELF::SHN_HIRESERVE)
1419 return SectionHeaderTable->sh_link;
1420 if (Header->e_shstrndx >= getNumSections())
1423 return Header->e_shstrndx;
1427 template<support::endianness target_endianness, bool is64Bits>
1428 template<typename T>
1430 ELFObjectFile<target_endianness, is64Bits>::getEntry(uint16_t Section,
1431 uint32_t Entry) const {
1432 return getEntry<T>(getSection(Section), Entry);
1435 template<support::endianness target_endianness, bool is64Bits>
1436 template<typename T>
1438 ELFObjectFile<target_endianness, is64Bits>::getEntry(const Elf_Shdr * Section,
1439 uint32_t Entry) const {
1440 return reinterpret_cast<const T *>(
1442 + Section->sh_offset
1443 + (Entry * Section->sh_entsize));
1446 template<support::endianness target_endianness, bool is64Bits>
1447 const typename ELFObjectFile<target_endianness, is64Bits>::Elf_Sym *
1448 ELFObjectFile<target_endianness, is64Bits>::getSymbol(DataRefImpl Symb) const {
1449 return getEntry<Elf_Sym>(SymbolTableSections[Symb.d.b], Symb.d.a);
1452 template<support::endianness target_endianness, bool is64Bits>
1453 const typename ELFObjectFile<target_endianness, is64Bits>::Elf_Rel *
1454 ELFObjectFile<target_endianness, is64Bits>::getRel(DataRefImpl Rel) const {
1455 return getEntry<Elf_Rel>(Rel.w.b, Rel.w.c);
1458 template<support::endianness target_endianness, bool is64Bits>
1459 const typename ELFObjectFile<target_endianness, is64Bits>::Elf_Rela *
1460 ELFObjectFile<target_endianness, is64Bits>::getRela(DataRefImpl Rela) const {
1461 return getEntry<Elf_Rela>(Rela.w.b, Rela.w.c);
1464 template<support::endianness target_endianness, bool is64Bits>
1465 const typename ELFObjectFile<target_endianness, is64Bits>::Elf_Shdr *
1466 ELFObjectFile<target_endianness, is64Bits>::getSection(DataRefImpl Symb) const {
1467 const Elf_Shdr *sec = getSection(Symb.d.b);
1468 if (sec->sh_type != ELF::SHT_SYMTAB || sec->sh_type != ELF::SHT_DYNSYM)
1469 // FIXME: Proper error handling.
1470 report_fatal_error("Invalid symbol table section!");
1474 template<support::endianness target_endianness, bool is64Bits>
1475 const typename ELFObjectFile<target_endianness, is64Bits>::Elf_Shdr *
1476 ELFObjectFile<target_endianness, is64Bits>::getSection(uint32_t index) const {
1479 if (!SectionHeaderTable || index >= getNumSections())
1480 // FIXME: Proper error handling.
1481 report_fatal_error("Invalid section index!");
1483 return reinterpret_cast<const Elf_Shdr *>(
1484 reinterpret_cast<const char *>(SectionHeaderTable)
1485 + (index * Header->e_shentsize));
1488 template<support::endianness target_endianness, bool is64Bits>
1489 const char *ELFObjectFile<target_endianness, is64Bits>
1490 ::getString(uint32_t section,
1491 ELF::Elf32_Word offset) const {
1492 return getString(getSection(section), offset);
1495 template<support::endianness target_endianness, bool is64Bits>
1496 const char *ELFObjectFile<target_endianness, is64Bits>
1497 ::getString(const Elf_Shdr *section,
1498 ELF::Elf32_Word offset) const {
1499 assert(section && section->sh_type == ELF::SHT_STRTAB && "Invalid section!");
1500 if (offset >= section->sh_size)
1501 // FIXME: Proper error handling.
1502 report_fatal_error("Symbol name offset outside of string table!");
1503 return (const char *)base() + section->sh_offset + offset;
1506 template<support::endianness target_endianness, bool is64Bits>
1507 error_code ELFObjectFile<target_endianness, is64Bits>
1508 ::getSymbolName(const Elf_Shdr *section,
1509 const Elf_Sym *symb,
1510 StringRef &Result) const {
1511 if (symb->st_name == 0) {
1512 const Elf_Shdr *section = getSection(symb);
1516 Result = getString(dot_shstrtab_sec, section->sh_name);
1517 return object_error::success;
1520 if (section == SymbolTableSections[0]) {
1521 // Symbol is in .dynsym, use .dynstr string table
1522 Result = getString(dot_dynstr_sec, symb->st_name);
1524 // Use the default symbol table name section.
1525 Result = getString(dot_strtab_sec, symb->st_name);
1527 return object_error::success;