Skip to content

Commit

Permalink
ObjCopy: support --dump-section on COFF
Browse files Browse the repository at this point in the history
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
  • Loading branch information
compnerd committed May 12, 2023
1 parent 0245dc9 commit 00e6d0e
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 8 deletions.
29 changes: 29 additions & 0 deletions llvm/lib/ObjCopy/COFF/COFFObjcopy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
16 changes: 8 additions & 8 deletions llvm/lib/ObjCopy/ConfigManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand Down
35 changes: 35 additions & 0 deletions llvm/test/tools/llvm-objcopy/COFF/dump-section.test
Original file line number Diff line number Diff line change
@@ -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:
...

0 comments on commit 00e6d0e

Please sign in to comment.