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:
parent
f4aa425c92
commit
579a3edad4
52
test/tools/llvm-objcopy/COFF/debug-dir-unmapped.test
Normal file
52
test/tools/llvm-objcopy/COFF/debug-dir-unmapped.test
Normal 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:
|
||||
...
|
68
test/tools/llvm-objcopy/COFF/patch-debug-dir2.test
Normal file
68
test/tools/llvm-objcopy/COFF/patch-debug-dir2.test
Normal 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:
|
||||
...
|
@ -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();
|
||||
|
@ -45,6 +45,7 @@ class COFFWriter {
|
||||
Error write(bool IsBigObj);
|
||||
|
||||
Error patchDebugDirectory();
|
||||
Expected<uint32_t> virtualAddressToFileAddress(uint32_t RVA);
|
||||
|
||||
public:
|
||||
virtual ~COFFWriter() {}
|
||||
|
Loading…
x
Reference in New Issue
Block a user