LLVM 19.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 }
886};
887
888// Takes the symbol table type to use as a parameter so that we can deduplicate
889// that code between the two symbol table types.
890template <class SymTabType>
892 void setSymTab(SymTabType *SymTab) { Symbols = SymTab; }
893
894protected:
896
897 SymTabType *Symbols = nullptr;
898
899public:
900 Error initialize(SectionTableRef SecTable) override;
901 void finalize() override;
902};
903
905 : public RelocSectionWithSymtabBase<SymbolTableSection> {
907
908 std::vector<Relocation> Relocations;
909 const Object &Obj;
910
911public:
912 RelocationSection(const Object &O) : Obj(O) {}
913 void addRelocation(Relocation Rel) { Relocations.push_back(Rel); }
914 Error accept(SectionVisitor &Visitor) const override;
915 Error accept(MutableSectionVisitor &Visitor) override;
917 bool AllowBrokenLinks,
918 function_ref<bool(const SectionBase *)> ToRemove) override;
919 Error removeSymbols(function_ref<bool(const Symbol &)> ToRemove) override;
920 void markSymbols() override;
922 const DenseMap<SectionBase *, SectionBase *> &FromTo) override;
923 const Object &getObject() const { return Obj; }
924
925 static bool classof(const SectionBase *S) {
927 return false;
929 }
930};
931
932// TODO: The way stripping and groups interact is complicated
933// and still needs to be worked on.
934
935class GroupSection : public SectionBase {
937 const SymbolTableSection *SymTab = nullptr;
938 Symbol *Sym = nullptr;
939 ELF::Elf32_Word FlagWord;
941
942public:
943 // TODO: Contents is present in several classes of the hierarchy.
944 // This needs to be refactored to avoid duplication.
946
948
949 void setSymTab(const SymbolTableSection *SymTabSec) { SymTab = SymTabSec; }
950 void setSymbol(Symbol *S) { Sym = S; }
951 void setFlagWord(ELF::Elf32_Word W) { FlagWord = W; }
952 void addMember(SectionBase *Sec) { GroupMembers.push_back(Sec); }
953
954 Error accept(SectionVisitor &) const override;
955 Error accept(MutableSectionVisitor &Visitor) override;
956 void finalize() override;
958 bool AllowBrokenLinks,
959 function_ref<bool(const SectionBase *)> ToRemove) override;
960 Error removeSymbols(function_ref<bool(const Symbol &)> ToRemove) override;
961 void markSymbols() override;
963 const DenseMap<SectionBase *, SectionBase *> &FromTo) override;
964 void onRemove() override;
965
966 static bool classof(const SectionBase *S) {
967 return S->OriginalType == ELF::SHT_GROUP;
968 }
969};
970
972public:
974
975 static bool classof(const SectionBase *S) {
976 return S->OriginalType == ELF::SHT_DYNSYM;
977 }
978};
979
980class DynamicSection : public Section {
981public:
983
984 static bool classof(const SectionBase *S) {
985 return S->OriginalType == ELF::SHT_DYNAMIC;
986 }
987};
988
990 : public RelocSectionWithSymtabBase<DynamicSymbolTableSection> {
992
993private:
994 ArrayRef<uint8_t> Contents;
995
996public:
998
999 Error accept(SectionVisitor &) const override;
1000 Error accept(MutableSectionVisitor &Visitor) override;
1002 bool AllowBrokenLinks,
1003 function_ref<bool(const SectionBase *)> ToRemove) override;
1004
1005 static bool classof(const SectionBase *S) {
1006 if (!(S->OriginalFlags & ELF::SHF_ALLOC))
1007 return false;
1009 }
1010};
1011
1014
1015private:
1016 StringRef FileName;
1017 uint32_t CRC32;
1018
1019 void init(StringRef File);
1020
1021public:
1022 // If we add this section from an external source we can use this ctor.
1023 explicit GnuDebugLinkSection(StringRef File, uint32_t PrecomputedCRC);
1024 Error accept(SectionVisitor &Visitor) const override;
1025 Error accept(MutableSectionVisitor &Visitor) override;
1026};
1027
1028class Reader {
1029public:
1030 virtual ~Reader();
1031 virtual Expected<std::unique_ptr<Object>> create(bool EnsureSymtab) const = 0;
1032};
1033
1034using object::Binary;
1035using object::ELFFile;
1038
1040protected:
1041 std::unique_ptr<Object> Obj;
1042
1043 void initFileHeader();
1044 void initHeaderSegment();
1048
1049public:
1050 BasicELFBuilder() : Obj(std::make_unique<Object>()) {}
1051};
1052
1054 MemoryBuffer *MemBuf;
1055 uint8_t NewSymbolVisibility;
1056 void addData(SymbolTableSection *SymTab);
1057
1058public:
1059 BinaryELFBuilder(MemoryBuffer *MB, uint8_t NewSymbolVisibility)
1060 : MemBuf(MB), NewSymbolVisibility(NewSymbolVisibility) {}
1061
1063};
1064
1066 const std::vector<IHexRecord> &Records;
1067
1068 void addDataSections();
1069
1070public:
1071 IHexELFBuilder(const std::vector<IHexRecord> &Records) : Records(Records) {}
1072
1074};
1075
1076template <class ELFT> class ELFBuilder {
1077private:
1078 using Elf_Addr = typename ELFT::Addr;
1079 using Elf_Shdr = typename ELFT::Shdr;
1080 using Elf_Word = typename ELFT::Word;
1081
1082 const ELFFile<ELFT> &ElfFile;
1083 Object &Obj;
1084 size_t EhdrOffset = 0;
1085 std::optional<StringRef> ExtractPartition;
1086
1087 void setParentSegment(Segment &Child);
1088 Error readProgramHeaders(const ELFFile<ELFT> &HeadersFile);
1089 Error initGroupSection(GroupSection *GroupSec);
1090 Error initSymbolTable(SymbolTableSection *SymTab);
1091 Error readSectionHeaders();
1092 Error readSections(bool EnsureSymtab);
1093 Error findEhdrOffset();
1094 Expected<SectionBase &> makeSection(const Elf_Shdr &Shdr);
1095
1096public:
1097 ELFBuilder(const ELFObjectFile<ELFT> &ElfObj, Object &Obj,
1098 std::optional<StringRef> ExtractPartition);
1099
1100 Error build(bool EnsureSymtab);
1101};
1102
1103class BinaryReader : public Reader {
1104 MemoryBuffer *MemBuf;
1105 uint8_t NewSymbolVisibility;
1106
1107public:
1108 BinaryReader(MemoryBuffer *MB, const uint8_t NewSymbolVisibility)
1109 : MemBuf(MB), NewSymbolVisibility(NewSymbolVisibility) {}
1110 Expected<std::unique_ptr<Object>> create(bool EnsureSymtab) const override;
1111};
1112
1113class IHexReader : public Reader {
1114 MemoryBuffer *MemBuf;
1115
1117 Error parseError(size_t LineNo, Error E) const {
1118 return LineNo == -1U
1119 ? createFileError(MemBuf->getBufferIdentifier(), std::move(E))
1120 : createFileError(MemBuf->getBufferIdentifier(), LineNo,
1121 std::move(E));
1122 }
1123 template <typename... Ts>
1124 Error parseError(size_t LineNo, char const *Fmt, const Ts &...Vals) const {
1126 return parseError(LineNo, std::move(E));
1127 }
1128
1129public:
1130 IHexReader(MemoryBuffer *MB) : MemBuf(MB) {}
1131
1132 Expected<std::unique_ptr<Object>> create(bool EnsureSymtab) const override;
1133};
1134
1135class ELFReader : public Reader {
1136 Binary *Bin;
1137 std::optional<StringRef> ExtractPartition;
1138
1139public:
1140 Expected<std::unique_ptr<Object>> create(bool EnsureSymtab) const override;
1141 explicit ELFReader(Binary *B, std::optional<StringRef> ExtractPartition)
1142 : Bin(B), ExtractPartition(ExtractPartition) {}
1143};
1144
1145class Object {
1146private:
1147 using SecPtr = std::unique_ptr<SectionBase>;
1148 using SegPtr = std::unique_ptr<Segment>;
1149
1150 std::vector<SecPtr> Sections;
1151 std::vector<SegPtr> Segments;
1152 std::vector<SecPtr> RemovedSections;
1154
1155 static bool sectionIsAlloc(const SectionBase &Sec) {
1156 return Sec.Flags & ELF::SHF_ALLOC;
1157 };
1158
1159public:
1160 template <class T>
1162 typename std::vector<std::unique_ptr<T>>::const_iterator>>;
1163
1164 // It is often the case that the ELF header and the program header table are
1165 // not present in any segment. This could be a problem during file layout,
1166 // because other segments may get assigned an offset where either of the
1167 // two should reside, which will effectively corrupt the resulting binary.
1168 // Other than that we use these segments to track program header offsets
1169 // when they may not follow the ELF header.
1172
1174 uint8_t OSABI;
1175 uint8_t ABIVersion;
1182
1183 bool HadShdrs = true;
1184 bool MustBeRelocatable = false;
1188
1189 bool IsMips64EL = false;
1190
1191 SectionTableRef sections() const { return SectionTableRef(Sections); }
1194 decltype(&sectionIsAlloc)>>
1196 return make_filter_range(make_pointee_range(Sections), sectionIsAlloc);
1197 }
1198
1199 const auto &getUpdatedSections() const { return UpdatedSections; }
1201
1203 auto SecIt =
1204 find_if(Sections, [&](const SecPtr &Sec) { return Sec->Name == Name; });
1205 return SecIt == Sections.end() ? nullptr : SecIt->get();
1206 }
1207 SectionTableRef removedSections() { return SectionTableRef(RemovedSections); }
1208
1210
1211 Error removeSections(bool AllowBrokenLinks,
1212 std::function<bool(const SectionBase &)> ToRemove);
1215 template <class T, class... Ts> T &addSection(Ts &&...Args) {
1216 auto Sec = std::make_unique<T>(std::forward<Ts>(Args)...);
1217 auto Ptr = Sec.get();
1218 MustBeRelocatable |= isa<RelocationSection>(*Ptr);
1219 Sections.emplace_back(std::move(Sec));
1220 Ptr->Index = Sections.size();
1221 return *Ptr;
1222 }
1225 Segments.emplace_back(std::make_unique<Segment>(Data));
1226 return *Segments.back();
1227 }
1228 bool isRelocatable() const {
1229 return (Type != ELF::ET_DYN && Type != ELF::ET_EXEC) || MustBeRelocatable;
1230 }
1231};
1232
1233} // end namespace elf
1234} // end namespace objcopy
1235} // end namespace llvm
1236
1237#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:474
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:222
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:506
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:2716
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:1258
SymbolTableSection * addSymTab(StringTableSection *StrTab)
Definition: ELFObject.cpp:1266
std::unique_ptr< Object > Obj
Definition: ELFObject.h:1041
BinaryELFBuilder(MemoryBuffer *MB, uint8_t NewSymbolVisibility)
Definition: ELFObject.h:1059
Expected< std::unique_ptr< Object > > build()
Definition: ELFObject.cpp:1312
BinaryReader(MemoryBuffer *MB, const uint8_t NewSymbolVisibility)
Definition: ELFObject.h:1108
Expected< std::unique_ptr< Object > > create(bool EnsureSymtab) const override
Definition: ELFObject.cpp:1923
Error visit(const SymbolTableSection &Sec) override
Definition: ELFObject.cpp:148
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:564
static bool classof(const SectionBase *S)
Definition: ELFObject.h:681
Error accept(SectionVisitor &Visitor) const override
Definition: ELFObject.cpp:486
DecompressedSection(const CompressedSection &Sec)
Definition: ELFObject.h:691
Error accept(SectionVisitor &) const override
Definition: ELFObject.cpp:1013
DynamicRelocationSection(ArrayRef< uint8_t > Data)
Definition: ELFObject.h:997
static bool classof(const SectionBase *S)
Definition: ELFObject.h:1005
Error removeSectionReferences(bool AllowBrokenLinks, function_ref< bool(const SectionBase *)> ToRemove) override
Definition: ELFObject.cpp:1021
DynamicSection(ArrayRef< uint8_t > Data)
Definition: ELFObject.h:982
static bool classof(const SectionBase *S)
Definition: ELFObject.h:984
static bool classof(const SectionBase *S)
Definition: ELFObject.h:975
DynamicSymbolTableSection(ArrayRef< uint8_t > Data)
Definition: ELFObject.h:973
Error build(bool EnsureSymtab)
Definition: ELFObject.cpp:1889
ELFReader(Binary *B, std::optional< StringRef > ExtractPartition)
Definition: ELFObject.h:1141
Expected< std::unique_ptr< Object > > create(bool EnsureSymtab) const override
Definition: ELFObject.cpp:1962
Error visit(Section &Sec) override
Definition: ELFObject.cpp:83
ELFSectionWriter(WritableMemoryBuffer &Buf)
Definition: ELFObject.h:146
Error visit(const SymbolTableSection &Sec) override
Definition: ELFObject.cpp:845
GroupSection(ArrayRef< uint8_t > Data)
Definition: ELFObject.h:947
void setSymTab(const SymbolTableSection *SymTabSec)
Definition: ELFObject.h:949
void replaceSectionReferences(const DenseMap< SectionBase *, SectionBase * > &FromTo) override
Definition: ELFObject.cpp:1096
Error accept(SectionVisitor &) const override
Definition: ELFObject.cpp:1184
static bool classof(const SectionBase *S)
Definition: ELFObject.h:966
ArrayRef< uint8_t > Contents
Definition: ELFObject.h:945
void addMember(SectionBase *Sec)
Definition: ELFObject.h:952
Error removeSectionReferences(bool AllowBrokenLinks, function_ref< bool(const SectionBase *)> ToRemove) override
Definition: ELFObject.cpp:1066
void setFlagWord(ELF::Elf32_Word W)
Definition: ELFObject.h:951
Error removeSymbols(function_ref< bool(const Symbol &)> ToRemove) override
Definition: ELFObject.cpp:1082
IHexELFBuilder(const std::vector< IHexRecord > &Records)
Definition: ELFObject.h:1071
Expected< std::unique_ptr< Object > > build()
Definition: ELFObject.cpp:1372
IHexReader(MemoryBuffer *MB)
Definition: ELFObject.h:1130
Expected< std::unique_ptr< Object > > create(bool EnsureSymtab) const override
Definition: ELFObject.cpp:1954
IHexSectionWriterBase(WritableMemoryBuffer &Buf)
Definition: ELFObject.h:290
void writeSection(const SectionBase *Sec, ArrayRef< uint8_t > Data)
Definition: ELFObject.cpp:335
Error visit(const Section &Sec) final
Definition: ELFObject.cpp:384
virtual void writeData(uint8_t Type, uint16_t Addr, ArrayRef< uint8_t > Data)
Definition: ELFObject.cpp:379
IHexSectionWriter(WritableMemoryBuffer &Buf)
Definition: ELFObject.h:304
void writeData(uint8_t Type, uint16_t Addr, ArrayRef< uint8_t > Data) override
Definition: ELFObject.cpp:409
Error visit(const StringTableSection &Sec) override
Definition: ELFObject.cpp:416
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:1191
StringTableSection * SectionNames
Definition: ELFObject.h:1185
SectionTableRef removedSections()
Definition: ELFObject.h:1207
bool isRelocatable() const
Definition: ELFObject.h:1228
iterator_range< filter_iterator< pointee_iterator< std::vector< SecPtr >::const_iterator >, decltype(&sectionIsAlloc)> > allocSections() const
Definition: ELFObject.h:1195
Error updateSection(StringRef Name, ArrayRef< uint8_t > Data)
Definition: ELFObject.cpp:2127
SectionIndexSection * SectionIndexTable
Definition: ELFObject.h:1187
Error removeSymbols(function_ref< bool(const Symbol &)> ToRemove)
Definition: ELFObject.cpp:2234
T & addSection(Ts &&...Args)
Definition: ELFObject.h:1215
Error removeSections(bool AllowBrokenLinks, std::function< bool(const SectionBase &)> ToRemove)
Definition: ELFObject.cpp:2158
Segment & addSegment(ArrayRef< uint8_t > Data)
Definition: ELFObject.h:1224
ConstRange< Segment > segments() const
Definition: ELFObject.h:1209
SymbolTableSection * SymbolTable
Definition: ELFObject.h:1186
const auto & getUpdatedSections() const
Definition: ELFObject.h:1199
SectionBase * findSection(StringRef Name)
Definition: ELFObject.h:1202
Error replaceSections(const DenseMap< SectionBase *, SectionBase * > &FromTo)
Definition: ELFObject.cpp:2210
void appendHexData(StringRef HexData)
Definition: ELFObject.cpp:502
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:494
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:908
const SectionBase * getSection() const
Definition: ELFObject.h:878
static bool classof(const SectionBase *S)
Definition: ELFObject.h:883
void addRelocation(Relocation Rel)
Definition: ELFObject.h:913
const Object & getObject() const
Definition: ELFObject.h:923
Error accept(SectionVisitor &Visitor) const override
Definition: ELFObject.cpp:976
Error removeSymbols(function_ref< bool(const Symbol &)> ToRemove) override
Definition: ELFObject.cpp:984
void replaceSectionReferences(const DenseMap< SectionBase *, SectionBase * > &FromTo) override
Definition: ELFObject.cpp:1001
static bool classof(const SectionBase *S)
Definition: ELFObject.h:925
Error removeSectionReferences(bool AllowBrokenLinks, function_ref< bool(const SectionBase *)> ToRemove) override
Definition: ELFObject.cpp:880
virtual void writeRecord(SRecord &Record, uint64_t Off)=0
void writeSection(const SectionBase &S, ArrayRef< uint8_t > Data)
Definition: ELFObject.cpp:2869
Error visit(const Section &S) override
Definition: ELFObject.cpp:2836
SRECSectionWriterBase(WritableMemoryBuffer &Buf, uint64_t StartOffset)
Definition: ELFObject.h:460
Error visit(const StringTableSection &Sec) override
Definition: ELFObject.cpp:2884
void writeRecord(SRecord &Record, uint64_t Off) override
Definition: ELFObject.cpp:2851
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:60
virtual Error removeSectionReferences(bool AllowBrokenLinks, function_ref< bool(const SectionBase *)> ToRemove)
Definition: ELFObject.cpp:51
virtual void restoreSymTabLink(SymbolTableSection &)
Definition: ELFObject.h:555
virtual void replaceSectionReferences(const DenseMap< SectionBase *, SectionBase * > &)
Definition: ELFObject.cpp:63
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:56
virtual Error accept(SectionVisitor &Visitor) const =0
void setSymTab(SymbolTableSection *SymTab)
Definition: ELFObject.h:793
Error accept(SectionVisitor &Visitor) const override
Definition: ELFObject.cpp:623
void reserve(size_t NumSymbols)
Definition: ELFObject.h:789
Error initialize(SectionTableRef SecTable) override
Definition: ELFObject.cpp:604
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:1668
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:1660
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:170
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:1041
Error initialize(SectionTableRef SecTable) override
Definition: ELFObject.cpp:1110
Section(ArrayRef< uint8_t > Data)
Definition: ELFObject.h:610
void restoreSymTabLink(SymbolTableSection &SymTab) override
Definition: ELFObject.cpp:432
bool hasContents() const override
Definition: ELFObject.h:619
Error accept(SectionVisitor &Visitor) const override
Definition: ELFObject.cpp:424
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:574
Error accept(SectionVisitor &Visitor) const override
Definition: ELFObject.cpp:589
const SectionBase * getStrTab() const
Definition: ELFObject.h:836
Error removeSectionReferences(bool AllowBrokenLinks, function_ref< bool(const SectionBase *)> ToRemove) override
Definition: ELFObject.cpp:722
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:861
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:697
void updateSymbols(function_ref< void(Symbol &)> Callable)
Definition: ELFObject.cpp:739
static bool classof(const SectionBase *S)
Definition: ELFObject.h:852
Expected< const Symbol * > getSymbolByIndex(uint32_t Index) const
Definition: ELFObject.cpp:828
Error removeSymbols(function_ref< bool(const Symbol &)> ToRemove) override
Definition: ELFObject.cpp:748
Error initialize(SectionTableRef SecTable) override
Definition: ELFObject.cpp:769
void replaceSectionReferences(const DenseMap< SectionBase *, SectionBase * > &FromTo) override
Definition: ELFObject.cpp:762
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
@ SHF_ALLOC
Definition: ELF.h:1155
@ SHF_COMPRESSED
Definition: ELF.h:1183
@ SHN_AMDGPU_LDS
Definition: ELF.h:1832
@ SHN_XINDEX
Definition: ELF.h:1056
@ SHN_HIOS
Definition: ELF.h:1053
@ SHN_ABS
Definition: ELF.h:1054
@ SHN_COMMON
Definition: ELF.h:1055
@ SHN_LOOS
Definition: ELF.h:1052
@ SHN_LOPROC
Definition: ELF.h:1050
@ SHN_UNDEF
Definition: ELF.h:1048
@ SHN_HIPROC
Definition: ELF.h:1051
@ SHT_STRTAB
Definition: ELF.h:1065
@ SHT_GROUP
Definition: ELF.h:1077
@ SHT_PROGBITS
Definition: ELF.h:1063
@ SHT_REL
Definition: ELF.h:1071
@ SHT_NULL
Definition: ELF.h:1062
@ SHT_NOBITS
Definition: ELF.h:1070
@ SHT_SYMTAB
Definition: ELF.h:1064
@ SHT_DYNAMIC
Definition: ELF.h:1068
@ SHT_SYMTAB_SHNDX
Definition: ELF.h:1078
@ SHT_RELA
Definition: ELF.h:1066
@ SHT_DYNSYM
Definition: ELF.h:1073
@ SHN_HEXAGON_SCOMMON_2
Definition: ELF.h:656
@ SHN_HEXAGON_SCOMMON_4
Definition: ELF.h:657
@ SHN_HEXAGON_SCOMMON_8
Definition: ELF.h:658
@ SHN_HEXAGON_SCOMMON
Definition: ELF.h:654
@ SHN_MIPS_TEXT
Definition: ELF.h:574
@ SHN_MIPS_DATA
Definition: ELF.h:575
@ SHN_MIPS_SUNDEFINED
Definition: ELF.h:577
@ SHN_MIPS_SCOMMON
Definition: ELF.h:576
@ SHN_MIPS_ACOMMON
Definition: ELF.h:573
@ ET_DYN
Definition: ELF.h:118
@ ET_EXEC
Definition: ELF.h:117
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:1325
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
Definition: Error.h:1244
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:581
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:1758
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:216
static uint8_t getChecksum(StringRef S)
Definition: ELFObject.cpp:206
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:2929
static SRecord getHeader(StringRef FileName)
Definition: ELFObject.cpp:2958
uint8_t getChecksum() const
Definition: ELFObject.cpp:2913
SRecLineData toString() const
Definition: ELFObject.cpp:2893
static uint8_t getType(uint32_t Address)
Definition: ELFObject.cpp:2950
ArrayRef< uint8_t > Data
Definition: ELFObject.h:424
uint16_t getShndx() const
Definition: ELFObject.cpp:667
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