1 //===- ELFObjectFile.cpp - 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 defines the ELFObjectFile class.
12 //===----------------------------------------------------------------------===//
14 #include "llvm/ADT/SmallVector.h"
15 #include "llvm/ADT/StringSwitch.h"
16 #include "llvm/ADT/Triple.h"
17 #include "llvm/ADT/DenseMap.h"
18 #include "llvm/Object/ObjectFile.h"
19 #include "llvm/Support/ELF.h"
20 #include "llvm/Support/Endian.h"
21 #include "llvm/Support/ErrorHandling.h"
22 #include "llvm/Support/MemoryBuffer.h"
27 using namespace object;
29 // Templates to choose Elf_Addr and Elf_Off depending on is64Bits.
31 template<support::endianness target_endianness>
32 struct ELFDataTypeTypedefHelperCommon {
33 typedef support::detail::packed_endian_specific_integral
34 <uint16_t, target_endianness, support::aligned> Elf_Half;
35 typedef support::detail::packed_endian_specific_integral
36 <uint32_t, target_endianness, support::aligned> Elf_Word;
37 typedef support::detail::packed_endian_specific_integral
38 <int32_t, target_endianness, support::aligned> Elf_Sword;
39 typedef support::detail::packed_endian_specific_integral
40 <uint64_t, target_endianness, support::aligned> Elf_Xword;
41 typedef support::detail::packed_endian_specific_integral
42 <int64_t, target_endianness, support::aligned> Elf_Sxword;
47 template<support::endianness target_endianness, bool is64Bits>
48 struct ELFDataTypeTypedefHelper;
51 template<support::endianness target_endianness>
52 struct ELFDataTypeTypedefHelper<target_endianness, false>
53 : ELFDataTypeTypedefHelperCommon<target_endianness> {
54 typedef support::detail::packed_endian_specific_integral
55 <uint32_t, target_endianness, support::aligned> Elf_Addr;
56 typedef support::detail::packed_endian_specific_integral
57 <uint32_t, target_endianness, support::aligned> Elf_Off;
61 template<support::endianness target_endianness>
62 struct ELFDataTypeTypedefHelper<target_endianness, true>
63 : ELFDataTypeTypedefHelperCommon<target_endianness>{
64 typedef support::detail::packed_endian_specific_integral
65 <uint64_t, target_endianness, support::aligned> Elf_Addr;
66 typedef support::detail::packed_endian_specific_integral
67 <uint64_t, target_endianness, support::aligned> Elf_Off;
71 // I really don't like doing this, but the alternative is copypasta.
72 #define LLVM_ELF_IMPORT_TYPES(target_endianness, is64Bits) \
74 ELFDataTypeTypedefHelper<target_endianness, is64Bits>::Elf_Addr Elf_Addr; \
76 ELFDataTypeTypedefHelper<target_endianness, is64Bits>::Elf_Off Elf_Off; \
78 ELFDataTypeTypedefHelper<target_endianness, is64Bits>::Elf_Half Elf_Half; \
80 ELFDataTypeTypedefHelper<target_endianness, is64Bits>::Elf_Word Elf_Word; \
82 ELFDataTypeTypedefHelper<target_endianness, is64Bits>::Elf_Sword Elf_Sword; \
84 ELFDataTypeTypedefHelper<target_endianness, is64Bits>::Elf_Xword Elf_Xword; \
86 ELFDataTypeTypedefHelper<target_endianness, is64Bits>::Elf_Sxword Elf_Sxword;
90 template<support::endianness target_endianness, bool is64Bits>
93 template<support::endianness target_endianness>
94 struct Elf_Shdr_Base<target_endianness, false> {
95 LLVM_ELF_IMPORT_TYPES(target_endianness, false)
96 Elf_Word sh_name; // Section name (index into string table)
97 Elf_Word sh_type; // Section type (SHT_*)
98 Elf_Word sh_flags; // Section flags (SHF_*)
99 Elf_Addr sh_addr; // Address where section is to be loaded
100 Elf_Off sh_offset; // File offset of section data, in bytes
101 Elf_Word sh_size; // Size of section, in bytes
102 Elf_Word sh_link; // Section type-specific header table index link
103 Elf_Word sh_info; // Section type-specific extra information
104 Elf_Word sh_addralign;// Section address alignment
105 Elf_Word sh_entsize; // Size of records contained within the section
108 template<support::endianness target_endianness>
109 struct Elf_Shdr_Base<target_endianness, true> {
110 LLVM_ELF_IMPORT_TYPES(target_endianness, true)
111 Elf_Word sh_name; // Section name (index into string table)
112 Elf_Word sh_type; // Section type (SHT_*)
113 Elf_Xword sh_flags; // Section flags (SHF_*)
114 Elf_Addr sh_addr; // Address where section is to be loaded
115 Elf_Off sh_offset; // File offset of section data, in bytes
116 Elf_Xword sh_size; // Size of section, in bytes
117 Elf_Word sh_link; // Section type-specific header table index link
118 Elf_Word sh_info; // Section type-specific extra information
119 Elf_Xword sh_addralign;// Section address alignment
120 Elf_Xword sh_entsize; // Size of records contained within the section
123 template<support::endianness target_endianness, bool is64Bits>
124 struct Elf_Shdr_Impl : Elf_Shdr_Base<target_endianness, is64Bits> {
125 using Elf_Shdr_Base<target_endianness, is64Bits>::sh_entsize;
126 using Elf_Shdr_Base<target_endianness, is64Bits>::sh_size;
128 /// @brief Get the number of entities this section contains if it has any.
129 unsigned getEntityCount() const {
132 return sh_size / sh_entsize;
138 template<support::endianness target_endianness, bool is64Bits>
141 template<support::endianness target_endianness>
142 struct Elf_Sym_Base<target_endianness, false> {
143 LLVM_ELF_IMPORT_TYPES(target_endianness, false)
144 Elf_Word st_name; // Symbol name (index into string table)
145 Elf_Addr st_value; // Value or address associated with the symbol
146 Elf_Word st_size; // Size of the symbol
147 unsigned char st_info; // Symbol's type and binding attributes
148 unsigned char st_other; // Must be zero; reserved
149 Elf_Half st_shndx; // Which section (header table index) it's defined in
152 template<support::endianness target_endianness>
153 struct Elf_Sym_Base<target_endianness, true> {
154 LLVM_ELF_IMPORT_TYPES(target_endianness, true)
155 Elf_Word st_name; // Symbol name (index into string table)
156 unsigned char st_info; // Symbol's type and binding attributes
157 unsigned char st_other; // Must be zero; reserved
158 Elf_Half st_shndx; // Which section (header table index) it's defined in
159 Elf_Addr st_value; // Value or address associated with the symbol
160 Elf_Xword st_size; // Size of the symbol
163 template<support::endianness target_endianness, bool is64Bits>
164 struct Elf_Sym_Impl : Elf_Sym_Base<target_endianness, is64Bits> {
165 using Elf_Sym_Base<target_endianness, is64Bits>::st_info;
167 // These accessors and mutators correspond to the ELF32_ST_BIND,
168 // ELF32_ST_TYPE, and ELF32_ST_INFO macros defined in the ELF specification:
169 unsigned char getBinding() const { return st_info >> 4; }
170 unsigned char getType() const { return st_info & 0x0f; }
171 void setBinding(unsigned char b) { setBindingAndType(b, getType()); }
172 void setType(unsigned char t) { setBindingAndType(getBinding(), t); }
173 void setBindingAndType(unsigned char b, unsigned char t) {
174 st_info = (b << 4) + (t & 0x0f);
180 template<support::endianness target_endianness, bool is64Bits, bool isRela>
183 template<support::endianness target_endianness>
184 struct Elf_Rel_Base<target_endianness, false, false> {
185 LLVM_ELF_IMPORT_TYPES(target_endianness, false)
186 Elf_Addr r_offset; // Location (file byte offset, or program virtual addr)
187 Elf_Word r_info; // Symbol table index and type of relocation to apply
190 template<support::endianness target_endianness>
191 struct Elf_Rel_Base<target_endianness, true, false> {
192 LLVM_ELF_IMPORT_TYPES(target_endianness, true)
193 Elf_Addr r_offset; // Location (file byte offset, or program virtual addr)
194 Elf_Xword r_info; // Symbol table index and type of relocation to apply
197 template<support::endianness target_endianness>
198 struct Elf_Rel_Base<target_endianness, false, true> {
199 LLVM_ELF_IMPORT_TYPES(target_endianness, false)
200 Elf_Addr r_offset; // Location (file byte offset, or program virtual addr)
201 Elf_Word r_info; // Symbol table index and type of relocation to apply
202 Elf_Sword r_addend; // Compute value for relocatable field by adding this
205 template<support::endianness target_endianness>
206 struct Elf_Rel_Base<target_endianness, true, true> {
207 LLVM_ELF_IMPORT_TYPES(target_endianness, true)
208 Elf_Addr r_offset; // Location (file byte offset, or program virtual addr)
209 Elf_Xword r_info; // Symbol table index and type of relocation to apply
210 Elf_Sxword r_addend; // Compute value for relocatable field by adding this.
213 template<support::endianness target_endianness, bool is64Bits, bool isRela>
216 template<support::endianness target_endianness, bool isRela>
217 struct Elf_Rel_Impl<target_endianness, true, isRela>
218 : Elf_Rel_Base<target_endianness, true, isRela> {
219 using Elf_Rel_Base<target_endianness, true, isRela>::r_info;
220 LLVM_ELF_IMPORT_TYPES(target_endianness, true)
222 // These accessors and mutators correspond to the ELF64_R_SYM, ELF64_R_TYPE,
223 // and ELF64_R_INFO macros defined in the ELF specification:
224 uint64_t getSymbol() const { return (r_info >> 32); }
225 unsigned char getType() const {
226 return (unsigned char) (r_info & 0xffffffffL);
228 void setSymbol(uint64_t s) { setSymbolAndType(s, getType()); }
229 void setType(unsigned char t) { setSymbolAndType(getSymbol(), t); }
230 void setSymbolAndType(uint64_t s, unsigned char t) {
231 r_info = (s << 32) + (t&0xffffffffL);
235 template<support::endianness target_endianness, bool isRela>
236 struct Elf_Rel_Impl<target_endianness, false, isRela>
237 : Elf_Rel_Base<target_endianness, false, isRela> {
238 using Elf_Rel_Base<target_endianness, false, isRela>::r_info;
239 LLVM_ELF_IMPORT_TYPES(target_endianness, false)
241 // These accessors and mutators correspond to the ELF32_R_SYM, ELF32_R_TYPE,
242 // and ELF32_R_INFO macros defined in the ELF specification:
243 uint32_t getSymbol() const { return (r_info >> 8); }
244 unsigned char getType() const { return (unsigned char) (r_info & 0x0ff); }
245 void setSymbol(uint32_t s) { setSymbolAndType(s, getType()); }
246 void setType(unsigned char t) { setSymbolAndType(getSymbol(), t); }
247 void setSymbolAndType(uint32_t s, unsigned char t) {
248 r_info = (s << 8) + t;
255 template<support::endianness target_endianness, bool is64Bits>
256 class ELFObjectFile : public ObjectFile {
257 LLVM_ELF_IMPORT_TYPES(target_endianness, is64Bits)
259 typedef Elf_Shdr_Impl<target_endianness, is64Bits> Elf_Shdr;
260 typedef Elf_Sym_Impl<target_endianness, is64Bits> Elf_Sym;
261 typedef Elf_Rel_Impl<target_endianness, is64Bits, false> Elf_Rel;
262 typedef Elf_Rel_Impl<target_endianness, is64Bits, true> Elf_Rela;
265 unsigned char e_ident[ELF::EI_NIDENT]; // ELF Identification bytes
266 Elf_Half e_type; // Type of file (see ET_*)
267 Elf_Half e_machine; // Required architecture for this file (see EM_*)
268 Elf_Word e_version; // Must be equal to 1
269 Elf_Addr e_entry; // Address to jump to in order to start program
270 Elf_Off e_phoff; // Program header table's file offset, in bytes
271 Elf_Off e_shoff; // Section header table's file offset, in bytes
272 Elf_Word e_flags; // Processor-specific flags
273 Elf_Half e_ehsize; // Size of ELF header, in bytes
274 Elf_Half e_phentsize;// Size of an entry in the program header table
275 Elf_Half e_phnum; // Number of entries in the program header table
276 Elf_Half e_shentsize;// Size of an entry in the section header table
277 Elf_Half e_shnum; // Number of entries in the section header table
278 Elf_Half e_shstrndx; // Section header table index of section name
280 bool checkMagic() const {
281 return (memcmp(e_ident, ELF::ElfMagic, strlen(ELF::ElfMagic))) == 0;
283 unsigned char getFileClass() const { return e_ident[ELF::EI_CLASS]; }
284 unsigned char getDataEncoding() const { return e_ident[ELF::EI_DATA]; }
287 typedef SmallVector<const Elf_Shdr*, 1> Sections_t;
288 typedef DenseMap<unsigned, unsigned> IndexMap_t;
290 const Elf_Ehdr *Header;
291 const Elf_Shdr *SectionHeaderTable;
292 const Elf_Shdr *dot_shstrtab_sec; // Section header string table.
293 const Elf_Shdr *dot_strtab_sec; // Symbol header string table.
294 Sections_t SymbolTableSections;
295 IndexMap_t SymbolTableSectionsIndexMap;
296 Sections_t RelocationTableSections;
298 void validateSymbol(DataRefImpl Symb) const;
299 bool isRelocationHasAddend(DataRefImpl Rel) const;
301 const T *getEntry(DataRefImpl Entry, Sections_t Sections) const;
302 const Elf_Sym *getSymbol(DataRefImpl Symb) const;
303 const Elf_Shdr *getSection(DataRefImpl index) const;
304 const Elf_Shdr *getSection(uint16_t index) const;
305 const Elf_Rel *getRel(DataRefImpl Rel) const;
306 const Elf_Rela *getRela(DataRefImpl Rela) const;
307 const char *getString(uint16_t section, uint32_t offset) const;
308 const char *getString(const Elf_Shdr *section, uint32_t offset) const;
311 virtual error_code getSymbolNext(DataRefImpl Symb, SymbolRef &Res) const;
312 virtual error_code getSymbolName(DataRefImpl Symb, StringRef &Res) const;
313 virtual error_code getSymbolOffset(DataRefImpl Symb, uint64_t &Res) const;
314 virtual error_code getSymbolAddress(DataRefImpl Symb, uint64_t &Res) const;
315 virtual error_code getSymbolSize(DataRefImpl Symb, uint64_t &Res) const;
316 virtual error_code getSymbolNMTypeChar(DataRefImpl Symb, char &Res) const;
317 virtual error_code isSymbolInternal(DataRefImpl Symb, bool &Res) const;
318 virtual error_code isSymbolGlobal(DataRefImpl Symb, bool &Res) const;
319 virtual error_code getSymbolType(DataRefImpl Symb, SymbolRef::SymbolType &Res) const;
321 virtual error_code getSectionNext(DataRefImpl Sec, SectionRef &Res) const;
322 virtual error_code getSectionName(DataRefImpl Sec, StringRef &Res) const;
323 virtual error_code getSectionAddress(DataRefImpl Sec, uint64_t &Res) const;
324 virtual error_code getSectionSize(DataRefImpl Sec, uint64_t &Res) const;
325 virtual error_code getSectionContents(DataRefImpl Sec, StringRef &Res) const;
326 virtual error_code isSectionText(DataRefImpl Sec, bool &Res) const;
327 virtual error_code isSectionData(DataRefImpl Sec, bool &Res) const;
328 virtual error_code isSectionBSS(DataRefImpl Sec, bool &Res) const;
329 virtual error_code sectionContainsSymbol(DataRefImpl Sec, DataRefImpl Symb,
332 virtual error_code getRelocationNext(DataRefImpl Rel,
333 RelocationRef &Res) const;
334 virtual error_code getRelocationAddress(DataRefImpl Rel,
335 uint64_t &Res) const;
336 virtual error_code getRelocationSymbol(DataRefImpl Rel,
337 SymbolRef &Res) const;
338 virtual error_code getRelocationType(DataRefImpl Rel,
339 uint32_t &Res) const;
340 virtual error_code getRelocationAdditionalInfo(DataRefImpl Rel,
344 ELFObjectFile(MemoryBuffer *Object, error_code &ec);
345 virtual symbol_iterator begin_symbols() const;
346 virtual symbol_iterator end_symbols() const;
347 virtual section_iterator begin_sections() const;
348 virtual section_iterator end_sections() const;
349 virtual relocation_iterator begin_relocations() const;
350 virtual relocation_iterator end_relocations() const;
352 virtual uint8_t getBytesInAddress() const;
353 virtual StringRef getFileFormatName() const;
354 virtual unsigned getArch() const;
358 template<support::endianness target_endianness, bool is64Bits>
359 void ELFObjectFile<target_endianness, is64Bits>
360 ::validateSymbol(DataRefImpl Symb) const {
361 const Elf_Sym *symb = getSymbol(Symb);
362 const Elf_Shdr *SymbolTableSection = SymbolTableSections[Symb.d.b];
363 // FIXME: We really need to do proper error handling in the case of an invalid
364 // input file. Because we don't use exceptions, I think we'll just pass
365 // an error object around.
367 && SymbolTableSection
368 && symb >= (const Elf_Sym*)(base()
369 + SymbolTableSection->sh_offset)
370 && symb < (const Elf_Sym*)(base()
371 + SymbolTableSection->sh_offset
372 + SymbolTableSection->sh_size)))
373 // FIXME: Proper error handling.
374 report_fatal_error("Symb must point to a valid symbol!");
377 template<support::endianness target_endianness, bool is64Bits>
378 error_code ELFObjectFile<target_endianness, is64Bits>
379 ::getSymbolNext(DataRefImpl Symb,
380 SymbolRef &Result) const {
381 validateSymbol(Symb);
382 const Elf_Shdr *SymbolTableSection = SymbolTableSections[Symb.d.b];
385 // Check to see if we are at the end of this symbol table.
386 if (Symb.d.a >= SymbolTableSection->getEntityCount()) {
387 // We are at the end. If there are other symbol tables, jump to them.
389 Symb.d.a = 1; // The 0th symbol in ELF is fake.
390 // Otherwise return the terminator.
391 if (Symb.d.b >= SymbolTableSections.size()) {
392 Symb.d.a = std::numeric_limits<uint32_t>::max();
393 Symb.d.b = std::numeric_limits<uint32_t>::max();
397 Result = SymbolRef(Symb, this);
398 return object_error::success;
401 template<support::endianness target_endianness, bool is64Bits>
402 error_code ELFObjectFile<target_endianness, is64Bits>
403 ::getSymbolName(DataRefImpl Symb,
404 StringRef &Result) const {
405 validateSymbol(Symb);
406 const Elf_Sym *symb = getSymbol(Symb);
407 if (symb->st_name == 0) {
408 const Elf_Shdr *section = getSection(symb->st_shndx);
412 Result = getString(dot_shstrtab_sec, section->sh_name);
413 return object_error::success;
416 // Use the default symbol table name section.
417 Result = getString(dot_strtab_sec, symb->st_name);
418 return object_error::success;
421 template<support::endianness target_endianness, bool is64Bits>
422 error_code ELFObjectFile<target_endianness, is64Bits>
423 ::getSymbolOffset(DataRefImpl Symb,
424 uint64_t &Result) const {
425 validateSymbol(Symb);
426 const Elf_Sym *symb = getSymbol(Symb);
427 const Elf_Shdr *Section;
428 switch (symb->st_shndx) {
429 case ELF::SHN_COMMON:
430 // Undefined symbols have no address yet.
432 Result = UnknownAddressOrSize;
433 return object_error::success;
435 Result = symb->st_value;
436 return object_error::success;
437 default: Section = getSection(symb->st_shndx);
440 switch (symb->getType()) {
441 case ELF::STT_SECTION:
442 Result = Section ? Section->sh_addr : UnknownAddressOrSize;
443 return object_error::success;
445 case ELF::STT_OBJECT:
446 case ELF::STT_NOTYPE:
447 Result = symb->st_value;
448 return object_error::success;
450 Result = UnknownAddressOrSize;
451 return object_error::success;
455 template<support::endianness target_endianness, bool is64Bits>
456 error_code ELFObjectFile<target_endianness, is64Bits>
457 ::getSymbolAddress(DataRefImpl Symb,
458 uint64_t &Result) const {
459 validateSymbol(Symb);
460 const Elf_Sym *symb = getSymbol(Symb);
461 const Elf_Shdr *Section;
462 switch (symb->st_shndx) {
463 case ELF::SHN_COMMON: // Fall through.
464 // Undefined symbols have no address yet.
466 Result = UnknownAddressOrSize;
467 return object_error::success;
469 Result = reinterpret_cast<uintptr_t>(base()+symb->st_value);
470 return object_error::success;
471 default: Section = getSection(symb->st_shndx);
473 const uint8_t* addr = base();
475 addr += Section->sh_offset;
476 switch (symb->getType()) {
477 case ELF::STT_SECTION:
478 Result = reinterpret_cast<uintptr_t>(addr);
479 return object_error::success;
480 case ELF::STT_FUNC: // Fall through.
481 case ELF::STT_OBJECT: // Fall through.
482 case ELF::STT_NOTYPE:
483 addr += symb->st_value;
484 Result = reinterpret_cast<uintptr_t>(addr);
485 return object_error::success;
487 Result = UnknownAddressOrSize;
488 return object_error::success;
492 template<support::endianness target_endianness, bool is64Bits>
493 error_code ELFObjectFile<target_endianness, is64Bits>
494 ::getSymbolSize(DataRefImpl Symb,
495 uint64_t &Result) const {
496 validateSymbol(Symb);
497 const Elf_Sym *symb = getSymbol(Symb);
498 if (symb->st_size == 0)
499 Result = UnknownAddressOrSize;
500 Result = symb->st_size;
501 return object_error::success;
504 template<support::endianness target_endianness, bool is64Bits>
505 error_code ELFObjectFile<target_endianness, is64Bits>
506 ::getSymbolNMTypeChar(DataRefImpl Symb,
507 char &Result) const {
508 validateSymbol(Symb);
509 const Elf_Sym *symb = getSymbol(Symb);
510 const Elf_Shdr *Section = getSection(symb->st_shndx);
515 switch (Section->sh_type) {
516 case ELF::SHT_PROGBITS:
517 case ELF::SHT_DYNAMIC:
518 switch (Section->sh_flags) {
519 case (ELF::SHF_ALLOC | ELF::SHF_EXECINSTR):
521 case (ELF::SHF_ALLOC | ELF::SHF_WRITE):
524 case (ELF::SHF_ALLOC | ELF::SHF_MERGE):
525 case (ELF::SHF_ALLOC | ELF::SHF_MERGE | ELF::SHF_STRINGS):
529 case ELF::SHT_NOBITS: ret = 'b';
533 switch (symb->st_shndx) {
538 case ELF::SHN_ABS: ret = 'a'; break;
539 case ELF::SHN_COMMON: ret = 'c'; break;
542 switch (symb->getBinding()) {
543 case ELF::STB_GLOBAL: ret = ::toupper(ret); break;
545 if (symb->st_shndx == ELF::SHN_UNDEF)
548 if (symb->getType() == ELF::STT_OBJECT)
554 if (ret == '?' && symb->getType() == ELF::STT_SECTION) {
556 if (error_code ec = getSymbolName(Symb, name))
558 Result = StringSwitch<char>(name)
559 .StartsWith(".debug", 'N')
560 .StartsWith(".note", 'n')
562 return object_error::success;
566 return object_error::success;
569 template<support::endianness target_endianness, bool is64Bits>
570 error_code ELFObjectFile<target_endianness, is64Bits>
571 ::getSymbolType(DataRefImpl Symb,
572 SymbolRef::SymbolType &Result) const {
573 validateSymbol(Symb);
574 const Elf_Sym *symb = getSymbol(Symb);
576 if (symb->st_shndx == ELF::SHN_UNDEF) {
577 Result = SymbolRef::ST_External;
578 return object_error::success;
581 switch (symb->getType()) {
583 Result = SymbolRef::ST_Function;
585 case ELF::STT_OBJECT:
586 Result = SymbolRef::ST_Data;
589 Result = SymbolRef::ST_Other;
592 return object_error::success;
595 template<support::endianness target_endianness, bool is64Bits>
596 error_code ELFObjectFile<target_endianness, is64Bits>
597 ::isSymbolGlobal(DataRefImpl Symb,
598 bool &Result) const {
599 validateSymbol(Symb);
600 const Elf_Sym *symb = getSymbol(Symb);
602 Result = symb->getBinding() == ELF::STB_GLOBAL;
603 return object_error::success;
606 template<support::endianness target_endianness, bool is64Bits>
607 error_code ELFObjectFile<target_endianness, is64Bits>
608 ::isSymbolInternal(DataRefImpl Symb,
609 bool &Result) const {
610 validateSymbol(Symb);
611 const Elf_Sym *symb = getSymbol(Symb);
613 if ( symb->getType() == ELF::STT_FILE
614 || symb->getType() == ELF::STT_SECTION)
617 return object_error::success;
620 template<support::endianness target_endianness, bool is64Bits>
621 error_code ELFObjectFile<target_endianness, is64Bits>
622 ::getSectionNext(DataRefImpl Sec, SectionRef &Result) const {
623 const uint8_t *sec = reinterpret_cast<const uint8_t *>(Sec.p);
624 sec += Header->e_shentsize;
625 Sec.p = reinterpret_cast<intptr_t>(sec);
626 Result = SectionRef(Sec, this);
627 return object_error::success;
630 template<support::endianness target_endianness, bool is64Bits>
631 error_code ELFObjectFile<target_endianness, is64Bits>
632 ::getSectionName(DataRefImpl Sec,
633 StringRef &Result) const {
634 const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p);
635 Result = StringRef(getString(dot_shstrtab_sec, sec->sh_name));
636 return object_error::success;
639 template<support::endianness target_endianness, bool is64Bits>
640 error_code ELFObjectFile<target_endianness, is64Bits>
641 ::getSectionAddress(DataRefImpl Sec,
642 uint64_t &Result) const {
643 const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p);
644 Result = sec->sh_addr;
645 return object_error::success;
648 template<support::endianness target_endianness, bool is64Bits>
649 error_code ELFObjectFile<target_endianness, is64Bits>
650 ::getSectionSize(DataRefImpl Sec,
651 uint64_t &Result) const {
652 const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p);
653 Result = sec->sh_size;
654 return object_error::success;
657 template<support::endianness target_endianness, bool is64Bits>
658 error_code ELFObjectFile<target_endianness, is64Bits>
659 ::getSectionContents(DataRefImpl Sec,
660 StringRef &Result) const {
661 const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p);
662 const char *start = (const char*)base() + sec->sh_offset;
663 Result = StringRef(start, sec->sh_size);
664 return object_error::success;
667 template<support::endianness target_endianness, bool is64Bits>
668 error_code ELFObjectFile<target_endianness, is64Bits>
669 ::isSectionText(DataRefImpl Sec,
670 bool &Result) const {
671 const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p);
672 if (sec->sh_flags & ELF::SHF_EXECINSTR)
676 return object_error::success;
679 template<support::endianness target_endianness, bool is64Bits>
680 error_code ELFObjectFile<target_endianness, is64Bits>
681 ::isSectionData(DataRefImpl Sec,
682 bool &Result) const {
683 const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p);
684 if (sec->sh_flags & (ELF::SHF_ALLOC | ELF::SHF_WRITE)
685 && sec->sh_type == ELF::SHT_PROGBITS)
689 return object_error::success;
692 template<support::endianness target_endianness, bool is64Bits>
693 error_code ELFObjectFile<target_endianness, is64Bits>
694 ::isSectionBSS(DataRefImpl Sec,
695 bool &Result) const {
696 const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p);
697 if (sec->sh_flags & (ELF::SHF_ALLOC | ELF::SHF_WRITE)
698 && sec->sh_type == ELF::SHT_NOBITS)
702 return object_error::success;
705 template<support::endianness target_endianness, bool is64Bits>
706 error_code ELFObjectFile<target_endianness, is64Bits>
707 ::sectionContainsSymbol(DataRefImpl Sec,
709 bool &Result) const {
710 // FIXME: Unimplemented.
712 return object_error::success;
716 template<support::endianness target_endianness, bool is64Bits>
717 error_code ELFObjectFile<target_endianness, is64Bits>
718 ::getRelocationNext(DataRefImpl Rel,
719 RelocationRef &Result) const {
720 const Elf_Shdr *RelocationTableSection = RelocationTableSections[Rel.d.b];
722 // Check to see if we are at the end of this relocation table.
723 if (++Rel.d.a >= RelocationTableSection->getEntityCount()) {
724 // We are at the end. If there are other relocation tables, jump to them.
726 // Otherwise return the terminator.
727 if (++Rel.d.b >= SymbolTableSections.size()) {
728 Rel.d.a = std::numeric_limits<uint32_t>::max();
729 Rel.d.b = std::numeric_limits<uint32_t>::max();
733 Result = RelocationRef(Rel, this);
734 return object_error::success;
737 template<support::endianness target_endianness, bool is64Bits>
738 error_code ELFObjectFile<target_endianness, is64Bits>
739 ::getRelocationSymbol(DataRefImpl Rel,
740 SymbolRef &Result) const {
742 const Elf_Shdr *sec = RelocationTableSections[Rel.d.b];
743 switch (sec->sh_type) {
745 report_fatal_error("Invalid section type in Rel!");
746 case ELF::SHT_REL : {
747 symbolIdx = getRel(Rel)->getSymbol();
750 case ELF::SHT_RELA : {
751 symbolIdx = getRela(Rel)->getSymbol();
755 DataRefImpl SymbolData;
756 IndexMap_t::const_iterator it = SymbolTableSectionsIndexMap.find(sec->sh_link);
757 if (it == SymbolTableSectionsIndexMap.end())
758 report_fatal_error("Relocation symbol table not found!");
759 SymbolData.d.a = symbolIdx;
760 SymbolData.d.b = it->second;
761 Result = SymbolRef(SymbolData, this);
762 return object_error::success;
765 template<support::endianness target_endianness, bool is64Bits>
766 error_code ELFObjectFile<target_endianness, is64Bits>
767 ::getRelocationAddress(DataRefImpl Rel,
768 uint64_t &Result) const {
770 const Elf_Shdr *sec = RelocationTableSections[Rel.d.b];
771 switch (sec->sh_type) {
773 report_fatal_error("Invalid section type in Rel!");
774 case ELF::SHT_REL : {
775 offset = getRel(Rel)->r_offset;
778 case ELF::SHT_RELA : {
779 offset = getRela(Rel)->r_offset;
784 const Elf_Shdr *secAddr = getSection(sec->sh_info);
785 Result = offset + reinterpret_cast<uintptr_t>(base() + secAddr->sh_offset);
786 return object_error::success;
789 template<support::endianness target_endianness, bool is64Bits>
790 error_code ELFObjectFile<target_endianness, is64Bits>
791 ::getRelocationType(DataRefImpl Rel,
792 uint32_t &Result) const {
793 const Elf_Shdr *sec = RelocationTableSections[Rel.d.b];
794 switch (sec->sh_type) {
796 report_fatal_error("Invalid section type in Rel!");
797 case ELF::SHT_REL : {
798 Result = getRel(Rel)->getType();
801 case ELF::SHT_RELA : {
802 Result = getRela(Rel)->getType();
806 return object_error::success;
809 template<support::endianness target_endianness, bool is64Bits>
810 error_code ELFObjectFile<target_endianness, is64Bits>
811 ::getRelocationAdditionalInfo(DataRefImpl Rel,
812 int64_t &Result) const {
813 const Elf_Shdr *sec = RelocationTableSections[Rel.d.b];
814 switch (sec->sh_type) {
816 report_fatal_error("Invalid section type in Rel!");
817 case ELF::SHT_REL : {
819 return object_error::success;
821 case ELF::SHT_RELA : {
822 Result = getRela(Rel)->r_addend;
823 return object_error::success;
830 template<support::endianness target_endianness, bool is64Bits>
831 ELFObjectFile<target_endianness, is64Bits>::ELFObjectFile(MemoryBuffer *Object
833 : ObjectFile(Binary::isELF, Object, ec)
834 , SectionHeaderTable(0)
835 , dot_shstrtab_sec(0)
836 , dot_strtab_sec(0) {
837 Header = reinterpret_cast<const Elf_Ehdr *>(base());
839 if (Header->e_shoff == 0)
843 reinterpret_cast<const Elf_Shdr *>(base() + Header->e_shoff);
844 uint32_t SectionTableSize = Header->e_shnum * Header->e_shentsize;
845 if (!( (const uint8_t *)SectionHeaderTable + SectionTableSize
846 <= base() + Data->getBufferSize()))
847 // FIXME: Proper error handling.
848 report_fatal_error("Section table goes past end of file!");
851 // To find the symbol tables we walk the section table to find SHT_STMTAB.
853 reinterpret_cast<const Elf_Shdr*>(SectionHeaderTable);
854 for (unsigned i = 0; i < Header->e_shnum; ++i) {
855 if (sh->sh_type == ELF::SHT_SYMTAB) {
856 SymbolTableSectionsIndexMap[i] = SymbolTableSections.size();
857 SymbolTableSections.push_back(sh);
859 if (sh->sh_type == ELF::SHT_REL || sh->sh_type == ELF::SHT_RELA) {
860 RelocationTableSections.push_back(sh);
865 // Get string table sections.
866 dot_shstrtab_sec = getSection(Header->e_shstrndx);
867 if (dot_shstrtab_sec) {
868 // Verify that the last byte in the string table in a null.
869 if (((const char*)base() + dot_shstrtab_sec->sh_offset)
870 [dot_shstrtab_sec->sh_size - 1] != 0)
871 // FIXME: Proper error handling.
872 report_fatal_error("String table must end with a null terminator!");
875 // Merge this into the above loop.
876 for (const char *i = reinterpret_cast<const char *>(SectionHeaderTable),
877 *e = i + Header->e_shnum * Header->e_shentsize;
878 i != e; i += Header->e_shentsize) {
879 const Elf_Shdr *sh = reinterpret_cast<const Elf_Shdr*>(i);
880 if (sh->sh_type == ELF::SHT_STRTAB) {
881 StringRef SectionName(getString(dot_shstrtab_sec, sh->sh_name));
882 if (SectionName == ".strtab") {
883 if (dot_strtab_sec != 0)
884 // FIXME: Proper error handling.
885 report_fatal_error("Already found section named .strtab!");
887 const char *dot_strtab = (const char*)base() + sh->sh_offset;
888 if (dot_strtab[sh->sh_size - 1] != 0)
889 // FIXME: Proper error handling.
890 report_fatal_error("String table must end with a null terminator!");
896 template<support::endianness target_endianness, bool is64Bits>
897 ObjectFile::symbol_iterator ELFObjectFile<target_endianness, is64Bits>
898 ::begin_symbols() const {
899 DataRefImpl SymbolData;
900 memset(&SymbolData, 0, sizeof(SymbolData));
901 if (SymbolTableSections.size() == 0) {
902 SymbolData.d.a = std::numeric_limits<uint32_t>::max();
903 SymbolData.d.b = std::numeric_limits<uint32_t>::max();
905 SymbolData.d.a = 1; // The 0th symbol in ELF is fake.
908 return symbol_iterator(SymbolRef(SymbolData, this));
911 template<support::endianness target_endianness, bool is64Bits>
912 ObjectFile::symbol_iterator ELFObjectFile<target_endianness, is64Bits>
913 ::end_symbols() const {
914 DataRefImpl SymbolData;
915 memset(&SymbolData, 0, sizeof(SymbolData));
916 SymbolData.d.a = std::numeric_limits<uint32_t>::max();
917 SymbolData.d.b = std::numeric_limits<uint32_t>::max();
918 return symbol_iterator(SymbolRef(SymbolData, this));
921 template<support::endianness target_endianness, bool is64Bits>
922 ObjectFile::section_iterator ELFObjectFile<target_endianness, is64Bits>
923 ::begin_sections() const {
925 memset(&ret, 0, sizeof(DataRefImpl));
926 ret.p = reinterpret_cast<intptr_t>(base() + Header->e_shoff);
927 return section_iterator(SectionRef(ret, this));
930 template<support::endianness target_endianness, bool is64Bits>
931 ObjectFile::section_iterator ELFObjectFile<target_endianness, is64Bits>
932 ::end_sections() const {
934 memset(&ret, 0, sizeof(DataRefImpl));
935 ret.p = reinterpret_cast<intptr_t>(base()
937 + (Header->e_shentsize * Header->e_shnum));
938 return section_iterator(SectionRef(ret, this));
941 template<support::endianness target_endianness, bool is64Bits>
942 ObjectFile::relocation_iterator ELFObjectFile<target_endianness, is64Bits>
943 ::begin_relocations() const {
945 memset(&RelData, 0, sizeof(RelData));
946 if (RelocationTableSections.size() == 0) {
947 RelData.d.a = std::numeric_limits<uint32_t>::max();
948 RelData.d.b = std::numeric_limits<uint32_t>::max();
953 return relocation_iterator(RelocationRef(RelData, this));
956 template<support::endianness target_endianness, bool is64Bits>
957 ObjectFile::relocation_iterator ELFObjectFile<target_endianness, is64Bits>
958 ::end_relocations() const {
960 memset(&RelData, 0, sizeof(RelData));
961 RelData.d.a = std::numeric_limits<uint32_t>::max();
962 RelData.d.b = std::numeric_limits<uint32_t>::max();
963 return relocation_iterator(RelocationRef(RelData, this));
966 template<support::endianness target_endianness, bool is64Bits>
967 uint8_t ELFObjectFile<target_endianness, is64Bits>::getBytesInAddress() const {
968 return is64Bits ? 8 : 4;
971 template<support::endianness target_endianness, bool is64Bits>
972 StringRef ELFObjectFile<target_endianness, is64Bits>
973 ::getFileFormatName() const {
974 switch(Header->e_ident[ELF::EI_CLASS]) {
975 case ELF::ELFCLASS32:
976 switch(Header->e_machine) {
980 return "ELF32-x86-64";
984 return "ELF32-unknown";
986 case ELF::ELFCLASS64:
987 switch(Header->e_machine) {
991 return "ELF64-x86-64";
993 return "ELF64-unknown";
996 // FIXME: Proper error handling.
997 report_fatal_error("Invalid ELFCLASS!");
1001 template<support::endianness target_endianness, bool is64Bits>
1002 unsigned ELFObjectFile<target_endianness, is64Bits>::getArch() const {
1003 switch(Header->e_machine) {
1006 case ELF::EM_X86_64:
1007 return Triple::x86_64;
1011 return Triple::UnknownArch;
1015 template<support::endianness target_endianness, bool is64Bits>
1016 template<typename T>
1018 ELFObjectFile<target_endianness, is64Bits>::getEntry(DataRefImpl Entry,
1019 Sections_t Sections) const {
1020 const Elf_Shdr *sec = Sections[Entry.d.b];
1021 return reinterpret_cast<const T *>(
1024 + (Entry.d.a * sec->sh_entsize));
1027 template<support::endianness target_endianness, bool is64Bits>
1028 const typename ELFObjectFile<target_endianness, is64Bits>::Elf_Sym *
1029 ELFObjectFile<target_endianness, is64Bits>::getSymbol(DataRefImpl Symb) const {
1030 return getEntry<Elf_Sym>(Symb, SymbolTableSections);
1033 template<support::endianness target_endianness, bool is64Bits>
1034 const typename ELFObjectFile<target_endianness, is64Bits>::Elf_Rel *
1035 ELFObjectFile<target_endianness, is64Bits>::getRel(DataRefImpl Rel) const {
1036 return getEntry<Elf_Rel>(Rel, RelocationTableSections);
1039 template<support::endianness target_endianness, bool is64Bits>
1040 const typename ELFObjectFile<target_endianness, is64Bits>::Elf_Rela *
1041 ELFObjectFile<target_endianness, is64Bits>::getRela(DataRefImpl Rela) const {
1042 return getEntry<Elf_Rela>(Rela, RelocationTableSections);
1045 template<support::endianness target_endianness, bool is64Bits>
1046 const typename ELFObjectFile<target_endianness, is64Bits>::Elf_Shdr *
1047 ELFObjectFile<target_endianness, is64Bits>::getSection(DataRefImpl Symb) const {
1048 const Elf_Shdr *sec = getSection(Symb.d.b);
1049 if (sec->sh_type != ELF::SHT_SYMTAB)
1050 // FIXME: Proper error handling.
1051 report_fatal_error("Invalid symbol table section!");
1055 template<support::endianness target_endianness, bool is64Bits>
1056 const typename ELFObjectFile<target_endianness, is64Bits>::Elf_Shdr *
1057 ELFObjectFile<target_endianness, is64Bits>::getSection(uint16_t index) const {
1058 if (index == 0 || index >= ELF::SHN_LORESERVE)
1060 if (!SectionHeaderTable || index >= Header->e_shnum)
1061 // FIXME: Proper error handling.
1062 report_fatal_error("Invalid section index!");
1064 return reinterpret_cast<const Elf_Shdr *>(
1065 reinterpret_cast<const char *>(SectionHeaderTable)
1066 + (index * Header->e_shentsize));
1069 template<support::endianness target_endianness, bool is64Bits>
1070 const char *ELFObjectFile<target_endianness, is64Bits>
1071 ::getString(uint16_t section,
1072 ELF::Elf32_Word offset) const {
1073 return getString(getSection(section), offset);
1076 template<support::endianness target_endianness, bool is64Bits>
1077 const char *ELFObjectFile<target_endianness, is64Bits>
1078 ::getString(const Elf_Shdr *section,
1079 ELF::Elf32_Word offset) const {
1080 assert(section && section->sh_type == ELF::SHT_STRTAB && "Invalid section!");
1081 if (offset >= section->sh_size)
1082 // FIXME: Proper error handling.
1083 report_fatal_error("Symbol name offset outside of string table!");
1084 return (const char *)base() + section->sh_offset + offset;
1087 // EI_CLASS, EI_DATA.
1088 static std::pair<unsigned char, unsigned char>
1089 getElfArchType(MemoryBuffer *Object) {
1090 if (Object->getBufferSize() < ELF::EI_NIDENT)
1091 return std::make_pair((uint8_t)ELF::ELFCLASSNONE,(uint8_t)ELF::ELFDATANONE);
1092 return std::make_pair( (uint8_t)Object->getBufferStart()[ELF::EI_CLASS]
1093 , (uint8_t)Object->getBufferStart()[ELF::EI_DATA]);
1098 ObjectFile *ObjectFile::createELFObjectFile(MemoryBuffer *Object) {
1099 std::pair<unsigned char, unsigned char> Ident = getElfArchType(Object);
1101 if (Ident.first == ELF::ELFCLASS32 && Ident.second == ELF::ELFDATA2LSB)
1102 return new ELFObjectFile<support::little, false>(Object, ec);
1103 else if (Ident.first == ELF::ELFCLASS32 && Ident.second == ELF::ELFDATA2MSB)
1104 return new ELFObjectFile<support::big, false>(Object, ec);
1105 else if (Ident.first == ELF::ELFCLASS64 && Ident.second == ELF::ELFDATA2LSB)
1106 return new ELFObjectFile<support::little, true>(Object, ec);
1107 else if (Ident.first == ELF::ELFCLASS64 && Ident.second == ELF::ELFDATA2MSB)
1108 return new ELFObjectFile<support::big, true>(Object, ec);
1109 // FIXME: Proper error handling.
1110 report_fatal_error("Not an ELF object file!");
1113 } // end namespace llvm