LLVM 20.0.0git
ELFObject.h
Go to the documentation of this file.
1//===- ELFObject.h ----------------------------------------------*- C++ -*-===//
2//
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
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef LLVM_LIB_OBJCOPY_ELF_ELFOBJECT_H
10#define LLVM_LIB_OBJCOPY_ELF_ELFOBJECT_H
11
12#include "llvm/ADT/ArrayRef.h"
13#include "llvm/ADT/StringRef.h"
14#include "llvm/ADT/Twine.h"
19#include "llvm/Support/Errc.h"
22#include <cstddef>
23#include <cstdint>
24#include <functional>
25#include <memory>
26#include <set>
27#include <vector>
28
29namespace llvm {
30enum class DebugCompressionType;
31namespace objcopy {
32namespace elf {
33
34class SectionBase;
35class Section;
36class OwnedDataSection;
37class StringTableSection;
38class SymbolTableSection;
39class RelocationSection;
40class DynamicRelocationSection;
41class GnuDebugLinkSection;
42class GroupSection;
43class SectionIndexSection;
44class CompressedSection;
45class DecompressedSection;
46class Segment;
47class Object;
48struct Symbol;
49
52
53public:
55
56 explicit SectionTableRef(ArrayRef<std::unique_ptr<SectionBase>> Secs)
57 : Sections(Secs) {}
58 SectionTableRef(const SectionTableRef &) = default;
59
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(); }
63
65
66 template <class T>
68 Twine TypeErrMsg);
69};
70
72
74public:
75 virtual ~SectionVisitor() = default;
76
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;
88};
89
91public:
92 virtual ~MutableSectionVisitor() = default;
93
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;
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;
105};
106
108protected:
110
111public:
112 virtual ~SectionWriter() = default;
113
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;
125
126 explicit SectionWriter(WritableMemoryBuffer &Buf) : Out(Buf) {}
127};
128
129template <class ELFT> class ELFSectionWriter : public SectionWriter {
130private:
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;
135
136public:
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;
145
147};
148
149template <class ELFT> class ELFSectionSizer : public MutableSectionVisitor {
150private:
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;
156
157public:
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;
169};
170
171#define MAKE_SEC_WRITER_FRIEND \
172 friend class SectionWriter; \
173 friend class IHexSectionWriterBase; \
174 friend class IHexSectionWriter; \
175 friend class SRECSectionWriter; \
176 friend class SRECSectionWriterBase; \
177 friend class SRECSizeCalculator; \
178 template <class ELFT> friend class ELFSectionWriter; \
179 template <class ELFT> friend class ELFSectionSizer;
180
182public:
184
185 Error visit(const SymbolTableSection &Sec) override;
186 Error visit(const RelocationSection &Sec) override;
187 Error visit(const GnuDebugLinkSection &Sec) override;
188 Error visit(const GroupSection &Sec) override;
189 Error visit(const SectionIndexSection &Sec) override;
190 Error visit(const CompressedSection &Sec) override;
191 Error visit(const DecompressedSection &Sec) override;
192
194 : SectionWriter(Buf) {}
195};
196
198
200 // Memory address of the record.
202 // Record type (see below).
204 // Record data in hexadecimal form.
206
207 // Helper method to get file length of the record
208 // including newline character
209 static size_t getLength(size_t DataSize) {
210 // :LLAAAATT[DD...DD]CC'
211 return DataSize * 2 + 11;
212 }
213
214 // Gets length of line in a file (getLength + CRLF).
215 static size_t getLineLength(size_t DataSize) {
216 return getLength(DataSize) + 2;
217 }
218
219 // Given type, address and data returns line which can
220 // be written to output file.
221 static IHexLineData getLine(uint8_t Type, uint16_t Addr,
223
224 // Parses the line and returns record if possible.
225 // Line should be trimmed from whitespace characters.
227
228 // Calculates checksum of stringified record representation
229 // S must NOT contain leading ':' and trailing whitespace
230 // characters
231 static uint8_t getChecksum(StringRef S);
232
233 enum Type {
234 // Contains data and a 16-bit starting address for the data.
235 // The byte count specifies number of data bytes in the record.
236 Data = 0,
237 // Must occur exactly once per file in the last line of the file.
238 // The data field is empty (thus byte count is 00) and the address
239 // field is typically 0000.
241 // The data field contains a 16-bit segment base address (thus byte
242 // count is always 02) compatible with 80x86 real mode addressing.
243 // The address field (typically 0000) is ignored. The segment address
244 // from the most recent 02 record is multiplied by 16 and added to each
245 // subsequent data record address to form the physical starting address
246 // for the data. This allows addressing up to one megabyte of address
247 // space.
249 // or 80x86 processors, specifies the initial content of the CS:IP
250 // registers. The address field is 0000, the byte count is always 04,
251 // the first two data bytes are the CS value, the latter two are the
252 // IP value.
254 // Allows for 32 bit addressing (up to 4GiB). The record's address field
255 // is ignored (typically 0000) and its byte count is always 02. The two
256 // data bytes (big endian) specify the upper 16 bits of the 32 bit
257 // absolute address for all subsequent type 00 records
259 // The address field is 0000 (not used) and the byte count is always 04.
260 // The four data bytes represent a 32-bit address value. In the case of
261 // 80386 and higher CPUs, this address is loaded into the EIP register.
263 // We have no other valid types
264 InvalidType = 6
265 };
266};
267
268// Base class for IHexSectionWriter. This class implements writing algorithm,
269// but doesn't actually write records. It is used for output buffer size
270// calculation in IHexWriter::finalize.
272 // 20-bit segment address
273 uint32_t SegmentAddr = 0;
274 // Extended linear address
275 uint32_t BaseAddr = 0;
276
277 // Write segment address corresponding to 'Addr'
278 uint64_t writeSegmentAddr(uint64_t Addr);
279 // Write extended linear (base) address corresponding to 'Addr'
280 uint64_t writeBaseAddr(uint64_t Addr);
281
282protected:
283 // Offset in the output buffer
285
287 virtual void writeData(uint8_t Type, uint16_t Addr, ArrayRef<uint8_t> Data);
288
289public:
291 : BinarySectionWriter(Buf) {}
292
293 uint64_t getBufferOffset() const { return Offset; }
294 Error visit(const Section &Sec) final;
295 Error visit(const OwnedDataSection &Sec) final;
296 Error visit(const StringTableSection &Sec) override;
297 Error visit(const DynamicRelocationSection &Sec) final;
299};
300
301// Real IHEX section writer
303public:
305
306 void writeData(uint8_t Type, uint16_t Addr, ArrayRef<uint8_t> Data) override;
307 Error visit(const StringTableSection &Sec) override;
308};
309
310class Writer {
311protected:
313 std::unique_ptr<WritableMemoryBuffer> Buf;
315
316public:
317 virtual ~Writer();
318 virtual Error finalize() = 0;
319 virtual Error write() = 0;
320
322};
323
324template <class ELFT> class ELFWriter : public Writer {
325private:
326 using Elf_Addr = typename ELFT::Addr;
327 using Elf_Shdr = typename ELFT::Shdr;
328 using Elf_Phdr = typename ELFT::Phdr;
329 using Elf_Ehdr = typename ELFT::Ehdr;
330
331 void initEhdrSegment();
332
333 void writeEhdr();
334 void writePhdr(const Segment &Seg);
335 void writeShdr(const SectionBase &Sec);
336
337 void writePhdrs();
338 void writeShdrs();
339 Error writeSectionData();
340 void writeSegmentData();
341
342 void assignOffsets();
343
344 std::unique_ptr<ELFSectionWriter<ELFT>> SecWriter;
345
346 size_t totalSize() const;
347
348public:
349 virtual ~ELFWriter() {}
351
352 // For --only-keep-debug, select an alternative section/segment layout
353 // algorithm.
355
356 Error finalize() override;
357 Error write() override;
358 ELFWriter(Object &Obj, raw_ostream &Out, bool WSH, bool OnlyKeepDebug);
359};
360
361class BinaryWriter : public Writer {
362private:
363 const uint8_t GapFill;
364 const uint64_t PadTo;
365 std::unique_ptr<BinarySectionWriter> SecWriter;
366
367 uint64_t TotalSize = 0;
368
369public:
371 Error finalize() override;
372 Error write() override;
374 : Writer(Obj, Out), GapFill(Config.GapFill), PadTo(Config.PadTo) {}
375};
376
377// A base class for writing ascii hex formats such as srec and ihex.
378class ASCIIHexWriter : public Writer {
379public:
381 : Writer(Obj, OS), OutputFileName(OutputFile) {}
382 Error finalize() override;
383
384protected:
386 size_t TotalSize = 0;
387 std::vector<const SectionBase *> Sections;
388
389 Error checkSection(const SectionBase &S) const;
390 virtual Expected<size_t>
391 getTotalSize(WritableMemoryBuffer &EmptyBuffer) const = 0;
392};
393
395public:
396 Error write() override;
398 : ASCIIHexWriter(Obj, Out, OutputFile) {}
399
400private:
401 uint64_t writeEntryPointRecord(uint8_t *Buf);
402 uint64_t writeEndOfFileRecord(uint8_t *Buf);
404 getTotalSize(WritableMemoryBuffer &EmptyBuffer) const override;
405};
406
408public:
410 : ASCIIHexWriter(Obj, OS, OutputFile) {}
411 Error write() override;
412
413private:
414 size_t writeHeader(uint8_t *Buf);
415 size_t writeTerminator(uint8_t *Buf, uint8_t Type);
417 getTotalSize(WritableMemoryBuffer &EmptyBuffer) const override;
418};
419
421struct SRecord {
422 uint8_t Type;
425 SRecLineData toString() const;
426 uint8_t getCount() const;
427 // Get address size in characters.
428 uint8_t getAddressSize() const;
429 uint8_t getChecksum() const;
430 size_t getSize() const;
431 static SRecord getHeader(StringRef FileName);
432 static uint8_t getType(uint32_t Address);
433
434 enum Type : uint8_t {
435 // Vendor specific text comment.
436 S0 = 0,
437 // Data that starts at a 16 bit address.
438 S1 = 1,
439 // Data that starts at a 24 bit address.
440 S2 = 2,
441 // Data that starts at a 32 bit address.
442 S3 = 3,
443 // Reserved.
444 S4 = 4,
445 // 16 bit count of S1/S2/S3 records (optional).
446 S5 = 5,
447 // 32 bit count of S1/S2/S3 records (optional).
448 S6 = 6,
449 // Terminates a series of S3 records.
450 S7 = 7,
451 // Terminates a series of S2 records.
452 S8 = 8,
453 // Terminates a series of S1 records.
454 S9 = 9
455 };
456};
457
459public:
461 uint64_t StartOffset)
462 : BinarySectionWriter(Buf), Offset(StartOffset), HeaderSize(StartOffset) {
463 }
464
466
467 void writeRecords(uint32_t Entry);
468 uint64_t getBufferOffset() const { return Offset; }
469 Error visit(const Section &S) override;
470 Error visit(const OwnedDataSection &S) override;
471 Error visit(const StringTableSection &S) override;
472 Error visit(const DynamicRelocationSection &S) override;
473 uint8_t getType() const { return Type; };
474
475protected:
476 // Offset in the output buffer.
478 // Sections start after the header.
480 // Type of records to write.
481 uint8_t Type = SRecord::S1;
482 std::vector<SRecord> Records;
483
485 virtual void writeRecord(SRecord &Record, uint64_t Off) = 0;
486};
487
488// An SRECSectionWriterBase that visits sections but does not write anything.
489// This class is only used to calculate the size of the output file.
491public:
493 : SRECSectionWriterBase(EmptyBuffer, Offset) {}
494
495protected:
496 void writeRecord(SRecord &Record, uint64_t Off) override {}
497};
498
500public:
503 Error visit(const StringTableSection &Sec) override;
504
505protected:
506 void writeRecord(SRecord &Record, uint64_t Off) override;
507};
508
510public:
511 std::string Name;
515
519 uint64_t OriginalOffset = std::numeric_limits<uint64_t>::max();
520
532 bool HasSymbol = false;
533
534 SectionBase() = default;
535 SectionBase(const SectionBase &) = default;
536
537 virtual ~SectionBase() = default;
538
539 virtual Error initialize(SectionTableRef SecTable);
540 virtual void finalize();
541 // Remove references to these sections. The list of sections must be sorted.
542 virtual Error
543 removeSectionReferences(bool AllowBrokenLinks,
544 function_ref<bool(const SectionBase *)> ToRemove);
545 virtual Error removeSymbols(function_ref<bool(const Symbol &)> ToRemove);
546 virtual Error accept(SectionVisitor &Visitor) const = 0;
547 virtual Error accept(MutableSectionVisitor &Visitor) = 0;
548 virtual void markSymbols();
549 virtual void
551 virtual bool hasContents() const { return false; }
552 // Notify the section that it is subject to removal.
553 virtual void onRemove();
554
556};
557
558class Segment {
559private:
560 struct SectionCompare {
561 bool operator()(const SectionBase *Lhs, const SectionBase *Rhs) const {
562 // Some sections might have the same address if one of them is empty. To
563 // fix this we can use the lexicographic ordering on ->Addr and the
564 // original index.
565 if (Lhs->OriginalOffset == Rhs->OriginalOffset)
566 return Lhs->OriginalIndex < Rhs->OriginalIndex;
567 return Lhs->OriginalOffset < Rhs->OriginalOffset;
568 }
569 };
570
571public:
580
585 std::set<const SectionBase *, SectionCompare> Sections;
586
588 Segment() = default;
589
590 const SectionBase *firstSection() const {
591 if (!Sections.empty())
592 return *Sections.begin();
593 return nullptr;
594 }
595
596 void removeSection(const SectionBase *Sec) { Sections.erase(Sec); }
597 void addSection(const SectionBase *Sec) { Sections.insert(Sec); }
598
600};
601
602class Section : public SectionBase {
604
605 ArrayRef<uint8_t> Contents;
606 SectionBase *LinkSection = nullptr;
607 bool HasSymTabLink = false;
608
609public:
610 explicit Section(ArrayRef<uint8_t> Data) : Contents(Data) {}
611
612 Error accept(SectionVisitor &Visitor) const override;
613 Error accept(MutableSectionVisitor &Visitor) override;
615 bool AllowBrokenLinks,
616 function_ref<bool(const SectionBase *)> ToRemove) override;
617 Error initialize(SectionTableRef SecTable) override;
618 void finalize() override;
619 bool hasContents() const override {
620 return Type != ELF::SHT_NOBITS && Type != ELF::SHT_NULL;
621 }
622 void restoreSymTabLink(SymbolTableSection &SymTab) override;
623};
624
627
628 std::vector<uint8_t> Data;
629
630public:
632 : Data(std::begin(Data), std::end(Data)) {
633 Name = SecName.str();
635 Size = Data.size();
636 OriginalOffset = std::numeric_limits<uint64_t>::max();
637 }
638
639 OwnedDataSection(const Twine &SecName, uint64_t SecAddr, uint64_t SecFlags,
640 uint64_t SecOff) {
641 Name = SecName.str();
643 Addr = SecAddr;
644 Flags = OriginalFlags = SecFlags;
645 OriginalOffset = SecOff;
646 }
647
649 : SectionBase(S), Data(std::begin(Data), std::end(Data)) {
650 Size = Data.size();
651 }
652
653 void appendHexData(StringRef HexData);
654 Error accept(SectionVisitor &Sec) const override;
655 Error accept(MutableSectionVisitor &Visitor) override;
656 bool hasContents() const override { return true; }
657};
658
661
662 uint32_t ChType = 0;
663 DebugCompressionType CompressionType;
664 uint64_t DecompressedSize;
665 uint64_t DecompressedAlign;
666 SmallVector<uint8_t, 128> CompressedData;
667
668public:
670 DebugCompressionType CompressionType, bool Is64Bits);
671 CompressedSection(ArrayRef<uint8_t> CompressedData, uint32_t ChType,
672 uint64_t DecompressedSize, uint64_t DecompressedAlign);
673
674 uint64_t getDecompressedSize() const { return DecompressedSize; }
675 uint64_t getDecompressedAlign() const { return DecompressedAlign; }
676 uint64_t getChType() const { return ChType; }
677
678 Error accept(SectionVisitor &Visitor) const override;
679 Error accept(MutableSectionVisitor &Visitor) override;
680
681 static bool classof(const SectionBase *S) {
683 }
684};
685
688
689public:
692 : SectionBase(Sec), ChType(Sec.getChType()) {
695 Flags = OriginalFlags = (Flags & ~ELF::SHF_COMPRESSED);
696 }
697
698 Error accept(SectionVisitor &Visitor) const override;
699 Error accept(MutableSectionVisitor &Visitor) override;
700};
701
702// There are two types of string tables that can exist, dynamic and not dynamic.
703// In the dynamic case the string table is allocated. Changing a dynamic string
704// table would mean altering virtual addresses and thus the memory image. So
705// dynamic string tables should not have an interface to modify them or
706// reconstruct them. This type lets us reconstruct a string table. To avoid
707// this class being used for dynamic string tables (which has happened) the
708// classof method checks that the particular instance is not allocated. This
709// then agrees with the makeSection method used to construct most sections.
712
713 StringTableBuilder StrTabBuilder;
714
715public:
718 }
719
722 void prepareForLayout();
723 Error accept(SectionVisitor &Visitor) const override;
724 Error accept(MutableSectionVisitor &Visitor) override;
725
726 static bool classof(const SectionBase *S) {
728 return false;
729 return S->OriginalType == ELF::SHT_STRTAB;
730 }
731};
732
733// Symbols have a st_shndx field that normally stores an index but occasionally
734// stores a different special value. This enum keeps track of what the st_shndx
735// field means. Most of the values are just copies of the special SHN_* values.
736// SYMBOL_SIMPLE_INDEX means that the st_shndx is just an index of a section.
756};
757
758struct Symbol {
759 uint8_t Binding;
763 std::string Name;
766 uint8_t Type;
768 uint8_t Visibility;
769 bool Referenced = false;
770
771 uint16_t getShndx() const;
772 bool isCommon() const;
773};
774
777
778private:
779 std::vector<uint32_t> Indexes;
780 SymbolTableSection *Symbols = nullptr;
781
782public:
785 assert(Size > 0);
786 Indexes.push_back(Index);
787 }
788
789 void reserve(size_t NumSymbols) {
790 Indexes.reserve(NumSymbols);
791 Size = NumSymbols * 4;
792 }
793 void setSymTab(SymbolTableSection *SymTab) { Symbols = SymTab; }
794 Error initialize(SectionTableRef SecTable) override;
795 void finalize() override;
796 Error accept(SectionVisitor &Visitor) const override;
797 Error accept(MutableSectionVisitor &Visitor) override;
798
800 Name = ".symtab_shndx";
801 Align = 4;
802 EntrySize = 4;
804 }
805};
806
809
810 void setStrTab(StringTableSection *StrTab) { SymbolNames = StrTab; }
811 void assignIndices();
812
813protected:
814 std::vector<std::unique_ptr<Symbol>> Symbols;
817 bool IndicesChanged = false;
818
819 using SymPtr = std::unique_ptr<Symbol>;
820
821public:
823
824 void addSymbol(Twine Name, uint8_t Bind, uint8_t Type, SectionBase *DefinedIn,
825 uint64_t Value, uint8_t Visibility, uint16_t Shndx,
826 uint64_t SymbolSize);
827 void prepareForLayout();
828 // An 'empty' symbol table still contains a null symbol.
829 bool empty() const { return Symbols.size() == 1; }
830 bool indicesChanged() const { return IndicesChanged; }
832 SectionIndexTable = ShndxTable;
833 }
835 void fillShndxTable();
836 const SectionBase *getStrTab() const { return SymbolNames; }
839 void updateSymbols(function_ref<void(Symbol &)> Callable);
840
842 bool AllowBrokenLinks,
843 function_ref<bool(const SectionBase *)> ToRemove) override;
844 Error initialize(SectionTableRef SecTable) override;
845 void finalize() override;
846 Error accept(SectionVisitor &Visitor) const override;
847 Error accept(MutableSectionVisitor &Visitor) override;
848 Error removeSymbols(function_ref<bool(const Symbol &)> ToRemove) override;
850 const DenseMap<SectionBase *, SectionBase *> &FromTo) override;
851
852 static bool classof(const SectionBase *S) {
853 return S->OriginalType == ELF::SHT_SYMTAB;
854 }
855};
856
858 Symbol *RelocSymbol = nullptr;
862};
863
864// All relocation sections denote relocations to apply to another section.
865// However, some relocation sections use a dynamic symbol table and others use
866// a regular symbol table. Because the types of the two symbol tables differ in
867// our system (because they should behave differently) we can't uniformly
868// represent all relocations with the same base class if we expose an interface
869// that mentions the symbol table type. So we split the two base types into two
870// different classes, one which handles the section the relocation is applied to
871// and another which handles the symbol table type. The symbol table type is
872// taken as a type parameter to the class (see RelocSectionWithSymtabBase).
874protected:
876
877public:
878 const SectionBase *getSection() const { return SecToApplyRel; }
880
881 StringRef getNamePrefix() const;
882
883 static bool classof(const SectionBase *S) {
885 S->OriginalType);
886 }
887};
888
889// Takes the symbol table type to use as a parameter so that we can deduplicate
890// that code between the two symbol table types.
891template <class SymTabType>
893 void setSymTab(SymTabType *SymTab) { Symbols = SymTab; }
894
895protected:
897
898 SymTabType *Symbols = nullptr;
899
900public:
901 Error initialize(SectionTableRef SecTable) override;
902 void finalize() override;
903};
904
906 : public RelocSectionWithSymtabBase<SymbolTableSection> {
908
909 std::vector<Relocation> Relocations;
910 const Object &Obj;
911
912public:
913 RelocationSection(const Object &O) : Obj(O) {}
914 void addRelocation(const Relocation &Rel) { Relocations.push_back(Rel); }
915 Error accept(SectionVisitor &Visitor) const override;
916 Error accept(MutableSectionVisitor &Visitor) override;
918 bool AllowBrokenLinks,
919 function_ref<bool(const SectionBase *)> ToRemove) override;
920 Error removeSymbols(function_ref<bool(const Symbol &)> ToRemove) override;
921 void markSymbols() override;
923 const DenseMap<SectionBase *, SectionBase *> &FromTo) override;
924 const Object &getObject() const { return Obj; }
925
926 static bool classof(const SectionBase *S) {
928 return false;
930 }
931};
932
933// TODO: The way stripping and groups interact is complicated
934// and still needs to be worked on.
935
936class GroupSection : public SectionBase {
938 const SymbolTableSection *SymTab = nullptr;
939 Symbol *Sym = nullptr;
940 ELF::Elf32_Word FlagWord;
942
943public:
944 template <class T>
947 // TODO: Contents is present in several classes of the hierarchy.
948 // This needs to be refactored to avoid duplication.
950
952
953 void setSymTab(const SymbolTableSection *SymTabSec) { SymTab = SymTabSec; }
954 void setSymbol(Symbol *S) { Sym = S; }
955 void setFlagWord(ELF::Elf32_Word W) { FlagWord = W; }
956 void addMember(SectionBase *Sec) { GroupMembers.push_back(Sec); }
957
958 Error accept(SectionVisitor &) const override;
959 Error accept(MutableSectionVisitor &Visitor) override;
960 void finalize() override;
962 bool AllowBrokenLinks,
963 function_ref<bool(const SectionBase *)> ToRemove) override;
964 Error removeSymbols(function_ref<bool(const Symbol &)> ToRemove) override;
965 void markSymbols() override;
967 const DenseMap<SectionBase *, SectionBase *> &FromTo) override;
968 void onRemove() override;
969
971 return make_pointee_range(GroupMembers);
972 }
973
974 static bool classof(const SectionBase *S) {
975 return S->OriginalType == ELF::SHT_GROUP;
976 }
977};
978
980public:
982
983 static bool classof(const SectionBase *S) {
984 return S->OriginalType == ELF::SHT_DYNSYM;
985 }
986};
987
988class DynamicSection : public Section {
989public:
991
992 static bool classof(const SectionBase *S) {
993 return S->OriginalType == ELF::SHT_DYNAMIC;
994 }
995};
996
998 : public RelocSectionWithSymtabBase<DynamicSymbolTableSection> {
1000
1001private:
1002 ArrayRef<uint8_t> Contents;
1003
1004public:
1006
1007 Error accept(SectionVisitor &) const override;
1008 Error accept(MutableSectionVisitor &Visitor) override;
1010 bool AllowBrokenLinks,
1011 function_ref<bool(const SectionBase *)> ToRemove) override;
1012
1013 static bool classof(const SectionBase *S) {
1014 if (!(S->OriginalFlags & ELF::SHF_ALLOC))
1015 return false;
1017 }
1018};
1019
1022
1023private:
1024 StringRef FileName;
1025 uint32_t CRC32;
1026
1027 void init(StringRef File);
1028
1029public:
1030 // If we add this section from an external source we can use this ctor.
1031 explicit GnuDebugLinkSection(StringRef File, uint32_t PrecomputedCRC);
1032 Error accept(SectionVisitor &Visitor) const override;
1033 Error accept(MutableSectionVisitor &Visitor) override;
1034};
1035
1036class Reader {
1037public:
1038 virtual ~Reader();
1039 virtual Expected<std::unique_ptr<Object>> create(bool EnsureSymtab) const = 0;
1040};
1041
1042using object::Binary;
1043using object::ELFFile;
1046
1048protected:
1049 std::unique_ptr<Object> Obj;
1050
1051 void initFileHeader();
1052 void initHeaderSegment();
1056
1057public:
1058 BasicELFBuilder() : Obj(std::make_unique<Object>()) {}
1059};
1060
1062 MemoryBuffer *MemBuf;
1063 uint8_t NewSymbolVisibility;
1064 void addData(SymbolTableSection *SymTab);
1065
1066public:
1067 BinaryELFBuilder(MemoryBuffer *MB, uint8_t NewSymbolVisibility)
1068 : MemBuf(MB), NewSymbolVisibility(NewSymbolVisibility) {}
1069
1071};
1072
1074 const std::vector<IHexRecord> &Records;
1075
1076 void addDataSections();
1077
1078public:
1079 IHexELFBuilder(const std::vector<IHexRecord> &Records) : Records(Records) {}
1080
1082};
1083
1084template <class ELFT> class ELFBuilder {
1085private:
1086 using Elf_Addr = typename ELFT::Addr;
1087 using Elf_Shdr = typename ELFT::Shdr;
1088 using Elf_Word = typename ELFT::Word;
1089
1090 const ELFFile<ELFT> &ElfFile;
1091 Object &Obj;
1092 size_t EhdrOffset = 0;
1093 std::optional<StringRef> ExtractPartition;
1094
1095 void setParentSegment(Segment &Child);
1096 Error readProgramHeaders(const ELFFile<ELFT> &HeadersFile);
1097 Error initGroupSection(GroupSection *GroupSec);
1098 Error initSymbolTable(SymbolTableSection *SymTab);
1099 Error readSectionHeaders();
1100 Error readSections(bool EnsureSymtab);
1101 Error findEhdrOffset();
1102 Expected<SectionBase &> makeSection(const Elf_Shdr &Shdr);
1103
1104public:
1105 ELFBuilder(const ELFObjectFile<ELFT> &ElfObj, Object &Obj,
1106 std::optional<StringRef> ExtractPartition);
1107
1108 Error build(bool EnsureSymtab);
1109};
1110
1111class BinaryReader : public Reader {
1112 MemoryBuffer *MemBuf;
1113 uint8_t NewSymbolVisibility;
1114
1115public:
1116 BinaryReader(MemoryBuffer *MB, const uint8_t NewSymbolVisibility)
1117 : MemBuf(MB), NewSymbolVisibility(NewSymbolVisibility) {}
1118 Expected<std::unique_ptr<Object>> create(bool EnsureSymtab) const override;
1119};
1120
1121class IHexReader : public Reader {
1122 MemoryBuffer *MemBuf;
1123
1125 Error parseError(size_t LineNo, Error E) const {
1126 return LineNo == -1U
1127 ? createFileError(MemBuf->getBufferIdentifier(), std::move(E))
1128 : createFileError(MemBuf->getBufferIdentifier(), LineNo,
1129 std::move(E));
1130 }
1131 template <typename... Ts>
1132 Error parseError(size_t LineNo, char const *Fmt, const Ts &...Vals) const {
1134 return parseError(LineNo, std::move(E));
1135 }
1136
1137public:
1138 IHexReader(MemoryBuffer *MB) : MemBuf(MB) {}
1139
1140 Expected<std::unique_ptr<Object>> create(bool EnsureSymtab) const override;
1141};
1142
1143class ELFReader : public Reader {
1144 Binary *Bin;
1145 std::optional<StringRef> ExtractPartition;
1146
1147public:
1148 Expected<std::unique_ptr<Object>> create(bool EnsureSymtab) const override;
1149 explicit ELFReader(Binary *B, std::optional<StringRef> ExtractPartition)
1150 : Bin(B), ExtractPartition(ExtractPartition) {}
1151};
1152
1153class Object {
1154private:
1155 using SecPtr = std::unique_ptr<SectionBase>;
1156 using SegPtr = std::unique_ptr<Segment>;
1157
1158 std::vector<SecPtr> Sections;
1159 std::vector<SegPtr> Segments;
1160 std::vector<SecPtr> RemovedSections;
1162
1163 static bool sectionIsAlloc(const SectionBase &Sec) {
1164 return Sec.Flags & ELF::SHF_ALLOC;
1165 };
1166
1167public:
1168 template <class T>
1170 typename std::vector<std::unique_ptr<T>>::const_iterator>>;
1171
1172 // It is often the case that the ELF header and the program header table are
1173 // not present in any segment. This could be a problem during file layout,
1174 // because other segments may get assigned an offset where either of the
1175 // two should reside, which will effectively corrupt the resulting binary.
1176 // Other than that we use these segments to track program header offsets
1177 // when they may not follow the ELF header.
1180
1182 uint8_t OSABI;
1183 uint8_t ABIVersion;
1190
1191 bool HadShdrs = true;
1192 bool MustBeRelocatable = false;
1196
1197 bool IsMips64EL = false;
1198
1199 SectionTableRef sections() const { return SectionTableRef(Sections); }
1202 decltype(&sectionIsAlloc)>>
1204 return make_filter_range(make_pointee_range(Sections), sectionIsAlloc);
1205 }
1206
1207 const auto &getUpdatedSections() const { return UpdatedSections; }
1209
1211 auto SecIt =
1212 find_if(Sections, [&](const SecPtr &Sec) { return Sec->Name == Name; });
1213 return SecIt == Sections.end() ? nullptr : SecIt->get();
1214 }
1215 SectionTableRef removedSections() { return SectionTableRef(RemovedSections); }
1216
1218
1219 Error removeSections(bool AllowBrokenLinks,
1220 std::function<bool(const SectionBase &)> ToRemove);
1224 template <class T, class... Ts> T &addSection(Ts &&...Args) {
1225 auto Sec = std::make_unique<T>(std::forward<Ts>(Args)...);
1226 auto Ptr = Sec.get();
1227 MustBeRelocatable |= isa<RelocationSection>(*Ptr);
1228 Sections.emplace_back(std::move(Sec));
1229 Ptr->Index = Sections.size();
1230 return *Ptr;
1231 }
1234 Segments.emplace_back(std::make_unique<Segment>(Data));
1235 return *Segments.back();
1236 }
1237 bool isRelocatable() const {
1238 return (Type != ELF::ET_DYN && Type != ELF::ET_EXEC) || MustBeRelocatable;
1239 }
1240};
1241
1242} // end namespace elf
1243} // end namespace objcopy
1244} // end namespace llvm
1245
1246#endif // LLVM_LIB_OBJCOPY_ELF_ELFOBJECT_H
ReachingDefAnalysis InstSet & ToRemove
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
Elf_Shdr Shdr
uint64_t Addr
std::string Name
#define MAKE_SEC_WRITER_FRIEND
Definition: ELFObject.h:171
RelaxConfig Config
Definition: ELF_riscv.cpp:506
Symbol * Sym
Definition: ELF_riscv.cpp:479
#define T
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
raw_pwrite_stream & OS
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: ArrayRef.h:41
size_t size() const
size - Get the array size.
Definition: ArrayRef.h:165
const T * data() const
Definition: ArrayRef.h:162
Lightweight error class with error context and mandatory checking.
Definition: Error.h:160
Tagged union holding either a T or a Error.
Definition: Error.h:481
This interface provides simple read-only access to a block of memory, and provides simple methods for...
Definition: MemoryBuffer.h:51
virtual StringRef getBufferIdentifier() const
Return an identifier for this buffer, typically the filename it was read from.
Definition: MemoryBuffer.h:76
void push_back(const T &Elt)
Definition: SmallVector.h:426
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1209
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
std::string str() const
str - Get the contents as an std::string.
Definition: StringRef.h:215
Utility for building string tables with deduplicated suffixes.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:81
std::string str() const
Return the twine contents as a std::string.
Definition: Twine.cpp:17
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
LLVM Value Representation.
Definition: Value.h:74
This class is an extension of MemoryBuffer, which allows copy-on-write access to the underlying conte...
Definition: MemoryBuffer.h:181
Specialization of filter_iterator_base for forward iteration only.
Definition: STLExtras.h:497
An efficient, type-erasing, non-owning reference to a callable.
A range adaptor for a pair of iterators.
Error checkSection(const SectionBase &S) const
Definition: ELFObject.cpp:2758
ASCIIHexWriter(Object &Obj, raw_ostream &OS, StringRef OutputFile)
Definition: ELFObject.h:380
std::vector< const SectionBase * > Sections
Definition: ELFObject.h:387
virtual Expected< size_t > getTotalSize(WritableMemoryBuffer &EmptyBuffer) const =0
StringTableSection * addStrTab()
Definition: ELFObject.cpp:1284
SymbolTableSection * addSymTab(StringTableSection *StrTab)
Definition: ELFObject.cpp:1292
std::unique_ptr< Object > Obj
Definition: ELFObject.h:1049
BinaryELFBuilder(MemoryBuffer *MB, uint8_t NewSymbolVisibility)
Definition: ELFObject.h:1067
Expected< std::unique_ptr< Object > > build()
Definition: ELFObject.cpp:1338
BinaryReader(MemoryBuffer *MB, const uint8_t NewSymbolVisibility)
Definition: ELFObject.h:1116
Expected< std::unique_ptr< Object > > create(bool EnsureSymtab) const override
Definition: ELFObject.cpp:1957
Error visit(const SymbolTableSection &Sec) override
Definition: ELFObject.cpp:167
BinarySectionWriter(WritableMemoryBuffer &Buf)
Definition: ELFObject.h:193
BinaryWriter(Object &Obj, raw_ostream &Out, const CommonConfig &Config)
Definition: ELFObject.h:373
Error accept(SectionVisitor &Visitor) const override
Definition: ELFObject.cpp:584
static bool classof(const SectionBase *S)
Definition: ELFObject.h:681
Error accept(SectionVisitor &Visitor) const override
Definition: ELFObject.cpp:505
DecompressedSection(const CompressedSection &Sec)
Definition: ELFObject.h:691
Error accept(SectionVisitor &) const override
Definition: ELFObject.cpp:1039
DynamicRelocationSection(ArrayRef< uint8_t > Data)
Definition: ELFObject.h:1005
static bool classof(const SectionBase *S)
Definition: ELFObject.h:1013
Error removeSectionReferences(bool AllowBrokenLinks, function_ref< bool(const SectionBase *)> ToRemove) override
Definition: ELFObject.cpp:1047
DynamicSection(ArrayRef< uint8_t > Data)
Definition: ELFObject.h:990
static bool classof(const SectionBase *S)
Definition: ELFObject.h:992
static bool classof(const SectionBase *S)
Definition: ELFObject.h:983
DynamicSymbolTableSection(ArrayRef< uint8_t > Data)
Definition: ELFObject.h:981
Error build(bool EnsureSymtab)
Definition: ELFObject.cpp:1923
ELFReader(Binary *B, std::optional< StringRef > ExtractPartition)
Definition: ELFObject.h:1149
Expected< std::unique_ptr< Object > > create(bool EnsureSymtab) const override
Definition: ELFObject.cpp:1996
Error visit(Section &Sec) override
Definition: ELFObject.cpp:85
ELFSectionWriter(WritableMemoryBuffer &Buf)
Definition: ELFObject.h:146
Error visit(const SymbolTableSection &Sec) override
Definition: ELFObject.cpp:865
GroupSection(ArrayRef< uint8_t > Data)
Definition: ELFObject.h:951
ConstRange< SectionBase > members() const
Definition: ELFObject.h:970
void setSymTab(const SymbolTableSection *SymTabSec)
Definition: ELFObject.h:953
void replaceSectionReferences(const DenseMap< SectionBase *, SectionBase * > &FromTo) override
Definition: ELFObject.cpp:1122
Error accept(SectionVisitor &) const override
Definition: ELFObject.cpp:1210
static bool classof(const SectionBase *S)
Definition: ELFObject.h:974
ArrayRef< uint8_t > Contents
Definition: ELFObject.h:949
void addMember(SectionBase *Sec)
Definition: ELFObject.h:956
Error removeSectionReferences(bool AllowBrokenLinks, function_ref< bool(const SectionBase *)> ToRemove) override
Definition: ELFObject.cpp:1092
void setFlagWord(ELF::Elf32_Word W)
Definition: ELFObject.h:955
Error removeSymbols(function_ref< bool(const Symbol &)> ToRemove) override
Definition: ELFObject.cpp:1108
IHexELFBuilder(const std::vector< IHexRecord > &Records)
Definition: ELFObject.h:1079
Expected< std::unique_ptr< Object > > build()
Definition: ELFObject.cpp:1398
IHexReader(MemoryBuffer *MB)
Definition: ELFObject.h:1138
Expected< std::unique_ptr< Object > > create(bool EnsureSymtab) const override
Definition: ELFObject.cpp:1988
IHexSectionWriterBase(WritableMemoryBuffer &Buf)
Definition: ELFObject.h:290
void writeSection(const SectionBase *Sec, ArrayRef< uint8_t > Data)
Definition: ELFObject.cpp:354
Error visit(const Section &Sec) final
Definition: ELFObject.cpp:403
virtual void writeData(uint8_t Type, uint16_t Addr, ArrayRef< uint8_t > Data)
Definition: ELFObject.cpp:398
IHexSectionWriter(WritableMemoryBuffer &Buf)
Definition: ELFObject.h:304
void writeData(uint8_t Type, uint16_t Addr, ArrayRef< uint8_t > Data) override
Definition: ELFObject.cpp:428
Error visit(const StringTableSection &Sec) override
Definition: ELFObject.cpp:435
IHexWriter(Object &Obj, raw_ostream &Out, StringRef OutputFile)
Definition: ELFObject.h:397
virtual Error visit(OwnedDataSection &Sec)=0
virtual Error visit(SymbolTableSection &Sec)=0
virtual Error visit(DecompressedSection &Sec)=0
virtual Error visit(StringTableSection &Sec)=0
virtual Error visit(GnuDebugLinkSection &Sec)=0
virtual Error visit(SectionIndexSection &Sec)=0
virtual Error visit(DynamicRelocationSection &Sec)=0
virtual Error visit(Section &Sec)=0
virtual Error visit(GroupSection &Sec)=0
virtual Error visit(CompressedSection &Sec)=0
virtual Error visit(RelocationSection &Sec)=0
SectionTableRef sections() const
Definition: ELFObject.h:1199
StringTableSection * SectionNames
Definition: ELFObject.h:1193
SectionTableRef removedSections()
Definition: ELFObject.h:1215
bool isRelocatable() const
Definition: ELFObject.h:1237
iterator_range< filter_iterator< pointee_iterator< std::vector< SecPtr >::const_iterator >, decltype(&sectionIsAlloc)> > allocSections() const
Definition: ELFObject.h:1203
Error updateSection(StringRef Name, ArrayRef< uint8_t > Data)
Definition: ELFObject.cpp:2160
SectionIndexSection * SectionIndexTable
Definition: ELFObject.h:1195
Error removeSymbols(function_ref< bool(const Symbol &)> ToRemove)
Definition: ELFObject.cpp:2276
T & addSection(Ts &&...Args)
Definition: ELFObject.h:1224
Error removeSections(bool AllowBrokenLinks, std::function< bool(const SectionBase &)> ToRemove)
Definition: ELFObject.cpp:2191
Segment & addSegment(ArrayRef< uint8_t > Data)
Definition: ELFObject.h:1233
ConstRange< Segment > segments() const
Definition: ELFObject.h:1217
SymbolTableSection * SymbolTable
Definition: ELFObject.h:1194
Error compressOrDecompressSections(const CommonConfig &Config)
Definition: ELFObjcopy.cpp:217
const auto & getUpdatedSections() const
Definition: ELFObject.h:1207
SectionBase * findSection(StringRef Name)
Definition: ELFObject.h:1210
Error replaceSections(const DenseMap< SectionBase *, SectionBase * > &FromTo)
Definition: ELFObject.cpp:2252
void appendHexData(StringRef HexData)
Definition: ELFObject.cpp:521
OwnedDataSection(const Twine &SecName, uint64_t SecAddr, uint64_t SecFlags, uint64_t SecOff)
Definition: ELFObject.h:639
Error accept(SectionVisitor &Sec) const override
Definition: ELFObject.cpp:513
OwnedDataSection(StringRef SecName, ArrayRef< uint8_t > Data)
Definition: ELFObject.h:631
OwnedDataSection(SectionBase &S, ArrayRef< uint8_t > Data)
Definition: ELFObject.h:648
bool hasContents() const override
Definition: ELFObject.h:656
virtual Expected< std::unique_ptr< Object > > create(bool EnsureSymtab) const =0
Error initialize(SectionTableRef SecTable) override
Definition: ELFObject.cpp:930
const SectionBase * getSection() const
Definition: ELFObject.h:878
static bool classof(const SectionBase *S)
Definition: ELFObject.h:883
const Object & getObject() const
Definition: ELFObject.h:924
void addRelocation(const Relocation &Rel)
Definition: ELFObject.h:914
Error accept(SectionVisitor &Visitor) const override
Definition: ELFObject.cpp:1002
Error removeSymbols(function_ref< bool(const Symbol &)> ToRemove) override
Definition: ELFObject.cpp:1010
void replaceSectionReferences(const DenseMap< SectionBase *, SectionBase * > &FromTo) override
Definition: ELFObject.cpp:1027
static bool classof(const SectionBase *S)
Definition: ELFObject.h:926
Error removeSectionReferences(bool AllowBrokenLinks, function_ref< bool(const SectionBase *)> ToRemove) override
Definition: ELFObject.cpp:902
virtual void writeRecord(SRecord &Record, uint64_t Off)=0
void writeSection(const SectionBase &S, ArrayRef< uint8_t > Data)
Definition: ELFObject.cpp:2911
Error visit(const Section &S) override
Definition: ELFObject.cpp:2878
SRECSectionWriterBase(WritableMemoryBuffer &Buf, uint64_t StartOffset)
Definition: ELFObject.h:460
Error visit(const StringTableSection &Sec) override
Definition: ELFObject.cpp:2926
void writeRecord(SRecord &Record, uint64_t Off) override
Definition: ELFObject.cpp:2893
SRECSectionWriter(WritableMemoryBuffer &Buf, uint64_t Offset)
Definition: ELFObject.h:501
SRECSizeCalculator(WritableMemoryBuffer &EmptyBuffer, uint64_t Offset)
Definition: ELFObject.h:492
void writeRecord(SRecord &Record, uint64_t Off) override
Definition: ELFObject.h:496
SRECWriter(Object &Obj, raw_ostream &OS, StringRef OutputFile)
Definition: ELFObject.h:409
ArrayRef< uint8_t > OriginalData
Definition: ELFObject.h:531
virtual Error initialize(SectionTableRef SecTable)
Definition: ELFObject.cpp:62
virtual Error removeSectionReferences(bool AllowBrokenLinks, function_ref< bool(const SectionBase *)> ToRemove)
Definition: ELFObject.cpp:53
virtual void restoreSymTabLink(SymbolTableSection &)
Definition: ELFObject.h:555
virtual void replaceSectionReferences(const DenseMap< SectionBase *, SectionBase * > &)
Definition: ELFObject.cpp:65
virtual Error accept(MutableSectionVisitor &Visitor)=0
virtual ~SectionBase()=default
virtual bool hasContents() const
Definition: ELFObject.h:551
SectionBase(const SectionBase &)=default
virtual Error removeSymbols(function_ref< bool(const Symbol &)> ToRemove)
Definition: ELFObject.cpp:58
virtual Error accept(SectionVisitor &Visitor) const =0
void setSymTab(SymbolTableSection *SymTab)
Definition: ELFObject.h:793
Error accept(SectionVisitor &Visitor) const override
Definition: ELFObject.cpp:643
void reserve(size_t NumSymbols)
Definition: ELFObject.h:789
Error initialize(SectionTableRef SecTable) override
Definition: ELFObject.cpp:624
pointee_iterator< const std::unique_ptr< SectionBase > * > iterator
Definition: ELFObject.h:54
Expected< T * > getSectionOfType(uint32_t Index, Twine IndexErrMsg, Twine TypeErrMsg)
Definition: ELFObject.cpp:1693
SectionTableRef(ArrayRef< std::unique_ptr< SectionBase > > Secs)
Definition: ELFObject.h:56
SectionTableRef(const SectionTableRef &)=default
Expected< SectionBase * > getSection(uint32_t Index, Twine ErrMsg)
Definition: ELFObject.cpp:1685
virtual Error visit(const CompressedSection &Sec)=0
virtual Error visit(const Section &Sec)=0
virtual Error visit(const DecompressedSection &Sec)=0
virtual Error visit(const GroupSection &Sec)=0
virtual Error visit(const SymbolTableSection &Sec)=0
virtual Error visit(const RelocationSection &Sec)=0
virtual Error visit(const SectionIndexSection &Sec)=0
virtual Error visit(const DynamicRelocationSection &Sec)=0
virtual Error visit(const GnuDebugLinkSection &Sec)=0
virtual Error visit(const StringTableSection &Sec)=0
virtual Error visit(const OwnedDataSection &Sec)=0
Error visit(const GroupSection &Sec) override=0
Error visit(const RelocationSection &Sec) override=0
Error visit(const SectionIndexSection &Sec) override=0
Error visit(const CompressedSection &Sec) override=0
Error visit(const Section &Sec) override
Definition: ELFObject.cpp:189
Error visit(const GnuDebugLinkSection &Sec) override=0
Error visit(const SymbolTableSection &Sec) override=0
WritableMemoryBuffer & Out
Definition: ELFObject.h:109
Error visit(const DecompressedSection &Sec) override=0
SectionWriter(WritableMemoryBuffer &Buf)
Definition: ELFObject.h:126
Error removeSectionReferences(bool AllowBrokenLinks, function_ref< bool(const SectionBase *)> ToRemove) override
Definition: ELFObject.cpp:1067
Error initialize(SectionTableRef SecTable) override
Definition: ELFObject.cpp:1136
Section(ArrayRef< uint8_t > Data)
Definition: ELFObject.h:610
void restoreSymTabLink(SymbolTableSection &SymTab) override
Definition: ELFObject.cpp:451
bool hasContents() const override
Definition: ELFObject.h:619
Error accept(SectionVisitor &Visitor) const override
Definition: ELFObject.cpp:443
void addSection(const SectionBase *Sec)
Definition: ELFObject.h:597
Segment(ArrayRef< uint8_t > Data)
Definition: ELFObject.h:587
ArrayRef< uint8_t > Contents
Definition: ELFObject.h:584
void removeSection(const SectionBase *Sec)
Definition: ELFObject.h:596
const SectionBase * firstSection() const
Definition: ELFObject.h:590
ArrayRef< uint8_t > getContents() const
Definition: ELFObject.h:599
std::set< const SectionBase *, SectionCompare > Sections
Definition: ELFObject.h:585
static bool classof(const SectionBase *S)
Definition: ELFObject.h:726
uint32_t findIndex(StringRef Name) const
Definition: ELFObject.cpp:594
Error accept(SectionVisitor &Visitor) const override
Definition: ELFObject.cpp:609
const SectionBase * getStrTab() const
Definition: ELFObject.h:836
Error removeSectionReferences(bool AllowBrokenLinks, function_ref< bool(const SectionBase *)> ToRemove) override
Definition: ELFObject.cpp:742
const SectionIndexSection * getShndxTable() const
Definition: ELFObject.h:834
std::vector< std::unique_ptr< Symbol > > Symbols
Definition: ELFObject.h:814
SectionIndexSection * SectionIndexTable
Definition: ELFObject.h:816
Error accept(SectionVisitor &Visitor) const override
Definition: ELFObject.cpp:881
void addSymbol(Twine Name, uint8_t Bind, uint8_t Type, SectionBase *DefinedIn, uint64_t Value, uint8_t Visibility, uint16_t Shndx, uint64_t SymbolSize)
Definition: ELFObject.cpp:717
void updateSymbols(function_ref< void(Symbol &)> Callable)
Definition: ELFObject.cpp:759
static bool classof(const SectionBase *S)
Definition: ELFObject.h:852
Expected< const Symbol * > getSymbolByIndex(uint32_t Index) const
Definition: ELFObject.cpp:848
Error removeSymbols(function_ref< bool(const Symbol &)> ToRemove) override
Definition: ELFObject.cpp:768
Error initialize(SectionTableRef SecTable) override
Definition: ELFObject.cpp:789
void replaceSectionReferences(const DenseMap< SectionBase *, SectionBase * > &FromTo) override
Definition: ELFObject.cpp:782
std::unique_ptr< Symbol > SymPtr
Definition: ELFObject.h:819
void setShndxTable(SectionIndexSection *ShndxTable)
Definition: ELFObject.h:831
StringTableSection * SymbolNames
Definition: ELFObject.h:815
virtual Error finalize()=0
virtual Error write()=0
std::unique_ptr< WritableMemoryBuffer > Buf
Definition: ELFObject.h:313
Writer(Object &O, raw_ostream &Out)
Definition: ELFObject.h:321
Represents a GOFF physical record.
Definition: GOFF.h:31
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:52
@ SHN_MIPS_TEXT
Definition: ELF.h:575
@ SHN_MIPS_DATA
Definition: ELF.h:576
@ SHN_MIPS_SUNDEFINED
Definition: ELF.h:578
@ SHN_MIPS_SCOMMON
Definition: ELF.h:577
@ SHN_MIPS_ACOMMON
Definition: ELF.h:574
@ ET_DYN
Definition: ELF.h:119
@ ET_EXEC
Definition: ELF.h:118
@ SHT_STRTAB
Definition: ELF.h:1091
@ SHT_GROUP
Definition: ELF.h:1103
@ SHT_PROGBITS
Definition: ELF.h:1089
@ SHT_REL
Definition: ELF.h:1097
@ SHT_NULL
Definition: ELF.h:1088
@ SHT_NOBITS
Definition: ELF.h:1096
@ SHT_SYMTAB
Definition: ELF.h:1090
@ SHT_CREL
Definition: ELF.h:1110
@ SHT_DYNAMIC
Definition: ELF.h:1094
@ SHT_SYMTAB_SHNDX
Definition: ELF.h:1104
@ SHT_RELA
Definition: ELF.h:1092
@ SHT_DYNSYM
Definition: ELF.h:1099
@ SHN_HEXAGON_SCOMMON_2
Definition: ELF.h:657
@ SHN_HEXAGON_SCOMMON_4
Definition: ELF.h:658
@ SHN_HEXAGON_SCOMMON_8
Definition: ELF.h:659
@ SHN_HEXAGON_SCOMMON
Definition: ELF.h:655
@ SHN_XINDEX
Definition: ELF.h:1082
@ SHN_HIOS
Definition: ELF.h:1079
@ SHN_ABS
Definition: ELF.h:1080
@ SHN_COMMON
Definition: ELF.h:1081
@ SHN_LOOS
Definition: ELF.h:1078
@ SHN_LOPROC
Definition: ELF.h:1076
@ SHN_UNDEF
Definition: ELF.h:1074
@ SHN_HIPROC
Definition: ELF.h:1077
@ SHF_ALLOC
Definition: ELF.h:1186
@ SHF_COMPRESSED
Definition: ELF.h:1214
@ SHN_AMDGPU_LDS
Definition: ELF.h:1893
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
Error createFileError(const Twine &F, Error E)
Concatenate a source file path and/or name with an Error.
Definition: Error.h:1380
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
Definition: Error.h:1286
iterator_range< pointee_iterator< WrappedIteratorT > > make_pointee_range(RangeT &&Range)
Definition: iterator.h:336
iterator_range< filter_iterator< detail::IterOfRange< RangeT >, PredicateT > > make_filter_range(RangeT &&Range, PredicateT Pred)
Convenience function that takes a range of elements and a predicate, and return a new filter_iterator...
Definition: STLExtras.h:572
DebugCompressionType
Definition: Compression.h:27
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1749
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
Definition: STLExtras.h:1886
Implement std::hash so that hash_code can be used in STL containers.
Definition: BitVector.h:858
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition: Alignment.h:39
static IHexLineData getLine(uint8_t Type, uint16_t Addr, ArrayRef< uint8_t > Data)
Definition: ELFObject.cpp:235
static uint8_t getChecksum(StringRef S)
Definition: ELFObject.cpp:225
static size_t getLength(size_t DataSize)
Definition: ELFObject.h:209
static size_t getLineLength(size_t DataSize)
Definition: ELFObject.h:215
uint8_t getAddressSize() const
Definition: ELFObject.cpp:2971
static SRecord getHeader(StringRef FileName)
Definition: ELFObject.cpp:3000
uint8_t getChecksum() const
Definition: ELFObject.cpp:2955
SRecLineData toString() const
Definition: ELFObject.cpp:2935
static uint8_t getType(uint32_t Address)
Definition: ELFObject.cpp:2992
ArrayRef< uint8_t > Data
Definition: ELFObject.h:424
uint16_t getShndx() const
Definition: ELFObject.cpp:687
SectionBase * DefinedIn
Definition: ELFObject.h:760
SymbolShndxType ShndxType
Definition: ELFObject.h:761
An iterator type that allows iterating over the pointees via some other iterator.
Definition: iterator.h:324
Definition: regcomp.c:192