Skip to content
This repository has been archived by the owner on Apr 23, 2020. It is now read-only.

Commit

Permalink
[llvm-objcopy] Add --dump-section
Browse files Browse the repository at this point in the history
Differential Revision: https://reviews.llvm.org/D49979

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@339358 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
paulsemel committed Aug 9, 2018
1 parent 5a282e5 commit 6bbc345
Show file tree
Hide file tree
Showing 5 changed files with 60 additions and 0 deletions.
16 changes: 16 additions & 0 deletions test/tools/llvm-objcopy/dump-section.test
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
# RUN: yaml2obj %s > %t
# RUN: llvm-objcopy -O binary -j .text %t %t2
# RUN: llvm-objcopy -O binary -only-keep .text %t %t3
# RUN: llvm-objcopy --dump-section .text=%t4 %t %t5
# RUN: llvm-objcopy --dump-section .foo=%t6 %t %t7
# RUN: not llvm-objcopy --dump-section .bar=%t8 %t %t9 2>&1 | FileCheck %s --check-prefix=NOBITS
# RUN: od -t x1 %t2 | FileCheck %s
# RUN: od -t x1 %t6 | FileCheck %s --check-prefix=NON-ALLOC
# RUN: wc -c %t2 | FileCheck %s --check-prefix=SIZE
# RUN: diff %t2 %t3
# RUN: diff %t4 %t3

!ELF
FileHeader:
Expand All @@ -17,6 +22,13 @@ Sections:
Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
AddressAlign: 0x0000000000001000
Content: "DEADBEEF"
- Name: .foo
Type: SHT_PROGBITS
Flags: [ SHF_WRITE ]
Content: "CAFE"
- Name: .bar
Type: SHT_NOBITS
Flags: [ SHF_WRITE ]
ProgramHeaders:
- Type: PT_LOAD
Flags: [ PF_X, PF_R ]
Expand All @@ -25,4 +37,8 @@ ProgramHeaders:

#CHECK: 0000000 de ad be ef

#NON-ALLOC: 0000000 ca fe

#SIZE: 4

#NOBITS: Can't dump section ".bar": it has no contents
3 changes: 3 additions & 0 deletions tools/llvm-objcopy/ObjcopyOpts.td
Original file line number Diff line number Diff line change
Expand Up @@ -102,3 +102,6 @@ def strip_unneeded : Flag<["-", "--"], "strip-unneeded">,
HelpText<"Remove all symbols not needed by relocations">;
def keep_file_symbols : Flag<["-", "--"], "keep-file-symbols">,
HelpText<"Do not remove file symbols">;
defm dump_section : Eq<"dump-section">,
MetaVarName<"section=file">,
HelpText<"Dump contents of section named <section> into file <file>">;
3 changes: 3 additions & 0 deletions tools/llvm-objcopy/Object.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -853,6 +853,9 @@ template <class ELFT> void ELFBuilder<ELFT>::readSectionHeaders() {
Sec.Align = Shdr.sh_addralign;
Sec.EntrySize = Shdr.sh_entsize;
Sec.Index = Index++;
Sec.OriginalData =
ArrayRef<uint8_t>(ElfFile.base() + Shdr.sh_offset,
(Shdr.sh_type == SHT_NOBITS) ? 0 : Shdr.sh_size);
}

// If a section index table exists we'll need to initialize it before we
Expand Down
1 change: 1 addition & 0 deletions tools/llvm-objcopy/Object.h
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,7 @@ class SectionBase {
uint64_t Offset = 0;
uint64_t Size = 0;
uint64_t Type = ELF::SHT_NULL;
ArrayRef<uint8_t> OriginalData;

virtual ~SectionBase() = default;

Expand Down
37 changes: 37 additions & 0 deletions tools/llvm-objcopy/llvm-objcopy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ struct CopyConfig {
std::vector<StringRef> Keep;
std::vector<StringRef> OnlyKeep;
std::vector<StringRef> AddSection;
std::vector<StringRef> DumpSection;
std::vector<StringRef> SymbolsToLocalize;
std::vector<StringRef> SymbolsToGlobalize;
std::vector<StringRef> SymbolsToWeaken;
Expand Down Expand Up @@ -323,6 +324,30 @@ static void SplitDWOToFile(const CopyConfig &Config, const Reader &Reader,
Writer->write();
}

static Error dumpSectionToFile(StringRef SecName, StringRef Filename,
Object &Obj) {
for (auto &Sec : Obj.sections()) {
if (Sec.Name == SecName) {
if (Sec.OriginalData.size() == 0)
return make_error<StringError>("Can't dump section \"" + SecName +
"\": it has no contents",
object_error::parse_failed);
Expected<std::unique_ptr<FileOutputBuffer>> BufferOrErr =
FileOutputBuffer::create(Filename, Sec.OriginalData.size());
if (!BufferOrErr)
return BufferOrErr.takeError();
std::unique_ptr<FileOutputBuffer> Buf = std::move(*BufferOrErr);
std::copy(Sec.OriginalData.begin(), Sec.OriginalData.end(),
Buf->getBufferStart());
if (Error E = Buf->commit())
return E;
return Error::success();
}
}
return make_error<StringError>("Section not found",
object_error::parse_failed);
}

// This function handles the high level operations of GNU objcopy including
// handling command line options. It's important to outline certain properties
// we expect to hold of the command line operations. Any operation that "keeps"
Expand Down Expand Up @@ -555,6 +580,16 @@ static void HandleArgs(const CopyConfig &Config, Object &Obj,
}
}

if (!Config.DumpSection.empty()) {
for (const auto &Flag : Config.DumpSection) {
std::pair<StringRef, StringRef> SecPair = Flag.split("=");
StringRef SecName = SecPair.first;
StringRef File = SecPair.second;
if (Error E = dumpSectionToFile(SecName, File, Obj))
reportError(Config.InputFilename, std::move(E));
}
}

if (!Config.AddGnuDebugLink.empty())
Obj.addSection<GnuDebugLinkSection>(Config.AddGnuDebugLink);
}
Expand Down Expand Up @@ -711,6 +746,8 @@ static CopyConfig ParseObjcopyOptions(ArrayRef<const char *> ArgsArr) {
Config.OnlyKeep.push_back(Arg->getValue());
for (auto Arg : InputArgs.filtered(OBJCOPY_add_section))
Config.AddSection.push_back(Arg->getValue());
for (auto Arg : InputArgs.filtered(OBJCOPY_dump_section))
Config.DumpSection.push_back(Arg->getValue());
Config.StripAll = InputArgs.hasArg(OBJCOPY_strip_all);
Config.StripAllGNU = InputArgs.hasArg(OBJCOPY_strip_all_gnu);
Config.StripDebug = InputArgs.hasArg(OBJCOPY_strip_debug);
Expand Down

0 comments on commit 6bbc345

Please sign in to comment.