From caa9493da85561c6a2308bf9821fe6d14323b8f5 Mon Sep 17 00:00:00 2001 From: Sergey Dmitriev Date: Thu, 14 Nov 2019 09:50:36 -0800 Subject: [PATCH] [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 --- .../llvm-objcopy/COFF/Inputs/x86_64-xrelocs.obj.gz | Bin 0 -> 88299 bytes llvm/test/tools/llvm-objcopy/COFF/add-section.test | 32 +++++++++++++++++++++ llvm/tools/llvm-objcopy/COFF/Reader.cpp | 4 +-- llvm/tools/llvm-objcopy/COFF/Writer.cpp | 22 ++++++++++++-- 4 files changed, 52 insertions(+), 6 deletions(-) create mode 100644 llvm/test/tools/llvm-objcopy/COFF/Inputs/x86_64-xrelocs.obj.gz diff --git a/llvm/test/tools/llvm-objcopy/COFF/Inputs/x86_64-xrelocs.obj.gz b/llvm/test/tools/llvm-objcopy/COFF/Inputs/x86_64-xrelocs.obj.gz new file mode 100644 index 0000000000000000000000000000000000000000..9b3cf4ad0e0e5248b02fe8824d3176ea34540536 GIT binary patch literal 88299 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 C( %t.in.xrelocs.obj +# RUN: llvm-objcopy --add-section=.test.section=%t.sec %t.in.xrelocs.obj %t1.xrelocs.obj +# RUN: llvm-readobj --file-headers --sections --section-data %t1.xrelocs.obj | FileCheck %s --check-prefixes=CHECK-EXTENDED-RELOCS + +# CHECK-EXTENDED-RELOCS: SectionCount: 5 +# CHECK-EXTENDED-RELOCS: Name: .data +# CHECK-EXTENDED-RELOCS-NEXT: VirtualSize: +# CHECK-EXTENDED-RELOCS-NEXT: VirtualAddress: +# CHECK-EXTENDED-RELOCS-NEXT: RawDataSize: +# CHECK-EXTENDED-RELOCS-NEXT: PointerToRawData: +# CHECK-EXTENDED-RELOCS-NEXT: PointerToRelocations: +# CHECK-EXTENDED-RELOCS-NEXT: PointerToLineNumbers: +# CHECK-EXTENDED-RELOCS-NEXT: RelocationCount: 65535 +# CHECK-EXTENDED-RELOCS-NEXT: LineNumberCount: 0 +# CHECK-EXTENDED-RELOCS-NEXT: Characteristics [ +# CHECK-EXTENDED-RELOCS-NEXT: IMAGE_SCN_ALIGN_16BYTES +# CHECK-EXTENDED-RELOCS-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA +# CHECK-EXTENDED-RELOCS-NEXT: IMAGE_SCN_LNK_NRELOC_OVFL +# CHECK-EXTENDED-RELOCS-NEXT: IMAGE_SCN_MEM_READ +# CHECK-EXTENDED-RELOCS-NEXT: IMAGE_SCN_MEM_WRITE +# CHECK-EXTENDED-RELOCS-NEXT: ] +# CHECK-EXTENDED-RELOCS: Name: .test.section +# CHECK-EXTENDED-RELOCS: Characteristics [ +# CHECK-EXTENDED-RELOCS-NEXT: IMAGE_SCN_ALIGN_1BYTES +# CHECK-EXTENDED-RELOCS-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA +# CHECK-EXTENDED-RELOCS-NEXT: ] +# CHECK-EXTENDED-RELOCS: SectionData ( +# CHECK-EXTENDED-RELOCS-NEXT: 0000: {{.+}}|DEADBEEF{{.+}}| +# CHECK-EXTENDED-RELOCS-NEXT: ) + ## Test that llvm-objcopy produces an error if the file with section contents ## to be added does not exist. # RUN: not llvm-objcopy --add-section=.another.section=%t2 %t %t3 2>&1 | FileCheck -DFILE1=%t -DFILE2=%t2 %s --check-prefixes=ERR1 diff --git a/llvm/tools/llvm-objcopy/COFF/Reader.cpp b/llvm/tools/llvm-objcopy/COFF/Reader.cpp index 2fcec00..7be9cce 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 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 6db3743..e35e047 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); -- 2.7.4