From 2f1a77872fea53f240b58e8da9e0e1ad54f0eaff Mon Sep 17 00:00:00 2001 From: Billy Laws Date: Wed, 18 Dec 2024 11:16:32 +0000 Subject: [PATCH] [objcopy][COFF] Do not strip .rdata section with --only-keep-debug When not in MinGW mode, the PE debug directory is placed in .rdata by the linker instead of .buildid. In addition to .buildid always explicitly preserve the section containing the debug directory to avoid causing errors later in patchDebugDirectory. --- llvm/lib/ObjCopy/COFF/COFFObjcopy.cpp | 10 ++- .../COFF/Inputs/i386-debug-rdata.yaml | 63 +++++++++++++++++++ .../COFF/only-keep-debug-rdata.test | 45 +++++++++++++ 3 files changed, 117 insertions(+), 1 deletion(-) create mode 100644 llvm/test/tools/llvm-objcopy/COFF/Inputs/i386-debug-rdata.yaml create mode 100644 llvm/test/tools/llvm-objcopy/COFF/only-keep-debug-rdata.test diff --git a/llvm/lib/ObjCopy/COFF/COFFObjcopy.cpp b/llvm/lib/ObjCopy/COFF/COFFObjcopy.cpp index 782d5b2f70c3e..cebcb823e6895 100644 --- a/llvm/lib/ObjCopy/COFF/COFFObjcopy.cpp +++ b/llvm/lib/ObjCopy/COFF/COFFObjcopy.cpp @@ -183,10 +183,18 @@ static Error handleArgs(const CommonConfig &Config, }); if (Config.OnlyKeepDebug) { + const data_directory *DebugDir = + Obj.DataDirectories.size() > DEBUG_DIRECTORY + ? &Obj.DataDirectories[DEBUG_DIRECTORY] + : nullptr; // For --only-keep-debug, we keep all other sections, but remove their // content. The VirtualSize field in the section header is kept intact. - Obj.truncateSections([](const Section &Sec) { + Obj.truncateSections([DebugDir](const Section &Sec) { return !isDebugSection(Sec) && Sec.Name != ".buildid" && + !(DebugDir && DebugDir->Size > 0 && + DebugDir->RelativeVirtualAddress >= Sec.Header.VirtualAddress && + DebugDir->RelativeVirtualAddress < + Sec.Header.VirtualAddress + Sec.Header.SizeOfRawData) && ((Sec.Header.Characteristics & (IMAGE_SCN_CNT_CODE | IMAGE_SCN_CNT_INITIALIZED_DATA)) != 0); }); diff --git a/llvm/test/tools/llvm-objcopy/COFF/Inputs/i386-debug-rdata.yaml b/llvm/test/tools/llvm-objcopy/COFF/Inputs/i386-debug-rdata.yaml new file mode 100644 index 0000000000000..02a6e9db19c19 --- /dev/null +++ b/llvm/test/tools/llvm-objcopy/COFF/Inputs/i386-debug-rdata.yaml @@ -0,0 +1,63 @@ +--- !COFF +OptionalHeader: + AddressOfEntryPoint: 4096 + ImageBase: 268435456 + 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: 8192 + Size: 28 +header: + Machine: IMAGE_FILE_MACHINE_I386 + Characteristics: [ IMAGE_FILE_EXECUTABLE_IMAGE, IMAGE_FILE_32BIT_MACHINE, IMAGE_FILE_DLL ] +sections: + - Name: .text + Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] + VirtualAddress: 4096 + VirtualSize: 18 + SectionData: 5589E58B45108B450C8B450831C05DC20C00 + SizeOfRawData: 512 + - Name: .rdata + Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ] + VirtualAddress: 8192 + VirtualSize: 109 + SectionData: 000000008D6978670000000002000000510000001C2000001C060000525344538B301061671ED0994C4C44205044422E010000002F686F6D652F6D652F446F63756D656E74732F6C6C766D2D6D696E67772F6C6C766D2D70726F6A6563742F6C6C766D2F746573742E70646200 + SizeOfRawData: 512 + - Name: .debug_abbrev + Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ] + VirtualAddress: 12288 + VirtualSize: 78 + SectionData: 011101250E1305030E10171B0E110112060000022E011101120640186E0E030E3A0B3B0B2719360B49133F1900000305000218030E3A0B3B0B49130000042400030E3E0B0B0B0000050F00000000 + SizeOfRawData: 512 + - Name: .debug_info + Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ] + VirtualAddress: 16384 + VirtualSize: 116 + SectionData: 700000000400000000000401000000001D006E000000000000007500000000100010120000000200100010120000000155A5000000BC0000000101B16B00000003029108D70000000101720000000302910CD500000001016B00000003029110D30000000101720000000004CF00000005040500 + SizeOfRawData: 512 + - Name: .debug_line + Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ] + VirtualAddress: 20480 + VirtualSize: 60 + SectionData: 3800000004001E000000010101FB0E0D00010101010000000100000100746573742E6300000000000005020010001001053D0ABA060B2E0204000101 + SizeOfRawData: 512 + - Name: .debug_str + Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ] + VirtualAddress: 24576 + VirtualSize: 217 + SectionData: 636C616E672076657273696F6E2032302E302E30676974202868747470733A2F2F6769746875622E636F6D2F62796C6177732F6C6C766D2D70726F6A6563742E67697420393963353263306236613662396366303765383365656265393364323831333635656165383732332900746573742E63002F686F6D652F6D652F446F63756D656E74732F6C6C766D2D6D696E67772F6C6C766D2D70726F6A6563742F6C6C766D005F5F446C6C4D61696E43525453746172747570403132005F446C6C4D61696E4352545374617274757000696E7400630062006100 + SizeOfRawData: 512 +symbols: [] +... diff --git a/llvm/test/tools/llvm-objcopy/COFF/only-keep-debug-rdata.test b/llvm/test/tools/llvm-objcopy/COFF/only-keep-debug-rdata.test new file mode 100644 index 0000000000000..affd4b65009f4 --- /dev/null +++ b/llvm/test/tools/llvm-objcopy/COFF/only-keep-debug-rdata.test @@ -0,0 +1,45 @@ +RUN: yaml2obj %p/Inputs/i386-debug-rdata.yaml -o %t.in.exe + +RUN: llvm-objcopy --only-keep-debug %t.in.exe %t.out.exe +RUN: llvm-readobj --sections %t.out.exe | FileCheck %s + +Check that all non-debug/rodata (which contains the debug directory in this case) +sections with IMAGE_SCN_CNT_CODE or IMAGE_SCN_CNT_INITIALIZED_DATA are truncated, +and no others. + +CHECK: Section { +CHECK-NEXT: Number: 1 +CHECK-NEXT: Name: .text (2E 74 65 78 74 00 00 00) +CHECK-NEXT: VirtualSize: 0x12 +CHECK-NEXT: VirtualAddress: 0x1000 +CHECK-NEXT: RawDataSize: 0 +CHECK: Section { +CHECK-NEXT: Number: 2 +CHECK-NEXT: Name: .rdata (2E 72 64 61 74 61 00 00) +CHECK-NEXT: VirtualSize: 0x6D +CHECK-NEXT: VirtualAddress: 0x2000 +CHECK-NEXT: RawDataSize: 512 +CHECK: Section { +CHECK-NEXT: Number: 3 +CHECK-NEXT: Name: .debug_abbrev (2F 34 00 00 00 00 00 00) +CHECK-NEXT: VirtualSize: 0x4E +CHECK-NEXT: VirtualAddress: 0x3000 +CHECK-NEXT: RawDataSize: 512 +CHECK: Section { +CHECK-NEXT: Number: 4 +CHECK-NEXT: Name: .debug_info (2F 32 39 00 00 00 00 00) +CHECK-NEXT: VirtualSize: 0x74 +CHECK-NEXT: VirtualAddress: 0x4000 +CHECK-NEXT: RawDataSize: 512 +CHECK: Section { +CHECK-NEXT: Number: 5 +CHECK-NEXT: Name: .debug_line (2F 34 31 00 00 00 00 00) +CHECK-NEXT: VirtualSize: 0x3C +CHECK-NEXT: VirtualAddress: 0x5000 +CHECK-NEXT: RawDataSize: 512 +CHECK: Section { +CHECK-NEXT: Number: 6 +CHECK-NEXT: Name: .debug_str (2F 31 38 00 00 00 00 00) +CHECK-NEXT: VirtualSize: 0xD9 +CHECK-NEXT: VirtualAddress: 0x6000 +CHECK-NEXT: RawDataSize: 512