diff options
author | Jake Ehrlich <jakehehrlich@google.com> | 2017-12-19 00:47:30 +0000 |
---|---|---|
committer | Jake Ehrlich <jakehehrlich@google.com> | 2017-12-19 00:47:30 +0000 |
commit | e8437de727ed208cc4a8b7b36b6165dca89fafcb (patch) | |
tree | 49925acbe0c18e22f600ec664772aa06bc11615f /llvm/tools/llvm-objcopy | |
parent | e29c0b88628c0f353d2fa1423525fe4acbd7ad67 (diff) | |
download | bcm5719-llvm-e8437de727ed208cc4a8b7b36b6165dca89fafcb.tar.gz bcm5719-llvm-e8437de727ed208cc4a8b7b36b6165dca89fafcb.zip |
[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
Diffstat (limited to 'llvm/tools/llvm-objcopy')
-rw-r--r-- | llvm/tools/llvm-objcopy/Object.cpp | 12 | ||||
-rw-r--r-- | llvm/tools/llvm-objcopy/Object.h | 15 | ||||
-rw-r--r-- | llvm/tools/llvm-objcopy/llvm-objcopy.cpp | 22 |
3 files changed, 48 insertions, 1 deletions
diff --git a/llvm/tools/llvm-objcopy/Object.cpp b/llvm/tools/llvm-objcopy/Object.cpp index bd5bcd7fc18..d5dfcac40e4 100644 --- a/llvm/tools/llvm-objcopy/Object.cpp +++ b/llvm/tools/llvm-objcopy/Object.cpp @@ -81,6 +81,11 @@ void Section::writeSection(FileOutputBuffer &Out) const { 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. diff --git a/llvm/tools/llvm-objcopy/Object.h b/llvm/tools/llvm-objcopy/Object.h index 9f98c04ad9b..b04b0c1a641 100644 --- a/llvm/tools/llvm-objcopy/Object.h +++ b/llvm/tools/llvm-objcopy/Object.h @@ -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; diff --git a/llvm/tools/llvm-objcopy/llvm-objcopy.cpp b/llvm/tools/llvm-objcopy/llvm-objcopy.cpp index 9d60ae42639..20ce93bb40e 100644 --- a/llvm/tools/llvm-objcopy/llvm-objcopy.cpp +++ b/llvm/tools/llvm-objcopy/llvm-objcopy.cpp @@ -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(const ELFObjectFile<ELFT> &ObjFile) { 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(const ELFObjectFile<ELFT> &ObjFile) { } 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()); } |