[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
This commit is contained in:
Sergey Dmitriev 2019-11-14 12:31:13 -08:00
parent 2c831971bf
commit 4d02263af0
2 changed files with 81 additions and 3 deletions

View File

@ -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) {

View File

@ -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
...