diff options
| author | Sergey Dmitriev <serguei.n.dmitriev@intel.com> | 2019-11-14 09:50:36 -0800 |
|---|---|---|
| committer | Sergey Dmitriev <serguei.n.dmitriev@intel.com> | 2019-11-14 10:31:50 -0800 |
| commit | caa9493da85561c6a2308bf9821fe6d14323b8f5 (patch) | |
| tree | 09d07e2a6b9a2f44681b52b2bd0f5baa1c5016c4 /llvm/tools | |
| parent | c6b09bff5671600f8e764d3847023d0996f328d9 (diff) | |
| download | bcm5719-llvm-caa9493da85561c6a2308bf9821fe6d14323b8f5.tar.gz bcm5719-llvm-caa9493da85561c6a2308bf9821fe6d14323b8f5.zip | |
[llvm-objcopy][COFF] Add support for extended relocation tables
Summary: This patch adds support for COFF objects with extended relocation tables to the llvm-objcopy tool.
Reviewers: jhenderson, MaskRay, mstorsjo, alexshap, rupprecht
Reviewed By: mstorsjo
Subscribers: jakehehrlich, abrachet, seiya, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D70205
Diffstat (limited to 'llvm/tools')
| -rw-r--r-- | llvm/tools/llvm-objcopy/COFF/Reader.cpp | 4 | ||||
| -rw-r--r-- | llvm/tools/llvm-objcopy/COFF/Writer.cpp | 22 |
2 files changed, 20 insertions, 6 deletions
diff --git a/llvm/tools/llvm-objcopy/COFF/Reader.cpp b/llvm/tools/llvm-objcopy/COFF/Reader.cpp index 2fcec0057c0..7be9cce2be3 100644 --- a/llvm/tools/llvm-objcopy/COFF/Reader.cpp +++ b/llvm/tools/llvm-objcopy/COFF/Reader.cpp @@ -63,6 +63,7 @@ Error COFFReader::readSections(Object &Obj) const { Sections.push_back(Section()); Section &S = Sections.back(); S.Header = *Sec; + S.Header.Characteristics &= ~COFF::IMAGE_SCN_LNK_NRELOC_OVFL; ArrayRef<uint8_t> Contents; if (Error E = COFFObj.getSectionContents(Sec, Contents)) return E; @@ -74,9 +75,6 @@ Error COFFReader::readSections(Object &Obj) const { S.Name = *NameOrErr; else return NameOrErr.takeError(); - if (Sec->hasExtendedRelocations()) - return createStringError(object_error::parse_failed, - "extended relocations not supported yet"); } Obj.addSections(Sections); return Error::success(); diff --git a/llvm/tools/llvm-objcopy/COFF/Writer.cpp b/llvm/tools/llvm-objcopy/COFF/Writer.cpp index 6db37435fd9..e35e0474a36 100644 --- a/llvm/tools/llvm-objcopy/COFF/Writer.cpp +++ b/llvm/tools/llvm-objcopy/COFF/Writer.cpp @@ -97,9 +97,16 @@ void COFFWriter::layoutSections() { S.Header.PointerToRawData = FileSize; FileSize += S.Header.SizeOfRawData; // For executables, this is already // aligned to FileAlignment. - S.Header.NumberOfRelocations = S.Relocs.size(); - S.Header.PointerToRelocations = - S.Header.NumberOfRelocations > 0 ? FileSize : 0; + if (S.Relocs.size() >= 0xffff) { + S.Header.Characteristics |= COFF::IMAGE_SCN_LNK_NRELOC_OVFL; + S.Header.NumberOfRelocations = 0xffff; + S.Header.PointerToRelocations = FileSize; + FileSize += sizeof(coff_relocation); + } else { + S.Header.NumberOfRelocations = S.Relocs.size(); + S.Header.PointerToRelocations = S.Relocs.size() ? FileSize : 0; + } + FileSize += S.Relocs.size() * sizeof(coff_relocation); FileSize = alignTo(FileSize, FileAlignment); @@ -307,6 +314,15 @@ void COFFWriter::writeSections() { S.Header.SizeOfRawData - Contents.size()); Ptr += S.Header.SizeOfRawData; + + if (S.Relocs.size() >= 0xffff) { + object::coff_relocation R; + R.VirtualAddress = S.Relocs.size() + 1; + R.SymbolTableIndex = 0; + R.Type = 0; + memcpy(Ptr, &R, sizeof(R)); + Ptr += sizeof(R); + } for (const auto &R : S.Relocs) { memcpy(Ptr, &R.Reloc, sizeof(R.Reloc)); Ptr += sizeof(R.Reloc); |

