[llvm] 4d02263 - [yaml2obj][COFF] Add support for extended relocation tables
Sergey Dmitriev via llvm-commits
llvm-commits at lists.llvm.org
Thu Nov 14 12:47:07 PST 2019
Author: Sergey Dmitriev
Date: 2019-11-14T12:39:28-08:00
New Revision: 4d02263af0d504593e6312b44dfa7749181a21e4
URL: https://github.com/llvm/llvm-project/commit/4d02263af0d504593e6312b44dfa7749181a21e4
DIFF: https://github.com/llvm/llvm-project/commit/4d02263af0d504593e6312b44dfa7749181a21e4.diff
LOG: [yaml2obj][COFF] Add support for extended relocation tables
Summary:
The tool does not correctly handle COFF sections with extended relocation tables (with IMAGE_SCN_LNK_NRELOC_OVFL bit set), this patch fixes this problem.
But I have cheated a bit in the test (to make it smaller) because extended relocation table is supposed to be used when the number of relocations exceeds 65534. Otherwise the test size would be pretty big.
Reviewers: jhenderson, MaskRay, mstorsjo
Reviewed By: mstorsjo
Subscribers: hiraditya, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D70251
Added:
llvm/test/tools/yaml2obj/coff-xrelocs.yaml
Modified:
llvm/lib/ObjectYAML/COFFEmitter.cpp
Removed:
################################################################################
diff --git a/llvm/lib/ObjectYAML/COFFEmitter.cpp b/llvm/lib/ObjectYAML/COFFEmitter.cpp
index efcdc51e1670..ec3ec55011f9 100644
--- a/llvm/lib/ObjectYAML/COFFEmitter.cpp
+++ b/llvm/lib/ObjectYAML/COFFEmitter.cpp
@@ -260,9 +260,12 @@ static bool layoutCOFF(COFFParser &CP) {
CurrentSectionDataOffset += S.Header.SizeOfRawData;
if (!S.Relocations.empty()) {
S.Header.PointerToRelocations = CurrentSectionDataOffset;
- S.Header.NumberOfRelocations = S.Relocations.size();
- CurrentSectionDataOffset +=
- S.Header.NumberOfRelocations * COFF::RelocationSize;
+ if (S.Header.Characteristics & COFF::IMAGE_SCN_LNK_NRELOC_OVFL) {
+ S.Header.NumberOfRelocations = 0xffff;
+ CurrentSectionDataOffset += COFF::RelocationSize;
+ } else
+ S.Header.NumberOfRelocations = S.Relocations.size();
+ CurrentSectionDataOffset += S.Relocations.size() * COFF::RelocationSize;
}
} else {
// Leave SizeOfRawData unaltered. For .bss sections in object files, it
@@ -506,6 +509,10 @@ static bool writeCOFF(COFFParser &CP, raw_ostream &OS) {
S.SectionData.writeAsBinary(OS);
assert(S.Header.SizeOfRawData >= S.SectionData.binary_size());
OS.write_zeros(S.Header.SizeOfRawData - S.SectionData.binary_size());
+ if (S.Header.Characteristics & COFF::IMAGE_SCN_LNK_NRELOC_OVFL)
+ OS << binary_le<uint32_t>(/*VirtualAddress=*/ S.Relocations.size() + 1)
+ << binary_le<uint32_t>(/*SymbolTableIndex=*/ 0)
+ << binary_le<uint16_t>(/*Type=*/ 0);
for (const COFFYAML::Relocation &R : S.Relocations) {
uint32_t SymbolTableIndex;
if (R.SymbolTableIndex) {
diff --git a/llvm/test/tools/yaml2obj/coff-xrelocs.yaml b/llvm/test/tools/yaml2obj/coff-xrelocs.yaml
new file mode 100644
index 000000000000..fbc22a1e99ca
--- /dev/null
+++ b/llvm/test/tools/yaml2obj/coff-xrelocs.yaml
@@ -0,0 +1,71 @@
+## This test checks that yaml2obj correctly handles COFF sections with
+## extended relocation tables (IMAGE_SCN_LNK_NRELOC_OVFL).
+# RUN: yaml2obj %s -o %t
+# RUN: llvm-readobj --sections --relocations %t | FileCheck %s --check-prefix=CHECK-OBJ
+# RUN: obj2yaml %t | FileCheck %s --check-prefix=CHECK-YAML
+
+# CHECK-OBJ: Sections [
+# CHECK-OBJ-NEXT: Section {
+# CHECK-OBJ-NEXT: Number: 1
+# CHECK-OBJ-NEXT: Name: .data
+# CHECK-OBJ: RawDataSize: 16
+# CHECK-OBJ: RelocationCount: 65535
+# CHECK-OBJ: Characteristics [
+# CHECK-OBJ-NEXT: IMAGE_SCN_ALIGN_16BYTES
+# CHECK-OBJ-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA
+# CHECK-OBJ-NEXT: IMAGE_SCN_LNK_NRELOC_OVFL
+# CHECK-OBJ-NEXT: IMAGE_SCN_MEM_READ
+# CHECK-OBJ-NEXT: ]
+# CHECK-OBJ-NEXT: }
+# CHECK-OBJ-NEXT: ]
+# CHECK-OBJ-NEXT: Relocations [
+# CHECK-OBJ-NEXT: Section (1) .data {
+# CHECK-OBJ-NEXT: 0x0 IMAGE_REL_AMD64_ADDR64 foo (0)
+# CHECK-OBJ-NEXT: 0x8 IMAGE_REL_AMD64_ADDR64 bar (1)
+# CHECK-OBJ-NEXT: }
+# CHECK-OBJ-NEXT: ]
+
+# CHECK-YAML: sections:
+# CHECK-YAML-NEXT: - Name: .data
+# CHECK-YAML-NEXT: Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_LNK_NRELOC_OVFL, IMAGE_SCN_MEM_READ ]
+# CHECK-YAML-NEXT: Alignment: 16
+# CHECK-YAML-NEXT: SectionData: '00000000000000000000000000000000'
+# CHECK-YAML-NEXT: Relocations:
+# CHECK-YAML-NEXT: - VirtualAddress: 0
+# CHECK-YAML-NEXT: SymbolName: foo
+# CHECK-YAML-NEXT: Type: IMAGE_REL_AMD64_ADDR64
+# CHECK-YAML-NEXT: - VirtualAddress: 8
+# CHECK-YAML-NEXT: SymbolName: bar
+# CHECK-YAML-NEXT: Type: IMAGE_REL_AMD64_ADDR64
+# CHECK-YAML-NEXT: symbols:
+
+--- !COFF
+header:
+ Machine: IMAGE_FILE_MACHINE_AMD64
+ Characteristics: [ ]
+sections:
+ - Name: .data
+ Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_LNK_NRELOC_OVFL, IMAGE_SCN_MEM_READ ]
+ Alignment: 16
+ SectionData: '00000000000000000000000000000000'
+ Relocations:
+ - VirtualAddress: 0
+ SymbolName: foo
+ Type: IMAGE_REL_AMD64_ADDR64
+ - VirtualAddress: 8
+ SymbolName: bar
+ Type: IMAGE_REL_AMD64_ADDR64
+symbols:
+ - Name: foo
+ Value: 0
+ SectionNumber: 0
+ SimpleType: IMAGE_SYM_TYPE_NULL
+ ComplexType: IMAGE_SYM_DTYPE_NULL
+ StorageClass: IMAGE_SYM_CLASS_EXTERNAL
+ - Name: bar
+ Value: 0
+ SectionNumber: 0
+ SimpleType: IMAGE_SYM_TYPE_NULL
+ ComplexType: IMAGE_SYM_DTYPE_NULL
+ StorageClass: IMAGE_SYM_CLASS_EXTERNAL
+...
More information about the llvm-commits
mailing list