1 //===- Object.h -------------------------------------------------*- C++ -*-===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #ifndef LLVM_TOOLS_OBJCOPY_OBJECT_H
10 #define LLVM_TOOLS_OBJCOPY_OBJECT_H
13 #include "CopyConfig.h"
14 #include "llvm/ADT/ArrayRef.h"
15 #include "llvm/ADT/StringRef.h"
16 #include "llvm/ADT/Twine.h"
17 #include "llvm/BinaryFormat/ELF.h"
18 #include "llvm/MC/StringTableBuilder.h"
19 #include "llvm/Object/ELFObjectFile.h"
20 #include "llvm/Support/FileOutputBuffer.h"
21 #include "llvm/Support/JamCRC.h"
30 enum class DebugCompressionType
;
36 class OwnedDataSection
;
37 class StringTableSection
;
38 class SymbolTableSection
;
39 class RelocationSection
;
40 class DynamicRelocationSection
;
41 class GnuDebugLinkSection
;
43 class SectionIndexSection
;
44 class CompressedSection
;
45 class DecompressedSection
;
50 class SectionTableRef
{
51 MutableArrayRef
<std::unique_ptr
<SectionBase
>> Sections
;
54 using iterator
= pointee_iterator
<std::unique_ptr
<SectionBase
> *>;
56 explicit SectionTableRef(MutableArrayRef
<std::unique_ptr
<SectionBase
>> Secs
)
58 SectionTableRef(const SectionTableRef
&) = default;
60 iterator
begin() { return iterator(Sections
.data()); }
61 iterator
end() { return iterator(Sections
.data() + Sections
.size()); }
63 SectionBase
*getSection(uint32_t Index
, Twine ErrMsg
);
66 T
*getSectionOfType(uint32_t Index
, Twine IndexErrMsg
, Twine TypeErrMsg
);
69 enum ElfType
{ ELFT_ELF32LE
, ELFT_ELF64LE
, ELFT_ELF32BE
, ELFT_ELF64BE
};
71 class SectionVisitor
{
73 virtual ~SectionVisitor() = default;
75 virtual void visit(const Section
&Sec
) = 0;
76 virtual void visit(const OwnedDataSection
&Sec
) = 0;
77 virtual void visit(const StringTableSection
&Sec
) = 0;
78 virtual void visit(const SymbolTableSection
&Sec
) = 0;
79 virtual void visit(const RelocationSection
&Sec
) = 0;
80 virtual void visit(const DynamicRelocationSection
&Sec
) = 0;
81 virtual void visit(const GnuDebugLinkSection
&Sec
) = 0;
82 virtual void visit(const GroupSection
&Sec
) = 0;
83 virtual void visit(const SectionIndexSection
&Sec
) = 0;
84 virtual void visit(const CompressedSection
&Sec
) = 0;
85 virtual void visit(const DecompressedSection
&Sec
) = 0;
88 class MutableSectionVisitor
{
90 virtual ~MutableSectionVisitor() = default;
92 virtual void visit(Section
&Sec
) = 0;
93 virtual void visit(OwnedDataSection
&Sec
) = 0;
94 virtual void visit(StringTableSection
&Sec
) = 0;
95 virtual void visit(SymbolTableSection
&Sec
) = 0;
96 virtual void visit(RelocationSection
&Sec
) = 0;
97 virtual void visit(DynamicRelocationSection
&Sec
) = 0;
98 virtual void visit(GnuDebugLinkSection
&Sec
) = 0;
99 virtual void visit(GroupSection
&Sec
) = 0;
100 virtual void visit(SectionIndexSection
&Sec
) = 0;
101 virtual void visit(CompressedSection
&Sec
) = 0;
102 virtual void visit(DecompressedSection
&Sec
) = 0;
105 class SectionWriter
: public SectionVisitor
{
110 virtual ~SectionWriter(){};
112 void visit(const Section
&Sec
) override
;
113 void visit(const OwnedDataSection
&Sec
) override
;
114 void visit(const StringTableSection
&Sec
) override
;
115 void visit(const DynamicRelocationSection
&Sec
) override
;
116 virtual void visit(const SymbolTableSection
&Sec
) override
= 0;
117 virtual void visit(const RelocationSection
&Sec
) override
= 0;
118 virtual void visit(const GnuDebugLinkSection
&Sec
) override
= 0;
119 virtual void visit(const GroupSection
&Sec
) override
= 0;
120 virtual void visit(const SectionIndexSection
&Sec
) override
= 0;
121 virtual void visit(const CompressedSection
&Sec
) override
= 0;
122 virtual void visit(const DecompressedSection
&Sec
) override
= 0;
124 explicit SectionWriter(Buffer
&Buf
) : Out(Buf
) {}
127 template <class ELFT
> class ELFSectionWriter
: public SectionWriter
{
129 using Elf_Word
= typename
ELFT::Word
;
130 using Elf_Rel
= typename
ELFT::Rel
;
131 using Elf_Rela
= typename
ELFT::Rela
;
132 using Elf_Sym
= typename
ELFT::Sym
;
135 virtual ~ELFSectionWriter() {}
136 void visit(const SymbolTableSection
&Sec
) override
;
137 void visit(const RelocationSection
&Sec
) override
;
138 void visit(const GnuDebugLinkSection
&Sec
) override
;
139 void visit(const GroupSection
&Sec
) override
;
140 void visit(const SectionIndexSection
&Sec
) override
;
141 void visit(const CompressedSection
&Sec
) override
;
142 void visit(const DecompressedSection
&Sec
) override
;
144 explicit ELFSectionWriter(Buffer
&Buf
) : SectionWriter(Buf
) {}
147 template <class ELFT
> class ELFSectionSizer
: public MutableSectionVisitor
{
149 using Elf_Rel
= typename
ELFT::Rel
;
150 using Elf_Rela
= typename
ELFT::Rela
;
151 using Elf_Sym
= typename
ELFT::Sym
;
152 using Elf_Word
= typename
ELFT::Word
;
153 using Elf_Xword
= typename
ELFT::Xword
;
156 void visit(Section
&Sec
) override
;
157 void visit(OwnedDataSection
&Sec
) override
;
158 void visit(StringTableSection
&Sec
) override
;
159 void visit(DynamicRelocationSection
&Sec
) override
;
160 void visit(SymbolTableSection
&Sec
) override
;
161 void visit(RelocationSection
&Sec
) override
;
162 void visit(GnuDebugLinkSection
&Sec
) override
;
163 void visit(GroupSection
&Sec
) override
;
164 void visit(SectionIndexSection
&Sec
) override
;
165 void visit(CompressedSection
&Sec
) override
;
166 void visit(DecompressedSection
&Sec
) override
;
169 #define MAKE_SEC_WRITER_FRIEND \
170 friend class SectionWriter; \
171 template <class ELFT> friend class ELFSectionWriter; \
172 template <class ELFT> friend class ELFSectionSizer;
174 class BinarySectionWriter
: public SectionWriter
{
176 virtual ~BinarySectionWriter() {}
178 void visit(const SymbolTableSection
&Sec
) override
;
179 void visit(const RelocationSection
&Sec
) override
;
180 void visit(const GnuDebugLinkSection
&Sec
) override
;
181 void visit(const GroupSection
&Sec
) override
;
182 void visit(const SectionIndexSection
&Sec
) override
;
183 void visit(const CompressedSection
&Sec
) override
;
184 void visit(const DecompressedSection
&Sec
) override
;
186 explicit BinarySectionWriter(Buffer
&Buf
) : SectionWriter(Buf
) {}
196 virtual Error
finalize() = 0;
197 virtual Error
write() = 0;
199 Writer(Object
&O
, Buffer
&B
) : Obj(O
), Buf(B
) {}
202 template <class ELFT
> class ELFWriter
: public Writer
{
204 using Elf_Addr
= typename
ELFT::Addr
;
205 using Elf_Shdr
= typename
ELFT::Shdr
;
206 using Elf_Phdr
= typename
ELFT::Phdr
;
207 using Elf_Ehdr
= typename
ELFT::Ehdr
;
209 void initEhdrSegment();
212 void writePhdr(const Segment
&Seg
);
213 void writeShdr(const SectionBase
&Sec
);
217 void writeSectionData();
219 void assignOffsets();
221 std::unique_ptr
<ELFSectionWriter
<ELFT
>> SecWriter
;
223 size_t totalSize() const;
226 virtual ~ELFWriter() {}
227 bool WriteSectionHeaders
= true;
229 Error
finalize() override
;
230 Error
write() override
;
231 ELFWriter(Object
&Obj
, Buffer
&Buf
, bool WSH
)
232 : Writer(Obj
, Buf
), WriteSectionHeaders(WSH
) {}
235 class BinaryWriter
: public Writer
{
237 std::unique_ptr
<BinarySectionWriter
> SecWriter
;
243 Error
finalize() override
;
244 Error
write() override
;
245 BinaryWriter(Object
&Obj
, Buffer
&Buf
) : Writer(Obj
, Buf
) {}
251 Segment
*ParentSegment
= nullptr;
252 uint64_t HeaderOffset
;
253 uint64_t OriginalOffset
= std::numeric_limits
<uint64_t>::max();
255 bool HasSymbol
= false;
259 uint32_t EntrySize
= 0;
262 uint64_t Link
= ELF::SHN_UNDEF
;
263 uint64_t NameIndex
= 0;
266 uint64_t Type
= ELF::SHT_NULL
;
267 ArrayRef
<uint8_t> OriginalData
;
269 SectionBase() = default;
270 SectionBase(const SectionBase
&) = default;
272 virtual ~SectionBase() = default;
274 virtual void initialize(SectionTableRef SecTable
);
275 virtual void finalize();
276 virtual Error
removeSectionReferences(const SectionBase
*Sec
);
277 virtual Error
removeSymbols(function_ref
<bool(const Symbol
&)> ToRemove
);
278 virtual void accept(SectionVisitor
&Visitor
) const = 0;
279 virtual void accept(MutableSectionVisitor
&Visitor
) = 0;
280 virtual void markSymbols();
285 struct SectionCompare
{
286 bool operator()(const SectionBase
*Lhs
, const SectionBase
*Rhs
) const {
287 // Some sections might have the same address if one of them is empty. To
288 // fix this we can use the lexicographic ordering on ->Addr and the
289 // address of the actully stored section.
290 if (Lhs
->OriginalOffset
== Rhs
->OriginalOffset
)
292 return Lhs
->OriginalOffset
< Rhs
->OriginalOffset
;
296 std::set
<const SectionBase
*, SectionCompare
> Sections
;
309 uint64_t OriginalOffset
;
310 Segment
*ParentSegment
= nullptr;
311 ArrayRef
<uint8_t> Contents
;
313 explicit Segment(ArrayRef
<uint8_t> Data
) : Contents(Data
) {}
316 const SectionBase
*firstSection() const {
317 if (!Sections
.empty())
318 return *Sections
.begin();
322 void removeSection(const SectionBase
*Sec
) { Sections
.erase(Sec
); }
323 void addSection(const SectionBase
*Sec
) { Sections
.insert(Sec
); }
326 class Section
: public SectionBase
{
327 MAKE_SEC_WRITER_FRIEND
329 ArrayRef
<uint8_t> Contents
;
330 SectionBase
*LinkSection
= nullptr;
333 explicit Section(ArrayRef
<uint8_t> Data
) : Contents(Data
) {}
335 void accept(SectionVisitor
&Visitor
) const override
;
336 void accept(MutableSectionVisitor
&Visitor
) override
;
337 Error
removeSectionReferences(const SectionBase
*Sec
) override
;
338 void initialize(SectionTableRef SecTable
) override
;
339 void finalize() override
;
342 class OwnedDataSection
: public SectionBase
{
343 MAKE_SEC_WRITER_FRIEND
345 std::vector
<uint8_t> Data
;
348 OwnedDataSection(StringRef SecName
, ArrayRef
<uint8_t> Data
)
349 : Data(std::begin(Data
), std::end(Data
)) {
350 Name
= SecName
.str();
351 Type
= ELF::SHT_PROGBITS
;
353 OriginalOffset
= std::numeric_limits
<uint64_t>::max();
356 void accept(SectionVisitor
&Sec
) const override
;
357 void accept(MutableSectionVisitor
&Visitor
) override
;
360 class CompressedSection
: public SectionBase
{
361 MAKE_SEC_WRITER_FRIEND
363 DebugCompressionType CompressionType
;
364 uint64_t DecompressedSize
;
365 uint64_t DecompressedAlign
;
366 SmallVector
<char, 128> CompressedData
;
369 CompressedSection(const SectionBase
&Sec
,
370 DebugCompressionType CompressionType
);
371 CompressedSection(ArrayRef
<uint8_t> CompressedData
, uint64_t DecompressedSize
,
372 uint64_t DecompressedAlign
);
374 uint64_t getDecompressedSize() const { return DecompressedSize
; }
375 uint64_t getDecompressedAlign() const { return DecompressedAlign
; }
377 void accept(SectionVisitor
&Visitor
) const override
;
378 void accept(MutableSectionVisitor
&Visitor
) override
;
380 static bool classof(const SectionBase
*S
) {
381 return (S
->Flags
& ELF::SHF_COMPRESSED
) ||
382 (StringRef(S
->Name
).startswith(".zdebug"));
386 class DecompressedSection
: public SectionBase
{
387 MAKE_SEC_WRITER_FRIEND
390 explicit DecompressedSection(const CompressedSection
&Sec
)
392 Size
= Sec
.getDecompressedSize();
393 Align
= Sec
.getDecompressedAlign();
394 Flags
= (Flags
& ~ELF::SHF_COMPRESSED
);
395 if (StringRef(Name
).startswith(".zdebug"))
396 Name
= "." + Name
.substr(2);
399 void accept(SectionVisitor
&Visitor
) const override
;
400 void accept(MutableSectionVisitor
&Visitor
) override
;
403 // There are two types of string tables that can exist, dynamic and not dynamic.
404 // In the dynamic case the string table is allocated. Changing a dynamic string
405 // table would mean altering virtual addresses and thus the memory image. So
406 // dynamic string tables should not have an interface to modify them or
407 // reconstruct them. This type lets us reconstruct a string table. To avoid
408 // this class being used for dynamic string tables (which has happened) the
409 // classof method checks that the particular instance is not allocated. This
410 // then agrees with the makeSection method used to construct most sections.
411 class StringTableSection
: public SectionBase
{
412 MAKE_SEC_WRITER_FRIEND
414 StringTableBuilder StrTabBuilder
;
417 StringTableSection() : StrTabBuilder(StringTableBuilder::ELF
) {
418 Type
= ELF::SHT_STRTAB
;
421 void addString(StringRef Name
);
422 uint32_t findIndex(StringRef Name
) const;
423 void finalize() override
;
424 void accept(SectionVisitor
&Visitor
) const override
;
425 void accept(MutableSectionVisitor
&Visitor
) override
;
427 static bool classof(const SectionBase
*S
) {
428 if (S
->Flags
& ELF::SHF_ALLOC
)
430 return S
->Type
== ELF::SHT_STRTAB
;
434 // Symbols have a st_shndx field that normally stores an index but occasionally
435 // stores a different special value. This enum keeps track of what the st_shndx
436 // field means. Most of the values are just copies of the special SHN_* values.
437 // SYMBOL_SIMPLE_INDEX means that the st_shndx is just an index of a section.
438 enum SymbolShndxType
{
439 SYMBOL_SIMPLE_INDEX
= 0,
440 SYMBOL_ABS
= ELF::SHN_ABS
,
441 SYMBOL_COMMON
= ELF::SHN_COMMON
,
442 SYMBOL_HEXAGON_SCOMMON
= ELF::SHN_HEXAGON_SCOMMON
,
443 SYMBOL_HEXAGON_SCOMMON_2
= ELF::SHN_HEXAGON_SCOMMON_2
,
444 SYMBOL_HEXAGON_SCOMMON_4
= ELF::SHN_HEXAGON_SCOMMON_4
,
445 SYMBOL_HEXAGON_SCOMMON_8
= ELF::SHN_HEXAGON_SCOMMON_8
,
446 SYMBOL_XINDEX
= ELF::SHN_XINDEX
,
451 SectionBase
*DefinedIn
= nullptr;
452 SymbolShndxType ShndxType
;
460 bool Referenced
= false;
462 uint16_t getShndx() const;
463 bool isCommon() const;
466 class SectionIndexSection
: public SectionBase
{
467 MAKE_SEC_WRITER_FRIEND
470 std::vector
<uint32_t> Indexes
;
471 SymbolTableSection
*Symbols
= nullptr;
474 virtual ~SectionIndexSection() {}
475 void addIndex(uint32_t Index
) {
476 Indexes
.push_back(Index
);
479 void setSymTab(SymbolTableSection
*SymTab
) { Symbols
= SymTab
; }
480 void initialize(SectionTableRef SecTable
) override
;
481 void finalize() override
;
482 void accept(SectionVisitor
&Visitor
) const override
;
483 void accept(MutableSectionVisitor
&Visitor
) override
;
485 SectionIndexSection() {
486 Name
= ".symtab_shndx";
489 Type
= ELF::SHT_SYMTAB_SHNDX
;
493 class SymbolTableSection
: public SectionBase
{
494 MAKE_SEC_WRITER_FRIEND
496 void setStrTab(StringTableSection
*StrTab
) { SymbolNames
= StrTab
; }
497 void assignIndices();
500 std::vector
<std::unique_ptr
<Symbol
>> Symbols
;
501 StringTableSection
*SymbolNames
= nullptr;
502 SectionIndexSection
*SectionIndexTable
= nullptr;
504 using SymPtr
= std::unique_ptr
<Symbol
>;
507 SymbolTableSection() { Type
= ELF::SHT_SYMTAB
; }
509 void addSymbol(Twine Name
, uint8_t Bind
, uint8_t Type
, SectionBase
*DefinedIn
,
510 uint64_t Value
, uint8_t Visibility
, uint16_t Shndx
,
512 void prepareForLayout();
513 // An 'empty' symbol table still contains a null symbol.
514 bool empty() const { return Symbols
.size() == 1; }
515 void setShndxTable(SectionIndexSection
*ShndxTable
) {
516 SectionIndexTable
= ShndxTable
;
518 const SectionIndexSection
*getShndxTable() const { return SectionIndexTable
; }
519 const SectionBase
*getStrTab() const { return SymbolNames
; }
520 const Symbol
*getSymbolByIndex(uint32_t Index
) const;
521 Symbol
*getSymbolByIndex(uint32_t Index
);
522 void updateSymbols(function_ref
<void(Symbol
&)> Callable
);
524 Error
removeSectionReferences(const SectionBase
*Sec
) override
;
525 void initialize(SectionTableRef SecTable
) override
;
526 void finalize() override
;
527 void accept(SectionVisitor
&Visitor
) const override
;
528 void accept(MutableSectionVisitor
&Visitor
) override
;
529 Error
removeSymbols(function_ref
<bool(const Symbol
&)> ToRemove
) override
;
531 static bool classof(const SectionBase
*S
) {
532 return S
->Type
== ELF::SHT_SYMTAB
;
537 Symbol
*RelocSymbol
= nullptr;
543 // All relocation sections denote relocations to apply to another section.
544 // However, some relocation sections use a dynamic symbol table and others use
545 // a regular symbol table. Because the types of the two symbol tables differ in
546 // our system (because they should behave differently) we can't uniformly
547 // represent all relocations with the same base class if we expose an interface
548 // that mentions the symbol table type. So we split the two base types into two
549 // different classes, one which handles the section the relocation is applied to
550 // and another which handles the symbol table type. The symbol table type is
551 // taken as a type parameter to the class (see RelocSectionWithSymtabBase).
552 class RelocationSectionBase
: public SectionBase
{
554 SectionBase
*SecToApplyRel
= nullptr;
557 const SectionBase
*getSection() const { return SecToApplyRel
; }
558 void setSection(SectionBase
*Sec
) { SecToApplyRel
= Sec
; }
560 static bool classof(const SectionBase
*S
) {
561 return S
->Type
== ELF::SHT_REL
|| S
->Type
== ELF::SHT_RELA
;
565 // Takes the symbol table type to use as a parameter so that we can deduplicate
566 // that code between the two symbol table types.
567 template <class SymTabType
>
568 class RelocSectionWithSymtabBase
: public RelocationSectionBase
{
569 SymTabType
*Symbols
= nullptr;
570 void setSymTab(SymTabType
*SymTab
) { Symbols
= SymTab
; }
573 RelocSectionWithSymtabBase() = default;
576 Error
removeSectionReferences(const SectionBase
*Sec
) override
;
577 void initialize(SectionTableRef SecTable
) override
;
578 void finalize() override
;
581 class RelocationSection
582 : public RelocSectionWithSymtabBase
<SymbolTableSection
> {
583 MAKE_SEC_WRITER_FRIEND
585 std::vector
<Relocation
> Relocations
;
588 void addRelocation(Relocation Rel
) { Relocations
.push_back(Rel
); }
589 void accept(SectionVisitor
&Visitor
) const override
;
590 void accept(MutableSectionVisitor
&Visitor
) override
;
591 Error
removeSymbols(function_ref
<bool(const Symbol
&)> ToRemove
) override
;
592 void markSymbols() override
;
594 static bool classof(const SectionBase
*S
) {
595 if (S
->Flags
& ELF::SHF_ALLOC
)
597 return S
->Type
== ELF::SHT_REL
|| S
->Type
== ELF::SHT_RELA
;
601 // TODO: The way stripping and groups interact is complicated
602 // and still needs to be worked on.
604 class GroupSection
: public SectionBase
{
605 MAKE_SEC_WRITER_FRIEND
606 const SymbolTableSection
*SymTab
= nullptr;
607 Symbol
*Sym
= nullptr;
608 ELF::Elf32_Word FlagWord
;
609 SmallVector
<SectionBase
*, 3> GroupMembers
;
612 // TODO: Contents is present in several classes of the hierarchy.
613 // This needs to be refactored to avoid duplication.
614 ArrayRef
<uint8_t> Contents
;
616 explicit GroupSection(ArrayRef
<uint8_t> Data
) : Contents(Data
) {}
618 void setSymTab(const SymbolTableSection
*SymTabSec
) { SymTab
= SymTabSec
; }
619 void setSymbol(Symbol
*S
) { Sym
= S
; }
620 void setFlagWord(ELF::Elf32_Word W
) { FlagWord
= W
; }
621 void addMember(SectionBase
*Sec
) { GroupMembers
.push_back(Sec
); }
623 void accept(SectionVisitor
&) const override
;
624 void accept(MutableSectionVisitor
&Visitor
) override
;
625 void finalize() override
;
626 Error
removeSymbols(function_ref
<bool(const Symbol
&)> ToRemove
) override
;
627 void markSymbols() override
;
629 static bool classof(const SectionBase
*S
) {
630 return S
->Type
== ELF::SHT_GROUP
;
634 class DynamicSymbolTableSection
: public Section
{
636 explicit DynamicSymbolTableSection(ArrayRef
<uint8_t> Data
) : Section(Data
) {}
638 static bool classof(const SectionBase
*S
) {
639 return S
->Type
== ELF::SHT_DYNSYM
;
643 class DynamicSection
: public Section
{
645 explicit DynamicSection(ArrayRef
<uint8_t> Data
) : Section(Data
) {}
647 static bool classof(const SectionBase
*S
) {
648 return S
->Type
== ELF::SHT_DYNAMIC
;
652 class DynamicRelocationSection
653 : public RelocSectionWithSymtabBase
<DynamicSymbolTableSection
> {
654 MAKE_SEC_WRITER_FRIEND
657 ArrayRef
<uint8_t> Contents
;
660 explicit DynamicRelocationSection(ArrayRef
<uint8_t> Data
) : Contents(Data
) {}
662 void accept(SectionVisitor
&) const override
;
663 void accept(MutableSectionVisitor
&Visitor
) override
;
665 static bool classof(const SectionBase
*S
) {
666 if (!(S
->Flags
& ELF::SHF_ALLOC
))
668 return S
->Type
== ELF::SHT_REL
|| S
->Type
== ELF::SHT_RELA
;
672 class GnuDebugLinkSection
: public SectionBase
{
673 MAKE_SEC_WRITER_FRIEND
679 void init(StringRef File
, StringRef Data
);
682 // If we add this section from an external source we can use this ctor.
683 explicit GnuDebugLinkSection(StringRef File
);
684 void accept(SectionVisitor
&Visitor
) const override
;
685 void accept(MutableSectionVisitor
&Visitor
) override
;
691 virtual std::unique_ptr
<Object
> create() const = 0;
694 using object::Binary
;
695 using object::ELFFile
;
696 using object::ELFObjectFile
;
697 using object::OwningBinary
;
699 class BinaryELFBuilder
{
701 MemoryBuffer
*MemBuf
;
702 std::unique_ptr
<Object
> Obj
;
704 void initFileHeader();
705 void initHeaderSegment();
706 StringTableSection
*addStrTab();
707 SymbolTableSection
*addSymTab(StringTableSection
*StrTab
);
708 void addData(SymbolTableSection
*SymTab
);
712 BinaryELFBuilder(uint16_t EM
, MemoryBuffer
*MB
)
713 : EMachine(EM
), MemBuf(MB
), Obj(llvm::make_unique
<Object
>()) {}
715 std::unique_ptr
<Object
> build();
718 template <class ELFT
> class ELFBuilder
{
720 using Elf_Addr
= typename
ELFT::Addr
;
721 using Elf_Shdr
= typename
ELFT::Shdr
;
722 using Elf_Word
= typename
ELFT::Word
;
724 const ELFFile
<ELFT
> &ElfFile
;
727 void setParentSegment(Segment
&Child
);
728 void readProgramHeaders();
729 void initGroupSection(GroupSection
*GroupSec
);
730 void initSymbolTable(SymbolTableSection
*SymTab
);
731 void readSectionHeaders();
732 SectionBase
&makeSection(const Elf_Shdr
&Shdr
);
735 ELFBuilder(const ELFObjectFile
<ELFT
> &ElfObj
, Object
&Obj
)
736 : ElfFile(*ElfObj
.getELFFile()), Obj(Obj
) {}
741 class BinaryReader
: public Reader
{
742 const MachineInfo
&MInfo
;
743 MemoryBuffer
*MemBuf
;
746 BinaryReader(const MachineInfo
&MI
, MemoryBuffer
*MB
)
747 : MInfo(MI
), MemBuf(MB
) {}
748 std::unique_ptr
<Object
> create() const override
;
751 class ELFReader
: public Reader
{
755 std::unique_ptr
<Object
> create() const override
;
756 explicit ELFReader(Binary
*B
) : Bin(B
) {}
761 using SecPtr
= std::unique_ptr
<SectionBase
>;
762 using SegPtr
= std::unique_ptr
<Segment
>;
764 std::vector
<SecPtr
> Sections
;
765 std::vector
<SegPtr
> Segments
;
769 using Range
= iterator_range
<
770 pointee_iterator
<typename
std::vector
<std::unique_ptr
<T
>>::iterator
>>;
773 using ConstRange
= iterator_range
<pointee_iterator
<
774 typename
std::vector
<std::unique_ptr
<T
>>::const_iterator
>>;
776 // It is often the case that the ELF header and the program header table are
777 // not present in any segment. This could be a problem during file layout,
778 // because other segments may get assigned an offset where either of the
779 // two should reside, which will effectively corrupt the resulting binary.
780 // Other than that we use these segments to track program header offsets
781 // when they may not follow the ELF header.
782 Segment ElfHdrSegment
;
783 Segment ProgramHdrSegment
;
794 StringTableSection
*SectionNames
= nullptr;
795 SymbolTableSection
*SymbolTable
= nullptr;
796 SectionIndexSection
*SectionIndexTable
= nullptr;
799 SectionTableRef
sections() { return SectionTableRef(Sections
); }
800 ConstRange
<SectionBase
> sections() const {
801 return make_pointee_range(Sections
);
803 Range
<Segment
> segments() { return make_pointee_range(Segments
); }
804 ConstRange
<Segment
> segments() const { return make_pointee_range(Segments
); }
806 Error
removeSections(std::function
<bool(const SectionBase
&)> ToRemove
);
807 Error
removeSymbols(function_ref
<bool(const Symbol
&)> ToRemove
);
808 template <class T
, class... Ts
> T
&addSection(Ts
&&... Args
) {
809 auto Sec
= llvm::make_unique
<T
>(std::forward
<Ts
>(Args
)...);
810 auto Ptr
= Sec
.get();
811 Sections
.emplace_back(std::move(Sec
));
812 Ptr
->Index
= Sections
.size();
815 Segment
&addSegment(ArrayRef
<uint8_t> Data
) {
816 Segments
.emplace_back(llvm::make_unique
<Segment
>(Data
));
817 return *Segments
.back();
821 } // end namespace elf
822 } // end namespace objcopy
823 } // end namespace llvm
825 #endif // LLVM_TOOLS_OBJCOPY_OBJECT_H