[llvm] r319467 - [llvm-objcopy] Add support for --only-keep/-j and --keep
Jake Ehrlich via llvm-commits
llvm-commits at lists.llvm.org
Thu Nov 30 12:14:53 PST 2017
Author: jakehehrlich
Date: Thu Nov 30 12:14:53 2017
New Revision: 319467
URL: http://llvm.org/viewvc/llvm-project?rev=319467&view=rev
Log:
[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
Added:
llvm/trunk/test/tools/llvm-objcopy/basic-keep.test
llvm/trunk/test/tools/llvm-objcopy/basic-only-keep.test
llvm/trunk/test/tools/llvm-objcopy/dump-section.test
llvm/trunk/test/tools/llvm-objcopy/explicit-keep-remove.test
llvm/trunk/test/tools/llvm-objcopy/explicit-only-keep-remove.test
llvm/trunk/test/tools/llvm-objcopy/keep-many.test
llvm/trunk/test/tools/llvm-objcopy/keep-only-keep.test
llvm/trunk/test/tools/llvm-objcopy/only-keep-many.test
llvm/trunk/test/tools/llvm-objcopy/only-keep-remove-strtab.test
llvm/trunk/test/tools/llvm-objcopy/only-keep-strip-non-alloc.test
llvm/trunk/test/tools/llvm-objcopy/strip-sections-keep.test
llvm/trunk/test/tools/llvm-objcopy/strip-sections-only-keep.test
Modified:
llvm/trunk/tools/llvm-objcopy/Object.h
llvm/trunk/tools/llvm-objcopy/llvm-objcopy.cpp
Added: llvm/trunk/test/tools/llvm-objcopy/basic-keep.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-objcopy/basic-keep.test?rev=319467&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-objcopy/basic-keep.test (added)
+++ llvm/trunk/test/tools/llvm-objcopy/basic-keep.test Thu Nov 30 12:14:53 2017
@@ -0,0 +1,19 @@
+# RUN: yaml2obj %s > %t
+# RUN: llvm-objcopy -strip-non-alloc -keep=.test %t %t2
+# RUN: llvm-readobj -file-headers -sections %t2 | FileCheck %s
+
+!ELF
+FileHeader:
+ Class: ELFCLASS64
+ Data: ELFDATA2LSB
+ Type: ET_REL
+ Machine: EM_X86_64
+Sections:
+ - Name: .test
+ Type: SHT_PROGBITS
+ Flags: [ ]
+
+# CHECK: SectionHeaderCount: 3
+
+# CHECK: Name: .test
+# CHECK: Name: .shstrtab
Added: llvm/trunk/test/tools/llvm-objcopy/basic-only-keep.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-objcopy/basic-only-keep.test?rev=319467&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-objcopy/basic-only-keep.test (added)
+++ llvm/trunk/test/tools/llvm-objcopy/basic-only-keep.test Thu Nov 30 12:14:53 2017
@@ -0,0 +1,23 @@
+# RUN: yaml2obj %s > %t
+# RUN: llvm-objcopy -only-keep=.test %t %t2
+# RUN: llvm-objcopy -j=.test %t %t3
+# RUN: llvm-readobj -file-headers -sections %t2 | FileCheck %s
+# RUN: diff %t2 %t3
+
+!ELF
+FileHeader:
+ Class: ELFCLASS64
+ Data: ELFDATA2LSB
+ Type: ET_REL
+ Machine: EM_X86_64
+Sections:
+ - Name: .test
+ Type: SHT_PROGBITS
+ Flags: [ ]
+
+# CHECK: SectionHeaderCount: 5
+
+# CHECK: Name: .test
+# CHECK: Name: .symtab
+# CHECK: Name: .strtab
+# CHECK: Name: .shstrtab
Added: llvm/trunk/test/tools/llvm-objcopy/dump-section.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-objcopy/dump-section.test?rev=319467&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-objcopy/dump-section.test (added)
+++ llvm/trunk/test/tools/llvm-objcopy/dump-section.test Thu Nov 30 12:14:53 2017
@@ -0,0 +1,28 @@
+# RUN: yaml2obj %s > %t
+# RUN: llvm-objcopy -O binary -j .text %t %t2
+# RUN: llvm-objcopy -O binary -only-keep .text %t %t3
+# RUN: od -t x1 %t2 | FileCheck %s
+# RUN: wc -c %t2 | FileCheck %s --check-prefix=SIZE
+# RUN: diff %t2 %t3
+
+!ELF
+FileHeader:
+ Class: ELFCLASS64
+ Data: ELFDATA2LSB
+ Type: ET_EXEC
+ Machine: EM_X86_64
+Sections:
+ - Name: .text
+ Type: SHT_PROGBITS
+ Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
+ AddressAlign: 0x0000000000001000
+ Content: "DEADBEEF"
+ProgramHeaders:
+- Type: PT_LOAD
+ Flags: [ PF_X, PF_R ]
+ Sections:
+ - Section: .text
+
+#CHECK: 0000000 de ad be ef
+
+#SIZE: 4
Added: llvm/trunk/test/tools/llvm-objcopy/explicit-keep-remove.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-objcopy/explicit-keep-remove.test?rev=319467&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-objcopy/explicit-keep-remove.test (added)
+++ llvm/trunk/test/tools/llvm-objcopy/explicit-keep-remove.test Thu Nov 30 12:14:53 2017
@@ -0,0 +1,21 @@
+# RUN: yaml2obj %s > %t
+# RUN: llvm-objcopy -R=.test -keep=.test %t %t2
+# RUN: llvm-readobj -file-headers -sections %t2 | FileCheck %s
+
+!ELF
+FileHeader:
+ Class: ELFCLASS64
+ Data: ELFDATA2LSB
+ Type: ET_REL
+ Machine: EM_X86_64
+Sections:
+ - Name: .test
+ Type: SHT_PROGBITS
+ Flags: [ ]
+
+# CHECK: SectionHeaderCount: 5
+
+# CHECK: Name: .test
+# CHECK: Name: .symtab
+# CHECK: Name: .strtab
+# CHECK: Name: .shstrtab
Added: llvm/trunk/test/tools/llvm-objcopy/explicit-only-keep-remove.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-objcopy/explicit-only-keep-remove.test?rev=319467&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-objcopy/explicit-only-keep-remove.test (added)
+++ llvm/trunk/test/tools/llvm-objcopy/explicit-only-keep-remove.test Thu Nov 30 12:14:53 2017
@@ -0,0 +1,21 @@
+# RUN: yaml2obj %s > %t
+# RUN: llvm-objcopy -R=.test -only-keep=.test %t %t2
+# RUN: llvm-readobj -file-headers -sections %t2 | FileCheck %s
+
+!ELF
+FileHeader:
+ Class: ELFCLASS64
+ Data: ELFDATA2LSB
+ Type: ET_REL
+ Machine: EM_X86_64
+Sections:
+ - Name: .test
+ Type: SHT_PROGBITS
+ Flags: [ ]
+
+# CHECK: SectionHeaderCount: 5
+
+# CHECK: Name: .test
+# CHECK: Name: .symtab
+# CHECK: Name: .strtab
+# CHECK: Name: .shstrtab
Added: llvm/trunk/test/tools/llvm-objcopy/keep-many.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-objcopy/keep-many.test?rev=319467&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-objcopy/keep-many.test (added)
+++ llvm/trunk/test/tools/llvm-objcopy/keep-many.test Thu Nov 30 12:14:53 2017
@@ -0,0 +1,27 @@
+# RUN: yaml2obj %s > %t
+# RUN: llvm-objcopy -strip-non-alloc -keep=.test -keep=.test3 %t %t2
+# RUN: llvm-readobj -file-headers -sections %t2 | FileCheck %s
+
+!ELF
+FileHeader:
+ Class: ELFCLASS64
+ Data: ELFDATA2LSB
+ Type: ET_REL
+ Machine: EM_X86_64
+Sections:
+ - Name: .test
+ Type: SHT_PROGBITS
+ Flags: [ ]
+ - Name: .test2
+ Type: SHT_PROGBITS
+ Flags: [ ]
+ - Name: .test3
+ Type: SHT_PROGBITS
+ Flags: [ ]
+
+
+# CHECK: SectionHeaderCount: 4
+
+# CHECK: Name: .test
+# CHECK: Name: .test3
+# CHECK: Name: .shstrtab
Added: llvm/trunk/test/tools/llvm-objcopy/keep-only-keep.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-objcopy/keep-only-keep.test?rev=319467&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-objcopy/keep-only-keep.test (added)
+++ llvm/trunk/test/tools/llvm-objcopy/keep-only-keep.test Thu Nov 30 12:14:53 2017
@@ -0,0 +1,27 @@
+# RUN: yaml2obj %s > %t
+# RUN: llvm-objcopy -keep=.test2 -only-keep=.test %t %t2
+# RUN: llvm-objcopy -j=.test -keep=.test2 %t %t3
+# RUN: llvm-readobj -file-headers -sections %t2 | FileCheck %s
+# RUN: diff %t2 %t3
+
+!ELF
+FileHeader:
+ Class: ELFCLASS64
+ Data: ELFDATA2LSB
+ Type: ET_REL
+ Machine: EM_X86_64
+Sections:
+ - Name: .test
+ Type: SHT_PROGBITS
+ - Name: .test2
+ Type: SHT_PROGBITS
+ - Name: .test3
+ Type: SHT_PROGBITS
+
+# CHECK: SectionHeaderCount: 6
+
+# CHECK: Name: .test
+# CHECK: Name: .test2
+# CHECK: Name: .symtab
+# CHECK: Name: .strtab
+# CHECK: Name: .shstrtab
Added: llvm/trunk/test/tools/llvm-objcopy/only-keep-many.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-objcopy/only-keep-many.test?rev=319467&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-objcopy/only-keep-many.test (added)
+++ llvm/trunk/test/tools/llvm-objcopy/only-keep-many.test Thu Nov 30 12:14:53 2017
@@ -0,0 +1,28 @@
+# RUN: yaml2obj %s > %t
+# RUN: llvm-objcopy -j .test1 -j .test2 %t %t2
+# RUN: llvm-readobj -file-headers -sections %t2 | FileCheck %s
+
+!ELF
+FileHeader:
+ Class: ELFCLASS64
+ Data: ELFDATA2LSB
+ Type: ET_REL
+ Machine: EM_X86_64
+Sections:
+ - Name: .test1
+ Type: SHT_PROGBITS
+ Flags: [ ]
+ - Name: .test2
+ Type: SHT_PROGBITS
+ Flags: [ ]
+ - Name: .test3
+ Type: SHT_PROGBITS
+ Flags: [ ]
+
+# CHECK: SectionHeaderCount: 6
+
+# CHECK: Name: .test1
+# CHECK: Name: .test2
+# CHECK: Name: .symtab
+# CHECK: Name: .strtab
+# CHECK: Name: .shstrtab
Added: llvm/trunk/test/tools/llvm-objcopy/only-keep-remove-strtab.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-objcopy/only-keep-remove-strtab.test?rev=319467&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-objcopy/only-keep-remove-strtab.test (added)
+++ llvm/trunk/test/tools/llvm-objcopy/only-keep-remove-strtab.test Thu Nov 30 12:14:53 2017
@@ -0,0 +1,21 @@
+# RUN: yaml2obj %s > %t
+# RUN: llvm-objcopy -R .symtab -R .strtab -only-keep=.test %t %t2
+# RUN: llvm-objcopy -j=.test -R .strtab -R .symtab %t %t3
+# RUN: llvm-readobj -file-headers -sections %t2 | FileCheck %s
+# RUN: diff %t2 %t3
+
+!ELF
+FileHeader:
+ Class: ELFCLASS64
+ Data: ELFDATA2LSB
+ Type: ET_REL
+ Machine: EM_X86_64
+Sections:
+ - Name: .test
+ Type: SHT_PROGBITS
+ Flags: [ ]
+
+# CHECK: SectionHeaderCount: 3
+
+# CHECK: Name: .test
+# CHECK: Name: .shstrtab
Added: llvm/trunk/test/tools/llvm-objcopy/only-keep-strip-non-alloc.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-objcopy/only-keep-strip-non-alloc.test?rev=319467&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-objcopy/only-keep-strip-non-alloc.test (added)
+++ llvm/trunk/test/tools/llvm-objcopy/only-keep-strip-non-alloc.test Thu Nov 30 12:14:53 2017
@@ -0,0 +1,19 @@
+# RUN: yaml2obj %s > %t
+# RUN: llvm-objcopy -strip-non-alloc -only-keep=.test %t %t2
+# RUN: llvm-readobj -file-headers -sections %t2 | FileCheck %s
+
+!ELF
+FileHeader:
+ Class: ELFCLASS64
+ Data: ELFDATA2LSB
+ Type: ET_REL
+ Machine: EM_X86_64
+Sections:
+ - Name: .test
+ Type: SHT_PROGBITS
+ Flags: [ ]
+
+# CHECK: SectionHeaderCount: 3
+
+# CHECK: Name: .test
+# CHECK: Name: .shstrtab
Added: llvm/trunk/test/tools/llvm-objcopy/strip-sections-keep.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-objcopy/strip-sections-keep.test?rev=319467&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-objcopy/strip-sections-keep.test (added)
+++ llvm/trunk/test/tools/llvm-objcopy/strip-sections-keep.test Thu Nov 30 12:14:53 2017
@@ -0,0 +1,13 @@
+# RUN: yaml2obj %s > %t
+# RUN: llvm-objcopy -strip-sections -keep=.shstrtab %t %t2
+# RUN: od -Ax -t c %t2 | FileCheck %s
+
+!ELF
+FileHeader:
+ Class: ELFCLASS64
+ Data: ELFDATA2LSB
+ Type: ET_REL
+ Machine: EM_X86_64
+Sections:
+
+# CHECK: \0 . s h s t r t a b \0
Added: llvm/trunk/test/tools/llvm-objcopy/strip-sections-only-keep.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-objcopy/strip-sections-only-keep.test?rev=319467&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-objcopy/strip-sections-only-keep.test (added)
+++ llvm/trunk/test/tools/llvm-objcopy/strip-sections-only-keep.test Thu Nov 30 12:14:53 2017
@@ -0,0 +1,20 @@
+# RUN: yaml2obj %s > %t
+# RUN: llvm-objcopy -strip-sections -only-keep=.test %t %t2
+# RUN: od -Ax -t x1 %t2 | FileCheck %s
+# RUN: od -Ax -t c %t2 | FileCheck %s -check-prefix=TEXT
+
+!ELF
+FileHeader:
+ Class: ELFCLASS64
+ Data: ELFDATA2LSB
+ Type: ET_REL
+ Machine: EM_X86_64
+Sections:
+ - Name: .test
+ Type: SHT_PROGBITS
+ Flags: [ ]
+ Content: "DEADBEEF"
+
+# CHECK: de ad be ef
+
+# TEXT-NOT: t e s t
Modified: llvm/trunk/tools/llvm-objcopy/Object.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-objcopy/Object.h?rev=319467&r1=319466&r2=319467&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-objcopy/Object.h (original)
+++ llvm/trunk/tools/llvm-objcopy/Object.h Thu Nov 30 12:14:53 2017
@@ -196,6 +196,7 @@ public:
SectionBase *DefinedIn, uint64_t Value, uint16_t Shndx,
uint64_t Sz);
void addSymbolNames();
+ const SectionBase *getStrTab() const { return SymbolNames; }
const Symbol *getSymbolByIndex(uint32_t Index) const;
void removeSectionReferences(const SectionBase *Sec) override;
void initialize(SectionTableRef SecTable) override;
@@ -368,6 +369,7 @@ public:
Object(const object::ELFObjectFile<ELFT> &Obj);
virtual ~Object() = default;
+ const SymbolTableSection *getSymTab() const { return SymbolTable; }
const SectionBase *getSectionHeaderStrTab() const { return SectionNames; }
void removeSections(std::function<bool(const SectionBase &)> ToRemove);
virtual size_t totalSize() const = 0;
Modified: llvm/trunk/tools/llvm-objcopy/llvm-objcopy.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-objcopy/llvm-objcopy.cpp?rev=319467&r1=319466&r2=319467&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-objcopy/llvm-objcopy.cpp (original)
+++ llvm/trunk/tools/llvm-objcopy/llvm-objcopy.cpp Thu Nov 30 12:14:53 2017
@@ -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<
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
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
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());
More information about the llvm-commits
mailing list