diff options
author | Benjamin Kramer <benny.kra@googlemail.com> | 2011-09-14 01:22:52 +0000 |
---|---|---|
committer | Benjamin Kramer <benny.kra@googlemail.com> | 2011-09-14 01:22:52 +0000 |
commit | 75d1cf339110b14c4ddf1253b687044a200caf13 (patch) | |
tree | fdb92e3dd91e7f54642878c812c19b385b1254a7 /llvm/lib/Object/ELFObjectFile.cpp | |
parent | 91ead3c1f51c4a0926bc0bb5867d84d74bf918d9 (diff) | |
download | llvm-75d1cf339110b14c4ddf1253b687044a200caf13.zip llvm-75d1cf339110b14c4ddf1253b687044a200caf13.tar.gz llvm-75d1cf339110b14c4ddf1253b687044a200caf13.tar.bz2 |
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!
llvm-svn: 139683
Diffstat (limited to 'llvm/lib/Object/ELFObjectFile.cpp')
-rw-r--r-- | llvm/lib/Object/ELFObjectFile.cpp | 79 |
1 files changed, 78 insertions, 1 deletions
diff --git a/llvm/lib/Object/ELFObjectFile.cpp b/llvm/lib/Object/ELFObjectFile.cpp index 15e7652..0458c07 100644 --- a/llvm/lib/Object/ELFObjectFile.cpp +++ b/llvm/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<target_endianness, is64Bits> template<support::endianness target_endianness, bool is64Bits> error_code ELFObjectFile<target_endianness, is64Bits> - ::getSymbolAddress(DataRefImpl Symb, + ::getSymbolOffset(DataRefImpl Symb, uint64_t &Result) const { validateSymbol(Symb); const Elf_Sym *symb = getSymbol(Symb); @@ -449,6 +452,43 @@ error_code ELFObjectFile<target_endianness, is64Bits> template<support::endianness target_endianness, bool is64Bits> error_code ELFObjectFile<target_endianness, is64Bits> + ::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<uintptr_t>(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<uintptr_t>(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<uintptr_t>(addr); + return object_error::success; + default: + Result = UnknownAddressOrSize; + return object_error::success; + } +} + +template<support::endianness target_endianness, bool is64Bits> +error_code ELFObjectFile<target_endianness, is64Bits> ::getSymbolSize(DataRefImpl Symb, uint64_t &Result) const { validateSymbol(Symb); @@ -526,6 +566,43 @@ error_code ELFObjectFile<target_endianness, is64Bits> template<support::endianness target_endianness, bool is64Bits> error_code ELFObjectFile<target_endianness, is64Bits> + ::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<support::endianness target_endianness, bool is64Bits> +error_code ELFObjectFile<target_endianness, is64Bits> + ::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<support::endianness target_endianness, bool is64Bits> +error_code ELFObjectFile<target_endianness, is64Bits> ::isSymbolInternal(DataRefImpl Symb, bool &Result) const { validateSymbol(Symb); |