diff options
author | Benjamin Kramer <benny.kra@googlemail.com> | 2011-09-08 20:52:17 +0000 |
---|---|---|
committer | Benjamin Kramer <benny.kra@googlemail.com> | 2011-09-08 20:52:17 +0000 |
commit | 022ecdf2777ccd81cb2abc4cafa16573073fec7b (patch) | |
tree | e8c6431ec13473be7d3c04482c5a10eb2c06e55f /llvm/lib/Object/COFFObjectFile.cpp | |
parent | dc55a80da3c2c5efcb1d21142f3fdc2435de2938 (diff) | |
download | bcm5719-llvm-022ecdf2777ccd81cb2abc4cafa16573073fec7b.tar.gz bcm5719-llvm-022ecdf2777ccd81cb2abc4cafa16573073fec7b.zip |
Add support for relocations to ObjectFile.
Patch by Danil Malyshev!
llvm-svn: 139314
Diffstat (limited to 'llvm/lib/Object/COFFObjectFile.cpp')
-rw-r--r-- | llvm/lib/Object/COFFObjectFile.cpp | 75 |
1 files changed, 73 insertions, 2 deletions
diff --git a/llvm/lib/Object/COFFObjectFile.cpp b/llvm/lib/Object/COFFObjectFile.cpp index 07de6bc9997..594fcd16981 100644 --- a/llvm/lib/Object/COFFObjectFile.cpp +++ b/llvm/lib/Object/COFFObjectFile.cpp @@ -327,7 +327,7 @@ COFFObjectFile::COFFObjectFile(MemoryBuffer *Object, error_code &ec) Header = reinterpret_cast<const coff_file_header *>(base() + HeaderStart); if (!checkAddr(Data, ec, uintptr_t(Header), sizeof(coff_file_header))) return; - + SectionTable = reinterpret_cast<const coff_section *>( base() + HeaderStart @@ -360,7 +360,7 @@ COFFObjectFile::COFFObjectFile(MemoryBuffer *Object, error_code &ec) ec = object_error::parse_failed; return; } - + ec = object_error::success; } @@ -445,6 +445,77 @@ error_code COFFObjectFile::getString(uint32_t offset, 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; + 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; +} +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; + getSection(Rel.d.b, Sect); + if (Sect->NumberOfRelocations > 0) + break; + } + } + Res = RelocationRef(Rel, this); + return object_error::success; +} +error_code COFFObjectFile::getRelocationAddress(DataRefImpl Rel, + uint64_t &Res) const { + const coff_section *Sect; + 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); + return object_error::success; +} +error_code COFFObjectFile::getRelocationSymbol(DataRefImpl Rel, + SymbolRef &Res) const { + const coff_relocation* R = toRel(Rel); + DataRefImpl Symb; + Symb.p = reinterpret_cast<uintptr_t>(SymbolTable + R->SymbolTableIndex); + Res = SymbolRef(Symb, this); + return object_error::success; +} +error_code COFFObjectFile::getRelocationType(DataRefImpl Rel, + uint32_t &Res) const { + const coff_relocation* R = toRel(Rel); + Res = R->Type; + return object_error::success; +} +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)); +} + + namespace llvm { ObjectFile *ObjectFile::createCOFFObjectFile(MemoryBuffer *Object) { |