[llvm] r321047 - [llvm-objcopy] Add option to add a progbits section from a file

Jake Ehrlich via llvm-commits llvm-commits at lists.llvm.org
Mon Dec 18 16:47:30 PST 2017


Author: jakehehrlich
Date: Mon Dec 18 16:47:30 2017
New Revision: 321047

URL: http://llvm.org/viewvc/llvm-project?rev=321047&view=rev
Log:
[llvm-objcopy] Add option to add a progbits section from a file

This change adds support for adding progbits sections with contents from a file

Differential Revision: https://reviews.llvm.org/D41212

Added:
    llvm/trunk/test/tools/llvm-objcopy/add-section-remove.test
    llvm/trunk/test/tools/llvm-objcopy/add-section.test
Modified:
    llvm/trunk/tools/llvm-objcopy/Object.cpp
    llvm/trunk/tools/llvm-objcopy/Object.h
    llvm/trunk/tools/llvm-objcopy/llvm-objcopy.cpp

Added: llvm/trunk/test/tools/llvm-objcopy/add-section-remove.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-objcopy/add-section-remove.test?rev=321047&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-objcopy/add-section-remove.test (added)
+++ llvm/trunk/test/tools/llvm-objcopy/add-section-remove.test Mon Dec 18 16:47:30 2017
@@ -0,0 +1,36 @@
+# RUN: yaml2obj %s > %t
+# RUN: echo 0000 > %t.sec
+# RUN: llvm-objcopy -R=.test2 -add-section=.test2=%t.sec %t %t2
+# RUN: llvm-readobj -file-headers -sections -section-data %t2 | FileCheck %s
+
+!ELF
+FileHeader:
+  Class:           ELFCLASS64
+  Data:            ELFDATA2LSB
+  Type:            ET_REL
+  Machine:         EM_X86_64
+Sections:
+  - Name:            .test1
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_ALLOC ]
+    Content:        "c3c3c3c3"
+  - Name:            .test2
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_ALLOC ]
+    Content:        "DEADBEEF"
+  - Name:            .test3
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_ALLOC ]
+    Content:        "32323232"
+
+# CHECK: SectionHeaderCount: 7
+
+# CHECK: Name: .test1
+# CHECK: Name: .test3
+# CHECK: Name: .symtab
+# CHECK: Name: .strtab
+# CHECK: Name: .shstrtab
+# CHECK: Name: .test2
+# CHECK: SectionData (
+# CHECK-NEXT:   0000: 30303030
+# CHECK-NEXT: )

Added: llvm/trunk/test/tools/llvm-objcopy/add-section.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-objcopy/add-section.test?rev=321047&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-objcopy/add-section.test (added)
+++ llvm/trunk/test/tools/llvm-objcopy/add-section.test Mon Dec 18 16:47:30 2017
@@ -0,0 +1,37 @@
+# RUN: yaml2obj %s > %t
+# RUN: llvm-objcopy -O binary -j .test2 %t %t.sec
+# RUN: llvm-objcopy -R=.test2 %t %t2
+# RUN: llvm-objcopy -add-section=.test2=%t.sec %t2 %t3
+# RUN: llvm-readobj -file-headers -sections -section-data %t3 | FileCheck %s
+
+!ELF
+FileHeader:
+  Class:           ELFCLASS64
+  Data:            ELFDATA2LSB
+  Type:            ET_REL
+  Machine:         EM_X86_64
+Sections:
+  - Name:            .test1
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_ALLOC ]
+    Content:        "c3c3c3c3"
+  - Name:            .test2
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_ALLOC ]
+    Content:        "DEADBEEF"
+  - Name:            .test3
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_ALLOC ]
+    Content:        "32323232"
+
+# CHECK: SectionHeaderCount: 7
+
+# CHECK: Name: .test1
+# CHECK: Name: .test3
+# CHECK: Name: .symtab
+# CHECK: Name: .strtab
+# CHECK: Name: .shstrtab
+# CHECK: Name: .test2
+# CHECK: SectionData (
+# CHECK-NEXT:   0000: DEADBEEF
+# CHECK-NEXT: )

Modified: llvm/trunk/tools/llvm-objcopy/Object.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-objcopy/Object.cpp?rev=321047&r1=321046&r2=321047&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-objcopy/Object.cpp (original)
+++ llvm/trunk/tools/llvm-objcopy/Object.cpp Mon Dec 18 16:47:30 2017
@@ -81,6 +81,11 @@ void Section::writeSection(FileOutputBuf
   std::copy(std::begin(Contents), std::end(Contents), Buf);
 }
 
