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/Errc.h"
21 #include "llvm/Support/FileOutputBuffer.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() const { return iterator(Sections
.data()); }
61 iterator
end() const { return iterator(Sections
.data() + Sections
.size()); }
62 size_t size() const { return Sections
.size(); }
64 SectionBase
*getSection(uint32_t Index
, Twine ErrMsg
);
67 T
*getSectionOfType(uint32_t Index
, Twine IndexErrMsg
, Twine TypeErrMsg
);
70 enum ElfType
{ ELFT_ELF32LE
, ELFT_ELF64LE
, ELFT_ELF32BE
, ELFT_ELF64BE
};
72 class SectionVisitor
{
74 virtual ~SectionVisitor() = default;
76 virtual void visit(const Section
&Sec
) = 0;
77 virtual void visit(const OwnedDataSection
&Sec
) = 0;
78 virtual void visit(const StringTableSection
&Sec
) = 0;
79 virtual void visit(const SymbolTableSection
&Sec
) = 0;
80 virtual void visit(const RelocationSection
&Sec
) = 0;
81 virtual void visit(const DynamicRelocationSection
&Sec
) = 0;
82 virtual void visit(const GnuDebugLinkSection
&Sec
) = 0;
83 virtual void visit(const GroupSection
&Sec
) = 0;
84 virtual void visit(const SectionIndexSection
&Sec
) = 0;
85 virtual void visit(const CompressedSection
&Sec
) = 0;
86 virtual void visit(const DecompressedSection
&Sec
) = 0;
89 class MutableSectionVisitor
{
91 virtual ~MutableSectionVisitor() = default;
93 virtual void visit(Section
&Sec
) = 0;
94 virtual void visit(OwnedDataSection
&Sec
) = 0;
95 virtual void visit(StringTableSection
&Sec
) = 0;
96 virtual void visit(SymbolTableSection
&Sec
) = 0;
97 virtual void visit(RelocationSection
&Sec
) = 0;
98 virtual void visit(DynamicRelocationSection
&Sec
) = 0;
99 virtual void visit(GnuDebugLinkSection
&Sec
) = 0;
100 virtual void visit(GroupSection
&Sec
) = 0;
101 virtual void visit(SectionIndexSection
&Sec
) = 0;
102 virtual void visit(CompressedSection
&Sec
) = 0;
103 virtual void visit(DecompressedSection
&Sec
) = 0;
106 class SectionWriter
: public SectionVisitor
{
111 virtual ~SectionWriter() = default;
113 void visit(const Section
&Sec
) override
;
114 void visit(const OwnedDataSection
&Sec
) override
;
115 void visit(const StringTableSection
&Sec
) override
;
116 void visit(const DynamicRelocationSection
&Sec
) override
;
117 virtual void visit(const SymbolTableSection
&Sec
) override
= 0;
118 virtual void visit(const RelocationSection
&Sec
) override
= 0;
119 virtual void visit(const GnuDebugLinkSection
&Sec
) override
= 0;
120 virtual void visit(const GroupSection
&Sec
) override
= 0;
121 virtual void visit(const SectionIndexSection
&Sec
) override
= 0;
122 virtual void visit(const CompressedSection
&Sec
) override
= 0;
123 virtual void visit(const DecompressedSection
&Sec
) override
= 0;
125 explicit SectionWriter(Buffer
&Buf
) : Out(Buf
) {}
128 template <class ELFT
> class ELFSectionWriter
: public SectionWriter
{
130 using Elf_Word
= typename
ELFT::Word
;
131 using Elf_Rel
= typename
ELFT::Rel
;
132 using Elf_Rela
= typename
ELFT::Rela
;
133 using Elf_Sym
= typename
ELFT::Sym
;
136 virtual ~ELFSectionWriter() {}
137 void visit(const SymbolTableSection
&Sec
) override
;
138 void visit(const RelocationSection
&Sec
) override
;
139 void visit(const GnuDebugLinkSection
&Sec
) override
;
140 void visit(const GroupSection
&Sec
) override
;
141 void visit(const SectionIndexSection
&Sec
) override
;
142 void visit(const CompressedSection
&Sec
) override
;
143 void visit(const DecompressedSection
&Sec
) override
;
145 explicit ELFSectionWriter(Buffer
&Buf
) : SectionWriter(Buf
) {}
148 template <class ELFT
> class ELFSectionSizer
: public MutableSectionVisitor
{
150 using Elf_Rel
= typename
ELFT::Rel
;
151 using Elf_Rela
= typename
ELFT::Rela
;
152 using Elf_Sym
= typename
ELFT::Sym
;
153 using Elf_Word
= typename
ELFT::Word
;
154 using Elf_Xword
= typename
ELFT::Xword
;
157 void visit(Section
&Sec
) override
;
158 void visit(OwnedDataSection
&Sec
) override
;
159 void visit(StringTableSection
&Sec
) override
;
160 void visit(DynamicRelocationSection
&Sec
) override
;
161 void visit(SymbolTableSection
&Sec
) override
;
162 void visit(RelocationSection
&Sec
) override
;
163 void visit(GnuDebugLinkSection
&Sec
) override
;
164 void visit(GroupSection
&Sec
) override
;
165 void visit(SectionIndexSection
&Sec
) override
;
166 void visit(CompressedSection
&Sec
) override
;
167 void visit(DecompressedSection
&Sec
) override
;
170 #define MAKE_SEC_WRITER_FRIEND \
171 friend class SectionWriter; \
172 friend class IHexSectionWriterBase; \
173 friend class IHexSectionWriter; \
174 template <class ELFT> friend class ELFSectionWriter; \
175 template <class ELFT> friend class ELFSectionSizer;
177 class BinarySectionWriter
: public SectionWriter
{
179 virtual ~BinarySectionWriter() {}
181 void visit(const SymbolTableSection
&Sec
) override
;
182 void visit(const RelocationSection
&Sec
) override
;
183 void visit(const GnuDebugLinkSection
&Sec
) override
;
184 void visit(const GroupSection
&Sec
) override
;
185 void visit(const SectionIndexSection
&Sec
) override
;
186 void visit(const CompressedSection
&Sec
) override
;
187 void visit(const DecompressedSection
&Sec
) override
;
189 explicit BinarySectionWriter(Buffer
&Buf
) : SectionWriter(Buf
) {}
192 using IHexLineData
= SmallVector
<char, 64>;
195 // Memory address of the record.
197 // Record type (see below).
199 // Record data in hexadecimal form.
202 // Helper method to get file length of the record
203 // including newline character
204 static size_t getLength(size_t DataSize
) {
205 // :LLAAAATT[DD...DD]CC'
206 return DataSize
* 2 + 11;
209 // Gets length of line in a file (getLength + CRLF).
210 static size_t getLineLength(size_t DataSize
) {
211 return getLength(DataSize
) + 2;
214 // Given type, address and data returns line which can
215 // be written to output file.
216 static IHexLineData
getLine(uint8_t Type
, uint16_t Addr
,
217 ArrayRef
<uint8_t> Data
);
219 // Parses the line and returns record if possible.
220 // Line should be trimmed from whitespace characters.
221 static Expected
<IHexRecord
> parse(StringRef Line
);
223 // Calculates checksum of stringified record representation
224 // S must NOT contain leading ':' and trailing whitespace
226 static uint8_t getChecksum(StringRef S
);
229 // Contains data and a 16-bit starting address for the data.
230 // The byte count specifies number of data bytes in the record.
232 // Must occur exactly once per file in the last line of the file.
233 // The data field is empty (thus byte count is 00) and the address
234 // field is typically 0000.
236 // The data field contains a 16-bit segment base address (thus byte
237 // count is always 02) compatible with 80x86 real mode addressing.
238 // The address field (typically 0000) is ignored. The segment address
239 // from the most recent 02 record is multiplied by 16 and added to each
240 // subsequent data record address to form the physical starting address
241 // for the data. This allows addressing up to one megabyte of address
244 // or 80x86 processors, specifies the initial content of the CS:IP
245 // registers. The address field is 0000, the byte count is always 04,
246 // the first two data bytes are the CS value, the latter two are the
249 // Allows for 32 bit addressing (up to 4GiB). The record's address field
250 // is ignored (typically 0000) and its byte count is always 02. The two
251 // data bytes (big endian) specify the upper 16 bits of the 32 bit
252 // absolute address for all subsequent type 00 records
254 // The address field is 0000 (not used) and the byte count is always 04.
255 // The four data bytes represent a 32-bit address value. In the case of
256 // 80386 and higher CPUs, this address is loaded into the EIP register.
258 // We have no other valid types
263 // Base class for IHexSectionWriter. This class implements writing algorithm,
264 // but doesn't actually write records. It is used for output buffer size
265 // calculation in IHexWriter::finalize.
266 class IHexSectionWriterBase
: public BinarySectionWriter
{
267 // 20-bit segment address
268 uint32_t SegmentAddr
= 0;
269 // Extended linear address
270 uint32_t BaseAddr
= 0;
272 // Write segment address corresponding to 'Addr'
273 uint64_t writeSegmentAddr(uint64_t Addr
);
274 // Write extended linear (base) address corresponding to 'Addr'
275 uint64_t writeBaseAddr(uint64_t Addr
);
278 // Offset in the output buffer
281 void writeSection(const SectionBase
*Sec
, ArrayRef
<uint8_t> Data
);
282 virtual void writeData(uint8_t Type
, uint16_t Addr
, ArrayRef
<uint8_t> Data
);
285 explicit IHexSectionWriterBase(Buffer
&Buf
) : BinarySectionWriter(Buf
) {}
287 uint64_t getBufferOffset() const { return Offset
; }
288 void visit(const Section
&Sec
) final
;
289 void visit(const OwnedDataSection
&Sec
) final
;
290 void visit(const StringTableSection
&Sec
) override
;
291 void visit(const DynamicRelocationSection
&Sec
) final
;
292 using BinarySectionWriter::visit
;
295 // Real IHEX section writer
296 class IHexSectionWriter
: public IHexSectionWriterBase
{
298 IHexSectionWriter(Buffer
&Buf
) : IHexSectionWriterBase(Buf
) {}
300 void writeData(uint8_t Type
, uint16_t Addr
, ArrayRef
<uint8_t> Data
) override
;
301 void visit(const StringTableSection
&Sec
) override
;
311 virtual Error
finalize() = 0;
312 virtual Error
write() = 0;
314 Writer(Object
&O
, Buffer
&B
) : Obj(O
), Buf(B
) {}
317 template <class ELFT
> class ELFWriter
: public Writer
{
319 using Elf_Addr
= typename
ELFT::Addr
;
320 using Elf_Shdr
= typename
ELFT::Shdr
;
321 using Elf_Phdr
= typename
ELFT::Phdr
;
322 using Elf_Ehdr
= typename
ELFT::Ehdr
;
324 void initEhdrSegment();
327 void writePhdr(const Segment
&Seg
);
328 void writeShdr(const SectionBase
&Sec
);
332 void writeSectionData();
333 void writeSegmentData();
335 void assignOffsets();
337 std::unique_ptr
<ELFSectionWriter
<ELFT
>> SecWriter
;
339 size_t totalSize() const;
342 virtual ~ELFWriter() {}
343 bool WriteSectionHeaders
;
345 Error
finalize() override
;
346 Error
write() override
;
347 ELFWriter(Object
&Obj
, Buffer
&Buf
, bool WSH
);
350 class BinaryWriter
: public Writer
{
352 std::unique_ptr
<BinarySectionWriter
> SecWriter
;
358 Error
finalize() override
;
359 Error
write() override
;
360 BinaryWriter(Object
&Obj
, Buffer
&Buf
) : Writer(Obj
, Buf
) {}
363 class IHexWriter
: public Writer
{
364 struct SectionCompare
{
365 bool operator()(const SectionBase
*Lhs
, const SectionBase
*Rhs
) const;
368 std::set
<const SectionBase
*, SectionCompare
> Sections
;
371 Error
checkSection(const SectionBase
&Sec
);
372 uint64_t writeEntryPointRecord(uint8_t *Buf
);
373 uint64_t writeEndOfFileRecord(uint8_t *Buf
);
377 Error
finalize() override
;
378 Error
write() override
;
379 IHexWriter(Object
&Obj
, Buffer
&Buf
) : Writer(Obj
, Buf
) {}
385 Segment
*ParentSegment
= nullptr;
386 uint64_t HeaderOffset
;
387 uint64_t OriginalOffset
= std::numeric_limits
<uint64_t>::max();
389 bool HasSymbol
= false;
393 uint32_t EntrySize
= 0;
396 uint64_t Link
= ELF::SHN_UNDEF
;
397 uint64_t NameIndex
= 0;
400 uint64_t Type
= ELF::SHT_NULL
;
401 ArrayRef
<uint8_t> OriginalData
;
403 SectionBase() = default;
404 SectionBase(const SectionBase
&) = default;
406 virtual ~SectionBase() = default;
408 virtual void initialize(SectionTableRef SecTable
);
409 virtual void finalize();
410 // Remove references to these sections. The list of sections must be sorted.
412 removeSectionReferences(bool AllowBrokenLinks
,
413 function_ref
<bool(const SectionBase
*)> ToRemove
);
414 virtual Error
removeSymbols(function_ref
<bool(const Symbol
&)> ToRemove
);
415 virtual void accept(SectionVisitor
&Visitor
) const = 0;
416 virtual void accept(MutableSectionVisitor
&Visitor
) = 0;
417 virtual void markSymbols();
419 replaceSectionReferences(const DenseMap
<SectionBase
*, SectionBase
*> &);
424 struct SectionCompare
{
425 bool operator()(const SectionBase
*Lhs
, const SectionBase
*Rhs
) const {
426 // Some sections might have the same address if one of them is empty. To
427 // fix this we can use the lexicographic ordering on ->Addr and the
428 // address of the actully stored section.
429 if (Lhs
->OriginalOffset
== Rhs
->OriginalOffset
)
431 return Lhs
->OriginalOffset
< Rhs
->OriginalOffset
;
435 std::set
<const SectionBase
*, SectionCompare
> Sections
;
448 uint64_t OriginalOffset
;
449 Segment
*ParentSegment
= nullptr;
450 ArrayRef
<uint8_t> Contents
;
452 explicit Segment(ArrayRef
<uint8_t> Data
) : Contents(Data
) {}
455 const SectionBase
*firstSection() const {
456 if (!Sections
.empty())
457 return *Sections
.begin();
461 void removeSection(const SectionBase
*Sec
) { Sections
.erase(Sec
); }
462 void addSection(const SectionBase
*Sec
) { Sections
.insert(Sec
); }
464 ArrayRef
<uint8_t> getContents() const { return Contents
; }
467 class Section
: public SectionBase
{
468 MAKE_SEC_WRITER_FRIEND
470 ArrayRef
<uint8_t> Contents
;
471 SectionBase
*LinkSection
= nullptr;
474 explicit Section(ArrayRef
<uint8_t> Data
) : Contents(Data
) {}
476 void accept(SectionVisitor
&Visitor
) const override
;
477 void accept(MutableSectionVisitor
&Visitor
) override
;
478 Error
removeSectionReferences(bool AllowBrokenLinks
,
479 function_ref
<bool(const SectionBase
*)> ToRemove
) override
;
480 void initialize(SectionTableRef SecTable
) override
;
481 void finalize() override
;
484 class OwnedDataSection
: public SectionBase
{
485 MAKE_SEC_WRITER_FRIEND
487 std::vector
<uint8_t> Data
;
490 OwnedDataSection(StringRef SecName
, ArrayRef
<uint8_t> Data
)
491 : Data(std::begin(Data
), std::end(Data
)) {
492 Name
= SecName
.str();
493 Type
= ELF::SHT_PROGBITS
;
495 OriginalOffset
= std::numeric_limits
<uint64_t>::max();
498 OwnedDataSection(const Twine
&SecName
, uint64_t SecAddr
, uint64_t SecFlags
,
500 Name
= SecName
.str();
501 Type
= ELF::SHT_PROGBITS
;
504 OriginalOffset
= SecOff
;
507 void appendHexData(StringRef HexData
);
508 void accept(SectionVisitor
&Sec
) const override
;
509 void accept(MutableSectionVisitor
&Visitor
) override
;
512 class CompressedSection
: public SectionBase
{
513 MAKE_SEC_WRITER_FRIEND
515 DebugCompressionType CompressionType
;
516 uint64_t DecompressedSize
;
517 uint64_t DecompressedAlign
;
518 SmallVector
<char, 128> CompressedData
;
521 CompressedSection(const SectionBase
&Sec
,
522 DebugCompressionType CompressionType
);
523 CompressedSection(ArrayRef
<uint8_t> CompressedData
, uint64_t DecompressedSize
,
524 uint64_t DecompressedAlign
);
526 uint64_t getDecompressedSize() const { return DecompressedSize
; }
527 uint64_t getDecompressedAlign() const { return DecompressedAlign
; }
529 void accept(SectionVisitor
&Visitor
) const override
;
530 void accept(MutableSectionVisitor
&Visitor
) override
;
532 static bool classof(const SectionBase
*S
) {
533 return (S
->Flags
& ELF::SHF_COMPRESSED
) ||
534 (StringRef(S
->Name
).startswith(".zdebug"));
538 class DecompressedSection
: public SectionBase
{
539 MAKE_SEC_WRITER_FRIEND
542 explicit DecompressedSection(const CompressedSection
&Sec
)
544 Size
= Sec
.getDecompressedSize();
545 Align
= Sec
.getDecompressedAlign();
546 Flags
= (Flags
& ~ELF::SHF_COMPRESSED
);
547 if (StringRef(Name
).startswith(".zdebug"))
548 Name
= "." + Name
.substr(2);
551 void accept(SectionVisitor
&Visitor
) const override
;
552 void accept(MutableSectionVisitor
&Visitor
) override
;
555 // There are two types of string tables that can exist, dynamic and not dynamic.
556 // In the dynamic case the string table is allocated. Changing a dynamic string
557 // table would mean altering virtual addresses and thus the memory image. So
558 // dynamic string tables should not have an interface to modify them or
559 // reconstruct them. This type lets us reconstruct a string table. To avoid
560 // this class being used for dynamic string tables (which has happened) the
561 // classof method checks that the particular instance is not allocated. This
562 // then agrees with the makeSection method used to construct most sections.
563 class StringTableSection
: public SectionBase
{
564 MAKE_SEC_WRITER_FRIEND
566 StringTableBuilder StrTabBuilder
;
569 StringTableSection() : StrTabBuilder(StringTableBuilder::ELF
) {
570 Type
= ELF::SHT_STRTAB
;
573 void addString(StringRef Name
);
574 uint32_t findIndex(StringRef Name
) const;
575 void prepareForLayout();
576 void accept(SectionVisitor
&Visitor
) const override
;
577 void accept(MutableSectionVisitor
&Visitor
) override
;
579 static bool classof(const SectionBase
*S
) {
580 if (S
->Flags
& ELF::SHF_ALLOC
)
582 return S
->Type
== ELF::SHT_STRTAB
;
586 // Symbols have a st_shndx field that normally stores an index but occasionally
587 // stores a different special value. This enum keeps track of what the st_shndx
588 // field means. Most of the values are just copies of the special SHN_* values.
589 // SYMBOL_SIMPLE_INDEX means that the st_shndx is just an index of a section.
590 enum SymbolShndxType
{
591 SYMBOL_SIMPLE_INDEX
= 0,
592 SYMBOL_ABS
= ELF::SHN_ABS
,
593 SYMBOL_COMMON
= ELF::SHN_COMMON
,
594 SYMBOL_LOPROC
= ELF::SHN_LOPROC
,
595 SYMBOL_AMDGPU_LDS
= ELF::SHN_AMDGPU_LDS
,
596 SYMBOL_HEXAGON_SCOMMON
= ELF::SHN_HEXAGON_SCOMMON
,
597 SYMBOL_HEXAGON_SCOMMON_2
= ELF::SHN_HEXAGON_SCOMMON_2
,
598 SYMBOL_HEXAGON_SCOMMON_4
= ELF::SHN_HEXAGON_SCOMMON_4
,
599 SYMBOL_HEXAGON_SCOMMON_8
= ELF::SHN_HEXAGON_SCOMMON_8
,
600 SYMBOL_HIPROC
= ELF::SHN_HIPROC
,
601 SYMBOL_LOOS
= ELF::SHN_LOOS
,
602 SYMBOL_HIOS
= ELF::SHN_HIOS
,
603 SYMBOL_XINDEX
= ELF::SHN_XINDEX
,
608 SectionBase
*DefinedIn
= nullptr;
609 SymbolShndxType ShndxType
;
617 bool Referenced
= false;
619 uint16_t getShndx() const;
620 bool isCommon() const;
623 class SectionIndexSection
: public SectionBase
{
624 MAKE_SEC_WRITER_FRIEND
627 std::vector
<uint32_t> Indexes
;
628 SymbolTableSection
*Symbols
= nullptr;
631 virtual ~SectionIndexSection() {}
632 void addIndex(uint32_t Index
) {
634 Indexes
.push_back(Index
);
637 void reserve(size_t NumSymbols
) {
638 Indexes
.reserve(NumSymbols
);
639 Size
= NumSymbols
* 4;
641 void setSymTab(SymbolTableSection
*SymTab
) { Symbols
= SymTab
; }
642 void initialize(SectionTableRef SecTable
) override
;
643 void finalize() override
;
644 void accept(SectionVisitor
&Visitor
) const override
;
645 void accept(MutableSectionVisitor
&Visitor
) override
;
647 SectionIndexSection() {
648 Name
= ".symtab_shndx";
651 Type
= ELF::SHT_SYMTAB_SHNDX
;
655 class SymbolTableSection
: public SectionBase
{
656 MAKE_SEC_WRITER_FRIEND
658 void setStrTab(StringTableSection
*StrTab
) { SymbolNames
= StrTab
; }
659 void assignIndices();
662 std::vector
<std::unique_ptr
<Symbol
>> Symbols
;
663 StringTableSection
*SymbolNames
= nullptr;
664 SectionIndexSection
*SectionIndexTable
= nullptr;
666 using SymPtr
= std::unique_ptr
<Symbol
>;
669 SymbolTableSection() { Type
= ELF::SHT_SYMTAB
; }
671 void addSymbol(Twine Name
, uint8_t Bind
, uint8_t Type
, SectionBase
*DefinedIn
,
672 uint64_t Value
, uint8_t Visibility
, uint16_t Shndx
,
673 uint64_t SymbolSize
);
674 void prepareForLayout();
675 // An 'empty' symbol table still contains a null symbol.
676 bool empty() const { return Symbols
.size() == 1; }
677 void setShndxTable(SectionIndexSection
*ShndxTable
) {
678 SectionIndexTable
= ShndxTable
;
680 const SectionIndexSection
*getShndxTable() const { return SectionIndexTable
; }
681 void fillShndxTable();
682 const SectionBase
*getStrTab() const { return SymbolNames
; }
683 const Symbol
*getSymbolByIndex(uint32_t Index
) const;
684 Symbol
*getSymbolByIndex(uint32_t Index
);
685 void updateSymbols(function_ref
<void(Symbol
&)> Callable
);
687 Error
removeSectionReferences(bool AllowBrokenLinks
,
688 function_ref
<bool(const SectionBase
*)> ToRemove
) override
;
689 void initialize(SectionTableRef SecTable
) override
;
690 void finalize() override
;
691 void accept(SectionVisitor
&Visitor
) const override
;
692 void accept(MutableSectionVisitor
&Visitor
) override
;
693 Error
removeSymbols(function_ref
<bool(const Symbol
&)> ToRemove
) override
;
694 void replaceSectionReferences(
695 const DenseMap
<SectionBase
*, SectionBase
*> &FromTo
) override
;
697 static bool classof(const SectionBase
*S
) {
698 return S
->Type
== ELF::SHT_SYMTAB
;
703 Symbol
*RelocSymbol
= nullptr;
709 // All relocation sections denote relocations to apply to another section.
710 // However, some relocation sections use a dynamic symbol table and others use
711 // a regular symbol table. Because the types of the two symbol tables differ in
712 // our system (because they should behave differently) we can't uniformly
713 // represent all relocations with the same base class if we expose an interface
714 // that mentions the symbol table type. So we split the two base types into two
715 // different classes, one which handles the section the relocation is applied to
716 // and another which handles the symbol table type. The symbol table type is
717 // taken as a type parameter to the class (see RelocSectionWithSymtabBase).
718 class RelocationSectionBase
: public SectionBase
{
720 SectionBase
*SecToApplyRel
= nullptr;
723 const SectionBase
*getSection() const { return SecToApplyRel
; }
724 void setSection(SectionBase
*Sec
) { SecToApplyRel
= Sec
; }
726 static bool classof(const SectionBase
*S
) {
727 return S
->Type
== ELF::SHT_REL
|| S
->Type
== ELF::SHT_RELA
;
731 // Takes the symbol table type to use as a parameter so that we can deduplicate
732 // that code between the two symbol table types.
733 template <class SymTabType
>
734 class RelocSectionWithSymtabBase
: public RelocationSectionBase
{
735 void setSymTab(SymTabType
*SymTab
) { Symbols
= SymTab
; }
738 RelocSectionWithSymtabBase() = default;
740 SymTabType
*Symbols
= nullptr;
743 void initialize(SectionTableRef SecTable
) override
;
744 void finalize() override
;
747 class RelocationSection
748 : public RelocSectionWithSymtabBase
<SymbolTableSection
> {
749 MAKE_SEC_WRITER_FRIEND
751 std::vector
<Relocation
> Relocations
;
754 void addRelocation(Relocation Rel
) { Relocations
.push_back(Rel
); }
755 void accept(SectionVisitor
&Visitor
) const override
;
756 void accept(MutableSectionVisitor
&Visitor
) override
;
757 Error
removeSectionReferences(bool AllowBrokenLinks
,
758 function_ref
<bool(const SectionBase
*)> ToRemove
) override
;
759 Error
removeSymbols(function_ref
<bool(const Symbol
&)> ToRemove
) override
;
760 void markSymbols() override
;
761 void replaceSectionReferences(
762 const DenseMap
<SectionBase
*, SectionBase
*> &FromTo
) override
;
764 static bool classof(const SectionBase
*S
) {
765 if (S
->Flags
& ELF::SHF_ALLOC
)
767 return S
->Type
== ELF::SHT_REL
|| S
->Type
== ELF::SHT_RELA
;
771 // TODO: The way stripping and groups interact is complicated
772 // and still needs to be worked on.
774 class GroupSection
: public SectionBase
{
775 MAKE_SEC_WRITER_FRIEND
776 const SymbolTableSection
*SymTab
= nullptr;
777 Symbol
*Sym
= nullptr;
778 ELF::Elf32_Word FlagWord
;
779 SmallVector
<SectionBase
*, 3> GroupMembers
;
782 // TODO: Contents is present in several classes of the hierarchy.
783 // This needs to be refactored to avoid duplication.
784 ArrayRef
<uint8_t> Contents
;
786 explicit GroupSection(ArrayRef
<uint8_t> Data
) : Contents(Data
) {}
788 void setSymTab(const SymbolTableSection
*SymTabSec
) { SymTab
= SymTabSec
; }
789 void setSymbol(Symbol
*S
) { Sym
= S
; }
790 void setFlagWord(ELF::Elf32_Word W
) { FlagWord
= W
; }
791 void addMember(SectionBase
*Sec
) { GroupMembers
.push_back(Sec
); }
793 void accept(SectionVisitor
&) const override
;
794 void accept(MutableSectionVisitor
&Visitor
) override
;
795 void finalize() override
;
796 Error
removeSymbols(function_ref
<bool(const Symbol
&)> ToRemove
) override
;
797 void markSymbols() override
;
798 void replaceSectionReferences(
799 const DenseMap
<SectionBase
*, SectionBase
*> &FromTo
) override
;
801 static bool classof(const SectionBase
*S
) {
802 return S
->Type
== ELF::SHT_GROUP
;
806 class DynamicSymbolTableSection
: public Section
{
808 explicit DynamicSymbolTableSection(ArrayRef
<uint8_t> Data
) : Section(Data
) {}
810 static bool classof(const SectionBase
*S
) {
811 return S
->Type
== ELF::SHT_DYNSYM
;
815 class DynamicSection
: public Section
{
817 explicit DynamicSection(ArrayRef
<uint8_t> Data
) : Section(Data
) {}
819 static bool classof(const SectionBase
*S
) {
820 return S
->Type
== ELF::SHT_DYNAMIC
;
824 class DynamicRelocationSection
825 : public RelocSectionWithSymtabBase
<DynamicSymbolTableSection
> {
826 MAKE_SEC_WRITER_FRIEND
829 ArrayRef
<uint8_t> Contents
;
832 explicit DynamicRelocationSection(ArrayRef
<uint8_t> Data
) : Contents(Data
) {}
834 void accept(SectionVisitor
&) const override
;
835 void accept(MutableSectionVisitor
&Visitor
) override
;
836 Error
removeSectionReferences(
837 bool AllowBrokenLinks
,
838 function_ref
<bool(const SectionBase
*)> ToRemove
) override
;
840 static bool classof(const SectionBase
*S
) {
841 if (!(S
->Flags
& ELF::SHF_ALLOC
))
843 return S
->Type
== ELF::SHT_REL
|| S
->Type
== ELF::SHT_RELA
;
847 class GnuDebugLinkSection
: public SectionBase
{
848 MAKE_SEC_WRITER_FRIEND
854 void init(StringRef File
);
857 // If we add this section from an external source we can use this ctor.
858 explicit GnuDebugLinkSection(StringRef File
, uint32_t PrecomputedCRC
);
859 void accept(SectionVisitor
&Visitor
) const override
;
860 void accept(MutableSectionVisitor
&Visitor
) override
;
866 virtual std::unique_ptr
<Object
> create(bool EnsureSymtab
) const = 0;
869 using object::Binary
;
870 using object::ELFFile
;
871 using object::ELFObjectFile
;
872 using object::OwningBinary
;
874 class BasicELFBuilder
{
876 std::unique_ptr
<Object
> Obj
;
878 void initFileHeader();
879 void initHeaderSegment();
880 StringTableSection
*addStrTab();
881 SymbolTableSection
*addSymTab(StringTableSection
*StrTab
);
885 BasicELFBuilder() : Obj(std::make_unique
<Object
>()) {}
888 class BinaryELFBuilder
: public BasicELFBuilder
{
889 MemoryBuffer
*MemBuf
;
890 uint8_t NewSymbolVisibility
;
891 void addData(SymbolTableSection
*SymTab
);
894 BinaryELFBuilder(MemoryBuffer
*MB
, uint8_t NewSymbolVisibility
)
895 : BasicELFBuilder(), MemBuf(MB
),
896 NewSymbolVisibility(NewSymbolVisibility
) {}
898 std::unique_ptr
<Object
> build();
901 class IHexELFBuilder
: public BasicELFBuilder
{
902 const std::vector
<IHexRecord
> &Records
;
904 void addDataSections();
907 IHexELFBuilder(const std::vector
<IHexRecord
> &Records
)
908 : BasicELFBuilder(), Records(Records
) {}
910 std::unique_ptr
<Object
> build();
913 template <class ELFT
> class ELFBuilder
{
915 using Elf_Addr
= typename
ELFT::Addr
;
916 using Elf_Shdr
= typename
ELFT::Shdr
;
917 using Elf_Word
= typename
ELFT::Word
;
919 const ELFFile
<ELFT
> &ElfFile
;
921 size_t EhdrOffset
= 0;
922 Optional
<StringRef
> ExtractPartition
;
924 void setParentSegment(Segment
&Child
);
925 void readProgramHeaders(const ELFFile
<ELFT
> &HeadersFile
);
926 void initGroupSection(GroupSection
*GroupSec
);
927 void initSymbolTable(SymbolTableSection
*SymTab
);
928 void readSectionHeaders();
929 void readSections(bool EnsureSymtab
);
930 void findEhdrOffset();
931 SectionBase
&makeSection(const Elf_Shdr
&Shdr
);
934 ELFBuilder(const ELFObjectFile
<ELFT
> &ElfObj
, Object
&Obj
,
935 Optional
<StringRef
> ExtractPartition
)
936 : ElfFile(*ElfObj
.getELFFile()), Obj(Obj
),
937 ExtractPartition(ExtractPartition
) {}
939 void build(bool EnsureSymtab
);
942 class BinaryReader
: public Reader
{
943 MemoryBuffer
*MemBuf
;
944 uint8_t NewSymbolVisibility
;
947 BinaryReader(MemoryBuffer
*MB
, const uint8_t NewSymbolVisibility
)
948 : MemBuf(MB
), NewSymbolVisibility(NewSymbolVisibility
) {}
949 std::unique_ptr
<Object
> create(bool EnsureSymtab
) const override
;
952 class IHexReader
: public Reader
{
953 MemoryBuffer
*MemBuf
;
955 Expected
<std::vector
<IHexRecord
>> parse() const;
956 Error
parseError(size_t LineNo
, Error E
) const {
958 ? createFileError(MemBuf
->getBufferIdentifier(), std::move(E
))
959 : createFileError(MemBuf
->getBufferIdentifier(), LineNo
,
962 template <typename
... Ts
>
963 Error
parseError(size_t LineNo
, char const *Fmt
, const Ts
&... Vals
) const {
964 Error E
= createStringError(errc::invalid_argument
, Fmt
, Vals
...);
965 return parseError(LineNo
, std::move(E
));
969 IHexReader(MemoryBuffer
*MB
) : MemBuf(MB
) {}
971 std::unique_ptr
<Object
> create(bool EnsureSymtab
) const override
;
974 class ELFReader
: public Reader
{
976 Optional
<StringRef
> ExtractPartition
;
979 std::unique_ptr
<Object
> create(bool EnsureSymtab
) const override
;
980 explicit ELFReader(Binary
*B
, Optional
<StringRef
> ExtractPartition
)
981 : Bin(B
), ExtractPartition(ExtractPartition
) {}
986 using SecPtr
= std::unique_ptr
<SectionBase
>;
987 using SegPtr
= std::unique_ptr
<Segment
>;
989 std::vector
<SecPtr
> Sections
;
990 std::vector
<SegPtr
> Segments
;
991 std::vector
<SecPtr
> RemovedSections
;
993 static bool sectionIsAlloc(const SectionBase
&Sec
) {
994 return Sec
.Flags
& ELF::SHF_ALLOC
;
999 using Range
= iterator_range
<
1000 pointee_iterator
<typename
std::vector
<std::unique_ptr
<T
>>::iterator
>>;
1003 using ConstRange
= iterator_range
<pointee_iterator
<
1004 typename
std::vector
<std::unique_ptr
<T
>>::const_iterator
>>;
1006 // It is often the case that the ELF header and the program header table are
1007 // not present in any segment. This could be a problem during file layout,
1008 // because other segments may get assigned an offset where either of the
1009 // two should reside, which will effectively corrupt the resulting binary.
1010 // Other than that we use these segments to track program header offsets
1011 // when they may not follow the ELF header.
1012 Segment ElfHdrSegment
;
1013 Segment ProgramHdrSegment
;
1024 bool HadShdrs
= true;
1025 bool MustBeRelocatable
= false;
1026 StringTableSection
*SectionNames
= nullptr;
1027 SymbolTableSection
*SymbolTable
= nullptr;
1028 SectionIndexSection
*SectionIndexTable
= nullptr;
1030 void sortSections();
1031 SectionTableRef
sections() { return SectionTableRef(Sections
); }
1032 ConstRange
<SectionBase
> sections() const {
1033 return make_pointee_range(Sections
);
1036 filter_iterator
<pointee_iterator
<std::vector
<SecPtr
>::const_iterator
>,
1037 decltype(§ionIsAlloc
)>>
1038 allocSections() const {
1039 return make_filter_range(make_pointee_range(Sections
), sectionIsAlloc
);
1042 SectionBase
*findSection(StringRef Name
) {
1044 find_if(Sections
, [&](const SecPtr
&Sec
) { return Sec
->Name
== Name
; });
1045 return SecIt
== Sections
.end() ? nullptr : SecIt
->get();
1047 SectionTableRef
removedSections() { return SectionTableRef(RemovedSections
); }
1049 Range
<Segment
> segments() { return make_pointee_range(Segments
); }
1050 ConstRange
<Segment
> segments() const { return make_pointee_range(Segments
); }
1052 Error
removeSections(bool AllowBrokenLinks
,
1053 std::function
<bool(const SectionBase
&)> ToRemove
);
1054 Error
removeSymbols(function_ref
<bool(const Symbol
&)> ToRemove
);
1055 template <class T
, class... Ts
> T
&addSection(Ts
&&... Args
) {
1056 auto Sec
= std::make_unique
<T
>(std::forward
<Ts
>(Args
)...);
1057 auto Ptr
= Sec
.get();
1058 MustBeRelocatable
|= isa
<RelocationSection
>(*Ptr
);
1059 Sections
.emplace_back(std::move(Sec
));
1060 Ptr
->Index
= Sections
.size();
1063 Segment
&addSegment(ArrayRef
<uint8_t> Data
) {
1064 Segments
.emplace_back(std::make_unique
<Segment
>(Data
));
1065 return *Segments
.back();
1067 bool isRelocatable() const {
1068 return (Type
!= ELF::ET_DYN
&& Type
!= ELF::ET_EXEC
) || MustBeRelocatable
;
1072 } // end namespace elf
1073 } // end namespace objcopy
1074 } // end namespace llvm
1076 #endif // LLVM_TOOLS_OBJCOPY_OBJECT_H