[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

llvm-svn: 321047
diff --git a/llvm/tools/llvm-objcopy/llvm-objcopy.cpp b/llvm/tools/llvm-objcopy/llvm-objcopy.cpp
index 9d60ae4..20ce93b 100644
--- a/llvm/tools/llvm-objcopy/llvm-objcopy.cpp
+++ b/llvm/tools/llvm-objcopy/llvm-objcopy.cpp
@@ -113,6 +113,10 @@
              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 @@
     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 @@
   }
 
   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());
 }