summaryrefslogtreecommitdiffstats
path: root/llvm/tools/llvm-objcopy/COFF
diff options
context:
space:
mode:
authorSergey Dmitriev <serguei.n.dmitriev@intel.com>2019-11-14 09:50:36 -0800
committerSergey Dmitriev <serguei.n.dmitriev@intel.com>2019-11-14 10:31:50 -0800
commitcaa9493da85561c6a2308bf9821fe6d14323b8f5 (patch)
tree09d07e2a6b9a2f44681b52b2bd0f5baa1c5016c4 /llvm/tools/llvm-objcopy/COFF
parentc6b09bff5671600f8e764d3847023d0996f328d9 (diff)
downloadbcm5719-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/llvm-objcopy/COFF')
-rw-r--r--llvm/tools/llvm-objcopy/COFF/Reader.cpp4
-rw-r--r--llvm/tools/llvm-objcopy/COFF/Writer.cpp22
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);
OpenPOWER on IntegriCloud