From: Danil Malyshev Date: Sun, 27 Nov 2011 10:12:52 +0000 (+0000) Subject: Fixed ObjectFile functions: X-Git-Url: http://plrg.eecs.uci.edu/git/?p=oota-llvm.git;a=commitdiff_plain;h=9b24738bd1dc791eb2c21b5562fcfe4b7b99fe2a Fixed ObjectFile functions: - getSymbolOffset() renamed as getSymbolFileOffset() - getSymbolFileOffset(), getSymbolAddress(), getRelocationAddress() returns same result for ELFObjectFile, MachOObjectFile and COFFObjectFile. - added getRelocationOffset() - fixed MachOObjectFile::getSymbolSize() - fixed MachOObjectFile::getSymbolSection() - fixed MachOObjectFile::getSymbolOffset() for symbols without section data. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@145180 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/llvm-c/Object.h b/include/llvm-c/Object.h index 92bb03b6825..6b465b3ed65 100644 --- a/include/llvm-c/Object.h +++ b/include/llvm-c/Object.h @@ -73,11 +73,12 @@ void LLVMMoveToNextRelocation(LLVMRelocationIteratorRef RI); // SymbolRef accessors const char *LLVMGetSymbolName(LLVMSymbolIteratorRef SI); uint64_t LLVMGetSymbolAddress(LLVMSymbolIteratorRef SI); -uint64_t LLVMGetSymbolOffset(LLVMSymbolIteratorRef SI); +uint64_t LLVMGetSymbolFileOffset(LLVMSymbolIteratorRef SI); uint64_t LLVMGetSymbolSize(LLVMSymbolIteratorRef SI); // RelocationRef accessors uint64_t LLVMGetRelocationAddress(LLVMRelocationIteratorRef RI); +uint64_t LLVMGetRelocationOffset(LLVMRelocationIteratorRef RI); LLVMSymbolIteratorRef LLVMGetRelocationSymbol(LLVMRelocationIteratorRef RI); uint64_t LLVMGetRelocationType(LLVMRelocationIteratorRef RI); // NOTE: Caller takes ownership of returned string of the two diff --git a/include/llvm/Object/COFF.h b/include/llvm/Object/COFF.h index 71e342fc8bf..73bde8ef412 100644 --- a/include/llvm/Object/COFF.h +++ b/include/llvm/Object/COFF.h @@ -105,7 +105,7 @@ private: 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 getSymbolFileOffset(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; @@ -135,6 +135,8 @@ protected: RelocationRef &Res) const; virtual error_code getRelocationAddress(DataRefImpl Rel, uint64_t &Res) const; + virtual error_code getRelocationOffset(DataRefImpl Rel, + uint64_t &Res) const; virtual error_code getRelocationSymbol(DataRefImpl Rel, SymbolRef &Res) const; virtual error_code getRelocationType(DataRefImpl Rel, diff --git a/include/llvm/Object/MachO.h b/include/llvm/Object/MachO.h index c6454ffeee8..7e3a90dab1a 100644 --- a/include/llvm/Object/MachO.h +++ b/include/llvm/Object/MachO.h @@ -49,7 +49,7 @@ public: 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 getSymbolFileOffset(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; @@ -79,6 +79,8 @@ protected: RelocationRef &Res) const; virtual error_code getRelocationAddress(DataRefImpl Rel, uint64_t &Res) const; + virtual error_code getRelocationOffset(DataRefImpl Rel, + uint64_t &Res) const; virtual error_code getRelocationSymbol(DataRefImpl Rel, SymbolRef &Res) const; virtual error_code getRelocationType(DataRefImpl Rel, diff --git a/include/llvm/Object/ObjectFile.h b/include/llvm/Object/ObjectFile.h index a0f3c4bdca8..fd180d4e58a 100644 --- a/include/llvm/Object/ObjectFile.h +++ b/include/llvm/Object/ObjectFile.h @@ -104,6 +104,7 @@ public: error_code getNext(RelocationRef &Result) const; error_code getAddress(uint64_t &Result) const; + error_code getOffset(uint64_t &Result) const; error_code getSymbol(SymbolRef &Result) const; error_code getType(uint64_t &Result) const; @@ -195,7 +196,7 @@ public: error_code getName(StringRef &Result) const; error_code getAddress(uint64_t &Result) const; - error_code getOffset(uint64_t &Result) const; + error_code getFileOffset(uint64_t &Result) const; error_code getSize(uint64_t &Result) const; error_code getType(SymbolRef::Type &Result) const; @@ -254,7 +255,7 @@ protected: virtual error_code getSymbolNext(DataRefImpl Symb, SymbolRef &Res) const = 0; virtual error_code getSymbolName(DataRefImpl Symb, StringRef &Res) const = 0; virtual error_code getSymbolAddress(DataRefImpl Symb, uint64_t &Res) const =0; - virtual error_code getSymbolOffset(DataRefImpl Symb, uint64_t &Res) const =0; + virtual error_code getSymbolFileOffset(DataRefImpl Symb, uint64_t &Res) const =0; virtual error_code getSymbolSize(DataRefImpl Symb, uint64_t &Res) const = 0; virtual error_code getSymbolType(DataRefImpl Symb, SymbolRef::Type &Res) const = 0; @@ -289,6 +290,8 @@ protected: RelocationRef &Res) const = 0; virtual error_code getRelocationAddress(DataRefImpl Rel, uint64_t &Res) const =0; + virtual error_code getRelocationOffset(DataRefImpl Rel, + uint64_t &Res) const =0; virtual error_code getRelocationSymbol(DataRefImpl Rel, SymbolRef &Res) const = 0; virtual error_code getRelocationType(DataRefImpl Rel, @@ -363,8 +366,8 @@ inline error_code SymbolRef::getAddress(uint64_t &Result) const { return OwningObject->getSymbolAddress(SymbolPimpl, Result); } -inline error_code SymbolRef::getOffset(uint64_t &Result) const { - return OwningObject->getSymbolOffset(SymbolPimpl, Result); +inline error_code SymbolRef::getFileOffset(uint64_t &Result) const { + return OwningObject->getSymbolFileOffset(SymbolPimpl, Result); } inline error_code SymbolRef::getSize(uint64_t &Result) const { @@ -486,6 +489,10 @@ inline error_code RelocationRef::getAddress(uint64_t &Result) const { return OwningObject->getRelocationAddress(RelocationPimpl, Result); } +inline error_code RelocationRef::getOffset(uint64_t &Result) const { + return OwningObject->getRelocationOffset(RelocationPimpl, Result); +} + inline error_code RelocationRef::getSymbol(SymbolRef &Result) const { return OwningObject->getRelocationSymbol(RelocationPimpl, Result); } diff --git a/lib/Object/COFFObjectFile.cpp b/lib/Object/COFFObjectFile.cpp index c6ce56221a5..8344ca071d3 100644 --- a/lib/Object/COFFObjectFile.cpp +++ b/lib/Object/COFFObjectFile.cpp @@ -101,7 +101,7 @@ error_code COFFObjectFile::getSymbolNext(DataRefImpl Symb, return getSymbolName(symb, Result); } -error_code COFFObjectFile::getSymbolOffset(DataRefImpl Symb, +error_code COFFObjectFile::getSymbolFileOffset(DataRefImpl Symb, uint64_t &Result) const { const coff_symbol *symb = toSymb(Symb); const coff_section *Section = NULL; @@ -113,7 +113,7 @@ error_code COFFObjectFile::getSymbolOffset(DataRefImpl Symb, if (Type == 'U' || Type == 'w') Result = UnknownAddressOrSize; else if (Section) - Result = Section->VirtualAddress + symb->Value; + Result = Section->PointerToRawData + symb->Value; else Result = symb->Value; return object_error::success; @@ -131,11 +131,9 @@ error_code COFFObjectFile::getSymbolAddress(DataRefImpl Symb, if (Type == 'U' || Type == 'w') Result = UnknownAddressOrSize; else if (Section) - Result = reinterpret_cast(base() + - Section->PointerToRawData + - symb->Value); + Result = Section->VirtualAddress + symb->Value; else - Result = reinterpret_cast(base() + symb->Value); + Result = symb->Value; return object_error::success; } @@ -624,6 +622,11 @@ error_code COFFObjectFile::getRelocationAddress(DataRefImpl Rel, Res = toRel(Rel)->VirtualAddress; return object_error::success; } +error_code COFFObjectFile::getRelocationOffset(DataRefImpl Rel, + uint64_t &Res) const { + Res = toRel(Rel)->VirtualAddress; + return object_error::success; +} error_code COFFObjectFile::getRelocationSymbol(DataRefImpl Rel, SymbolRef &Res) const { const coff_relocation* R = toRel(Rel); diff --git a/lib/Object/ELFObjectFile.cpp b/lib/Object/ELFObjectFile.cpp index d1a43e7b958..a6c4c257d0e 100644 --- a/lib/Object/ELFObjectFile.cpp +++ b/lib/Object/ELFObjectFile.cpp @@ -325,7 +325,7 @@ 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 getSymbolFileOffset(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; @@ -355,6 +355,8 @@ protected: RelocationRef &Res) const; virtual error_code getRelocationAddress(DataRefImpl Rel, uint64_t &Res) const; + virtual error_code getRelocationOffset(DataRefImpl Rel, + uint64_t &Res) const; virtual error_code getRelocationSymbol(DataRefImpl Rel, SymbolRef &Res) const; virtual error_code getRelocationType(DataRefImpl Rel, @@ -462,7 +464,7 @@ ELFObjectFile template error_code ELFObjectFile - ::getSymbolOffset(DataRefImpl Symb, + ::getSymbolFileOffset(DataRefImpl Symb, uint64_t &Result) const { validateSymbol(Symb); const Elf_Sym *symb = getSymbol(Symb); @@ -486,7 +488,8 @@ error_code ELFObjectFile case ELF::STT_FUNC: case ELF::STT_OBJECT: case ELF::STT_NOTYPE: - Result = symb->st_value; + Result = symb->st_value + + (Section ? Section->sh_offset - Section->sh_addr : 0); return object_error::success; default: Result = UnknownAddressOrSize; @@ -502,28 +505,25 @@ error_code ELFObjectFile const Elf_Sym *symb = getSymbol(Symb); const Elf_Shdr *Section; switch (getSymbolTableIndex(symb)) { - case ELF::SHN_COMMON: // Fall through. + case ELF::SHN_COMMON: // 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); + Result = symb->st_value; return object_error::success; default: Section = getSection(symb); } - const uint8_t* addr = base(); - if (Section) - addr += Section->sh_offset; + switch (symb->getType()) { case ELF::STT_SECTION: - Result = reinterpret_cast(addr); + Result = Section ? Section->sh_addr : UnknownAddressOrSize; return object_error::success; - case ELF::STT_FUNC: // Fall through. - case ELF::STT_OBJECT: // Fall through. + case ELF::STT_FUNC: + case ELF::STT_OBJECT: case ELF::STT_NOTYPE: - addr += symb->st_value; - Result = reinterpret_cast(addr); + Result = symb->st_value; return object_error::success; default: Result = UnknownAddressOrSize; @@ -920,6 +920,29 @@ error_code ELFObjectFile return object_error::success; } +template +error_code ELFObjectFile + ::getRelocationOffset(DataRefImpl Rel, + uint64_t &Result) const { + uint64_t offset; + const Elf_Shdr *sec = getSection(Rel.w.b); + switch (sec->sh_type) { + default : + report_fatal_error("Invalid section type in Rel!"); + case ELF::SHT_REL : { + offset = getRel(Rel)->r_offset; + break; + } + case ELF::SHT_RELA : { + offset = getRela(Rel)->r_offset; + break; + } + } + + Result = offset - sec->sh_addr; + return object_error::success; +} + template error_code ELFObjectFile ::getRelocationType(DataRefImpl Rel, diff --git a/lib/Object/MachOObjectFile.cpp b/lib/Object/MachOObjectFile.cpp index 65ce5f882a0..bb4f6a275b0 100644 --- a/lib/Object/MachOObjectFile.cpp +++ b/lib/Object/MachOObjectFile.cpp @@ -125,23 +125,27 @@ error_code MachOObjectFile::getSymbolName(DataRefImpl DRI, return object_error::success; } -error_code MachOObjectFile::getSymbolOffset(DataRefImpl DRI, - uint64_t &Result) const { - uint64_t SectionOffset; - uint8_t SectionIndex; +error_code MachOObjectFile::getSymbolFileOffset(DataRefImpl DRI, + uint64_t &Result) const { if (MachOObj->is64Bit()) { InMemoryStruct Entry; getSymbol64TableEntry(DRI, Entry); Result = Entry->Value; - SectionIndex = Entry->SectionIndex; + if (Entry->SectionIndex) { + InMemoryStruct Section; + getSection64(Sections[Entry->SectionIndex-1], Section); + Result += Section->Offset - Section->Address; + } } else { InMemoryStruct Entry; getSymbolTableEntry(DRI, Entry); Result = Entry->Value; - SectionIndex = Entry->SectionIndex; + if (Entry->SectionIndex) { + InMemoryStruct Section; + getSection(Sections[Entry->SectionIndex-1], Section); + Result += Section->Offset - Section->Address; + } } - getSectionAddress(Sections[SectionIndex-1], SectionOffset); - Result -= SectionOffset; return object_error::success; } @@ -162,7 +166,50 @@ error_code MachOObjectFile::getSymbolAddress(DataRefImpl DRI, error_code MachOObjectFile::getSymbolSize(DataRefImpl DRI, uint64_t &Result) const { - Result = UnknownAddressOrSize; + uint32_t LoadCommandCount = MachOObj->getHeader().NumLoadCommands; + uint64_t BeginOffset; + uint64_t EndOffset = 0; + uint8_t SectionIndex; + if (MachOObj->is64Bit()) { + InMemoryStruct Entry; + getSymbol64TableEntry(DRI, Entry); + BeginOffset = Entry->Value; + SectionIndex = Entry->SectionIndex; + if (!SectionIndex) { + Result = UnknownAddressOrSize; + return object_error::success; + } + DRI.d.b++; + moveToNextSymbol(DRI); + if (DRI.d.a < LoadCommandCount) { + getSymbol64TableEntry(DRI, Entry); + if (Entry->SectionIndex == SectionIndex) + EndOffset += Entry->Value; + } + } else { + InMemoryStruct Entry; + getSymbolTableEntry(DRI, Entry); + BeginOffset = Entry->Value; + SectionIndex = Entry->SectionIndex; + if (!SectionIndex) { + Result = UnknownAddressOrSize; + return object_error::success; + } + DRI.d.b++; + moveToNextSymbol(DRI); + if (DRI.d.a < LoadCommandCount) { + getSymbolTableEntry(DRI, Entry); + if (Entry->SectionIndex == SectionIndex) + EndOffset += Entry->Value; + } + } + if (!EndOffset) { + uint64_t Size; + getSectionSize(Sections[SectionIndex-1], Size); + getSectionAddress(Sections[SectionIndex-1], EndOffset); + EndOffset += Size; + } + Result = EndOffset - BeginOffset; return object_error::success; } @@ -275,7 +322,7 @@ error_code MachOObjectFile::getSymbolSection(DataRefImpl Symb, if (index == 0) Res = end_sections(); else - Res = section_iterator(SectionRef(Sections[index], this)); + Res = section_iterator(SectionRef(Sections[index-1], this)); return object_error::success; } @@ -614,7 +661,7 @@ error_code MachOObjectFile::getRelocationAddress(DataRefImpl Rel, bool isScattered = (Arch != Triple::x86_64) && (RE->Word0 & macho::RF_Scattered); uint64_t RelAddr = 0; - if (isScattered) + if (isScattered) RelAddr = RE->Word0 & 0xFFFFFF; else RelAddr = RE->Word0; @@ -622,6 +669,20 @@ error_code MachOObjectFile::getRelocationAddress(DataRefImpl Rel, Res = reinterpret_cast(sectAddress + RelAddr); return object_error::success; } +error_code MachOObjectFile::getRelocationOffset(DataRefImpl Rel, + uint64_t &Res) const { + InMemoryStruct RE; + getRelocation(Rel, RE); + + unsigned Arch = getArch(); + bool isScattered = (Arch != Triple::x86_64) && + (RE->Word0 & macho::RF_Scattered); + if (isScattered) + Res = RE->Word0 & 0xFFFFFF; + else + Res = RE->Word0; + return object_error::success; +} error_code MachOObjectFile::getRelocationSymbol(DataRefImpl Rel, SymbolRef &Res) const { InMemoryStruct RE; diff --git a/lib/Object/Object.cpp b/lib/Object/Object.cpp index 719bf882f22..f061ea7cebe 100644 --- a/lib/Object/Object.cpp +++ b/lib/Object/Object.cpp @@ -150,9 +150,9 @@ uint64_t LLVMGetSymbolAddress(LLVMSymbolIteratorRef SI) { return ret; } -uint64_t LLVMGetSymbolOffset(LLVMSymbolIteratorRef SI) { +uint64_t LLVMGetSymbolFileOffset(LLVMSymbolIteratorRef SI) { uint64_t ret; - if (error_code ec = (*unwrap(SI))->getOffset(ret)) + if (error_code ec = (*unwrap(SI))->getFileOffset(ret)) report_fatal_error(ec.message()); return ret; } @@ -172,6 +172,13 @@ uint64_t LLVMGetRelocationAddress(LLVMRelocationIteratorRef RI) { return ret; } +uint64_t LLVMGetRelocationOffset(LLVMRelocationIteratorRef RI) { + uint64_t ret; + if (error_code ec = (*unwrap(RI))->getOffset(ret)) + report_fatal_error(ec.message()); + return ret; +} + LLVMSymbolIteratorRef LLVMGetRelocationSymbol(LLVMRelocationIteratorRef RI) { SymbolRef ret; if (error_code ec = (*unwrap(RI))->getSymbol(ret)) diff --git a/tools/llvm-nm/llvm-nm.cpp b/tools/llvm-nm/llvm-nm.cpp index e79d72d1933..254421510f4 100644 --- a/tools/llvm-nm/llvm-nm.cpp +++ b/tools/llvm-nm/llvm-nm.cpp @@ -286,7 +286,7 @@ static void DumpSymbolNamesFromObject(ObjectFile *obj) { if (error(i->getSize(s.Size))) break; } if (PrintAddress) - if (error(i->getOffset(s.Address))) break; + if (error(i->getFileOffset(s.Address))) break; if (error(i->getNMTypeChar(s.TypeChar))) break; if (error(i->getName(s.Name))) break; SymbolList.push_back(s); diff --git a/tools/llvm-objdump/MachODump.cpp b/tools/llvm-objdump/MachODump.cpp index 4ccae5148bd..ef5258dc9b2 100644 --- a/tools/llvm-objdump/MachODump.cpp +++ b/tools/llvm-objdump/MachODump.cpp @@ -419,7 +419,7 @@ void llvm::DisassembleInputMachO(StringRef Filename) { // Start at the address of the symbol relative to the section's address. uint64_t Start = 0; - Symbols[SymIdx].getOffset(Start); + Symbols[SymIdx].getFileOffset(Start); // Stop disassembling either at the beginning of the next symbol or at // the end of the section. @@ -432,7 +432,7 @@ void llvm::DisassembleInputMachO(StringRef Filename) { if (NextSymType == SymbolRef::ST_Function) { Sections[SectIdx].containsSymbol(Symbols[NextSymIdx], containsNextSym); - Symbols[NextSymIdx].getOffset(NextSym); + Symbols[NextSymIdx].getFileOffset(NextSym); break; } ++NextSymIdx; diff --git a/tools/llvm-objdump/llvm-objdump.cpp b/tools/llvm-objdump/llvm-objdump.cpp index 9071d58b0e7..0f0ae1ceb7f 100644 --- a/tools/llvm-objdump/llvm-objdump.cpp +++ b/tools/llvm-objdump/llvm-objdump.cpp @@ -186,7 +186,7 @@ static void DisassembleObject(const ObjectFile *Obj, bool InlineRelocs) { bool contains; if (!error(i->containsSymbol(*si, contains)) && contains) { uint64_t Address; - if (error(si->getOffset(Address))) break; + if (error(si->getFileOffset(Address))) break; StringRef Name; if (error(si->getName(Name))) break; Symbols.push_back(std::make_pair(Address, Name)); @@ -485,7 +485,7 @@ static void PrintSymbolTable(const ObjectFile *o) { uint64_t Size; section_iterator Section = o->end_sections(); if (error(si->getName(Name))) continue; - if (error(si->getOffset(Offset))) continue; + if (error(si->getFileOffset(Offset))) continue; if (error(si->isGlobal(Global))) continue; if (error(si->getType(Type))) continue; if (error(si->isWeak(Weak))) continue;