From 9b2b812fea4df160437e7b7d56e38f6335189ad0 Mon Sep 17 00:00:00 2001 From: "Michael J. Spencer" Date: Mon, 17 Oct 2011 23:54:46 +0000 Subject: Object: Add isSymbolAbsolute and getSymbolSection. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@142317 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/Object/COFF.h | 3 + include/llvm/Object/MachO.h | 3 + include/llvm/Object/ObjectFile.h | 118 +++++++++++++++++++++++---------------- lib/Object/COFFObjectFile.cpp | 22 ++++++++ lib/Object/ELFObjectFile.cpp | 29 ++++++++++ lib/Object/MachOObjectFile.cpp | 37 ++++++++++++ 6 files changed, 163 insertions(+), 49 deletions(-) diff --git a/include/llvm/Object/COFF.h b/include/llvm/Object/COFF.h index 5cb87edca4..db05c98aaf 100644 --- a/include/llvm/Object/COFF.h +++ b/include/llvm/Object/COFF.h @@ -108,6 +108,9 @@ protected: virtual error_code isSymbolGlobal(DataRefImpl Symb, bool &Res) const; virtual error_code isSymbolWeak(DataRefImpl Symb, bool &Res) const; virtual error_code getSymbolType(DataRefImpl Symb, SymbolRef::Type &Res) const; + virtual error_code isSymbolAbsolute(DataRefImpl Symb, bool &Res) const; + virtual error_code getSymbolSection(DataRefImpl Symb, + section_iterator &Res) const; virtual error_code getSectionNext(DataRefImpl Sec, SectionRef &Res) const; virtual error_code getSectionName(DataRefImpl Sec, StringRef &Res) const; diff --git a/include/llvm/Object/MachO.h b/include/llvm/Object/MachO.h index fe1c4ded07..0962994be2 100644 --- a/include/llvm/Object/MachO.h +++ b/include/llvm/Object/MachO.h @@ -56,6 +56,9 @@ protected: virtual error_code isSymbolGlobal(DataRefImpl Symb, bool &Res) const; virtual error_code isSymbolWeak(DataRefImpl Symb, bool &Res) const; virtual error_code getSymbolType(DataRefImpl Symb, SymbolRef::Type &Res) const; + virtual error_code isSymbolAbsolute(DataRefImpl Symb, bool &Res) const; + virtual error_code getSymbolSection(DataRefImpl Symb, + section_iterator &Res) const; virtual error_code getSectionNext(DataRefImpl Sec, SectionRef &Res) const; virtual error_code getSectionName(DataRefImpl Sec, StringRef &Res) const; diff --git a/include/llvm/Object/ObjectFile.h b/include/llvm/Object/ObjectFile.h index 4fd73c667a..5581225b53 100644 --- a/include/llvm/Object/ObjectFile.h +++ b/include/llvm/Object/ObjectFile.h @@ -78,55 +78,7 @@ static bool operator ==(const DataRefImpl &a, const DataRefImpl &b) { return std::memcmp(&a, &b, sizeof(DataRefImpl)) == 0; } -/// SymbolRef - This is a value type class that represents a single symbol in -/// the list of symbols in the object file. -class SymbolRef { - friend class SectionRef; - DataRefImpl SymbolPimpl; - const ObjectFile *OwningObject; - -public: - SymbolRef() : OwningObject(NULL) { - std::memset(&SymbolPimpl, 0, sizeof(SymbolPimpl)); - } - - enum Type { - ST_Function, - ST_Data, - ST_External, // Defined in another object file - ST_Other - }; - - SymbolRef(DataRefImpl SymbolP, const ObjectFile *Owner); - - bool operator==(const SymbolRef &Other) const; - - error_code getNext(SymbolRef &Result) const; - - error_code getName(StringRef &Result) const; - error_code getAddress(uint64_t &Result) const; - error_code getOffset(uint64_t &Result) const; - error_code getSize(uint64_t &Result) const; - error_code getType(SymbolRef::Type &Result) const; - - /// Returns the ascii char that should be displayed in a symbol table dump via - /// nm for this symbol. - error_code getNMTypeChar(char &Result) const; - - /// Returns true for symbols that are internal to the object file format such - /// as section symbols. - error_code isInternal(bool &Result) const; - - /// Returns true for symbols that can be used in another objects, - /// such as library functions - error_code isGlobal(bool &Result) const; - - /// Returns true for weak symbols. - error_code isWeak(bool &Result) const; - - DataRefImpl getRawDataRefImpl() const; -}; -typedef content_iterator symbol_iterator; +class SymbolRef; /// RelocationRef - This is a value type class that represents a single /// relocation in the list of relocations in the object file. @@ -201,6 +153,63 @@ public: }; typedef content_iterator section_iterator; +/// SymbolRef - This is a value type class that represents a single symbol in +/// the list of symbols in the object file. +class SymbolRef { + friend class SectionRef; + DataRefImpl SymbolPimpl; + const ObjectFile *OwningObject; + +public: + SymbolRef() : OwningObject(NULL) { + std::memset(&SymbolPimpl, 0, sizeof(SymbolPimpl)); + } + + enum Type { + ST_Function, + ST_Data, + ST_External, // Defined in another object file + ST_Other + }; + + SymbolRef(DataRefImpl SymbolP, const ObjectFile *Owner); + + bool operator==(const SymbolRef &Other) const; + + error_code getNext(SymbolRef &Result) const; + + error_code getName(StringRef &Result) const; + error_code getAddress(uint64_t &Result) const; + error_code getOffset(uint64_t &Result) const; + error_code getSize(uint64_t &Result) const; + error_code getType(SymbolRef::Type &Result) const; + + /// Returns the ascii char that should be displayed in a symbol table dump via + /// nm for this symbol. + error_code getNMTypeChar(char &Result) const; + + /// Returns true for symbols that are internal to the object file format such + /// as section symbols. + error_code isInternal(bool &Result) const; + + /// Returns true for symbols that can be used in another objects, + /// such as library functions + error_code isGlobal(bool &Result) const; + + /// Returns true for weak symbols. + error_code isWeak(bool &Result) const; + + /// @brief Return true for absolute symbols. + error_code isAbsolute(bool &Result) const; + + /// @brief Get section this symbol is defined in reference to. Result is + /// end_sections() if it is undefined or is an absolute symbol. + error_code getSection(section_iterator &Result) const; + + DataRefImpl getRawDataRefImpl() const; +}; +typedef content_iterator symbol_iterator; + const uint64_t UnknownAddressOrSize = ~0ULL; /// ObjectFile - This class is the base class for all object file types. @@ -238,6 +247,9 @@ protected: virtual error_code isSymbolInternal(DataRefImpl Symb, bool &Res) const = 0; virtual error_code isSymbolGlobal(DataRefImpl Symb, bool &Res) const = 0; virtual error_code isSymbolWeak(DataRefImpl Symb, bool &Res) const = 0; + virtual error_code isSymbolAbsolute(DataRefImpl Symb, bool &Res) const = 0; + virtual error_code getSymbolSection(DataRefImpl Symb, + section_iterator &Res) const = 0; // Same as above for SectionRef. friend class SectionRef; @@ -352,6 +364,14 @@ inline error_code SymbolRef::isWeak(bool &Result) const { return OwningObject->isSymbolWeak(SymbolPimpl, Result); } +inline error_code SymbolRef::isAbsolute(bool &Result) const { + return OwningObject->isSymbolAbsolute(SymbolPimpl, Result); +} + +inline error_code SymbolRef::getSection(section_iterator &Result) const { + return OwningObject->getSymbolSection(SymbolPimpl, Result); +} + inline error_code SymbolRef::getType(SymbolRef::Type &Result) const { return OwningObject->getSymbolType(SymbolPimpl, Result); } diff --git a/lib/Object/COFFObjectFile.cpp b/lib/Object/COFFObjectFile.cpp index 0859bca40a..13356520d7 100644 --- a/lib/Object/COFFObjectFile.cpp +++ b/lib/Object/COFFObjectFile.cpp @@ -268,6 +268,28 @@ error_code COFFObjectFile::isSymbolInternal(DataRefImpl Symb, return object_error::success; } +error_code COFFObjectFile::isSymbolAbsolute(DataRefImpl Symb, + bool &Result) const { + const coff_symbol *symb = toSymb(Symb); + Result = symb->SectionNumber == COFF::IMAGE_SYM_ABSOLUTE; + return object_error::success; +} + +error_code COFFObjectFile::getSymbolSection(DataRefImpl Symb, + section_iterator &Result) const { + const coff_symbol *symb = toSymb(Symb); + if (symb->SectionNumber <= COFF::IMAGE_SYM_UNDEFINED) + Result = end_sections(); + else { + const coff_section *sec; + if (error_code ec = getSection(symb->SectionNumber, sec)) return ec; + DataRefImpl Sec; + Sec.p = reinterpret_cast(sec); + Result = section_iterator(SectionRef(Sec, this)); + } + return object_error::success; +} + error_code COFFObjectFile::getSectionNext(DataRefImpl Sec, SectionRef &Result) const { const coff_section *sec = toSec(Sec); diff --git a/lib/Object/ELFObjectFile.cpp b/lib/Object/ELFObjectFile.cpp index a3c8248912..a5e3910d16 100644 --- a/lib/Object/ELFObjectFile.cpp +++ b/lib/Object/ELFObjectFile.cpp @@ -333,6 +333,9 @@ protected: virtual error_code isSymbolGlobal(DataRefImpl Symb, bool &Res) const; virtual error_code isSymbolWeak(DataRefImpl Symb, bool &Res) const; virtual error_code getSymbolType(DataRefImpl Symb, SymbolRef::Type &Res) const; + virtual error_code isSymbolAbsolute(DataRefImpl Symb, bool &Res) const; + virtual error_code getSymbolSection(DataRefImpl Symb, + section_iterator &Res) const; virtual error_code getSectionNext(DataRefImpl Sec, SectionRef &Res) const; virtual error_code getSectionName(DataRefImpl Sec, StringRef &Res) const; @@ -653,6 +656,32 @@ error_code ELFObjectFile return object_error::success; } +template +error_code ELFObjectFile + ::isSymbolAbsolute(DataRefImpl Symb, bool &Res) const { + validateSymbol(Symb); + const Elf_Sym *symb = getSymbol(Symb); + Res = symb->st_shndx == ELF::SHN_ABS; + return object_error::success; +} + +template +error_code ELFObjectFile + ::getSymbolSection(DataRefImpl Symb, + section_iterator &Res) const { + validateSymbol(Symb); + const Elf_Sym *symb = getSymbol(Symb); + const Elf_Shdr *sec = getSection(symb); + if (!sec) + Res = end_sections(); + else { + DataRefImpl Sec; + Sec.p = reinterpret_cast(sec); + Res = section_iterator(SectionRef(Sec, this)); + } + return object_error::success; +} + template error_code ELFObjectFile ::isSymbolInternal(DataRefImpl Symb, diff --git a/lib/Object/MachOObjectFile.cpp b/lib/Object/MachOObjectFile.cpp index c757dd3590..472e0727c3 100644 --- a/lib/Object/MachOObjectFile.cpp +++ b/lib/Object/MachOObjectFile.cpp @@ -242,6 +242,43 @@ error_code MachOObjectFile::isSymbolWeak(DataRefImpl Symb, bool &Res) const { return object_error::success; } +error_code MachOObjectFile::isSymbolAbsolute(DataRefImpl Symb, bool &Res) const{ + uint8_t n_type; + if (MachOObj->is64Bit()) { + InMemoryStruct Entry; + getSymbol64TableEntry(Symb, Entry); + n_type = Entry->Type; + } else { + InMemoryStruct Entry; + getSymbolTableEntry(Symb, Entry); + n_type = Entry->Type; + } + + Res = (n_type & MachO::NlistMaskType) == MachO::NListTypeAbsolute; + return object_error::success; +} + +error_code MachOObjectFile::getSymbolSection(DataRefImpl Symb, + section_iterator &Res) const { + uint8_t index; + if (MachOObj->is64Bit()) { + InMemoryStruct Entry; + getSymbol64TableEntry(Symb, Entry); + index = Entry->SectionIndex; + } else { + InMemoryStruct Entry; + getSymbolTableEntry(Symb, Entry); + index = Entry->SectionIndex; + } + + if (index == 0) + Res = end_sections(); + else + Res = section_iterator(SectionRef(Sections[index], this)); + + return object_error::success; +} + error_code MachOObjectFile::getSymbolType(DataRefImpl Symb, SymbolRef::Type &Res) const { uint8_t n_type; -- cgit v1.2.3