[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