1 //===- ELFObject.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_LIB_OBJCOPY_ELF_ELFOBJECT_H
10 #define LLVM_LIB_OBJCOPY_ELF_ELFOBJECT_H
12 #include "llvm/ADT/ArrayRef.h"
13 #include "llvm/ADT/StringRef.h"
14 #include "llvm/ADT/Twine.h"
15 #include "llvm/BinaryFormat/ELF.h"
16 #include "llvm/MC/StringTableBuilder.h"
17 #include "llvm/ObjCopy/CommonConfig.h"
18 #include "llvm/Object/ELFObjectFile.h"
19 #include "llvm/Support/Errc.h"
20 #include "llvm/Support/FileOutputBuffer.h"
21 #include "llvm/Support/MemoryBuffer.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 ArrayRef
<std::unique_ptr
<SectionBase
>> Sections
;
54 using iterator
= pointee_iterator
<const std::unique_ptr
<SectionBase
> *>;
56 explicit SectionTableRef(ArrayRef
<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 Expected
<SectionBase
*> getSection(uint32_t Index
, Twine ErrMsg
);
67 Expected
<T
*> getSectionOfType(uint32_t Index
, Twine IndexErrMsg
,
71 enum ElfType
{ ELFT_ELF32LE
, ELFT_ELF64LE
, ELFT_ELF32BE
, ELFT_ELF64BE
};
73 class SectionVisitor
{
75 virtual ~SectionVisitor() = default;
77 virtual Error
visit(const Section
&Sec
) = 0;
78 virtual Error
visit(const OwnedDataSection
&Sec
) = 0;
79 virtual Error
visit(const StringTableSection
&Sec
) = 0;
80 virtual Error
visit(const SymbolTableSection
&Sec
) = 0;
81 virtual Error
visit(const RelocationSection
&Sec
) = 0;
82 virtual Error
visit(const DynamicRelocationSection
&Sec
) = 0;
83 virtual Error
visit(const GnuDebugLinkSection
&Sec
) = 0;
84 virtual Error
visit(const GroupSection
&Sec
) = 0;
85 virtual Error
visit(const SectionIndexSection
&Sec
) = 0;
86 virtual Error
visit(const CompressedSection
&Sec
) = 0;
87 virtual Error
visit(const DecompressedSection
&Sec
) = 0;
90 class MutableSectionVisitor
{
92 virtual ~MutableSectionVisitor() = default;
94 virtual Error
visit(Section
&Sec
) = 0;
95 virtual Error
visit(OwnedDataSection
&Sec
) = 0;
96 virtual Error
visit(StringTableSection
&Sec
) = 0;
97 virtual Error
visit(SymbolTableSection
&Sec
) = 0;
98 virtual Error
visit(RelocationSection
&Sec
) = 0;
99 virtual Error
visit(DynamicRelocationSection
&Sec
) = 0;
100 virtual Error
visit(GnuDebugLinkSection
&Sec
) = 0;
101 virtual Error
visit(GroupSection
&Sec
) = 0;
102 virtual Error
visit(SectionIndexSection
&Sec
) = 0;
103 virtual Error
visit(CompressedSection
&Sec
) = 0;
104 virtual Error
visit(DecompressedSection
&Sec
) = 0;
107 class SectionWriter
: public SectionVisitor
{
109 WritableMemoryBuffer
&Out
;
112 virtual ~SectionWriter() = default;
114 Error
visit(const Section
&Sec
) override
;
115 Error
visit(const OwnedDataSection
&Sec
) override
;
116 Error
visit(const StringTableSection
&Sec
) override
;
117 Error
visit(const DynamicRelocationSection
&Sec
) override
;
118 Error
visit(const SymbolTableSection
&Sec
) override
= 0;
119 Error
visit(const RelocationSection
&Sec
) override
= 0;
120 Error
visit(const GnuDebugLinkSection
&Sec
) override
= 0;
121 Error
visit(const GroupSection
&Sec
) override
= 0;
122 Error
visit(const SectionIndexSection
&Sec
) override
= 0;
123 Error
visit(const CompressedSection
&Sec
) override
= 0;
124 Error
visit(const DecompressedSection
&Sec
) override
= 0;
126 explicit SectionWriter(WritableMemoryBuffer
&Buf
) : Out(Buf
) {}
129 template <class ELFT
> class ELFSectionWriter
: public SectionWriter
{
131 using Elf_Word
= typename
ELFT::Word
;
132 using Elf_Rel
= typename
ELFT::Rel
;
133 using Elf_Rela
= typename
ELFT::Rela
;
134 using Elf_Sym
= typename
ELFT::Sym
;
137 virtual ~ELFSectionWriter() {}
138 Error
visit(const SymbolTableSection
&Sec
) override
;
139 Error
visit(const RelocationSection
&Sec
) override
;
140 Error
visit(const GnuDebugLinkSection
&Sec
) override
;
141 Error
visit(const GroupSection
&Sec
) override
;
142 Error
visit(const SectionIndexSection
&Sec
) override
;
143 Error
visit(const CompressedSection
&Sec
) override
;
144 Error
visit(const DecompressedSection
&Sec
) override
;
146 explicit ELFSectionWriter(WritableMemoryBuffer
&Buf
) : SectionWriter(Buf
) {}
149 template <class ELFT
> class ELFSectionSizer
: public MutableSectionVisitor
{
151 using Elf_Rel
= typename
ELFT::Rel
;
152 using Elf_Rela
= typename
ELFT::Rela
;
153 using Elf_Sym
= typename
ELFT::Sym
;
154 using Elf_Word
= typename
ELFT::Word
;
155 using Elf_Xword
= typename
ELFT::Xword
;
158 Error
visit(Section
&Sec
) override
;
159 Error
visit(OwnedDataSection
&Sec
) override
;
160 Error
visit(StringTableSection
&Sec
) override
;
161 Error
visit(DynamicRelocationSection
&Sec
) override
;
162 Error
visit(SymbolTableSection
&Sec
) override
;
163 Error
visit(RelocationSection
&Sec
) override
;
164 Error
visit(GnuDebugLinkSection
&Sec
) override
;
165 Error
visit(GroupSection
&Sec
) override
;
166 Error
visit(SectionIndexSection
&Sec
) override
;
167 Error
visit(CompressedSection
&Sec
) override
;
168 Error
visit(DecompressedSection
&Sec
) override
;
171 #define MAKE_SEC_WRITER_FRIEND \
172 friend class SectionWriter; \
173 friend class IHexSectionWriterBase; \
174 friend class IHexSectionWriter; \
175 template <class ELFT> friend class ELFSectionWriter; \
176 template <class ELFT> friend class ELFSectionSizer;
178 class BinarySectionWriter
: public SectionWriter
{
180 virtual ~BinarySectionWriter() {}
182 Error
visit(const SymbolTableSection
&Sec
) override
;
183 Error
visit(const RelocationSection
&Sec
) override
;
184 Error
visit(const GnuDebugLinkSection
&Sec
) override
;
185 Error
visit(const GroupSection
&Sec
) override
;
186 Error
visit(const SectionIndexSection
&Sec
) override
;
187 Error
visit(const CompressedSection
&Sec
) override
;
188 Error
visit(const DecompressedSection
&Sec
) override
;
190 explicit BinarySectionWriter(WritableMemoryBuffer
&Buf
)
191 : SectionWriter(Buf
) {}
194 using IHexLineData
= SmallVector
<char, 64>;
197 // Memory address of the record.
199 // Record type (see below).
201 // Record data in hexadecimal form.
204 // Helper method to get file length of the record
205 // including newline character
206 static size_t getLength(size_t DataSize
) {
207 // :LLAAAATT[DD...DD]CC'
208 return DataSize
* 2 + 11;
211 // Gets length of line in a file (getLength + CRLF).
212 static size_t getLineLength(size_t DataSize
) {
213 return getLength(DataSize
) + 2;
216 // Given type, address and data returns line which can
217 // be written to output file.
218 static IHexLineData
getLine(uint8_t Type
, uint16_t Addr
,
219 ArrayRef
<uint8_t> Data
);
221 // Parses the line and returns record if possible.
222 // Line should be trimmed from whitespace characters.
223 static Expected
<IHexRecord
> parse(StringRef Line
);
225 // Calculates checksum of stringified record representation
226 // S must NOT contain leading ':' and trailing whitespace
228 static uint8_t getChecksum(StringRef S
);
231 // Contains data and a 16-bit starting address for the data.
232 // The byte count specifies number of data bytes in the record.
234 // Must occur exactly once per file in the last line of the file.
235 // The data field is empty (thus byte count is 00) and the address
236 // field is typically 0000.
238 // The data field contains a 16-bit segment base address (thus byte
239 // count is always 02) compatible with 80x86 real mode addressing.
240 // The address field (typically 0000) is ignored. The segment address
241 // from the most recent 02 record is multiplied by 16 and added to each
242 // subsequent data record address to form the physical starting address
243 // for the data. This allows addressing up to one megabyte of address
246 // or 80x86 processors, specifies the initial content of the CS:IP
247 // registers. The address field is 0000, the byte count is always 04,
248 // the first two data bytes are the CS value, the latter two are the
251 // Allows for 32 bit addressing (up to 4GiB). The record's address field
252 // is ignored (typically 0000) and its byte count is always 02. The two
253 // data bytes (big endian) specify the upper 16 bits of the 32 bit
254 // absolute address for all subsequent type 00 records
256 // The address field is 0000 (not used) and the byte count is always 04.
257 // The four data bytes represent a 32-bit address value. In the case of
258 // 80386 and higher CPUs, this address is loaded into the EIP register.
260 // We have no other valid types
265 // Base class for IHexSectionWriter. This class implements writing algorithm,
266 // but doesn't actually write records. It is used for output buffer size
267 // calculation in IHexWriter::finalize.
268 class IHexSectionWriterBase
: public BinarySectionWriter
{
269 // 20-bit segment address
270 uint32_t SegmentAddr
= 0;
271 // Extended linear address
272 uint32_t BaseAddr
= 0;
274 // Write segment address corresponding to 'Addr'
275 uint64_t writeSegmentAddr(uint64_t Addr
);
276 // Write extended linear (base) address corresponding to 'Addr'
277 uint64_t writeBaseAddr(uint64_t Addr
);
280 // Offset in the output buffer
283 void writeSection(const SectionBase
*Sec
, ArrayRef
<uint8_t> Data
);
284 virtual void writeData(uint8_t Type
, uint16_t Addr
, ArrayRef
<uint8_t> Data
);
287 explicit IHexSectionWriterBase(WritableMemoryBuffer
&Buf
)
288 : BinarySectionWriter(Buf
) {}
290 uint64_t getBufferOffset() const { return Offset
; }
291 Error
visit(const Section
&Sec
) final
;
292 Error
visit(const OwnedDataSection
&Sec
) final
;
293 Error
visit(const StringTableSection
&Sec
) override
;
294 Error
visit(const DynamicRelocationSection
&Sec
) final
;
295 using BinarySectionWriter::visit
;
298 // Real IHEX section writer
299 class IHexSectionWriter
: public IHexSectionWriterBase
{
301 IHexSectionWriter(WritableMemoryBuffer
&Buf
) : IHexSectionWriterBase(Buf
) {}
303 void writeData(uint8_t Type
, uint16_t Addr
, ArrayRef
<uint8_t> Data
) override
;
304 Error
visit(const StringTableSection
&Sec
) override
;
310 std::unique_ptr
<WritableMemoryBuffer
> Buf
;
315 virtual Error
finalize() = 0;
316 virtual Error
write() = 0;
318 Writer(Object
&O
, raw_ostream
&Out
) : Obj(O
), Out(Out
) {}
321 template <class ELFT
> class ELFWriter
: public Writer
{
323 using Elf_Addr
= typename
ELFT::Addr
;
324 using Elf_Shdr
= typename
ELFT::Shdr
;
325 using Elf_Phdr
= typename
ELFT::Phdr
;
326 using Elf_Ehdr
= typename
ELFT::Ehdr
;
328 void initEhdrSegment();
331 void writePhdr(const Segment
&Seg
);
332 void writeShdr(const SectionBase
&Sec
);
336 Error
writeSectionData();
337 void writeSegmentData();
339 void assignOffsets();
341 std::unique_ptr
<ELFSectionWriter
<ELFT
>> SecWriter
;
343 size_t totalSize() const;
346 virtual ~ELFWriter() {}
347 bool WriteSectionHeaders
;
349 // For --only-keep-debug, select an alternative section/segment layout
353 Error
finalize() override
;
354 Error
write() override
;
355 ELFWriter(Object
&Obj
, raw_ostream
&Out
, bool WSH
, bool OnlyKeepDebug
);
358 class BinaryWriter
: public Writer
{
360 const uint8_t GapFill
;
361 const uint64_t PadTo
;
362 std::unique_ptr
<BinarySectionWriter
> SecWriter
;
364 uint64_t TotalSize
= 0;
368 Error
finalize() override
;
369 Error
write() override
;
370 BinaryWriter(Object
&Obj
, raw_ostream
&Out
, const CommonConfig
&Config
)
371 : Writer(Obj
, Out
), GapFill(Config
.GapFill
), PadTo(Config
.PadTo
) {}
374 class IHexWriter
: public Writer
{
375 struct SectionCompare
{
376 bool operator()(const SectionBase
*Lhs
, const SectionBase
*Rhs
) const;
379 std::set
<const SectionBase
*, SectionCompare
> Sections
;
380 size_t TotalSize
= 0;
382 Error
checkSection(const SectionBase
&Sec
);
383 uint64_t writeEntryPointRecord(uint8_t *Buf
);
384 uint64_t writeEndOfFileRecord(uint8_t *Buf
);
388 Error
finalize() override
;
389 Error
write() override
;
390 IHexWriter(Object
&Obj
, raw_ostream
&Out
) : Writer(Obj
, Out
) {}
396 Segment
*ParentSegment
= nullptr;
397 uint64_t HeaderOffset
= 0;
400 uint32_t OriginalIndex
= 0;
401 uint64_t OriginalFlags
= 0;
402 uint64_t OriginalType
= ELF::SHT_NULL
;
403 uint64_t OriginalOffset
= std::numeric_limits
<uint64_t>::max();
407 uint32_t EntrySize
= 0;
410 uint64_t Link
= ELF::SHN_UNDEF
;
411 uint64_t NameIndex
= 0;
414 uint64_t Type
= ELF::SHT_NULL
;
415 ArrayRef
<uint8_t> OriginalData
;
416 bool HasSymbol
= false;
418 SectionBase() = default;
419 SectionBase(const SectionBase
&) = default;
421 virtual ~SectionBase() = default;
423 virtual Error
initialize(SectionTableRef SecTable
);
424 virtual void finalize();
425 // Remove references to these sections. The list of sections must be sorted.
427 removeSectionReferences(bool AllowBrokenLinks
,
428 function_ref
<bool(const SectionBase
*)> ToRemove
);
429 virtual Error
removeSymbols(function_ref
<bool(const Symbol
&)> ToRemove
);
430 virtual Error
accept(SectionVisitor
&Visitor
) const = 0;
431 virtual Error
accept(MutableSectionVisitor
&Visitor
) = 0;
432 virtual void markSymbols();
434 replaceSectionReferences(const DenseMap
<SectionBase
*, SectionBase
*> &);
435 virtual bool hasContents() const { return false; }
436 // Notify the section that it is subject to removal.
437 virtual void onRemove();
439 virtual void restoreSymTabLink(SymbolTableSection
&) {}
444 struct SectionCompare
{
445 bool operator()(const SectionBase
*Lhs
, const SectionBase
*Rhs
) const {
446 // Some sections might have the same address if one of them is empty. To
447 // fix this we can use the lexicographic ordering on ->Addr and the
449 if (Lhs
->OriginalOffset
== Rhs
->OriginalOffset
)
450 return Lhs
->OriginalIndex
< Rhs
->OriginalIndex
;
451 return Lhs
->OriginalOffset
< Rhs
->OriginalOffset
;
461 uint64_t FileSize
= 0;
462 uint64_t MemSize
= 0;
466 uint64_t OriginalOffset
= 0;
467 Segment
*ParentSegment
= nullptr;
468 ArrayRef
<uint8_t> Contents
;
469 std::set
<const SectionBase
*, SectionCompare
> Sections
;
471 explicit Segment(ArrayRef
<uint8_t> Data
) : Contents(Data
) {}
474 const SectionBase
*firstSection() const {
475 if (!Sections
.empty())
476 return *Sections
.begin();
480 void removeSection(const SectionBase
*Sec
) { Sections
.erase(Sec
); }
481 void addSection(const SectionBase
*Sec
) { Sections
.insert(Sec
); }
483 ArrayRef
<uint8_t> getContents() const { return Contents
; }
486 class Section
: public SectionBase
{
487 MAKE_SEC_WRITER_FRIEND
489 ArrayRef
<uint8_t> Contents
;
490 SectionBase
*LinkSection
= nullptr;
491 bool HasSymTabLink
= false;
494 explicit Section(ArrayRef
<uint8_t> Data
) : Contents(Data
) {}
496 Error
accept(SectionVisitor
&Visitor
) const override
;
497 Error
accept(MutableSectionVisitor
&Visitor
) override
;
498 Error
removeSectionReferences(
499 bool AllowBrokenLinks
,
500 function_ref
<bool(const SectionBase
*)> ToRemove
) override
;
501 Error
initialize(SectionTableRef SecTable
) override
;
502 void finalize() override
;
503 bool hasContents() const override
{
504 return Type
!= ELF::SHT_NOBITS
&& Type
!= ELF::SHT_NULL
;
506 void restoreSymTabLink(SymbolTableSection
&SymTab
) override
;
509 class OwnedDataSection
: public SectionBase
{
510 MAKE_SEC_WRITER_FRIEND
512 std::vector
<uint8_t> Data
;
515 OwnedDataSection(StringRef SecName
, ArrayRef
<uint8_t> Data
)
516 : Data(std::begin(Data
), std::end(Data
)) {
517 Name
= SecName
.str();
518 Type
= OriginalType
= ELF::SHT_PROGBITS
;
520 OriginalOffset
= std::numeric_limits
<uint64_t>::max();
523 OwnedDataSection(const Twine
&SecName
, uint64_t SecAddr
, uint64_t SecFlags
,
525 Name
= SecName
.str();
526 Type
= OriginalType
= ELF::SHT_PROGBITS
;
528 Flags
= OriginalFlags
= SecFlags
;
529 OriginalOffset
= SecOff
;
532 OwnedDataSection(SectionBase
&S
, ArrayRef
<uint8_t> Data
)
533 : SectionBase(S
), Data(std::begin(Data
), std::end(Data
)) {
537 void appendHexData(StringRef HexData
);
538 Error
accept(SectionVisitor
&Sec
) const override
;
539 Error
accept(MutableSectionVisitor
&Visitor
) override
;
540 bool hasContents() const override
{ return true; }
543 class CompressedSection
: public SectionBase
{
544 MAKE_SEC_WRITER_FRIEND
547 DebugCompressionType CompressionType
;
548 uint64_t DecompressedSize
;
549 uint64_t DecompressedAlign
;
550 SmallVector
<uint8_t, 128> CompressedData
;
553 CompressedSection(const SectionBase
&Sec
,
554 DebugCompressionType CompressionType
, bool Is64Bits
);
555 CompressedSection(ArrayRef
<uint8_t> CompressedData
, uint32_t ChType
,
556 uint64_t DecompressedSize
, uint64_t DecompressedAlign
);
558 uint64_t getDecompressedSize() const { return DecompressedSize
; }
559 uint64_t getDecompressedAlign() const { return DecompressedAlign
; }
560 uint64_t getChType() const { return ChType
; }
562 Error
accept(SectionVisitor
&Visitor
) const override
;
563 Error
accept(MutableSectionVisitor
&Visitor
) override
;
565 static bool classof(const SectionBase
*S
) {
566 return S
->OriginalFlags
& ELF::SHF_COMPRESSED
;
570 class DecompressedSection
: public SectionBase
{
571 MAKE_SEC_WRITER_FRIEND
575 explicit DecompressedSection(const CompressedSection
&Sec
)
576 : SectionBase(Sec
), ChType(Sec
.getChType()) {
577 Size
= Sec
.getDecompressedSize();
578 Align
= Sec
.getDecompressedAlign();
579 Flags
= OriginalFlags
= (Flags
& ~ELF::SHF_COMPRESSED
);
582 Error
accept(SectionVisitor
&Visitor
) const override
;
583 Error
accept(MutableSectionVisitor
&Visitor
) override
;
586 // There are two types of string tables that can exist, dynamic and not dynamic.
587 // In the dynamic case the string table is allocated. Changing a dynamic string
588 // table would mean altering virtual addresses and thus the memory image. So
589 // dynamic string tables should not have an interface to modify them or
590 // reconstruct them. This type lets us reconstruct a string table. To avoid
591 // this class being used for dynamic string tables (which has happened) the
592 // classof method checks that the particular instance is not allocated. This
593 // then agrees with the makeSection method used to construct most sections.
594 class StringTableSection
: public SectionBase
{
595 MAKE_SEC_WRITER_FRIEND
597 StringTableBuilder StrTabBuilder
;
600 StringTableSection() : StrTabBuilder(StringTableBuilder::ELF
) {
601 Type
= OriginalType
= ELF::SHT_STRTAB
;
604 void addString(StringRef Name
);
605 uint32_t findIndex(StringRef Name
) const;
606 void prepareForLayout();
607 Error
accept(SectionVisitor
&Visitor
) const override
;
608 Error
accept(MutableSectionVisitor
&Visitor
) override
;
610 static bool classof(const SectionBase
*S
) {
611 if (S
->OriginalFlags
& ELF::SHF_ALLOC
)
613 return S
->OriginalType
== ELF::SHT_STRTAB
;
617 // Symbols have a st_shndx field that normally stores an index but occasionally
618 // stores a different special value. This enum keeps track of what the st_shndx
619 // field means. Most of the values are just copies of the special SHN_* values.
620 // SYMBOL_SIMPLE_INDEX means that the st_shndx is just an index of a section.
621 enum SymbolShndxType
{
622 SYMBOL_SIMPLE_INDEX
= 0,
623 SYMBOL_ABS
= ELF::SHN_ABS
,
624 SYMBOL_COMMON
= ELF::SHN_COMMON
,
625 SYMBOL_LOPROC
= ELF::SHN_LOPROC
,
626 SYMBOL_AMDGPU_LDS
= ELF::SHN_AMDGPU_LDS
,
627 SYMBOL_HEXAGON_SCOMMON
= ELF::SHN_HEXAGON_SCOMMON
,
628 SYMBOL_HEXAGON_SCOMMON_2
= ELF::SHN_HEXAGON_SCOMMON_2
,
629 SYMBOL_HEXAGON_SCOMMON_4
= ELF::SHN_HEXAGON_SCOMMON_4
,
630 SYMBOL_HEXAGON_SCOMMON_8
= ELF::SHN_HEXAGON_SCOMMON_8
,
631 SYMBOL_MIPS_ACOMMON
= ELF::SHN_MIPS_ACOMMON
,
632 SYMBOL_MIPS_TEXT
= ELF::SHN_MIPS_TEXT
,
633 SYMBOL_MIPS_DATA
= ELF::SHN_MIPS_DATA
,
634 SYMBOL_MIPS_SCOMMON
= ELF::SHN_MIPS_SCOMMON
,
635 SYMBOL_MIPS_SUNDEFINED
= ELF::SHN_MIPS_SUNDEFINED
,
636 SYMBOL_HIPROC
= ELF::SHN_HIPROC
,
637 SYMBOL_LOOS
= ELF::SHN_LOOS
,
638 SYMBOL_HIOS
= ELF::SHN_HIOS
,
639 SYMBOL_XINDEX
= ELF::SHN_XINDEX
,
644 SectionBase
*DefinedIn
= nullptr;
645 SymbolShndxType ShndxType
;
653 bool Referenced
= false;
655 uint16_t getShndx() const;
656 bool isCommon() const;
659 class SectionIndexSection
: public SectionBase
{
660 MAKE_SEC_WRITER_FRIEND
663 std::vector
<uint32_t> Indexes
;
664 SymbolTableSection
*Symbols
= nullptr;
667 virtual ~SectionIndexSection() {}
668 void addIndex(uint32_t Index
) {
670 Indexes
.push_back(Index
);
673 void reserve(size_t NumSymbols
) {
674 Indexes
.reserve(NumSymbols
);
675 Size
= NumSymbols
* 4;
677 void setSymTab(SymbolTableSection
*SymTab
) { Symbols
= SymTab
; }
678 Error
initialize(SectionTableRef SecTable
) override
;
679 void finalize() override
;
680 Error
accept(SectionVisitor
&Visitor
) const override
;
681 Error
accept(MutableSectionVisitor
&Visitor
) override
;
683 SectionIndexSection() {
684 Name
= ".symtab_shndx";
687 Type
= OriginalType
= ELF::SHT_SYMTAB_SHNDX
;
691 class SymbolTableSection
: public SectionBase
{
692 MAKE_SEC_WRITER_FRIEND
694 void setStrTab(StringTableSection
*StrTab
) { SymbolNames
= StrTab
; }
695 void assignIndices();
698 std::vector
<std::unique_ptr
<Symbol
>> Symbols
;
699 StringTableSection
*SymbolNames
= nullptr;
700 SectionIndexSection
*SectionIndexTable
= nullptr;
701 bool IndicesChanged
= false;
703 using SymPtr
= std::unique_ptr
<Symbol
>;
706 SymbolTableSection() { Type
= OriginalType
= ELF::SHT_SYMTAB
; }
708 void addSymbol(Twine Name
, uint8_t Bind
, uint8_t Type
, SectionBase
*DefinedIn
,
709 uint64_t Value
, uint8_t Visibility
, uint16_t Shndx
,
710 uint64_t SymbolSize
);
711 void prepareForLayout();
712 // An 'empty' symbol table still contains a null symbol.
713 bool empty() const { return Symbols
.size() == 1; }
714 bool indicesChanged() const { return IndicesChanged
; }
715 void setShndxTable(SectionIndexSection
*ShndxTable
) {
716 SectionIndexTable
= ShndxTable
;
718 const SectionIndexSection
*getShndxTable() const { return SectionIndexTable
; }
719 void fillShndxTable();
720 const SectionBase
*getStrTab() const { return SymbolNames
; }
721 Expected
<const Symbol
*> getSymbolByIndex(uint32_t Index
) const;
722 Expected
<Symbol
*> getSymbolByIndex(uint32_t Index
);
723 void updateSymbols(function_ref
<void(Symbol
&)> Callable
);
725 Error
removeSectionReferences(
726 bool AllowBrokenLinks
,
727 function_ref
<bool(const SectionBase
*)> ToRemove
) override
;
728 Error
initialize(SectionTableRef SecTable
) override
;
729 void finalize() override
;
730 Error
accept(SectionVisitor
&Visitor
) const override
;
731 Error
accept(MutableSectionVisitor
&Visitor
) override
;
732 Error
removeSymbols(function_ref
<bool(const Symbol
&)> ToRemove
) override
;
733 void replaceSectionReferences(
734 const DenseMap
<SectionBase
*, SectionBase
*> &FromTo
) override
;
736 static bool classof(const SectionBase
*S
) {
737 return S
->OriginalType
== ELF::SHT_SYMTAB
;
742 Symbol
*RelocSymbol
= nullptr;
748 // All relocation sections denote relocations to apply to another section.
749 // However, some relocation sections use a dynamic symbol table and others use
750 // a regular symbol table. Because the types of the two symbol tables differ in
751 // our system (because they should behave differently) we can't uniformly
752 // represent all relocations with the same base class if we expose an interface
753 // that mentions the symbol table type. So we split the two base types into two
754 // different classes, one which handles the section the relocation is applied to
755 // and another which handles the symbol table type. The symbol table type is
756 // taken as a type parameter to the class (see RelocSectionWithSymtabBase).
757 class RelocationSectionBase
: public SectionBase
{
759 SectionBase
*SecToApplyRel
= nullptr;
762 const SectionBase
*getSection() const { return SecToApplyRel
; }
763 void setSection(SectionBase
*Sec
) { SecToApplyRel
= Sec
; }
765 StringRef
getNamePrefix() const;
767 static bool classof(const SectionBase
*S
) {
768 return S
->OriginalType
== ELF::SHT_REL
|| S
->OriginalType
== ELF::SHT_RELA
;
772 // Takes the symbol table type to use as a parameter so that we can deduplicate
773 // that code between the two symbol table types.
774 template <class SymTabType
>
775 class RelocSectionWithSymtabBase
: public RelocationSectionBase
{
776 void setSymTab(SymTabType
*SymTab
) { Symbols
= SymTab
; }
779 RelocSectionWithSymtabBase() = default;
781 SymTabType
*Symbols
= nullptr;
784 Error
initialize(SectionTableRef SecTable
) override
;
785 void finalize() override
;
788 class RelocationSection
789 : public RelocSectionWithSymtabBase
<SymbolTableSection
> {
790 MAKE_SEC_WRITER_FRIEND
792 std::vector
<Relocation
> Relocations
;
796 RelocationSection(const Object
&O
) : Obj(O
) {}
797 void addRelocation(Relocation Rel
) { Relocations
.push_back(Rel
); }
798 Error
accept(SectionVisitor
&Visitor
) const override
;
799 Error
accept(MutableSectionVisitor
&Visitor
) override
;
800 Error
removeSectionReferences(
801 bool AllowBrokenLinks
,
802 function_ref
<bool(const SectionBase
*)> ToRemove
) override
;
803 Error
removeSymbols(function_ref
<bool(const Symbol
&)> ToRemove
) override
;
804 void markSymbols() override
;
805 void replaceSectionReferences(
806 const DenseMap
<SectionBase
*, SectionBase
*> &FromTo
) override
;
807 const Object
&getObject() const { return Obj
; }
809 static bool classof(const SectionBase
*S
) {
810 if (S
->OriginalFlags
& ELF::SHF_ALLOC
)
812 return S
->OriginalType
== ELF::SHT_REL
|| S
->OriginalType
== ELF::SHT_RELA
;
816 // TODO: The way stripping and groups interact is complicated
817 // and still needs to be worked on.
819 class GroupSection
: public SectionBase
{
820 MAKE_SEC_WRITER_FRIEND
821 const SymbolTableSection
*SymTab
= nullptr;
822 Symbol
*Sym
= nullptr;
823 ELF::Elf32_Word FlagWord
;
824 SmallVector
<SectionBase
*, 3> GroupMembers
;
827 // TODO: Contents is present in several classes of the hierarchy.
828 // This needs to be refactored to avoid duplication.
829 ArrayRef
<uint8_t> Contents
;
831 explicit GroupSection(ArrayRef
<uint8_t> Data
) : Contents(Data
) {}
833 void setSymTab(const SymbolTableSection
*SymTabSec
) { SymTab
= SymTabSec
; }
834 void setSymbol(Symbol
*S
) { Sym
= S
; }
835 void setFlagWord(ELF::Elf32_Word W
) { FlagWord
= W
; }
836 void addMember(SectionBase
*Sec
) { GroupMembers
.push_back(Sec
); }
838 Error
accept(SectionVisitor
&) const override
;
839 Error
accept(MutableSectionVisitor
&Visitor
) override
;
840 void finalize() override
;
841 Error
removeSectionReferences(
842 bool AllowBrokenLinks
,
843 function_ref
<bool(const SectionBase
*)> ToRemove
) override
;
844 Error
removeSymbols(function_ref
<bool(const Symbol
&)> ToRemove
) override
;
845 void markSymbols() override
;
846 void replaceSectionReferences(
847 const DenseMap
<SectionBase
*, SectionBase
*> &FromTo
) override
;
848 void onRemove() override
;
850 static bool classof(const SectionBase
*S
) {
851 return S
->OriginalType
== ELF::SHT_GROUP
;
855 class DynamicSymbolTableSection
: public Section
{
857 explicit DynamicSymbolTableSection(ArrayRef
<uint8_t> Data
) : Section(Data
) {}
859 static bool classof(const SectionBase
*S
) {
860 return S
->OriginalType
== ELF::SHT_DYNSYM
;
864 class DynamicSection
: public Section
{
866 explicit DynamicSection(ArrayRef
<uint8_t> Data
) : Section(Data
) {}
868 static bool classof(const SectionBase
*S
) {
869 return S
->OriginalType
== ELF::SHT_DYNAMIC
;
873 class DynamicRelocationSection
874 : public RelocSectionWithSymtabBase
<DynamicSymbolTableSection
> {
875 MAKE_SEC_WRITER_FRIEND
878 ArrayRef
<uint8_t> Contents
;
881 explicit DynamicRelocationSection(ArrayRef
<uint8_t> Data
) : Contents(Data
) {}
883 Error
accept(SectionVisitor
&) const override
;
884 Error
accept(MutableSectionVisitor
&Visitor
) override
;
885 Error
removeSectionReferences(
886 bool AllowBrokenLinks
,
887 function_ref
<bool(const SectionBase
*)> ToRemove
) override
;
889 static bool classof(const SectionBase
*S
) {
890 if (!(S
->OriginalFlags
& ELF::SHF_ALLOC
))
892 return S
->OriginalType
== ELF::SHT_REL
|| S
->OriginalType
== ELF::SHT_RELA
;
896 class GnuDebugLinkSection
: public SectionBase
{
897 MAKE_SEC_WRITER_FRIEND
903 void init(StringRef File
);
906 // If we add this section from an external source we can use this ctor.
907 explicit GnuDebugLinkSection(StringRef File
, uint32_t PrecomputedCRC
);
908 Error
accept(SectionVisitor
&Visitor
) const override
;
909 Error
accept(MutableSectionVisitor
&Visitor
) override
;
915 virtual Expected
<std::unique_ptr
<Object
>> create(bool EnsureSymtab
) const = 0;
918 using object::Binary
;
919 using object::ELFFile
;
920 using object::ELFObjectFile
;
921 using object::OwningBinary
;
923 class BasicELFBuilder
{
925 std::unique_ptr
<Object
> Obj
;
927 void initFileHeader();
928 void initHeaderSegment();
929 StringTableSection
*addStrTab();
930 SymbolTableSection
*addSymTab(StringTableSection
*StrTab
);
931 Error
initSections();
934 BasicELFBuilder() : Obj(std::make_unique
<Object
>()) {}
937 class BinaryELFBuilder
: public BasicELFBuilder
{
938 MemoryBuffer
*MemBuf
;
939 uint8_t NewSymbolVisibility
;
940 void addData(SymbolTableSection
*SymTab
);
943 BinaryELFBuilder(MemoryBuffer
*MB
, uint8_t NewSymbolVisibility
)
944 : MemBuf(MB
), NewSymbolVisibility(NewSymbolVisibility
) {}
946 Expected
<std::unique_ptr
<Object
>> build();
949 class IHexELFBuilder
: public BasicELFBuilder
{
950 const std::vector
<IHexRecord
> &Records
;
952 void addDataSections();
955 IHexELFBuilder(const std::vector
<IHexRecord
> &Records
) : Records(Records
) {}
957 Expected
<std::unique_ptr
<Object
>> build();
960 template <class ELFT
> class ELFBuilder
{
962 using Elf_Addr
= typename
ELFT::Addr
;
963 using Elf_Shdr
= typename
ELFT::Shdr
;
964 using Elf_Word
= typename
ELFT::Word
;
966 const ELFFile
<ELFT
> &ElfFile
;
968 size_t EhdrOffset
= 0;
969 std::optional
<StringRef
> ExtractPartition
;
971 void setParentSegment(Segment
&Child
);
972 Error
readProgramHeaders(const ELFFile
<ELFT
> &HeadersFile
);
973 Error
initGroupSection(GroupSection
*GroupSec
);
974 Error
initSymbolTable(SymbolTableSection
*SymTab
);
975 Error
readSectionHeaders();
976 Error
readSections(bool EnsureSymtab
);
977 Error
findEhdrOffset();
978 Expected
<SectionBase
&> makeSection(const Elf_Shdr
&Shdr
);
981 ELFBuilder(const ELFObjectFile
<ELFT
> &ElfObj
, Object
&Obj
,
982 std::optional
<StringRef
> ExtractPartition
);
984 Error
build(bool EnsureSymtab
);
987 class BinaryReader
: public Reader
{
988 MemoryBuffer
*MemBuf
;
989 uint8_t NewSymbolVisibility
;
992 BinaryReader(MemoryBuffer
*MB
, const uint8_t NewSymbolVisibility
)
993 : MemBuf(MB
), NewSymbolVisibility(NewSymbolVisibility
) {}
994 Expected
<std::unique_ptr
<Object
>> create(bool EnsureSymtab
) const override
;
997 class IHexReader
: public Reader
{
998 MemoryBuffer
*MemBuf
;
1000 Expected
<std::vector
<IHexRecord
>> parse() const;
1001 Error
parseError(size_t LineNo
, Error E
) const {
1002 return LineNo
== -1U
1003 ? createFileError(MemBuf
->getBufferIdentifier(), std::move(E
))
1004 : createFileError(MemBuf
->getBufferIdentifier(), LineNo
,
1007 template <typename
... Ts
>
1008 Error
parseError(size_t LineNo
, char const *Fmt
, const Ts
&...Vals
) const {
1009 Error E
= createStringError(errc::invalid_argument
, Fmt
, Vals
...);
1010 return parseError(LineNo
, std::move(E
));
1014 IHexReader(MemoryBuffer
*MB
) : MemBuf(MB
) {}
1016 Expected
<std::unique_ptr
<Object
>> create(bool EnsureSymtab
) const override
;
1019 class ELFReader
: public Reader
{
1021 std::optional
<StringRef
> ExtractPartition
;
1024 Expected
<std::unique_ptr
<Object
>> create(bool EnsureSymtab
) const override
;
1025 explicit ELFReader(Binary
*B
, std::optional
<StringRef
> ExtractPartition
)
1026 : Bin(B
), ExtractPartition(ExtractPartition
) {}
1031 using SecPtr
= std::unique_ptr
<SectionBase
>;
1032 using SegPtr
= std::unique_ptr
<Segment
>;
1034 std::vector
<SecPtr
> Sections
;
1035 std::vector
<SegPtr
> Segments
;
1036 std::vector
<SecPtr
> RemovedSections
;
1037 DenseMap
<SectionBase
*, std::vector
<uint8_t>> UpdatedSections
;
1039 static bool sectionIsAlloc(const SectionBase
&Sec
) {
1040 return Sec
.Flags
& ELF::SHF_ALLOC
;
1045 using ConstRange
= iterator_range
<pointee_iterator
<
1046 typename
std::vector
<std::unique_ptr
<T
>>::const_iterator
>>;
1048 // It is often the case that the ELF header and the program header table are
1049 // not present in any segment. This could be a problem during file layout,
1050 // because other segments may get assigned an offset where either of the
1051 // two should reside, which will effectively corrupt the resulting binary.
1052 // Other than that we use these segments to track program header offsets
1053 // when they may not follow the ELF header.
1054 Segment ElfHdrSegment
;
1055 Segment ProgramHdrSegment
;
1067 bool HadShdrs
= true;
1068 bool MustBeRelocatable
= false;
1069 StringTableSection
*SectionNames
= nullptr;
1070 SymbolTableSection
*SymbolTable
= nullptr;
1071 SectionIndexSection
*SectionIndexTable
= nullptr;
1073 bool IsMips64EL
= false;
1075 SectionTableRef
sections() const { return SectionTableRef(Sections
); }
1077 filter_iterator
<pointee_iterator
<std::vector
<SecPtr
>::const_iterator
>,
1078 decltype(§ionIsAlloc
)>>
1079 allocSections() const {
1080 return make_filter_range(make_pointee_range(Sections
), sectionIsAlloc
);
1083 const auto &getUpdatedSections() const { return UpdatedSections
; }
1084 Error
updateSection(StringRef Name
, ArrayRef
<uint8_t> Data
);
1086 SectionBase
*findSection(StringRef Name
) {
1088 find_if(Sections
, [&](const SecPtr
&Sec
) { return Sec
->Name
== Name
; });
1089 return SecIt
== Sections
.end() ? nullptr : SecIt
->get();
1091 SectionTableRef
removedSections() { return SectionTableRef(RemovedSections
); }
1093 ConstRange
<Segment
> segments() const { return make_pointee_range(Segments
); }
1095 Error
removeSections(bool AllowBrokenLinks
,
1096 std::function
<bool(const SectionBase
&)> ToRemove
);
1097 Error
replaceSections(const DenseMap
<SectionBase
*, SectionBase
*> &FromTo
);
1098 Error
removeSymbols(function_ref
<bool(const Symbol
&)> ToRemove
);
1099 template <class T
, class... Ts
> T
&addSection(Ts
&&...Args
) {
1100 auto Sec
= std::make_unique
<T
>(std::forward
<Ts
>(Args
)...);
1101 auto Ptr
= Sec
.get();
1102 MustBeRelocatable
|= isa
<RelocationSection
>(*Ptr
);
1103 Sections
.emplace_back(std::move(Sec
));
1104 Ptr
->Index
= Sections
.size();
1107 Error
addNewSymbolTable();
1108 Segment
&addSegment(ArrayRef
<uint8_t> Data
) {
1109 Segments
.emplace_back(std::make_unique
<Segment
>(Data
));
1110 return *Segments
.back();
1112 bool isRelocatable() const {
1113 return (Type
!= ELF::ET_DYN
&& Type
!= ELF::ET_EXEC
) || MustBeRelocatable
;
1117 } // end namespace elf
1118 } // end namespace objcopy
1119 } // end namespace llvm
1121 #endif // LLVM_LIB_OBJCOPY_ELF_ELFOBJECT_H