diff options
Diffstat (limited to 'include/llvm/Object/ELFObjectFile.h')
| -rw-r--r-- | include/llvm/Object/ELFObjectFile.h | 62 | 
1 files changed, 53 insertions, 9 deletions
diff --git a/include/llvm/Object/ELFObjectFile.h b/include/llvm/Object/ELFObjectFile.h index c2d6438f45ba5..9bd4c3241118d 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<ELFT>::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<ELFT>::Elf_Shdr * Section = EF.getSection(ESym); +    if (Section != nullptr) +      Result += Section->sh_addr; +  }    return object_error::success;  } @@ -389,22 +408,33 @@ uint32_t ELFObjectFile<ELFT>::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 <class ELFT> -std::error_code -ELFObjectFile<ELFT>::getSymbolSection(DataRefImpl Symb, -                                      section_iterator &Res) const { -  const Elf_Sym *ESym = getSymbol(Symb); +section_iterator +ELFObjectFile<ELFT>::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<intptr_t>(ESec); -    Res = section_iterator(SectionRef(Sec, this)); +    return section_iterator(SectionRef(Sec, this));    } +} + +template <class ELFT> +std::error_code +ELFObjectFile<ELFT>::getSymbolSection(DataRefImpl Symb, +                                      section_iterator &Res) const { +  Res = getSymbolSection(getSymbol(Symb));    return object_error::success;  } @@ -565,6 +595,20 @@ ELFObjectFile<ELFT>::getRelocationSymbol(DataRefImpl Rel) const {    return symbol_iterator(SymbolRef(SymbolData, this));  } +// ELF relocations can target sections, by targetting a symbol of type +// STT_SECTION +template <class ELFT> +section_iterator +ELFObjectFile<ELFT>::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 <class ELFT>  std::error_code  ELFObjectFile<ELFT>::getRelocationAddress(DataRefImpl Rel, @@ -908,7 +952,7 @@ unsigned ELFObjectFile<ELFT>::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;  | 
