1 //===- Object.h -------------------------------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #ifndef LLVM_TOOLS_OBJCOPY_OBJECT_H
11 #define LLVM_TOOLS_OBJCOPY_OBJECT_H
13 #include "llvm/ADT/ArrayRef.h"
14 #include "llvm/ADT/StringRef.h"
15 #include "llvm/ADT/Twine.h"
16 #include "llvm/BinaryFormat/ELF.h"
17 #include "llvm/MC/StringTableBuilder.h"
18 #include "llvm/Object/ELFObjectFile.h"
19 #include "llvm/Support/FileOutputBuffer.h"
20 #include "llvm/Support/JamCRC.h"
29 enum class DebugCompressionType
;
35 class OwnedDataSection
;
36 class StringTableSection
;
37 class SymbolTableSection
;
38 class RelocationSection
;
39 class DynamicRelocationSection
;
40 class GnuDebugLinkSection
;
42 class SectionIndexSection
;
43 class CompressedSection
;
44 class DecompressedSection
;
49 class SectionTableRef
{
50 MutableArrayRef
<std::unique_ptr
<SectionBase
>> Sections
;
53 using iterator
= pointee_iterator
<std::unique_ptr
<SectionBase
> *>;
55 explicit SectionTableRef(MutableArrayRef
<std::unique_ptr
<SectionBase
>> Secs
)
57 SectionTableRef(const SectionTableRef
&) = default;
59 iterator
begin() { return iterator(Sections
.data()); }
60 iterator
end() { return iterator(Sections
.data() + Sections
.size()); }
62 SectionBase
*getSection(uint32_t Index
, Twine ErrMsg
);
65 T
*getSectionOfType(uint32_t Index
, Twine IndexErrMsg
, Twine TypeErrMsg
);
68 enum ElfType
{ ELFT_ELF32LE
, ELFT_ELF64LE
, ELFT_ELF32BE
, ELFT_ELF64BE
};
70 // This type keeps track of the machine info for various architectures. This
71 // lets us map architecture names to ELF types and the e_machine value of the
79 class SectionVisitor
{
81 virtual ~SectionVisitor();
83 virtual void visit(const Section
&Sec
) = 0;
84 virtual void visit(const OwnedDataSection
&Sec
) = 0;
85 virtual void visit(const StringTableSection
&Sec
) = 0;
86 virtual void visit(const SymbolTableSection
&Sec
) = 0;
87 virtual void visit(const RelocationSection
&Sec
) = 0;
88 virtual void visit(const DynamicRelocationSection
&Sec
) = 0;
89 virtual void visit(const GnuDebugLinkSection
&Sec
) = 0;
90 virtual void visit(const GroupSection
&Sec
) = 0;
91 virtual void visit(const SectionIndexSection
&Sec
) = 0;
92 virtual void visit(const CompressedSection
&Sec
) = 0;
93 virtual void visit(const DecompressedSection
&Sec
) = 0;
96 class SectionWriter
: public SectionVisitor
{
101 virtual ~SectionWriter(){};
103 void visit(const Section
&Sec
) override
;
104 void visit(const OwnedDataSection
&Sec
) override
;
105 void visit(const StringTableSection
&Sec
) override
;
106 void visit(const DynamicRelocationSection
&Sec
) override
;
107 virtual void visit(const SymbolTableSection
&Sec
) override
= 0;
108 virtual void visit(const RelocationSection
&Sec
) override
= 0;
109 virtual void visit(const GnuDebugLinkSection
&Sec
) override
= 0;
110 virtual void visit(const GroupSection
&Sec
) override
= 0;
111 virtual void visit(const SectionIndexSection
&Sec
) override
= 0;
112 virtual void visit(const CompressedSection
&Sec
) override
= 0;
113 virtual void visit(const DecompressedSection
&Sec
) override
= 0;
115 explicit SectionWriter(Buffer
&Buf
) : Out(Buf
) {}
118 template <class ELFT
> class ELFSectionWriter
: public SectionWriter
{
120 using Elf_Word
= typename
ELFT::Word
;
121 using Elf_Rel
= typename
ELFT::Rel
;
122 using Elf_Rela
= typename
ELFT::Rela
;
123 using Elf_Sym
= typename
ELFT::Sym
;
126 virtual ~ELFSectionWriter() {}
127 void visit(const SymbolTableSection
&Sec
) override
;
128 void visit(const RelocationSection
&Sec
) override
;
129 void visit(const GnuDebugLinkSection
&Sec
) override
;
130 void visit(const GroupSection
&Sec
) override
;
131 void visit(const SectionIndexSection
&Sec
) override
;
132 void visit(const CompressedSection
&Sec
) override
;
133 void visit(const DecompressedSection
&Sec
) override
;
135 explicit ELFSectionWriter(Buffer
&Buf
) : SectionWriter(Buf
) {}
138 #define MAKE_SEC_WRITER_FRIEND \
139 friend class SectionWriter; \
140 template <class ELFT> friend class ELFSectionWriter;
142 class BinarySectionWriter
: public SectionWriter
{
144 virtual ~BinarySectionWriter() {}
146 void visit(const SymbolTableSection
&Sec
) override
;
147 void visit(const RelocationSection
&Sec
) override
;
148 void visit(const GnuDebugLinkSection
&Sec
) override
;
149 void visit(const GroupSection
&Sec
) override
;
150 void visit(const SectionIndexSection
&Sec
) override
;
151 void visit(const CompressedSection
&Sec
) override
;
152 void visit(const DecompressedSection
&Sec
) override
;
154 explicit BinarySectionWriter(Buffer
&Buf
) : SectionWriter(Buf
) {}
157 // The class Buffer abstracts out the common interface of FileOutputBuffer and
158 // WritableMemoryBuffer so that the hierarchy of Writers depends on this
159 // abstract interface and doesn't depend on a particular implementation.
160 // TODO: refactor the buffer classes in LLVM to enable us to use them here
167 virtual void allocate(size_t Size
) = 0;
168 virtual uint8_t *getBufferStart() = 0;
169 virtual Error
commit() = 0;
171 explicit Buffer(StringRef Name
) : Name(Name
) {}
172 StringRef
getName() const { return Name
; }
175 class FileBuffer
: public Buffer
{
176 std::unique_ptr
<FileOutputBuffer
> Buf
;
179 void allocate(size_t Size
) override
;
180 uint8_t *getBufferStart() override
;
181 Error
commit() override
;
183 explicit FileBuffer(StringRef FileName
) : Buffer(FileName
) {}
186 class MemBuffer
: public Buffer
{
187 std::unique_ptr
<WritableMemoryBuffer
> Buf
;
190 void allocate(size_t Size
) override
;
191 uint8_t *getBufferStart() override
;
192 Error
commit() override
;
194 explicit MemBuffer(StringRef Name
) : Buffer(Name
) {}
196 std::unique_ptr
<WritableMemoryBuffer
> releaseMemoryBuffer();
206 virtual void finalize() = 0;
207 virtual void write() = 0;
209 Writer(Object
&O
, Buffer
&B
) : Obj(O
), Buf(B
) {}
212 template <class ELFT
> class ELFWriter
: public Writer
{
214 using Elf_Addr
= typename
ELFT::Addr
;
215 using Elf_Shdr
= typename
ELFT::Shdr
;
216 using Elf_Phdr
= typename
ELFT::Phdr
;
217 using Elf_Ehdr
= typename
ELFT::Ehdr
;
219 void initEhdrSegment();
222 void writePhdr(const Segment
&Seg
);
223 void writeShdr(const SectionBase
&Sec
);
227 void writeSectionData();
229 void assignOffsets();
231 std::unique_ptr
<ELFSectionWriter
<ELFT
>> SecWriter
;
233 size_t totalSize() const;
236 virtual ~ELFWriter() {}
237 bool WriteSectionHeaders
= true;
239 void finalize() override
;
240 void write() override
;
241 ELFWriter(Object
&Obj
, Buffer
&Buf
, bool WSH
)
242 : Writer(Obj
, Buf
), WriteSectionHeaders(WSH
) {}
245 class BinaryWriter
: public Writer
{
247 std::unique_ptr
<BinarySectionWriter
> SecWriter
;
253 void finalize() override
;
254 void write() override
;
255 BinaryWriter(Object
&Obj
, Buffer
&Buf
) : Writer(Obj
, Buf
) {}
261 Segment
*ParentSegment
= nullptr;
262 uint64_t HeaderOffset
;
263 uint64_t OriginalOffset
= std::numeric_limits
<uint64_t>::max();
265 bool HasSymbol
= false;
269 uint32_t EntrySize
= 0;
272 uint64_t Link
= ELF::SHN_UNDEF
;
273 uint64_t NameIndex
= 0;
276 uint64_t Type
= ELF::SHT_NULL
;
277 ArrayRef
<uint8_t> OriginalData
;
279 SectionBase() = default;
280 SectionBase(const SectionBase
&) = default;
282 virtual ~SectionBase() = default;
284 virtual void initialize(SectionTableRef SecTable
);
285 virtual void finalize();
286 virtual void removeSectionReferences(const SectionBase
*Sec
);
287 virtual void removeSymbols(function_ref
<bool(const Symbol
&)> ToRemove
);
288 virtual void accept(SectionVisitor
&Visitor
) const = 0;
289 virtual void markSymbols();
294 struct SectionCompare
{
295 bool operator()(const SectionBase
*Lhs
, const SectionBase
*Rhs
) const {
296 // Some sections might have the same address if one of them is empty. To
297 // fix this we can use the lexicographic ordering on ->Addr and the
298 // address of the actully stored section.
299 if (Lhs
->OriginalOffset
== Rhs
->OriginalOffset
)
301 return Lhs
->OriginalOffset
< Rhs
->OriginalOffset
;
305 std::set
<const SectionBase
*, SectionCompare
> Sections
;
306 ArrayRef
<uint8_t> Contents
;
319 uint64_t OriginalOffset
;
320 Segment
*ParentSegment
= nullptr;
322 explicit Segment(ArrayRef
<uint8_t> Data
) : Contents(Data
) {}
325 const SectionBase
*firstSection() const {
326 if (!Sections
.empty())
327 return *Sections
.begin();
331 void removeSection(const SectionBase
*Sec
) { Sections
.erase(Sec
); }
332 void addSection(const SectionBase
*Sec
) { Sections
.insert(Sec
); }
335 class Section
: public SectionBase
{
336 MAKE_SEC_WRITER_FRIEND
338 ArrayRef
<uint8_t> Contents
;
339 SectionBase
*LinkSection
= nullptr;
342 explicit Section(ArrayRef
<uint8_t> Data
) : Contents(Data
) {}
344 void accept(SectionVisitor
&Visitor
) const override
;
345 void removeSectionReferences(const SectionBase
*Sec
) override
;
346 void initialize(SectionTableRef SecTable
) override
;
347 void finalize() override
;
350 class OwnedDataSection
: public SectionBase
{
351 MAKE_SEC_WRITER_FRIEND
353 std::vector
<uint8_t> Data
;
356 OwnedDataSection(StringRef SecName
, ArrayRef
<uint8_t> Data
)
357 : Data(std::begin(Data
), std::end(Data
)) {
358 Name
= SecName
.str();
359 Type
= ELF::SHT_PROGBITS
;
361 OriginalOffset
= std::numeric_limits
<uint64_t>::max();
364 void accept(SectionVisitor
&Sec
) const override
;
367 class CompressedSection
: public SectionBase
{
368 MAKE_SEC_WRITER_FRIEND
370 DebugCompressionType CompressionType
;
371 uint64_t DecompressedSize
;
372 uint64_t DecompressedAlign
;
373 SmallVector
<char, 128> CompressedData
;
376 CompressedSection(const SectionBase
&Sec
,
377 DebugCompressionType CompressionType
);
378 CompressedSection(ArrayRef
<uint8_t> CompressedData
, uint64_t DecompressedSize
,
379 uint64_t DecompressedAlign
);
381 uint64_t getDecompressedSize() const { return DecompressedSize
; }
382 uint64_t getDecompressedAlign() const { return DecompressedAlign
; }
384 void accept(SectionVisitor
&Visitor
) const override
;
386 static bool classof(const SectionBase
*S
) {
387 return (S
->Flags
& ELF::SHF_COMPRESSED
) ||
388 (StringRef(S
->Name
).startswith(".zdebug"));
392 class DecompressedSection
: public SectionBase
{
393 MAKE_SEC_WRITER_FRIEND
396 explicit DecompressedSection(const CompressedSection
&Sec
)
398 Size
= Sec
.getDecompressedSize();
399 Align
= Sec
.getDecompressedAlign();
400 Flags
= (Flags
& ~ELF::SHF_COMPRESSED
);
401 if (StringRef(Name
).startswith(".zdebug"))
402 Name
= "." + Name
.substr(2);
405 void accept(SectionVisitor
&Visitor
) const override
;
408 // There are two types of string tables that can exist, dynamic and not dynamic.
409 // In the dynamic case the string table is allocated. Changing a dynamic string
410 // table would mean altering virtual addresses and thus the memory image. So
411 // dynamic string tables should not have an interface to modify them or
412 // reconstruct them. This type lets us reconstruct a string table. To avoid
413 // this class being used for dynamic string tables (which has happened) the
414 // classof method checks that the particular instance is not allocated. This
415 // then agrees with the makeSection method used to construct most sections.
416 class StringTableSection
: public SectionBase
{
417 MAKE_SEC_WRITER_FRIEND
419 StringTableBuilder StrTabBuilder
;
422 StringTableSection() : StrTabBuilder(StringTableBuilder::ELF
) {
423 Type
= ELF::SHT_STRTAB
;
426 void addString(StringRef Name
);
427 uint32_t findIndex(StringRef Name
) const;
428 void finalize() override
;
429 void accept(SectionVisitor
&Visitor
) const override
;
431 static bool classof(const SectionBase
*S
) {
432 if (S
->Flags
& ELF::SHF_ALLOC
)
434 return S
->Type
== ELF::SHT_STRTAB
;
438 // Symbols have a st_shndx field that normally stores an index but occasionally
439 // stores a different special value. This enum keeps track of what the st_shndx
440 // field means. Most of the values are just copies of the special SHN_* values.
441 // SYMBOL_SIMPLE_INDEX means that the st_shndx is just an index of a section.
442 enum SymbolShndxType
{
443 SYMBOL_SIMPLE_INDEX
= 0,
444 SYMBOL_ABS
= ELF::SHN_ABS
,
445 SYMBOL_COMMON
= ELF::SHN_COMMON
,
446 SYMBOL_HEXAGON_SCOMMON
= ELF::SHN_HEXAGON_SCOMMON
,
447 SYMBOL_HEXAGON_SCOMMON_2
= ELF::SHN_HEXAGON_SCOMMON_2
,
448 SYMBOL_HEXAGON_SCOMMON_4
= ELF::SHN_HEXAGON_SCOMMON_4
,
449 SYMBOL_HEXAGON_SCOMMON_8
= ELF::SHN_HEXAGON_SCOMMON_8
,
450 SYMBOL_XINDEX
= ELF::SHN_XINDEX
,
455 SectionBase
*DefinedIn
= nullptr;
456 SymbolShndxType ShndxType
;
464 bool Referenced
= false;
466 uint16_t getShndx() const;
469 class SectionIndexSection
: public SectionBase
{
470 MAKE_SEC_WRITER_FRIEND
473 std::vector
<uint32_t> Indexes
;
474 SymbolTableSection
*Symbols
= nullptr;
477 virtual ~SectionIndexSection() {}
478 void addIndex(uint32_t Index
) {
479 Indexes
.push_back(Index
);
482 void setSymTab(SymbolTableSection
*SymTab
) { Symbols
= SymTab
; }
483 void initialize(SectionTableRef SecTable
) override
;
484 void finalize() override
;
485 void accept(SectionVisitor
&Visitor
) const override
;
487 SectionIndexSection() {
488 Name
= ".symtab_shndx";
491 Type
= ELF::SHT_SYMTAB_SHNDX
;
495 class SymbolTableSection
: public SectionBase
{
496 MAKE_SEC_WRITER_FRIEND
498 void setStrTab(StringTableSection
*StrTab
) { SymbolNames
= StrTab
; }
499 void assignIndices();
502 std::vector
<std::unique_ptr
<Symbol
>> Symbols
;
503 StringTableSection
*SymbolNames
= nullptr;
504 SectionIndexSection
*SectionIndexTable
= nullptr;
506 using SymPtr
= std::unique_ptr
<Symbol
>;
509 SymbolTableSection() { Type
= ELF::SHT_SYMTAB
; }
511 void addSymbol(Twine Name
, uint8_t Bind
, uint8_t Type
, SectionBase
*DefinedIn
,
512 uint64_t Value
, uint8_t Visibility
, uint16_t Shndx
,
514 void prepareForLayout();
515 // An 'empty' symbol table still contains a null symbol.
516 bool empty() const { return Symbols
.size() == 1; }
517 void setShndxTable(SectionIndexSection
*ShndxTable
) {
518 SectionIndexTable
= ShndxTable
;
520 const SectionIndexSection
*getShndxTable() const { return SectionIndexTable
; }
521 const SectionBase
*getStrTab() const { return SymbolNames
; }
522 const Symbol
*getSymbolByIndex(uint32_t Index
) const;
523 Symbol
*getSymbolByIndex(uint32_t Index
);
524 void updateSymbols(function_ref
<void(Symbol
&)> Callable
);
526 void removeSectionReferences(const SectionBase
*Sec
) override
;
527 void initialize(SectionTableRef SecTable
) override
;
528 void finalize() override
;
529 void accept(SectionVisitor
&Visitor
) const override
;
530 void removeSymbols(function_ref
<bool(const Symbol
&)> ToRemove
) override
;
532 static bool classof(const SectionBase
*S
) {
533 return S
->Type
== ELF::SHT_SYMTAB
;
538 Symbol
*RelocSymbol
= nullptr;
544 // All relocation sections denote relocations to apply to another section.
545 // However, some relocation sections use a dynamic symbol table and others use
546 // a regular symbol table. Because the types of the two symbol tables differ in
547 // our system (because they should behave differently) we can't uniformly
548 // represent all relocations with the same base class if we expose an interface
549 // that mentions the symbol table type. So we split the two base types into two
550 // different classes, one which handles the section the relocation is applied to
551 // and another which handles the symbol table type. The symbol table type is
552 // taken as a type parameter to the class (see RelocSectionWithSymtabBase).
553 class RelocationSectionBase
: public SectionBase
{
555 SectionBase
*SecToApplyRel
= nullptr;
558 const SectionBase
*getSection() const { return SecToApplyRel
; }
559 void setSection(SectionBase
*Sec
) { SecToApplyRel
= Sec
; }
561 static bool classof(const SectionBase
*S
) {
562 return S
->Type
== ELF::SHT_REL
|| S
->Type
== ELF::SHT_RELA
;
566 // Takes the symbol table type to use as a parameter so that we can deduplicate
567 // that code between the two symbol table types.
568 template <class SymTabType
>
569 class RelocSectionWithSymtabBase
: public RelocationSectionBase
{
570 SymTabType
*Symbols
= nullptr;
571 void setSymTab(SymTabType
*SymTab
) { Symbols
= SymTab
; }
574 RelocSectionWithSymtabBase() = default;
577 void removeSectionReferences(const SectionBase
*Sec
) override
;
578 void initialize(SectionTableRef SecTable
) override
;
579 void finalize() override
;
582 class RelocationSection
583 : public RelocSectionWithSymtabBase
<SymbolTableSection
> {
584 MAKE_SEC_WRITER_FRIEND
586 std::vector
<Relocation
> Relocations
;
589 void addRelocation(Relocation Rel
) { Relocations
.push_back(Rel
); }
590 void accept(SectionVisitor
&Visitor
) const override
;
591 void 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 initialize(SectionTableRef SecTable
) override
{};
624 void accept(SectionVisitor
&) const override
;
625 void finalize() override
;
626 void 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
;
664 static bool classof(const SectionBase
*S
) {
665 if (!(S
->Flags
& ELF::SHF_ALLOC
))
667 return S
->Type
== ELF::SHT_REL
|| S
->Type
== ELF::SHT_RELA
;
671 class GnuDebugLinkSection
: public SectionBase
{
672 MAKE_SEC_WRITER_FRIEND
678 void init(StringRef File
, StringRef Data
);
681 // If we add this section from an external source we can use this ctor.
682 explicit GnuDebugLinkSection(StringRef File
);
683 void accept(SectionVisitor
&Visitor
) const override
;
689 virtual std::unique_ptr
<Object
> create() const = 0;
692 using object::Binary
;
693 using object::ELFFile
;
694 using object::ELFObjectFile
;
695 using object::OwningBinary
;
697 template <class ELFT
> class BinaryELFBuilder
{
698 using Elf_Sym
= typename
ELFT::Sym
;
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
;
792 StringTableSection
*SectionNames
= nullptr;
793 SymbolTableSection
*SymbolTable
= nullptr;
794 SectionIndexSection
*SectionIndexTable
= nullptr;
797 SectionTableRef
sections() { return SectionTableRef(Sections
); }
798 ConstRange
<SectionBase
> sections() const {
799 return make_pointee_range(Sections
);
801 Range
<Segment
> segments() { return make_pointee_range(Segments
); }
802 ConstRange
<Segment
> segments() const { return make_pointee_range(Segments
); }
804 void removeSections(std::function
<bool(const SectionBase
&)> ToRemove
);
805 void removeSymbols(function_ref
<bool(const Symbol
&)> ToRemove
);
806 template <class T
, class... Ts
> T
&addSection(Ts
&&... Args
) {
807 auto Sec
= llvm::make_unique
<T
>(std::forward
<Ts
>(Args
)...);
808 auto Ptr
= Sec
.get();
809 Sections
.emplace_back(std::move(Sec
));
810 Ptr
->Index
= Sections
.size();
813 Segment
&addSegment(ArrayRef
<uint8_t> Data
) {
814 Segments
.emplace_back(llvm::make_unique
<Segment
>(Data
));
815 return *Segments
.back();
818 } // end namespace objcopy
819 } // end namespace llvm
821 #endif // LLVM_TOOLS_OBJCOPY_OBJECT_H