[llvm] 00e6d0e - ObjCopy: support `--dump-section` on COFF

Saleem Abdulrasool via llvm-commits llvm-commits at lists.llvm.org
Fri May 12 14:42:31 PDT 2023


Author: Saleem Abdulrasool
Date: 2023-05-12T14:42:06-07:00
New Revision: 00e6d0e9ac5cb42b1878bb57acf2151ab27b389d

URL: https://github.com/llvm/llvm-project/commit/00e6d0e9ac5cb42b1878bb57acf2151ab27b389d
DIFF: https://github.com/llvm/llvm-project/commit/00e6d0e9ac5cb42b1878bb57acf2151ab27b389d.diff

LOG: ObjCopy: support `--dump-section` on COFF

Add support for --dump-section on COFF files. This is helpful for
extracting specific content from an object file on Windows.

Differential Revision: https://reviews.llvm.org/D150305
Reviewed By: @alexander-shaposhnikov, @jhenderson, @hjyamauchi

Added: 
    llvm/test/tools/llvm-objcopy/COFF/dump-section.test

Modified: 
    llvm/lib/ObjCopy/COFF/COFFObjcopy.cpp
    llvm/lib/ObjCopy/ConfigManager.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/ObjCopy/COFF/COFFObjcopy.cpp b/llvm/lib/ObjCopy/COFF/COFFObjcopy.cpp
index 37fb22740dca5..2ea8525ff530a 100644
--- a/llvm/lib/ObjCopy/COFF/COFFObjcopy.cpp
+++ b/llvm/lib/ObjCopy/COFF/COFFObjcopy.cpp
@@ -130,8 +130,37 @@ static uint32_t flagsToCharacteristics(SectionFlag AllFlags, uint32_t OldChar) {
   return NewCharacteristics;
 }
 
+static Error dumpSection(Object &O, StringRef SectionName, StringRef FileName) {
+  for (const coff::Section &Section : O.getSections()) {
+    if (Section.Name != SectionName)
+      continue;
+
+    ArrayRef<uint8_t> Contents = Section.getContents();
+
+    std::unique_ptr<FileOutputBuffer> Buffer;
+    if (auto B = FileOutputBuffer::create(FileName, Contents.size()))
+      Buffer = std::move(*B);
+    else
+      return B.takeError();
+
+    llvm::copy(Contents, Buffer->getBufferStart());
+    if (Error E = Buffer->commit())
+      return E;
+
+    return Error::success();
+  }
+  return createStringError(object_error::parse_failed, "section '%s' not found",
+                           SectionName.str().c_str());
+}
+
 static Error handleArgs(const CommonConfig &Config,
                         const COFFConfig &COFFConfig, Object &Obj) {
+  for (StringRef Op : Config.DumpSection) {
+    auto [Section, File] = Op.split('=');
+    if (Error E = dumpSection(Obj, Section, File))
+      return E;
+  }
+
   // Perform the actual section removals.
   Obj.removeSections([&Config](const Section &Sec) {
     // Contrary to --only-keep-debug, --only-section fully removes sections that

diff  --git a/llvm/lib/ObjCopy/ConfigManager.cpp b/llvm/lib/ObjCopy/ConfigManager.cpp
index 77321829e614b..5b8e2f5dc2003 100644
--- a/llvm/lib/ObjCopy/ConfigManager.cpp
+++ b/llvm/lib/ObjCopy/ConfigManager.cpp
@@ -15,14 +15,14 @@ namespace objcopy {
 
 Expected<const COFFConfig &> ConfigManager::getCOFFConfig() const {
   if (!Common.SplitDWO.empty() || !Common.SymbolsPrefix.empty() ||
-      !Common.AllocSectionsPrefix.empty() || !Common.DumpSection.empty() ||
-      !Common.KeepSection.empty() || !Common.SymbolsToGlobalize.empty() ||
-      !Common.SymbolsToKeep.empty() || !Common.SymbolsToLocalize.empty() ||
-      !Common.SymbolsToWeaken.empty() || !Common.SymbolsToKeepGlobal.empty() ||
-      !Common.SectionsToRename.empty() || !Common.SetSectionAlignment.empty() ||
-      !Common.SetSectionType.empty() || Common.ExtractDWO ||
-      Common.PreserveDates || Common.StripDWO || Common.StripNonAlloc ||
-      Common.StripSections || Common.Weaken || Common.DecompressDebugSections ||
+      !Common.AllocSectionsPrefix.empty() || !Common.KeepSection.empty() ||
+      !Common.SymbolsToGlobalize.empty() || !Common.SymbolsToKeep.empty() ||
+      !Common.SymbolsToLocalize.empty() || !Common.SymbolsToWeaken.empty() ||
+      !Common.SymbolsToKeepGlobal.empty() || !Common.SectionsToRename.empty() ||
+      !Common.SetSectionAlignment.empty() || !Common.SetSectionType.empty() ||
+      Common.ExtractDWO || Common.PreserveDates || Common.StripDWO ||
+      Common.StripNonAlloc || Common.StripSections || Common.Weaken ||
+      Common.DecompressDebugSections ||
       Common.DiscardMode == DiscardType::Locals || !Common.SymbolsToAdd.empty())
     return createStringError(llvm::errc::invalid_argument,
                              "option is not supported for COFF");

diff  --git a/llvm/test/tools/llvm-objcopy/COFF/dump-section.test b/llvm/test/tools/llvm-objcopy/COFF/dump-section.test
new file mode 100644
index 0000000000000..591135af5492f
--- /dev/null
+++ b/llvm/test/tools/llvm-objcopy/COFF/dump-section.test
@@ -0,0 +1,35 @@
+# RUN: yaml2obj %s -o %t.obj
+# RUN: llvm-objcopy --dump-section .data=%t.dat %t.obj
+# RUN: wc -c %t.dat | FileCheck %s --ignore-case -check-prefix CHECK-EMPTY-SIZE
+# RUN: llvm-objcopy --dump-section .text.f=%t.txt %t.obj
+# RUN: od -t x1 %t.txt | FileCheck %s --ignore-case -check-prefix CHECK-TEXT-F
+# RUN: not llvm-objcopy --dump-section non-existent=/dev/null %t.obj 2>&1 | FileCheck %s -check-prefix CHECK-NO-SECTION
+# RUN: not llvm-objcopy --dump-section .text=%T %t.obj 2>&1 | FileCheck -DOBJ=%t.obj -DMSG=%errc_EISDIR %s -check-prefix CHECK-INVALID-DESTINATION
+
+# CHECK-EMPTY-SIZE: 0
+
+# CHECK-TEXT-F: 0000000 b8 20 00 00 00 c3
+
+# CHECK-NO-SECTION: section 'non-existent' not found
+
+# CHECK-INVALID-DESTINATION: error: '[[OBJ]]': [[MSG]]
+
+--- !COFF
+header:
+  Machine:         IMAGE_FILE_MACHINE_AMD64
+  Characteristics: [  ]
+sections:
+  - Name:            .text
+    Characteristics: [ ]
+    Alignment:       4
+    SectionData:     ''
+  - Name:            .data
+    Characteristics: [ ]
+    Alignment:       4
+    SectionData:     ''
+  - Name:            .text.f
+    Characteristics: [ ]
+    Alignment:       16
+    SectionData:     B820000000C3
+symbols:
+...


        


More information about the llvm-commits mailing list