- if (symb->getType() == ELF::STT_OBJECT)
- ret = 'V';
- else
- ret = 'W';
- }
-
- if (ret == '?' && symb->getType() == ELF::STT_SECTION) {
- StringRef name;
- if (error_code ec = getSymbolName(Symb, name))
- return ec;
- Result = StringSwitch<char>(name)
- .StartsWith(".debug", 'N')
- .StartsWith(".note", 'n');
- return object_error::success;
- }
-
- Result = ret;
- return object_error::success;
-}
-
-template<support::endianness target_endianness, bool is64Bits>
-error_code ELFObjectFile<target_endianness, is64Bits>
- ::isSymbolInternal(DataRefImpl Symb,
- bool &Result) const {
- validateSymbol(Symb);
- const Elf_Sym *symb = getSymbol(Symb);
-
- if ( symb->getType() == ELF::STT_FILE
- || symb->getType() == ELF::STT_SECTION)
- Result = true;
- Result = false;
- return object_error::success;
-}
-
-template<support::endianness target_endianness, bool is64Bits>
-error_code ELFObjectFile<target_endianness, is64Bits>
- ::getSectionNext(DataRefImpl Sec, SectionRef &Result) const {
- const uint8_t *sec = reinterpret_cast<const uint8_t *>(Sec.p);
- sec += Header->e_shentsize;
- Sec.p = reinterpret_cast<intptr_t>(sec);
- Result = SectionRef(Sec, this);
- return object_error::success;
-}
-
-template<support::endianness target_endianness, bool is64Bits>
-error_code ELFObjectFile<target_endianness, is64Bits>
- ::getSectionName(DataRefImpl Sec,
- StringRef &Result) const {
- const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p);
- Result = StringRef(getString(dot_shstrtab_sec, sec->sh_name));
- return object_error::success;
-}
-
-template<support::endianness target_endianness, bool is64Bits>
-error_code ELFObjectFile<target_endianness, is64Bits>
- ::getSectionAddress(DataRefImpl Sec,
- uint64_t &Result) const {
- const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p);
- Result = sec->sh_addr;
- return object_error::success;
-}
-
-template<support::endianness target_endianness, bool is64Bits>
-error_code ELFObjectFile<target_endianness, is64Bits>
- ::getSectionSize(DataRefImpl Sec,
- uint64_t &Result) const {
- const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p);
- Result = sec->sh_size;
- return object_error::success;
-}
-
-template<support::endianness target_endianness, bool is64Bits>
-error_code ELFObjectFile<target_endianness, is64Bits>
- ::getSectionContents(DataRefImpl Sec,
- StringRef &Result) const {
- const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p);
- const char *start = (const char*)base() + sec->sh_offset;
- Result = StringRef(start, sec->sh_size);
- return object_error::success;
-}
-
-template<support::endianness target_endianness, bool is64Bits>
-error_code ELFObjectFile<target_endianness, is64Bits>
- ::isSectionText(DataRefImpl Sec,
- bool &Result) const {
- const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p);
- if (sec->sh_flags & ELF::SHF_EXECINSTR)
- Result = true;
- else
- Result = false;
- return object_error::success;
-}
-
-template<support::endianness target_endianness, bool is64Bits>
-ELFObjectFile<target_endianness, is64Bits>::ELFObjectFile(MemoryBuffer *Object
- , error_code &ec)
- : ObjectFile(Binary::isELF, Object, ec)
- , SectionHeaderTable(0)
- , dot_shstrtab_sec(0)
- , dot_strtab_sec(0) {
- Header = reinterpret_cast<const Elf_Ehdr *>(base());
-
- if (Header->e_shoff == 0)
- return;
-
- SectionHeaderTable =
- reinterpret_cast<const Elf_Shdr *>(base() + Header->e_shoff);
- uint32_t SectionTableSize = Header->e_shnum * Header->e_shentsize;
- if (!( (const uint8_t *)SectionHeaderTable + SectionTableSize
- <= base() + Data->getBufferSize()))
- // FIXME: Proper error handling.
- report_fatal_error("Section table goes past end of file!");
-
-
- // To find the symbol tables we walk the section table to find SHT_STMTAB.
- for (const char *i = reinterpret_cast<const char *>(SectionHeaderTable),
- *e = i + Header->e_shnum * Header->e_shentsize;
- i != e; i += Header->e_shentsize) {
- const Elf_Shdr *sh = reinterpret_cast<const Elf_Shdr*>(i);
- if (sh->sh_type == ELF::SHT_SYMTAB) {
- SymbolTableSections.push_back(sh);
- }
- }
-
- // Get string table sections.
- dot_shstrtab_sec = getSection(Header->e_shstrndx);
- if (dot_shstrtab_sec) {
- // Verify that the last byte in the string table in a null.
- if (((const char*)base() + dot_shstrtab_sec->sh_offset)
- [dot_shstrtab_sec->sh_size - 1] != 0)
- // FIXME: Proper error handling.
- report_fatal_error("String table must end with a null terminator!");
- }
-
- // Merge this into the above loop.
- for (const char *i = reinterpret_cast<const char *>(SectionHeaderTable),
- *e = i + Header->e_shnum * Header->e_shentsize;
- i != e; i += Header->e_shentsize) {
- const Elf_Shdr *sh = reinterpret_cast<const Elf_Shdr*>(i);
- if (sh->sh_type == ELF::SHT_STRTAB) {
- StringRef SectionName(getString(dot_shstrtab_sec, sh->sh_name));
- if (SectionName == ".strtab") {
- if (dot_strtab_sec != 0)
- // FIXME: Proper error handling.
- report_fatal_error("Already found section named .strtab!");
- dot_strtab_sec = sh;
- const char *dot_strtab = (const char*)base() + sh->sh_offset;
- if (dot_strtab[sh->sh_size - 1] != 0)
- // FIXME: Proper error handling.
- report_fatal_error("String table must end with a null terminator!");
- }
- }
- }
-}
-
-template<support::endianness target_endianness, bool is64Bits>
-ObjectFile::symbol_iterator ELFObjectFile<target_endianness, is64Bits>
- ::begin_symbols() const {
- DataRefImpl SymbolData;
- memset(&SymbolData, 0, sizeof(SymbolData));
- if (SymbolTableSections.size() == 0) {
- SymbolData.d.a = std::numeric_limits<uint32_t>::max();
- SymbolData.d.b = std::numeric_limits<uint32_t>::max();
- } else {
- SymbolData.d.a = 1; // The 0th symbol in ELF is fake.
- SymbolData.d.b = 0;
- }
- return symbol_iterator(SymbolRef(SymbolData, this));
-}
-
-template<support::endianness target_endianness, bool is64Bits>
-ObjectFile::symbol_iterator ELFObjectFile<target_endianness, is64Bits>
- ::end_symbols() const {
- DataRefImpl SymbolData;
- memset(&SymbolData, 0, sizeof(SymbolData));
- SymbolData.d.a = std::numeric_limits<uint32_t>::max();
- SymbolData.d.b = std::numeric_limits<uint32_t>::max();
- return symbol_iterator(SymbolRef(SymbolData, this));
-}
-
-template<support::endianness target_endianness, bool is64Bits>
-ObjectFile::section_iterator ELFObjectFile<target_endianness, is64Bits>
- ::begin_sections() const {
- DataRefImpl ret;
- memset(&ret, 0, sizeof(DataRefImpl));
- ret.p = reinterpret_cast<intptr_t>(base() + Header->e_shoff);
- return section_iterator(SectionRef(ret, this));
-}
-
-template<support::endianness target_endianness, bool is64Bits>
-ObjectFile::section_iterator ELFObjectFile<target_endianness, is64Bits>
- ::end_sections() const {
- DataRefImpl ret;
- memset(&ret, 0, sizeof(DataRefImpl));
- ret.p = reinterpret_cast<intptr_t>(base()
- + Header->e_shoff
- + (Header->e_shentsize * Header->e_shnum));
- return section_iterator(SectionRef(ret, this));
-}
-
-template<support::endianness target_endianness, bool is64Bits>
-uint8_t ELFObjectFile<target_endianness, is64Bits>::getBytesInAddress() const {
- return is64Bits ? 8 : 4;
-}
-
-template<support::endianness target_endianness, bool is64Bits>
-StringRef ELFObjectFile<target_endianness, is64Bits>
- ::getFileFormatName() const {
- switch(Header->e_ident[ELF::EI_CLASS]) {
- case ELF::ELFCLASS32:
- switch(Header->e_machine) {
- case ELF::EM_386:
- return "ELF32-i386";
- case ELF::EM_X86_64:
- return "ELF32-x86-64";
- default:
- return "ELF32-unknown";
- }
- case ELF::ELFCLASS64:
- switch(Header->e_machine) {
- case ELF::EM_386:
- return "ELF64-i386";
- case ELF::EM_X86_64:
- return "ELF64-x86-64";
- default:
- return "ELF64-unknown";
- }
- default:
- // FIXME: Proper error handling.
- report_fatal_error("Invalid ELFCLASS!");
- }
-}
-
-template<support::endianness target_endianness, bool is64Bits>
-unsigned ELFObjectFile<target_endianness, is64Bits>::getArch() const {
- switch(Header->e_machine) {
- case ELF::EM_386:
- return Triple::x86;
- case ELF::EM_X86_64:
- return Triple::x86_64;
- default:
- return Triple::UnknownArch;