1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-19 02:52:53 +02:00

[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
This commit is contained in:
Jake Ehrlich 2017-12-19 00:47:30 +00:00
parent f51f69bd75
commit 9f580d4e7a
5 changed files with 121 additions and 1 deletions

View File

@ -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: )

View File

@ -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: )

View File

@ -81,6 +81,11 @@ void Section::writeSection(FileOutputBuffer &Out) const {
std::copy(std::begin(Contents), std::end(Contents), Buf); 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) { void StringTableSection::addString(StringRef Name) {
StrTabBuilder.add(Name); StrTabBuilder.add(Name);
Size = StrTabBuilder.getSize(); Size = StrTabBuilder.getSize();
@ -676,6 +681,13 @@ void Object<ELFT>::removeSections(
Sections.erase(Iter, std::end(Sections)); 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() { template <class ELFT> void ELFObject<ELFT>::sortSections() {
// Put all sections in offset order. Maintain the ordering as closely as // Put all sections in offset order. Maintain the ordering as closely as
// possible while meeting that demand however. // possible while meeting that demand however.

View File

@ -126,6 +126,20 @@ public:
void writeSection(FileOutputBuffer &Out) const override; 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. // 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 // 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 // table would mean altering virtual addresses and thus the memory image. So
@ -372,6 +386,7 @@ public:
const SymbolTableSection *getSymTab() const { return SymbolTable; } const SymbolTableSection *getSymTab() const { return SymbolTable; }
const SectionBase *getSectionHeaderStrTab() const { return SectionNames; } const SectionBase *getSectionHeaderStrTab() const { return SectionNames; }
void removeSections(std::function<bool(const SectionBase &)> ToRemove); void removeSections(std::function<bool(const SectionBase &)> ToRemove);
void addSection(StringRef SecName, ArrayRef<uint8_t> Data);
virtual size_t totalSize() const = 0; virtual size_t totalSize() const = 0;
virtual void finalize() = 0; virtual void finalize() = 0;
virtual void write(FileOutputBuffer &Out) const = 0; virtual void write(FileOutputBuffer &Out) const = 0;

View File

@ -113,6 +113,10 @@ static cl::opt<std::string>
cl::desc("Equivalent to extract-dwo on the input file to " cl::desc("Equivalent to extract-dwo on the input file to "
"<dwo-file>, then strip-dwo on the input file"), "<dwo-file>, then strip-dwo on the input file"),
cl::value_desc("dwo-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)>; 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); Obj = llvm::make_unique<ELFObject<ELFT>>(ObjFile);
if (!SplitDWO.empty()) if (!SplitDWO.empty())
SplitDWOToFile<ELFT>(ObjFile, SplitDWO.getValue()); SplitDWOToFile<ELFT>(ObjFile, SplitDWO.getValue());
SectionPred RemovePred = [](const SectionBase &) { return false; }; SectionPred RemovePred = [](const SectionBase &) { return false; };
@ -286,6 +290,22 @@ template <class ELFT> void CopyBinary(const ELFObjectFile<ELFT> &ObjFile) {
} }
Obj->removeSections(RemovePred); 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(); Obj->finalize();
WriteObjectFile(*Obj, OutputFilename.getValue()); WriteObjectFile(*Obj, OutputFilename.getValue());
} }