1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2025-01-31 20:51:52 +01:00

[llvm-objcopy] [COFF] Fix a misconception about debug directory payloads

The debug directory payload is not located directly after the
debug directory entry itself, but can essentially be located anywhere
in the binary (even outside of mapped sections, although we don't
handle that case).

Differential Revision: https://reviews.llvm.org/D78921
This commit is contained in:
Martin Storsjö 2020-04-27 14:30:42 +03:00
parent f4aa425c92
commit 579a3edad4
4 changed files with 142 additions and 4 deletions

View File

@ -0,0 +1,52 @@
## Check that we error out when trying to patch up debug directories that
## point to data outside of the runtime mapped sections (as we don't try to
## locate and copy such payloads from the padding areas of the input file).
# RUN: yaml2obj %s -o %t.in.exe
# RUN: not llvm-objcopy --remove-section .rdata %t.in.exe %t.out.exe 2>&1 | FileCheck %s
# CHECK: error: '{{.*}}{{/|\\}}debug-dir-unmapped.test.tmp.out.exe': debug directory payload outside of mapped sections not supported
--- !COFF
OptionalHeader:
AddressOfEntryPoint: 4096
ImageBase: 1073741824
SectionAlignment: 4096
FileAlignment: 512
MajorOperatingSystemVersion: 6
MinorOperatingSystemVersion: 0
MajorImageVersion: 0
MinorImageVersion: 0
MajorSubsystemVersion: 6
MinorSubsystemVersion: 0
Subsystem: IMAGE_SUBSYSTEM_WINDOWS_CUI
DLLCharacteristics: [ ]
SizeOfStackReserve: 1048576
SizeOfStackCommit: 4096
SizeOfHeapReserve: 1048576
SizeOfHeapCommit: 4096
Debug:
RelativeVirtualAddress: 12288
Size: 28
header:
Machine: IMAGE_FILE_MACHINE_AMD64
Characteristics: [ ]
sections:
- Name: .text
Characteristics: [ ]
VirtualAddress: 4096
VirtualSize: 16
SectionData: C3909090909090909090909090909090
- Name: .rdata
Characteristics: [ ]
VirtualAddress: 8192
VirtualSize: 32
SectionData: FFFFFFFF00000000FFFFFFFF00000000
- Name: .buildid
Characteristics: [ ]
VirtualAddress: 12288
VirtualSize: 28
SectionData: 0000000042EE405C00000000020000001900000000000000E4070000
symbols:
...

View File

@ -0,0 +1,68 @@
## Check that we successfully patch the PointerToRawData field in more than
## one debug directory entry.
# RUN: yaml2obj %s -o %t.in.exe
# RUN: llvm-readobj --coff-debug-directory %t.in.exe | FileCheck %s --check-prefixes=DEBUG-DIRS,DEBUG-DIRS-PRE
# RUN: llvm-readobj --sections %t.in.exe | FileCheck %s --check-prefixes=SECTIONS,SECTIONS-PRE
# RUN: llvm-objcopy --remove-section .rdata %t.in.exe %t.out.exe
# RUN: llvm-readobj --coff-debug-directory %t.out.exe | FileCheck %s --check-prefixes=DEBUG-DIRS,DEBUG-DIRS-POST
# RUN: llvm-readobj --sections %t.out.exe | FileCheck %s --check-prefixes=SECTIONS,SECTIONS-POST
# DEBUG-DIRS: AddressOfRawData: 0x3038
# DEBUG-DIRS-PRE-NEXT: PointerToRawData: 0x638
# DEBUG-DIRS-POST-NEXT: PointerToRawData: 0x438
# DEBUG-DIRS: AddressOfRawData: 0x3051
# DEBUG-DIRS-PRE-NEXT: PointerToRawData: 0x651
# DEBUG-DIRS-POST-NEXT: PointerToRawData: 0x451
# SECTIONS: Name: .buildid
# SECTIONS-NEXT: VirtualSize:
# SECTIONS-NEXT: VirtualAddress:
# SECTIONS-NEXT: RawDataSize:
# SECTIONS-PRE-NEXT: PointerToRawData: 0x600
# SECTIONS-POST-NEXT: PointerToRawData: 0x400
--- !COFF
OptionalHeader:
AddressOfEntryPoint: 4096
ImageBase: 5368709120
SectionAlignment: 4096
FileAlignment: 512
MajorOperatingSystemVersion: 6
MinorOperatingSystemVersion: 0
MajorImageVersion: 0
MinorImageVersion: 0
MajorSubsystemVersion: 6
MinorSubsystemVersion: 0
Subsystem: IMAGE_SUBSYSTEM_WINDOWS_CUI
DLLCharacteristics: [ ]
SizeOfStackReserve: 1048576
SizeOfStackCommit: 4096
SizeOfHeapReserve: 1048576
SizeOfHeapCommit: 4096
Debug:
RelativeVirtualAddress: 12288
Size: 56
header:
Machine: IMAGE_FILE_MACHINE_AMD64
Characteristics: [ ]
sections:
- Name: .text
Characteristics: [ ]
VirtualAddress: 4096
VirtualSize: 1
SectionData: C3
- Name: .rdata
Characteristics: [ ]
VirtualAddress: 8192
VirtualSize: 32
SectionData: FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF0000000000000000
- Name: .buildid
Characteristics: [ ]
VirtualAddress: 12288
VirtualSize: 85
SectionData: 0000000046C7A65E00000000020000001900000038300000380600000000000046C7A65E000000001400000004000000513000005106000052534453B3411F5F27A80D2A4C4C44205044422E010000000001000000
symbols:
...

View File

@ -383,6 +383,16 @@ Error COFFWriter::write(bool IsBigObj) {
return Buf.commit();
}
Expected<uint32_t> COFFWriter::virtualAddressToFileAddress(uint32_t RVA) {
for (const auto &S : Obj.getSections()) {
if (RVA >= S.Header.VirtualAddress &&
RVA < S.Header.VirtualAddress + S.Header.SizeOfRawData)
return S.Header.PointerToRawData + RVA - S.Header.VirtualAddress;
}
return createStringError(object_error::parse_failed,
"debug directory payload not found");
}
// Locate which sections contain the debug directories, iterate over all
// the debug_directory structs in there, and set the PointerToRawData field
// in all of them, according to their new physical location in the file.
@ -406,10 +416,17 @@ Error COFFWriter::patchDebugDirectory() {
uint8_t *End = Ptr + Dir->Size;
while (Ptr < End) {
debug_directory *Debug = reinterpret_cast<debug_directory *>(Ptr);
Debug->PointerToRawData =
S.Header.PointerToRawData + Offset + sizeof(debug_directory);
Ptr += sizeof(debug_directory) + Debug->SizeOfData;
Offset += sizeof(debug_directory) + Debug->SizeOfData;
if (!Debug->AddressOfRawData)
return createStringError(object_error::parse_failed,
"debug directory payload outside of "
"mapped sections not supported");
if (Expected<uint32_t> FilePosOrErr =
virtualAddressToFileAddress(Debug->AddressOfRawData))
Debug->PointerToRawData = *FilePosOrErr;
else
return FilePosOrErr.takeError();
Ptr += sizeof(debug_directory);
Offset += sizeof(debug_directory);
}
// Debug directory found and patched, all done.
return Error::success();

View File

@ -45,6 +45,7 @@ class COFFWriter {
Error write(bool IsBigObj);
Error patchDebugDirectory();
Expected<uint32_t> virtualAddressToFileAddress(uint32_t RVA);
public:
virtual ~COFFWriter() {}