From 5a5ac124e1efaf208671f01c46edb15f29ed2a0b Mon Sep 17 00:00:00 2001 From: Dimitry Andric Date: Wed, 27 May 2015 18:44:32 +0000 Subject: Vendor import of llvm trunk r238337: https://llvm.org/svn/llvm-project/llvm/trunk@238337 --- include/llvm/Object/ELFObjectFile.h | 62 +++++++++++++++++++++++++++++++------ 1 file changed, 53 insertions(+), 9 deletions(-) (limited to 'include/llvm/Object/ELFObjectFile.h') diff --git a/include/llvm/Object/ELFObjectFile.h b/include/llvm/Object/ELFObjectFile.h index c2d6438f45ba..9bd4c3241118 100644 --- a/include/llvm/Object/ELFObjectFile.h +++ b/include/llvm/Object/ELFObjectFile.h @@ -86,6 +86,7 @@ protected: std::error_code getSymbolOther(DataRefImpl Symb, uint8_t &Res) const override; std::error_code getSymbolType(DataRefImpl Symb, SymbolRef::Type &Res) const override; + section_iterator getSymbolSection(const Elf_Sym *Symb) const; std::error_code getSymbolSection(DataRefImpl Symb, section_iterator &Res) const override; @@ -112,6 +113,7 @@ protected: std::error_code getRelocationOffset(DataRefImpl Rel, uint64_t &Res) const override; symbol_iterator getRelocationSymbol(DataRefImpl Rel) const override; + section_iterator getRelocationSection(DataRefImpl Rel) const override; std::error_code getRelocationType(DataRefImpl Rel, uint64_t &Res) const override; std::error_code @@ -177,6 +179,20 @@ protected: return DRI; } + bool isExportedToOtherDSO(const Elf_Sym *ESym) const { + unsigned char Binding = ESym->getBinding(); + unsigned char Visibility = ESym->getVisibility(); + + // A symbol is exported if its binding is either GLOBAL or WEAK, and its + // visibility is either DEFAULT or PROTECTED. All other symbols are not + // exported. + if ((Binding == ELF::STB_GLOBAL || Binding == ELF::STB_WEAK) && + (Visibility == ELF::STV_DEFAULT || Visibility == ELF::STV_PROTECTED)) + return true; + + return false; + } + // This flag is used for classof, to distinguish ELFObjectFile from // its subclass. If more subclasses will be created, this flag will // have to become an enum. @@ -300,8 +316,11 @@ std::error_code ELFObjectFile::getSymbolAddress(DataRefImpl Symb, ESym->getType() == ELF::STT_FUNC) Result &= ~1; - if (Header->e_type == ELF::ET_REL) - Result += EF.getSection(ESym)->sh_addr; + if (Header->e_type == ELF::ET_REL) { + const typename ELFFile::Elf_Shdr * Section = EF.getSection(ESym); + if (Section != nullptr) + Result += Section->sh_addr; + } return object_error::success; } @@ -389,22 +408,33 @@ uint32_t ELFObjectFile::getSymbolFlags(DataRefImpl Symb) const { EF.getSymbolTableIndex(ESym) == ELF::SHN_COMMON) Result |= SymbolRef::SF_Common; + if (isExportedToOtherDSO(ESym)) + Result |= SymbolRef::SF_Exported; + + if (ESym->getVisibility() == ELF::STV_HIDDEN) + Result |= SymbolRef::SF_Hidden; + return Result; } template -std::error_code -ELFObjectFile::getSymbolSection(DataRefImpl Symb, - section_iterator &Res) const { - const Elf_Sym *ESym = getSymbol(Symb); +section_iterator +ELFObjectFile::getSymbolSection(const Elf_Sym *ESym) const { const Elf_Shdr *ESec = EF.getSection(ESym); if (!ESec) - Res = section_end(); + return section_end(); else { DataRefImpl Sec; Sec.p = reinterpret_cast(ESec); - Res = section_iterator(SectionRef(Sec, this)); + return section_iterator(SectionRef(Sec, this)); } +} + +template +std::error_code +ELFObjectFile::getSymbolSection(DataRefImpl Symb, + section_iterator &Res) const { + Res = getSymbolSection(getSymbol(Symb)); return object_error::success; } @@ -565,6 +595,20 @@ ELFObjectFile::getRelocationSymbol(DataRefImpl Rel) const { return symbol_iterator(SymbolRef(SymbolData, this)); } +// ELF relocations can target sections, by targetting a symbol of type +// STT_SECTION +template +section_iterator +ELFObjectFile::getRelocationSection(DataRefImpl Rel) const { + symbol_iterator Sym = getRelocationSymbol(Rel); + if (Sym == symbol_end()) + return section_end(); + const Elf_Sym *ESym = getSymbol(Sym->getRawDataRefImpl()); + if (ESym->getType() != ELF::STT_SECTION) + return section_end(); + return getSymbolSection(ESym); +} + template std::error_code ELFObjectFile::getRelocationAddress(DataRefImpl Rel, @@ -908,7 +952,7 @@ unsigned ELFObjectFile::getArch() const { case ELF::EM_SPARC: case ELF::EM_SPARC32PLUS: - return Triple::sparc; + return IsLittleEndian ? Triple::sparcel : Triple::sparc; case ELF::EM_SPARCV9: return Triple::sparcv9; -- cgit v1.2.3