diff options
author | Jake Ehrlich <jakehehrlich@google.com> | 2017-11-30 20:14:53 +0000 |
---|---|---|
committer | Jake Ehrlich <jakehehrlich@google.com> | 2017-11-30 20:14:53 +0000 |
commit | ef3b80c57ba7c1c910a1d31548cf51f630913a04 (patch) | |
tree | f32acad3ac4138b7e3e367d4d4fe492b2094026d /llvm/tools/llvm-objcopy/llvm-objcopy.cpp | |
parent | aef1dfc690adc6478efcd059bdbb65d0195082b8 (diff) | |
download | bcm5719-llvm-ef3b80c57ba7c1c910a1d31548cf51f630913a04.tar.gz bcm5719-llvm-ef3b80c57ba7c1c910a1d31548cf51f630913a04.zip |
[llvm-objcopy] Add support for --only-keep/-j and --keep
This change adds support for the --only-keep option and the -j alias as well.
A common use case for these being used together is to dump a specific section's
data. Additionally the --keep option is added (GNU objcopy doesn't have this)
to avoid removing a bunch of things. This allows people to err on the side of
stripping aggressively and then to keep the specific bits that they need for
their application.
Differential Revision: https://reviews.llvm.org/D39021
llvm-svn: 319467
Diffstat (limited to 'llvm/tools/llvm-objcopy/llvm-objcopy.cpp')
-rw-r--r-- | llvm/tools/llvm-objcopy/llvm-objcopy.cpp | 53 |
1 files changed, 53 insertions, 0 deletions
diff --git a/llvm/tools/llvm-objcopy/llvm-objcopy.cpp b/llvm/tools/llvm-objcopy/llvm-objcopy.cpp index 09553e85202..615667bf99a 100644 --- a/llvm/tools/llvm-objcopy/llvm-objcopy.cpp +++ b/llvm/tools/llvm-objcopy/llvm-objcopy.cpp @@ -89,6 +89,13 @@ static cl::opt<bool> StripAll( static cl::opt<bool> StripAllGNU("strip-all-gnu", cl::desc("Removes symbol, relocation, and debug information")); +static cl::list<std::string> Keep("keep", cl::desc("Keep <section>"), + cl::value_desc("section")); +static cl::list<std::string> OnlyKeep("only-keep", + cl::desc("Remove all but <section>"), + cl::value_desc("section")); +static cl::alias OnlyKeepA("j", cl::desc("Alias for only-keep"), + cl::aliasopt(OnlyKeep)); static cl::opt<bool> StripDebug("strip-debug", cl::desc("Removes all debug information")); static cl::opt<bool> StripSections("strip-sections", @@ -150,6 +157,13 @@ void SplitDWOToFile(const ELFObjectFile<ELFT> &ObjFile, StringRef File) { WriteObjectFile(DWOFile, File); } +// 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" +// should keep regardless of a remove. Additionally any removal should respect +// any previous removals. Lastly whether or not something is removed shouldn't +// depend a) on the order the options occur in or b) on some opaque priority +// system. The only priority is that keeps/copies overrule removes. template <class ELFT> void CopyBinary(const ELFObjectFile<ELFT> &ObjFile) { std::unique_ptr<Object<ELFT>> Obj; @@ -166,6 +180,8 @@ void CopyBinary(const ELFObjectFile<ELFT> &ObjFile) { SectionPred RemovePred = [](const SectionBase &) { return false; }; + // Removes: + if (!ToRemove.empty()) { RemovePred = [&](const SectionBase &Sec) { return std::find(std::begin(ToRemove), std::end(ToRemove), Sec.Name) != @@ -234,6 +250,43 @@ void CopyBinary(const ELFObjectFile<ELFT> &ObjFile) { return (Sec.Flags & SHF_ALLOC) == 0; }; + // Explicit copies: + + if (!OnlyKeep.empty()) { + RemovePred = [RemovePred, &Obj](const SectionBase &Sec) { + // Explicitly keep these sections regardless of previous removes. + if (std::find(std::begin(OnlyKeep), std::end(OnlyKeep), Sec.Name) != + std::end(OnlyKeep)) + return false; + + // Allow all implicit removes. + if (RemovePred(Sec)) { + return true; + } + + // Keep special sections. + if (Obj->getSectionHeaderStrTab() == &Sec) { + return false; + } + if (Obj->getSymTab() == &Sec || Obj->getSymTab()->getStrTab() == &Sec) { + return false; + } + // Remove everything else. + return true; + }; + } + + if (!Keep.empty()) { + RemovePred = [RemovePred](const SectionBase &Sec) { + // Explicitly keep these sections regardless of previous removes. + if (std::find(std::begin(Keep), std::end(Keep), Sec.Name) != + std::end(Keep)) + return false; + // Otherwise defer to RemovePred. + return RemovePred(Sec); + }; + } + Obj->removeSections(RemovePred); Obj->finalize(); WriteObjectFile(*Obj, OutputFilename.getValue()); |