mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-22 18:54:02 +01: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:
parent
f51f69bd75
commit
9f580d4e7a
36
test/tools/llvm-objcopy/add-section-remove.test
Normal file
36
test/tools/llvm-objcopy/add-section-remove.test
Normal 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: )
|
37
test/tools/llvm-objcopy/add-section.test
Normal file
37
test/tools/llvm-objcopy/add-section.test
Normal 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: )
|
@ -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.
|
||||
|
@ -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;
|
||||
|
@ -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());
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user