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

Martin Storsjö via llvm-commits llvm-commits at lists.llvm.org
Wed Apr 29 10:56:54 PDT 2020


Author: Martin Storsjö
Date: 2020-04-29T20:35:36+03:00
New Revision: 23e35f7c88549de8c76ee5b0643ce5116062563c

URL: https://github.com/llvm/llvm-project/commit/23e35f7c88549de8c76ee5b0643ce5116062563c
DIFF: https://github.com/llvm/llvm-project/commit/23e35f7c88549de8c76ee5b0643ce5116062563c.diff

LOG: [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

Added: 
    llvm/test/tools/llvm-objcopy/COFF/debug-dir-unmapped.test
    llvm/test/tools/llvm-objcopy/COFF/patch-debug-dir2.test

Modified: 
    llvm/tools/llvm-objcopy/COFF/Writer.cpp
    llvm/tools/llvm-objcopy/COFF/Writer.h

Removed: 
    


################################################################################
diff  --git a/llvm/test/tools/llvm-objcopy/COFF/debug-dir-unmapped.test b/llvm/test/tools/llvm-objcopy/COFF/debug-dir-unmapped.test
new file mode 100644
index 000000000000..b7966c14d7d9
--- /dev/null
+++ b/llvm/test/tools/llvm-objcopy/COFF/debug-dir-unmapped.test
@@ -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:
+...

diff  --git a/llvm/test/tools/llvm-objcopy/COFF/patch-debug-dir2.test b/llvm/test/tools/llvm-objcopy/COFF/patch-debug-dir2.test
new file mode 100644
index 000000000000..c18a73a4af3b
--- /dev/null
+++ b/llvm/test/tools/llvm-objcopy/COFF/patch-debug-dir2.test
@@ -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:
+...

diff  --git a/llvm/tools/llvm-objcopy/COFF/Writer.cpp b/llvm/tools/llvm-objcopy/COFF/Writer.cpp
index e35e0474a36d..6b560890a4c1 100644
--- a/llvm/tools/llvm-objcopy/COFF/Writer.cpp
+++ b/llvm/tools/llvm-objcopy/COFF/Writer.cpp
@@ -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();

diff  --git a/llvm/tools/llvm-objcopy/COFF/Writer.h b/llvm/tools/llvm-objcopy/COFF/Writer.h
index 681a8d5e4a66..3c0bdcbd5d6f 100644
--- a/llvm/tools/llvm-objcopy/COFF/Writer.h
+++ b/llvm/tools/llvm-objcopy/COFF/Writer.h
@@ -45,6 +45,7 @@ class COFFWriter {
   Error write(bool IsBigObj);
 
   Error patchDebugDirectory();
+  Expected<uint32_t> virtualAddressToFileAddress(uint32_t RVA);
 
 public:
   virtual ~COFFWriter() {}


        


More information about the llvm-commits mailing list