llvm.org GIT mirror llvm / e812fcb
[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 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@321047 91177308-0d34-0410-b5e6-96231b3b80d8 Jake Ehrlich 2 years ago
5 changed file(s) with 121 addition(s) and 1 deletion(s). Raw diff Collapse all Expand all
0 # RUN: yaml2obj %s > %t
1 # RUN: echo 0000 > %t.sec
2 # RUN: llvm-objcopy -R=.test2 -add-section=.test2=%t.sec %t %t2
3 # RUN: llvm-readobj -file-headers -sections -section-data %t2 | FileCheck %s
4
5 !ELF
6 FileHeader:
7 Class: ELFCLASS64
8 Data: ELFDATA2LSB
9 Type: ET_REL
10 Machine: EM_X86_64
11 Sections:
12 - Name: .test1
13 Type: SHT_PROGBITS
14 Flags: [ SHF_ALLOC ]
15 Content: "c3c3c3c3"
16 - Name: .test2
17 Type: SHT_PROGBITS
18 Flags: [ SHF_ALLOC ]
19 Content: "DEADBEEF"
20 - Name: .test3
21 Type: SHT_PROGBITS
22 Flags: [ SHF_ALLOC ]
23 Content: "32323232"
24
25 # CHECK: SectionHeaderCount: 7
26
27 # CHECK: Name: .test1
28 # CHECK: Name: .test3
29 # CHECK: Name: .symtab
30 # CHECK: Name: .strtab
31 # CHECK: Name: .shstrtab
32 # CHECK: Name: .test2
33 # CHECK: SectionData (
34 # CHECK-NEXT: 0000: 30303030
35 # CHECK-NEXT: )
0 # RUN: yaml2obj %s > %t
1 # RUN: llvm-objcopy -O binary -j .test2 %t %t.sec
2 # RUN: llvm-objcopy -R=.test2 %t %t2
3 # RUN: llvm-objcopy -add-section=.test2=%t.sec %t2 %t3
4 # RUN: llvm-readobj -file-headers -sections -section-data %t3 | FileCheck %s
5
6 !ELF
7 FileHeader:
8 Class: ELFCLASS64
9 Data: ELFDATA2LSB
10 Type: ET_REL
11 Machine: EM_X86_64
12 Sections:
13 - Name: .test1
14 Type: SHT_PROGBITS
15 Flags: [ SHF_ALLOC ]
16 Content: "c3c3c3c3"
17 - Name: .test2
18 Type: SHT_PROGBITS
19 Flags: [ SHF_ALLOC ]
20 Content: "DEADBEEF"
21 - Name: .test3
22 Type: SHT_PROGBITS
23 Flags: [ SHF_ALLOC ]
24 Content: "32323232"
25
26 # CHECK: SectionHeaderCount: 7
27
28 # CHECK: Name: .test1
29 # CHECK: Name: .test3
30 # CHECK: Name: .symtab
31 # CHECK: Name: .strtab
32 # CHECK: Name: .shstrtab
33 # CHECK: Name: .test2
34 # CHECK: SectionData (
35 # CHECK-NEXT: 0000: DEADBEEF
36 # CHECK-NEXT: )
7878 return;
7979 uint8_t *Buf = Out.getBufferStart() + Offset;
8080 std::copy(std::begin(Contents), std::end(Contents), Buf);
81 }
82
83 void OwnedDataSection::writeSection(FileOutputBuffer &Out) const {
84 uint8_t *Buf = Out.getBufferStart() + Offset;
85 std::copy(std::begin(Data), std::end(Data), Buf);
8186 }
8287
8388 void StringTableSection::addString(StringRef Name) {
673678 }
674679 // Now finally get rid of them all togethor.
675680 Sections.erase(Iter, std::end(Sections));
681 }
682
683 template
684 void Object::addSection(StringRef SecName, ArrayRef Data) {
685 auto Sec = llvm::make_unique(SecName, Data);
686 Sec->OriginalOffset = ~0ULL;
687 Sections.push_back(std::move(Sec));
676688 }
677689
678690 template void ELFObject::sortSections() {
125125 void writeSection(FileOutputBuffer &Out) const override;
126126 };
127127
128 class OwnedDataSection : public SectionBase {
129 private:
130 std::vector Data;
131
132 public:
133 OwnedDataSection(StringRef SecName, ArrayRef Data)
134 : Data(std::begin(Data), std::end(Data)) {
135 Name = SecName;
136 Type = ELF::SHT_PROGBITS;
137 Size = Data.size();
138 }
139 void writeSection(FileOutputBuffer &Out) const override;
140 };
141
128142 // There are two types of string tables that can exist, dynamic and not dynamic.
129143 // In the dynamic case the string table is allocated. Changing a dynamic string
130144 // table would mean altering virtual addresses and thus the memory image. So
371385 const SymbolTableSection *getSymTab() const { return SymbolTable; }
372386 const SectionBase *getSectionHeaderStrTab() const { return SectionNames; }
373387 void removeSections(std::function ToRemove);
388 void addSection(StringRef SecName, ArrayRef Data);
374389 virtual size_t totalSize() const = 0;
375390 virtual void finalize() = 0;
376391 virtual void write(FileOutputBuffer &Out) const = 0;
112112 cl::desc("Equivalent to extract-dwo on the input file to "
113113 ", then strip-dwo on the input file"),
114114 cl::value_desc("dwo-file"));
115 static cl::list AddSection(
116 "add-section",
117 cl::desc("Make a section named
with the contents of ."),
118 cl::value_desc("section=file"));
115119
116120 using SectionPred = std::function;
117121
173177 Obj = llvm::make_unique>(ObjFile);
174178
175179 if (!SplitDWO.empty())
176 SplitDWOToFile(ObjFile, SplitDWO.getValue());
180 SplitDWOToFile(ObjFile, SplitDWO.getValue());
177181
178182 SectionPred RemovePred = [](const SectionBase &) { return false; };
179183
285289 }
286290
287291 Obj->removeSections(RemovePred);
292
293 if (!AddSection.empty()) {
294 for (const auto &Flag : AddSection) {
295 auto SecPair = StringRef(Flag).split("=");
296 auto SecName = SecPair.first;
297 auto File = SecPair.second;
298 auto BufOrErr = MemoryBuffer::getFile(File);
299 if (!BufOrErr)
300 reportError(File, BufOrErr.getError());
301 auto Buf = std::move(*BufOrErr);
302 auto BufPtr = reinterpret_cast(Buf->getBufferStart());
303 auto BufSize = Buf->getBufferSize();
304 Obj->addSection(SecName, ArrayRef(BufPtr, BufSize));
305 }
306 }
307
288308 Obj->finalize();
289309 WriteObjectFile(*Obj, OutputFilename.getValue());
290310 }