+void OwnedDataSection::writeSection(FileOutputBuffer &Out) const {
+  uint8_t *Buf = Out.getBufferStart() + Offset;
+  std::copy(std::begin(Data), std::end(Data), Buf);
+}
+
 void StringTableSection::addString(StringRef Name) {
   StrTabBuilder.add(Name);
   Size = StrTabBuilder.getSize();
@@ -676,6 +681,13 @@ void Object<ELFT>::removeSections(
   Sections.erase(Iter, std::end(Sections));
 }
 
+template <class ELFT>
+void Object<ELFT>::addSection(StringRef SecName, ArrayRef<uint8_t> Data) {
+  auto Sec = llvm::make_unique<OwnedDataSection>(SecName, Data);
+  Sec->OriginalOffset = ~0ULL;
+  Sections.push_back(std::move(Sec));
+}
+
 template <class ELFT> void ELFObject<ELFT>::sortSections() {
   // Put all sections in offset order. Maintain the ordering as closely as
   // possible while meeting that demand however.

Modified: llvm/trunk/tools/llvm-objcopy/Object.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-objcopy/Object.h?rev=321047&r1=321046&r2=321047&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-objcopy/Object.h (original)
+++ llvm/trunk/tools/llvm-objcopy/Object.h Mon Dec 18 16:47:30 2017
@@ -126,6 +126,20 @@ public:
   void writeSection(FileOutputBuffer &Out) const override;
 };
 
+class OwnedDataSection : public SectionBase {
+private:
+  std::vector<uint8_t> Data;
+
+public:
+  OwnedDataSection(StringRef SecName, ArrayRef<uint8_t> Data)
+      : Data(std::begin(Data), std::end(Data)) {
+    Name = SecName;
+    Type = ELF::SHT_PROGBITS;
+    Size = Data.size();
+  }
+  void writeSection(FileOutputBuffer &Out) const override;
+};
+
 // There are two types of string tables that can exist, dynamic and not dynamic.
 // In the dynamic case the string table is allocated. Changing a dynamic string
 // table would mean altering virtual addresses and thus the memory image. So
@@ -372,6 +386,7 @@ public:
   const SymbolTableSection *getSymTab() const { return SymbolTable; }
   const SectionBase *getSectionHeaderStrTab() const { return SectionNames; }
   void removeSections(std::function<bool(const SectionBase &)> ToRemove);
+  void addSection(StringRef SecName, ArrayRef<uint8_t> Data);
   virtual size_t totalSize() const = 0;
   virtual void finalize() = 0;
   virtual void write(FileOutputBuffer &Out) 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=321047&r1=321046&r2=321047&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-objcopy/llvm-objcopy.cpp (original)
+++ llvm/trunk/tools/llvm-objcopy/llvm-objcopy.cpp Mon Dec 18 16:47:30 2017
@@ -113,6 +113,10 @@ static cl::opt<std::string>
              cl::desc("Equivalent to extract-dwo on the input file to "
                       "<dwo-file>, then strip-dwo on the input file"),
              cl::value_desc("dwo-file"));
+static cl::list<std::string> AddSection(
+    "add-section",
+    cl::desc("Make a section named <section> with the contents of <file>."),
+    cl::value_desc("section=file"));
 
 using SectionPred = std::function<bool(const SectionBase &Sec)>;
 
@@ -174,7 +178,7 @@ template <class ELFT> void CopyBinary(co
     Obj = llvm::make_unique<ELFObject<ELFT>>(ObjFile);
 
   if (!SplitDWO.empty())
-    SplitDWOToFile<ELFT>(ObjFile, SplitDWO.getValue()); 
+    SplitDWOToFile<ELFT>(ObjFile, SplitDWO.getValue());
 
   SectionPred RemovePred = [](const SectionBase &) { return false; };
 
@@ -286,6 +290,22 @@ template <class ELFT> void CopyBinary(co
   }
 
   Obj->removeSections(RemovePred);
+
+  if (!AddSection.empty()) {
+    for (const auto &Flag : AddSection) {
+      auto SecPair = StringRef(Flag).split("=");
+      auto SecName = SecPair.first;
+      auto File = SecPair.second;
+      auto BufOrErr = MemoryBuffer::getFile(File);
+      if (!BufOrErr)
+        reportError(File, BufOrErr.getError());
+      auto Buf = std::move(*BufOrErr);
+      auto BufPtr = reinterpret_cast<const uint8_t *>(Buf->getBufferStart());
+      auto BufSize = Buf->getBufferSize();
+      Obj->addSection(SecName, ArrayRef<uint8_t>(BufPtr, BufSize));
+    }
+  }
+
   Obj->finalize();
   WriteObjectFile(*Obj, OutputFilename.getValue());
 }




More information about the llvm-commits mailing list