Skip to content

Commit 4d02263

Browse files
committed
[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
1 parent 2c83197 commit 4d02263

File tree

2 files changed

+81
-3
lines changed

2 files changed

+81
-3
lines changed

llvm/lib/ObjectYAML/COFFEmitter.cpp

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -260,9 +260,12 @@ static bool layoutCOFF(COFFParser &CP) {
260260
CurrentSectionDataOffset += S.Header.SizeOfRawData;
261261
if (!S.Relocations.empty()) {
262262
S.Header.PointerToRelocations = CurrentSectionDataOffset;
263-
S.Header.NumberOfRelocations = S.Relocations.size();
264-
CurrentSectionDataOffset +=
265-
S.Header.NumberOfRelocations * COFF::RelocationSize;
263+
if (S.Header.Characteristics & COFF::IMAGE_SCN_LNK_NRELOC_OVFL) {
264+
S.Header.NumberOfRelocations = 0xffff;
265+
CurrentSectionDataOffset += COFF::RelocationSize;
266+
} else
267+
S.Header.NumberOfRelocations = S.Relocations.size();
268+
CurrentSectionDataOffset += S.Relocations.size() * COFF::RelocationSize;
266269
}
267270
} else {
268271
// Leave SizeOfRawData unaltered. For .bss sections in object files, it
@@ -506,6 +509,10 @@ static bool writeCOFF(COFFParser &CP, raw_ostream &OS) {
506509
S.SectionData.writeAsBinary(OS);
507510
assert(S.Header.SizeOfRawData >= S.SectionData.binary_size());
508511
OS.write_zeros(S.Header.SizeOfRawData - S.SectionData.binary_size());
512+
if (S.Header.Characteristics & COFF::IMAGE_SCN_LNK_NRELOC_OVFL)
513+
OS << binary_le<uint32_t>(/*VirtualAddress=*/ S.Relocations.size() + 1)
514+
<< binary_le<uint32_t>(/*SymbolTableIndex=*/ 0)
515+
<< binary_le<uint16_t>(/*Type=*/ 0);
509516
for (const COFFYAML::Relocation &R : S.Relocations) {
510517
uint32_t SymbolTableIndex;
511518
if (R.SymbolTableIndex) {
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
## This test checks that yaml2obj correctly handles COFF sections with
2+
## extended relocation tables (IMAGE_SCN_LNK_NRELOC_OVFL).
3+
# RUN: yaml2obj %s -o %t
4+
# RUN: llvm-readobj --sections --relocations %t | FileCheck %s --check-prefix=CHECK-OBJ
5+
# RUN: obj2yaml %t | FileCheck %s --check-prefix=CHECK-YAML
6+
7+
# CHECK-OBJ: Sections [
8+
# CHECK-OBJ-NEXT: Section {
9+
# CHECK-OBJ-NEXT: Number: 1
10+
# CHECK-OBJ-NEXT: Name: .data
11+
# CHECK-OBJ: RawDataSize: 16
12+
# CHECK-OBJ: RelocationCount: 65535
13+
# CHECK-OBJ: Characteristics [
14+
# CHECK-OBJ-NEXT: IMAGE_SCN_ALIGN_16BYTES
15+
# CHECK-OBJ-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA
16+
# CHECK-OBJ-NEXT: IMAGE_SCN_LNK_NRELOC_OVFL
17+
# CHECK-OBJ-NEXT: IMAGE_SCN_MEM_READ
18+
# CHECK-OBJ-NEXT: ]
19+
# CHECK-OBJ-NEXT: }
20+
# CHECK-OBJ-NEXT: ]
21+
# CHECK-OBJ-NEXT: Relocations [
22+
# CHECK-OBJ-NEXT: Section (1) .data {
23+
# CHECK-OBJ-NEXT: 0x0 IMAGE_REL_AMD64_ADDR64 foo (0)
24+
# CHECK-OBJ-NEXT: 0x8 IMAGE_REL_AMD64_ADDR64 bar (1)
25+
# CHECK-OBJ-NEXT: }
26+
# CHECK-OBJ-NEXT: ]
27+
28+
# CHECK-YAML: sections:
29+
# CHECK-YAML-NEXT: - Name: .data
30+
# CHECK-YAML-NEXT: Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_LNK_NRELOC_OVFL, IMAGE_SCN_MEM_READ ]
31+
# CHECK-YAML-NEXT: Alignment: 16
32+
# CHECK-YAML-NEXT: SectionData: '00000000000000000000000000000000'
33+
# CHECK-YAML-NEXT: Relocations:
34+
# CHECK-YAML-NEXT: - VirtualAddress: 0
35+
# CHECK-YAML-NEXT: SymbolName: foo
36+
# CHECK-YAML-NEXT: Type: IMAGE_REL_AMD64_ADDR64
37+
# CHECK-YAML-NEXT: - VirtualAddress: 8
38+
# CHECK-YAML-NEXT: SymbolName: bar
39+
# CHECK-YAML-NEXT: Type: IMAGE_REL_AMD64_ADDR64
40+
# CHECK-YAML-NEXT: symbols:
41+
42+
--- !COFF
43+
header:
44+
Machine: IMAGE_FILE_MACHINE_AMD64
45+
Characteristics: [ ]
46+
sections:
47+
- Name: .data
48+
Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_LNK_NRELOC_OVFL, IMAGE_SCN_MEM_READ ]
49+
Alignment: 16
50+
SectionData: '00000000000000000000000000000000'
51+
Relocations:
52+
- VirtualAddress: 0
53+
SymbolName: foo
54+
Type: IMAGE_REL_AMD64_ADDR64
55+
- VirtualAddress: 8
56+
SymbolName: bar
57+
Type: IMAGE_REL_AMD64_ADDR64
58+
symbols:
59+
- Name: foo
60+
Value: 0
61+
SectionNumber: 0
62+
SimpleType: IMAGE_SYM_TYPE_NULL
63+
ComplexType: IMAGE_SYM_DTYPE_NULL
64+
StorageClass: IMAGE_SYM_CLASS_EXTERNAL
65+
- Name: bar
66+
Value: 0
67+
SectionNumber: 0
68+
SimpleType: IMAGE_SYM_TYPE_NULL
69+
ComplexType: IMAGE_SYM_DTYPE_NULL
70+
StorageClass: IMAGE_SYM_CLASS_EXTERNAL
71+
...

0 commit comments

Comments
 (0)