virtual std::error_code getSymbolVersion(SymbolRef Symb, StringRef &Version,
bool &IsDefault) const = 0;
+
+ virtual uint64_t getSectionFlags(SectionRef Sec) const = 0;
+ virtual uint32_t getSectionType(SectionRef Sec) const = 0;
+
+ static inline bool classof(const Binary *v) { return v->isELF(); }
};
template <class ELFT> class ELFObjectFile : public ELFObjectFileBase {
void moveSectionNext(DataRefImpl &Sec) const override;
std::error_code getSectionName(DataRefImpl Sec,
StringRef &Res) const override;
- std::error_code getSectionAddress(DataRefImpl Sec,
- uint64_t &Res) const override;
- std::error_code getSectionSize(DataRefImpl Sec, uint64_t &Res) const override;
+ uint64_t getSectionAddress(DataRefImpl Sec) const override;
+ uint64_t getSectionSize(DataRefImpl Sec) const override;
std::error_code getSectionContents(DataRefImpl Sec,
StringRef &Res) const override;
- std::error_code getSectionAlignment(DataRefImpl Sec,
- uint64_t &Res) const override;
- std::error_code isSectionText(DataRefImpl Sec, bool &Res) const override;
- std::error_code isSectionData(DataRefImpl Sec, bool &Res) const override;
- std::error_code isSectionBSS(DataRefImpl Sec, bool &Res) const override;
- std::error_code isSectionRequiredForExecution(DataRefImpl Sec,
- bool &Res) const override;
- std::error_code isSectionVirtual(DataRefImpl Sec, bool &Res) const override;
- std::error_code isSectionZeroInit(DataRefImpl Sec, bool &Res) const override;
- std::error_code isSectionReadOnlyData(DataRefImpl Sec,
- bool &Res) const override;
- std::error_code sectionContainsSymbol(DataRefImpl Sec, DataRefImpl Symb,
- bool &Result) const override;
+ uint64_t getSectionAlignment(DataRefImpl Sec) const override;
+ bool isSectionText(DataRefImpl Sec) const override;
+ bool isSectionData(DataRefImpl Sec) const override;
+ bool isSectionBSS(DataRefImpl Sec) const override;
+ bool isSectionVirtual(DataRefImpl Sec) const override;
+ bool sectionContainsSymbol(DataRefImpl Sec, DataRefImpl Symb) const override;
relocation_iterator section_rel_begin(DataRefImpl Sec) const override;
relocation_iterator section_rel_end(DataRefImpl Sec) const override;
section_iterator getRelocatedSection(DataRefImpl Sec) const override;
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.
std::error_code getSymbolVersion(SymbolRef Symb, StringRef &Version,
bool &IsDefault) const override;
+ uint64_t getSectionFlags(SectionRef Sec) const override;
+ uint32_t getSectionType(SectionRef Sec) const override;
+
uint8_t getBytesInAddress() const override;
StringRef getFileFormatName() const override;
unsigned getArch() const override;
return object_error::success;
}
+template <class ELFT>
+uint64_t ELFObjectFile<ELFT>::getSectionFlags(SectionRef Sec) const {
+ DataRefImpl DRI = Sec.getRawDataRefImpl();
+ return toELFShdrIter(DRI)->sh_flags;
+}
+
+template <class ELFT>
+uint32_t ELFObjectFile<ELFT>::getSectionType(SectionRef Sec) const {
+ DataRefImpl DRI = Sec.getRawDataRefImpl();
+ return toELFShdrIter(DRI)->sh_type;
+}
+
template <class ELFT>
std::error_code ELFObjectFile<ELFT>::getSymbolAddress(DataRefImpl Symb,
uint64_t &Result) const {
const Elf_Ehdr *Header = EF.getHeader();
Result = ESym->st_value;
- // Clear the ARM/Thumb indicator flag.
- if (Header->e_machine == ELF::EM_ARM && ESym->getType() == ELF::STT_FUNC)
+ // Clear the ARM/Thumb or microMIPS indicator flag.
+ if ((Header->e_machine == ELF::EM_ARM || Header->e_machine == ELF::EM_MIPS) &&
+ ESym->getType() == ELF::STT_FUNC)
Result &= ~1;
if (Header->e_type == ELF::ET_REL)
EF.getSymbolTableIndex(ESym) == ELF::SHN_COMMON)
Result |= SymbolRef::SF_Common;
+ if (isExportedToOtherDSO(ESym))
+ Result |= SymbolRef::SF_Exported;
+
return Result;
}
}
template <class ELFT>
-std::error_code ELFObjectFile<ELFT>::getSectionAddress(DataRefImpl Sec,
- uint64_t &Result) const {
- Result = toELFShdrIter(Sec)->sh_addr;
- return object_error::success;
+uint64_t ELFObjectFile<ELFT>::getSectionAddress(DataRefImpl Sec) const {
+ return toELFShdrIter(Sec)->sh_addr;
}
template <class ELFT>
-std::error_code ELFObjectFile<ELFT>::getSectionSize(DataRefImpl Sec,
- uint64_t &Result) const {
- Result = toELFShdrIter(Sec)->sh_size;
- return object_error::success;
+uint64_t ELFObjectFile<ELFT>::getSectionSize(DataRefImpl Sec) const {
+ return toELFShdrIter(Sec)->sh_size;
}
template <class ELFT>
}
template <class ELFT>
-std::error_code
-ELFObjectFile<ELFT>::getSectionAlignment(DataRefImpl Sec,
- uint64_t &Result) const {
- Result = toELFShdrIter(Sec)->sh_addralign;
- return object_error::success;
+uint64_t ELFObjectFile<ELFT>::getSectionAlignment(DataRefImpl Sec) const {
+ return toELFShdrIter(Sec)->sh_addralign;
}
template <class ELFT>
-std::error_code ELFObjectFile<ELFT>::isSectionText(DataRefImpl Sec,
- bool &Result) const {
- Result = toELFShdrIter(Sec)->sh_flags & ELF::SHF_EXECINSTR;
- return object_error::success;
+bool ELFObjectFile<ELFT>::isSectionText(DataRefImpl Sec) const {
+ return toELFShdrIter(Sec)->sh_flags & ELF::SHF_EXECINSTR;
}
template <class ELFT>
-std::error_code ELFObjectFile<ELFT>::isSectionData(DataRefImpl Sec,
- bool &Result) const {
+bool ELFObjectFile<ELFT>::isSectionData(DataRefImpl Sec) const {
Elf_Shdr_Iter EShdr = toELFShdrIter(Sec);
- Result = EShdr->sh_flags & (ELF::SHF_ALLOC | ELF::SHF_WRITE) &&
- EShdr->sh_type == ELF::SHT_PROGBITS;
- return object_error::success;
+ return EShdr->sh_flags & (ELF::SHF_ALLOC | ELF::SHF_WRITE) &&
+ EShdr->sh_type == ELF::SHT_PROGBITS;
}
template <class ELFT>
-std::error_code ELFObjectFile<ELFT>::isSectionBSS(DataRefImpl Sec,
- bool &Result) const {
+bool ELFObjectFile<ELFT>::isSectionBSS(DataRefImpl Sec) const {
Elf_Shdr_Iter EShdr = toELFShdrIter(Sec);
- Result = EShdr->sh_flags & (ELF::SHF_ALLOC | ELF::SHF_WRITE) &&
- EShdr->sh_type == ELF::SHT_NOBITS;
- return object_error::success;
+ return EShdr->sh_flags & (ELF::SHF_ALLOC | ELF::SHF_WRITE) &&
+ EShdr->sh_type == ELF::SHT_NOBITS;
}
template <class ELFT>
-std::error_code
-ELFObjectFile<ELFT>::isSectionRequiredForExecution(DataRefImpl Sec,
- bool &Result) const {
- Result = toELFShdrIter(Sec)->sh_flags & ELF::SHF_ALLOC;
- return object_error::success;
+bool ELFObjectFile<ELFT>::isSectionVirtual(DataRefImpl Sec) const {
+ return toELFShdrIter(Sec)->sh_type == ELF::SHT_NOBITS;
}
template <class ELFT>
-std::error_code ELFObjectFile<ELFT>::isSectionVirtual(DataRefImpl Sec,
- bool &Result) const {
- Result = toELFShdrIter(Sec)->sh_type == ELF::SHT_NOBITS;
- return object_error::success;
-}
-
-template <class ELFT>
-std::error_code ELFObjectFile<ELFT>::isSectionZeroInit(DataRefImpl Sec,
- bool &Result) const {
- Result = toELFShdrIter(Sec)->sh_type == ELF::SHT_NOBITS;
- return object_error::success;
-}
-
-template <class ELFT>
-std::error_code ELFObjectFile<ELFT>::isSectionReadOnlyData(DataRefImpl Sec,
- bool &Result) const {
- Elf_Shdr_Iter EShdr = toELFShdrIter(Sec);
- Result = !(EShdr->sh_flags & (ELF::SHF_WRITE | ELF::SHF_EXECINSTR));
- return object_error::success;
-}
-
-template <class ELFT>
-std::error_code ELFObjectFile<ELFT>::sectionContainsSymbol(DataRefImpl Sec,
- DataRefImpl Symb,
- bool &Result) const {
+bool ELFObjectFile<ELFT>::sectionContainsSymbol(DataRefImpl Sec,
+ DataRefImpl Symb) const {
Elf_Sym_Iter ESym = toELFSymIter(Symb);
uintX_t Index = ESym->st_shndx;
bool Reserved = Index >= ELF::SHN_LORESERVE && Index <= ELF::SHN_HIRESERVE;
- Result = !Reserved && (&*toELFShdrIter(Sec) == EF.getSection(ESym->st_shndx));
- return object_error::success;
+ return !Reserved && (&*toELFShdrIter(Sec) == EF.getSection(ESym->st_shndx));
}
template <class ELFT>
Result.append(fmtbuf.begin(), fmtbuf.end());
break;
}
+ case ELF::EM_386:
case ELF::EM_ARM:
case ELF::EM_HEXAGON:
case ELF::EM_MIPS:
template <class ELFT>
StringRef ELFObjectFile<ELFT>::getFileFormatName() const {
+ bool IsLittleEndian = ELFT::TargetEndianness == support::little;
switch (EF.getHeader()->e_ident[ELF::EI_CLASS]) {
case ELF::ELFCLASS32:
switch (EF.getHeader()->e_machine) {
case ELF::EM_X86_64:
return "ELF32-x86-64";
case ELF::EM_ARM:
- return "ELF32-arm";
+ return (IsLittleEndian ? "ELF32-arm-little" : "ELF32-arm-big");
case ELF::EM_HEXAGON:
return "ELF32-hexagon";
case ELF::EM_MIPS:
case ELF::EM_X86_64:
return "ELF64-x86-64";
case ELF::EM_AARCH64:
- return "ELF64-aarch64";
+ return (IsLittleEndian ? "ELF64-aarch64-little" : "ELF64-aarch64-big");
case ELF::EM_PPC64:
return "ELF64-ppc64";
case ELF::EM_S390:
default:
report_fatal_error("Invalid ELFCLASS!");
}
+ case ELF::EM_PPC:
+ return Triple::ppc;
case ELF::EM_PPC64:
return IsLittleEndian ? Triple::ppc64le : Triple::ppc64;
case ELF::EM_S390:
}
inline std::pair<symbol_iterator, symbol_iterator>
-getELFDynamicSymbolIterators(SymbolicFile *Obj) {
+getELFDynamicSymbolIterators(const SymbolicFile *Obj) {
return cast<ELFObjectFileBase>(Obj)->getELFDynamicSymbolIterators();
}