diff options
author | Michael J. Spencer <bigcheesegs@gmail.com> | 2011-10-07 18:15:25 +0000 |
---|---|---|
committer | Michael J. Spencer <bigcheesegs@gmail.com> | 2011-10-07 18:15:25 +0000 |
commit | f1164a2487750f891694fc2e3347860e50f705fb (patch) | |
tree | 5d899fbf0e0a465a57c019d659046c4d334d5968 /lib/Object/COFFObjectFile.cpp | |
parent | b76761351f36ce0a68762ba800dd88f6ecd4bccb (diff) |
Change relocation API to be per section.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@141376 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Object/COFFObjectFile.cpp')
-rw-r--r-- | lib/Object/COFFObjectFile.cpp | 157 |
1 files changed, 114 insertions, 43 deletions
diff --git a/lib/Object/COFFObjectFile.cpp b/lib/Object/COFFObjectFile.cpp index 10afad832e..9255c2321f 100644 --- a/lib/Object/COFFObjectFile.cpp +++ b/lib/Object/COFFObjectFile.cpp @@ -12,6 +12,7 @@ //===----------------------------------------------------------------------===// #include "llvm/Object/COFF.h" +#include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringSwitch.h" #include "llvm/ADT/Triple.h" @@ -364,6 +365,33 @@ error_code COFFObjectFile::sectionContainsSymbol(DataRefImpl Sec, return object_error::success; } +relocation_iterator COFFObjectFile::getSectionRelBegin(DataRefImpl Sec) const { + const coff_section *sec = toSec(Sec); + DataRefImpl ret; + std::memset(&ret, 0, sizeof(ret)); + if (sec->NumberOfRelocations == 0) + ret.p = 0; + else + ret.p = reinterpret_cast<uintptr_t>(base() + sec->PointerToRelocations); + + return relocation_iterator(RelocationRef(ret, this)); +} + +relocation_iterator COFFObjectFile::getSectionRelEnd(DataRefImpl Sec) const { + const coff_section *sec = toSec(Sec); + DataRefImpl ret; + std::memset(&ret, 0, sizeof(ret)); + if (sec->NumberOfRelocations == 0) + ret.p = 0; + else + ret.p = reinterpret_cast<uintptr_t>( + reinterpret_cast<const coff_relocation*>( + base() + sec->PointerToRelocations) + + sec->NumberOfRelocations); + + return relocation_iterator(RelocationRef(ret, this)); +} + COFFObjectFile::COFFObjectFile(MemoryBuffer *Object, error_code &ec) : ObjectFile(Binary::isCOFF, Object, ec) { // Check that we at least have enough room for a header. @@ -427,14 +455,14 @@ COFFObjectFile::COFFObjectFile(MemoryBuffer *Object, error_code &ec) ec = object_error::success; } -ObjectFile::symbol_iterator COFFObjectFile::begin_symbols() const { +symbol_iterator COFFObjectFile::begin_symbols() const { DataRefImpl ret; std::memset(&ret, 0, sizeof(DataRefImpl)); ret.p = reinterpret_cast<intptr_t>(SymbolTable); return symbol_iterator(SymbolRef(ret, this)); } -ObjectFile::symbol_iterator COFFObjectFile::end_symbols() const { +symbol_iterator COFFObjectFile::end_symbols() const { // The symbol table ends where the string table begins. DataRefImpl ret; std::memset(&ret, 0, sizeof(DataRefImpl)); @@ -442,14 +470,14 @@ ObjectFile::symbol_iterator COFFObjectFile::end_symbols() const { return symbol_iterator(SymbolRef(ret, this)); } -ObjectFile::section_iterator COFFObjectFile::begin_sections() const { +section_iterator COFFObjectFile::begin_sections() const { DataRefImpl ret; std::memset(&ret, 0, sizeof(DataRefImpl)); ret.p = reinterpret_cast<intptr_t>(SectionTable); return section_iterator(SectionRef(ret, this)); } -ObjectFile::section_iterator COFFObjectFile::end_sections() const { +section_iterator COFFObjectFile::end_sections() const { DataRefImpl ret; std::memset(&ret, 0, sizeof(DataRefImpl)); ret.p = reinterpret_cast<intptr_t>(SectionTable + Header->NumberOfSections); @@ -508,42 +536,27 @@ error_code COFFObjectFile::getString(uint32_t offset, return object_error::success; } +error_code COFFObjectFile::getSymbol(uint32_t index, + const coff_symbol *&Result) const { + if (index > 0 && index < Header->NumberOfSymbols) + Result = SymbolTable + index; + else + return object_error::parse_failed; + return object_error::success; +} + const coff_relocation *COFFObjectFile::toRel(DataRefImpl Rel) const { - assert(Rel.d.b < Header->NumberOfSections && "Section index out of range!"); - const coff_section *Sect = NULL; - getSection(Rel.d.b, Sect); - assert(Rel.d.a < Sect->NumberOfRelocations && "Relocation index out of range!"); - return - reinterpret_cast<const coff_relocation*>(base() + - Sect->PointerToRelocations) + - Rel.d.a; + return reinterpret_cast<const coff_relocation*>(Rel.p); } error_code COFFObjectFile::getRelocationNext(DataRefImpl Rel, RelocationRef &Res) const { - const coff_section *Sect = NULL; - if (error_code ec = getSection(Rel.d.b, Sect)) - return ec; - if (++Rel.d.a >= Sect->NumberOfRelocations) { - Rel.d.a = 0; - while (++Rel.d.b < Header->NumberOfSections) { - const coff_section *Sect = NULL; - getSection(Rel.d.b, Sect); - if (Sect->NumberOfRelocations > 0) - break; - } - } + ++*reinterpret_cast<const coff_relocation**>(&Rel.p); Res = RelocationRef(Rel, this); return object_error::success; } error_code COFFObjectFile::getRelocationAddress(DataRefImpl Rel, uint64_t &Res) const { - const coff_section *Sect = NULL; - if (error_code ec = getSection(Rel.d.b, Sect)) - return ec; - const coff_relocation* R = toRel(Rel); - Res = reinterpret_cast<uintptr_t>(base() + - Sect->PointerToRawData + - R->VirtualAddress); + Res = toRel(Rel)->VirtualAddress; return object_error::success; } error_code COFFObjectFile::getRelocationSymbol(DataRefImpl Rel, @@ -560,25 +573,83 @@ error_code COFFObjectFile::getRelocationType(DataRefImpl Rel, Res = R->Type; return object_error::success; } + +#define LLVM_COFF_SWITCH_RELOC_TYPE_NAME(enum) \ + case COFF::enum: res = #enum; break; + +error_code COFFObjectFile::getRelocationTypeName(DataRefImpl Rel, + SmallVectorImpl<char> &Result) const { + const coff_relocation *reloc = toRel(Rel); + StringRef res; + switch (Header->Machine) { + case COFF::IMAGE_FILE_MACHINE_AMD64: + switch (reloc->Type) { + LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_ABSOLUTE); + LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_ADDR64); + LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_ADDR32); + LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_ADDR32NB); + LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_REL32); + LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_REL32_1); + LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_REL32_2); + LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_REL32_3); + LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_REL32_4); + LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_REL32_5); + LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_SECTION); + LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_SECREL); + LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_SECREL7); + LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_TOKEN); + LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_SREL32); + LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_PAIR); + LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_SSPAN32); + default: + res = "Unknown"; + } + break; + case COFF::IMAGE_FILE_MACHINE_I386: + switch (reloc->Type) { + LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_ABSOLUTE); + LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_DIR16); + LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_REL16); + LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_DIR32); + LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_DIR32NB); + LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_SEG12); + LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_SECTION); + LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_SECREL); + LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_TOKEN); + LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_SECREL7); + LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_REL32); + default: + res = "Unknown"; + } + break; + default: + res = "Unknown"; + } + Result.append(res.begin(), res.end()); + return object_error::success; +} + +#undef LLVM_COFF_SWITCH_RELOC_TYPE_NAME + error_code COFFObjectFile::getRelocationAdditionalInfo(DataRefImpl Rel, int64_t &Res) const { Res = 0; return object_error::success; } -ObjectFile::relocation_iterator COFFObjectFile::begin_relocations() const { - DataRefImpl ret; - ret.d.a = 0; - ret.d.b = 1; - return relocation_iterator(RelocationRef(ret, this)); -} -ObjectFile::relocation_iterator COFFObjectFile::end_relocations() const { - DataRefImpl ret; - ret.d.a = 0; - ret.d.b = Header->NumberOfSections; - return relocation_iterator(RelocationRef(ret, this)); +error_code COFFObjectFile::getRelocationValueString(DataRefImpl Rel, + SmallVectorImpl<char> &Result) const { + const coff_relocation *reloc = toRel(Rel); + const coff_symbol *symb; + if (error_code ec = getSymbol(reloc->SymbolTableIndex, symb)) return ec; + DataRefImpl sym; + ::memset(&sym, 0, sizeof(sym)); + sym.p = reinterpret_cast<uintptr_t>(symb); + StringRef symname; + if (error_code ec = getSymbolName(sym, symname)) return ec; + Result.append(symname.begin(), symname.end()); + return object_error::success; } - namespace llvm { ObjectFile *ObjectFile::createCOFFObjectFile(MemoryBuffer *Object) { |