From ac241fe9f0d73c6f632e4f7f89e06b698d39da54 Mon Sep 17 00:00:00 2001 From: Benjamin Kramer Date: Wed, 14 Sep 2011 01:22:52 +0000 Subject: Object: make the following changes into SymbolRef - Add enum SymbolType and function getSymbolType() - Add function isGlobal() - it's returns true for symbols that can be used in another objects, such as library functions. - Rename function getAddress() to getOffset() and add new function getAddress(), because currently getAddress() returns section offset of symbol first byte. new getAddress() return symbol address. - Change usage SymbolRef::getAddress() to getOffset() in tools/llvm-nm and tools/llvm-objdump. Patch by Danil Malyshev! git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@139683 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Object/ELFObjectFile.cpp | 79 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 78 insertions(+), 1 deletion(-) (limited to 'lib/Object/ELFObjectFile.cpp') diff --git a/lib/Object/ELFObjectFile.cpp b/lib/Object/ELFObjectFile.cpp index 15e7652774..0458c0713c 100644 --- a/lib/Object/ELFObjectFile.cpp +++ b/lib/Object/ELFObjectFile.cpp @@ -310,10 +310,13 @@ class ELFObjectFile : public ObjectFile { protected: virtual error_code getSymbolNext(DataRefImpl Symb, SymbolRef &Res) const; virtual error_code getSymbolName(DataRefImpl Symb, StringRef &Res) const; + virtual error_code getSymbolOffset(DataRefImpl Symb, uint64_t &Res) const; virtual error_code getSymbolAddress(DataRefImpl Symb, uint64_t &Res) const; virtual error_code getSymbolSize(DataRefImpl Symb, uint64_t &Res) const; virtual error_code getSymbolNMTypeChar(DataRefImpl Symb, char &Res) const; virtual error_code isSymbolInternal(DataRefImpl Symb, bool &Res) const; + virtual error_code isSymbolGlobal(DataRefImpl Symb, bool &Res) const; + virtual error_code getSymbolType(DataRefImpl Symb, SymbolRef::SymbolType &Res) const; virtual error_code getSectionNext(DataRefImpl Sec, SectionRef &Res) const; virtual error_code getSectionName(DataRefImpl Sec, StringRef &Res) const; @@ -415,7 +418,7 @@ error_code ELFObjectFile template error_code ELFObjectFile - ::getSymbolAddress(DataRefImpl Symb, + ::getSymbolOffset(DataRefImpl Symb, uint64_t &Result) const { validateSymbol(Symb); const Elf_Sym *symb = getSymbol(Symb); @@ -447,6 +450,43 @@ error_code ELFObjectFile } } +template +error_code ELFObjectFile + ::getSymbolAddress(DataRefImpl Symb, + uint64_t &Result) const { + validateSymbol(Symb); + const Elf_Sym *symb = getSymbol(Symb); + const Elf_Shdr *Section; + switch (symb->st_shndx) { + case ELF::SHN_COMMON: // Fall through. + // Undefined symbols have no address yet. + case ELF::SHN_UNDEF: + Result = UnknownAddressOrSize; + return object_error::success; + case ELF::SHN_ABS: + Result = reinterpret_cast(base()+symb->st_value); + return object_error::success; + default: Section = getSection(symb->st_shndx); + } + const uint8_t* addr = base(); + if (Section) + addr += Section->sh_offset; + switch (symb->getType()) { + case ELF::STT_SECTION: + Result = reinterpret_cast(addr); + return object_error::success; + case ELF::STT_FUNC: // Fall through. + case ELF::STT_OBJECT: // Fall through. + case ELF::STT_NOTYPE: + addr += symb->st_value; + Result = reinterpret_cast(addr); + return object_error::success; + default: + Result = UnknownAddressOrSize; + return object_error::success; + } +} + template error_code ELFObjectFile ::getSymbolSize(DataRefImpl Symb, @@ -524,6 +564,43 @@ error_code ELFObjectFile return object_error::success; } +template +error_code ELFObjectFile + ::getSymbolType(DataRefImpl Symb, + SymbolRef::SymbolType &Result) const { + validateSymbol(Symb); + const Elf_Sym *symb = getSymbol(Symb); + + if (symb->st_shndx == ELF::SHN_UNDEF) { + Result = SymbolRef::ST_External; + return object_error::success; + } + + switch (symb->getType()) { + case ELF::STT_FUNC: + Result = SymbolRef::ST_Function; + break; + case ELF::STT_OBJECT: + Result = SymbolRef::ST_Data; + break; + default: + Result = SymbolRef::ST_Other; + break; + } + return object_error::success; +} + +template +error_code ELFObjectFile + ::isSymbolGlobal(DataRefImpl Symb, + bool &Result) const { + validateSymbol(Symb); + const Elf_Sym *symb = getSymbol(Symb); + + Result = symb->getBinding() == ELF::STB_GLOBAL; + return object_error::success; +} + template error_code ELFObjectFile ::isSymbolInternal(DataRefImpl Symb, -- cgit v1.2.3-18-g5258