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.
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
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
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 {
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);
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.
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 virtual ArrayRef<uint8_t> getContents() const { return {}; }
553 // Notify the section that it is subject to removal.
554 virtual void onRemove();
555
557};
558
559class Segment {
560private:
561 struct SectionCompare {
562 bool operator()(const SectionBase *Lhs, const SectionBase *Rhs) const {
563 // Some sections might have the same address if one of them is empty. To
564 // fix this we can use the lexicographic ordering on ->Addr and the
565 // original index.
566 if (Lhs->OriginalOffset == Rhs->OriginalOffset)
567 return Lhs->OriginalIndex < Rhs->OriginalIndex;
568 return Lhs->OriginalOffset < Rhs->OriginalOffset;
569 }
570 };
571
572public:
581
586 std::set<const SectionBase *, SectionCompare> Sections;
587
589 Segment() = default;
590
591 const SectionBase *firstSection() const {
592 if (!Sections.empty())
593 return *Sections.begin();
594 return nullptr;
595 }
596
597 void removeSection(const SectionBase *Sec) { Sections.erase(Sec); }
598 void addSection(const SectionBase *Sec) { Sections.insert(Sec); }
599
601};
602
603class Section : public SectionBase {
605
606 ArrayRef<uint8_t> Contents;
607 SectionBase *LinkSection = nullptr;
608 bool HasSymTabLink = false;
609
610public:
611 explicit Section(ArrayRef<uint8_t> Data) : Contents(Data) {}
612
613 Error accept(SectionVisitor &Visitor) const override;
614 Error accept(MutableSectionVisitor &Visitor) override;
616 bool AllowBrokenLinks,
617 function_ref<bool(const SectionBase *)> ToRemove) override;
618 Error initialize(SectionTableRef SecTable) override;
619 void finalize() override;
620 bool hasContents() const override {
621 return Type != ELF::SHT_NOBITS && Type != ELF::SHT_NULL;
622 }
623 ArrayRef<uint8_t> getContents() const override { return Contents; }
624
625 void restoreSymTabLink(SymbolTableSection &SymTab) override;
626};
627
630
631 std::vector<uint8_t> Data;
632
633public:
635 : Data(std::begin(Data), std::end(Data)) {
636 Name = SecName.str();
638 Size = Data.size();
639 OriginalOffset = std::numeric_limits<uint64_t>::max();
640 }
641
642 OwnedDataSection(const Twine &SecName, uint64_t SecAddr, uint64_t SecFlags,
643 uint64_t SecOff) {
644 Name = SecName.str();
646 Addr = SecAddr;
647 Flags = OriginalFlags = SecFlags;
648 OriginalOffset = SecOff;
649 }
650
652 : SectionBase(S), Data(std::begin(Data), std::end(Data)) {
653 Size = Data.size();
654 }
655
656 void appendHexData(StringRef HexData);
657 Error accept(SectionVisitor &Sec) const override;
658 Error accept(MutableSectionVisitor &Visitor) override;
659 bool hasContents() const override { return true; }
660 ArrayRef<uint8_t> getContents() const override { return Data; }
661};
662
665
666 uint32_t ChType = 0;
667 DebugCompressionType CompressionType;
668 uint64_t DecompressedSize;
669 uint64_t DecompressedAlign;
670 SmallVector<uint8_t, 128> CompressedData;
671
672public:
674 DebugCompressionType CompressionType, bool Is64Bits);
675 CompressedSection(ArrayRef<uint8_t> CompressedData, uint32_t ChType,
676 uint64_t DecompressedSize, uint64_t DecompressedAlign);
677
678 uint64_t getDecompressedSize() const { return DecompressedSize; }
679 uint64_t getDecompressedAlign() const { return DecompressedAlign; }
680 uint64_t getChType() const { return ChType; }
681
682 Error accept(SectionVisitor &Visitor) const override;
683 Error accept(MutableSectionVisitor &Visitor) override;
684
685 static bool classof(const SectionBase *S) {
687 }
688};
689
692
693public:
696 : SectionBase(Sec), ChType(Sec.getChType()) {
699 Flags = OriginalFlags = (Flags & ~ELF::SHF_COMPRESSED);
700 }
701
702 Error accept(SectionVisitor &Visitor) const override;
703 Error accept(MutableSectionVisitor &Visitor) override;
704};
705
706// There are two types of string tables that can exist, dynamic and not dynamic.
707// In the dynamic case the string table is allocated. Changing a dynamic string
708// table would mean altering virtual addresses and thus the memory image. So
709// dynamic string tables should not have an interface to modify them or
710// reconstruct them. This type lets us reconstruct a string table. To avoid
711// this class being used for dynamic string tables (which has happened) the
712// classof method checks that the particular instance is not allocated. This
713// then agrees with the makeSection method used to construct most sections.
716
717 StringTableBuilder StrTabBuilder;
718
719public:
722 }
723
726 void prepareForLayout();
727 Error accept(SectionVisitor &Visitor) const override;
728 Error accept(MutableSectionVisitor &Visitor) override;
729
730 static bool classof(const SectionBase *S) {
732 return false;
733 return S->OriginalType == ELF::SHT_STRTAB;
734 }
735};
736
737// Symbols have a st_shndx field that normally stores an index but occasionally
738// stores a different special value. This enum keeps track of what the st_shndx
739// field means. Most of the values are just copies of the special SHN_* values.
740// SYMBOL_SIMPLE_INDEX means that the st_shndx is just an index of a section.
760};
761
762struct Symbol {
767 std::string Name;
773 bool Referenced = false;
774
775 uint16_t getShndx() const;
776 bool isCommon() const;
777};
778
781
782private:
783 std::vector<uint32_t> Indexes;
784 SymbolTableSection *Symbols = nullptr;
785
786public:
789 assert(Size > 0);
790 Indexes.push_back(Index);
791 }
792
793 void reserve(size_t NumSymbols) {
794 Indexes.reserve(NumSymbols);
795 Size = NumSymbols * 4;
796 }
797 void setSymTab(SymbolTableSection *SymTab) { Symbols = SymTab; }
798 Error initialize(SectionTableRef SecTable) override;
799 void finalize() override;
800 Error accept(SectionVisitor &Visitor) const override;
801 Error accept(MutableSectionVisitor &Visitor) override;
802
804 Name = ".symtab_shndx";
805 Align = 4;
806 EntrySize = 4;
808 }
809};
810
813
814 void setStrTab(StringTableSection *StrTab) { SymbolNames = StrTab; }
815 void assignIndices();
816
817protected:
818 std::vector<std::unique_ptr<Symbol>> Symbols;
821 bool IndicesChanged = false;
822
823 using SymPtr = std::unique_ptr<Symbol>;
824
825public:
827
828 void addSymbol(Twine Name, uint8_t Bind, uint8_t Type, SectionBase *DefinedIn,
829 uint64_t Value, uint8_t Visibility, uint16_t Shndx,
830 uint64_t SymbolSize);
831 void prepareForLayout();
832 // An 'empty' symbol table still contains a null symbol.
833 bool empty() const { return Symbols.size() == 1; }
834 bool indicesChanged() const { return IndicesChanged; }
836 SectionIndexTable = ShndxTable;
837 }
839 void fillShndxTable();
840 const SectionBase *getStrTab() const { return SymbolNames; }
843 void updateSymbols(function_ref<void(Symbol &)> Callable);
844
846 bool AllowBrokenLinks,
847 function_ref<bool(const SectionBase *)> ToRemove) override;
848 Error initialize(SectionTableRef SecTable) override;
849 void finalize() override;
850 Error accept(SectionVisitor &Visitor) const override;
851 Error accept(MutableSectionVisitor &Visitor) override;
852 Error removeSymbols(function_ref<bool(const Symbol &)> ToRemove) override;
854 const DenseMap<SectionBase *, SectionBase *> &FromTo) override;
855
856 static bool classof(const SectionBase *S) {
857 return S->OriginalType == ELF::SHT_SYMTAB;
858 }
859};
860
862 Symbol *RelocSymbol = nullptr;
866};
867
868// All relocation sections denote relocations to apply to another section.
869// However, some relocation sections use a dynamic symbol table and others use
870// a regular symbol table. Because the types of the two symbol tables differ in
871// our system (because they should behave differently) we can't uniformly
872// represent all relocations with the same base class if we expose an interface
873// that mentions the symbol table type. So we split the two base types into two
874// different classes, one which handles the section the relocation is applied to
875// and another which handles the symbol table type. The symbol table type is
876// taken as a type parameter to the class (see RelocSectionWithSymtabBase).
878protected:
880
881public:
882 const SectionBase *getSection() const { return SecToApplyRel; }
884
885 StringRef getNamePrefix() const;
886
887 static bool classof(const SectionBase *S) {
889 S->OriginalType);
890 }
891};
892
893// Takes the symbol table type to use as a parameter so that we can deduplicate
894// that code between the two symbol table types.
895template <class SymTabType>
897 void setSymTab(SymTabType *SymTab) { Symbols = SymTab; }
898
899protected:
901
902 SymTabType *Symbols = nullptr;
903
904public:
905 Error initialize(SectionTableRef SecTable) override;
906 void finalize() override;
907};
908
910 : public RelocSectionWithSymtabBase<SymbolTableSection> {
912
913 std::vector<Relocation> Relocations;
914 const Object &Obj;
915
916public:
917 RelocationSection(const Object &O) : Obj(O) {}
918 void addRelocation(const Relocation &Rel) { Relocations.push_back(Rel); }
919 Error accept(SectionVisitor &Visitor) const override;
920 Error accept(MutableSectionVisitor &Visitor) override;
922 bool AllowBrokenLinks,
923 function_ref<bool(const SectionBase *)> ToRemove) override;
924 Error removeSymbols(function_ref<bool(const Symbol &)> ToRemove) override;
925 void markSymbols() override;
927 const DenseMap<SectionBase *, SectionBase *> &FromTo) override;
928 const Object &getObject() const { return Obj; }
929
930 static bool classof(const SectionBase *S) {
932 return false;
934 }
935};
936
937// TODO: The way stripping and groups interact is complicated
938// and still needs to be worked on.
939
940class GroupSection : public SectionBase {
942 const SymbolTableSection *SymTab = nullptr;
943 Symbol *Sym = nullptr;
944 ELF::Elf32_Word FlagWord;
946
947public:
948 template <class T>
951 // TODO: Contents is present in several classes of the hierarchy.
952 // This needs to be refactored to avoid duplication.
954
956
957 void setSymTab(const SymbolTableSection *SymTabSec) { SymTab = SymTabSec; }
958 void setSymbol(Symbol *S) { Sym = S; }
959 void setFlagWord(ELF::Elf32_Word W) { FlagWord = W; }
960 void addMember(SectionBase *Sec) { GroupMembers.push_back(Sec); }
961
962 Error accept(SectionVisitor &) const override;
963 Error accept(MutableSectionVisitor &Visitor) override;
964 void finalize() override;
966 bool AllowBrokenLinks,
967 function_ref<bool(const SectionBase *)> ToRemove) override;
968 Error removeSymbols(function_ref<bool(const Symbol &)> ToRemove) override;
969 void markSymbols() override;
971 const DenseMap<SectionBase *, SectionBase *> &FromTo) override;
972 void onRemove() override;
973
975 return make_pointee_range(GroupMembers);
976 }
977
978 static bool classof(const SectionBase *S) {
979 return S->OriginalType == ELF::SHT_GROUP;
980 }
981};
982
984public:
986
987 static bool classof(const SectionBase *S) {
988 return S->OriginalType == ELF::SHT_DYNSYM;
989 }
990};
991
992class DynamicSection : public Section {
993public:
995
996 static bool classof(const SectionBase *S) {
997 return S->OriginalType == ELF::SHT_DYNAMIC;
998 }
999};
1000
1002 : public RelocSectionWithSymtabBase<DynamicSymbolTableSection> {
1004
1005private:
1006 ArrayRef<uint8_t> Contents;
1007
1008public:
1010
1011 Error accept(SectionVisitor &) const override;
1012 Error accept(MutableSectionVisitor &Visitor) override;
1014 bool AllowBrokenLinks,
1015 function_ref<bool(const SectionBase *)> ToRemove) override;
1016
1017 static bool classof(const SectionBase *S) {
1018 if (!(S->OriginalFlags & ELF::SHF_ALLOC))
1019 return false;
1021 }
1022};
1023
1026
1027private:
1028 StringRef FileName;
1029 uint32_t CRC32;
1030
1031 void init(StringRef File);
1032
1033public:
1034 // If we add this section from an external source we can use this ctor.
1035 explicit GnuDebugLinkSection(StringRef File, uint32_t PrecomputedCRC);
1036 Error accept(SectionVisitor &Visitor) const override;
1037 Error accept(MutableSectionVisitor &Visitor) override;
1038};
1039
1040class Reader {
1041public:
1042 virtual ~Reader();
1043 virtual Expected<std::unique_ptr<Object>> create(bool EnsureSymtab) const = 0;
1044};
1045
1046using object::Binary;
1047using object::ELFFile;
1050
1052protected:
1053 std::unique_ptr<Object> Obj;
1054
1055 void initFileHeader();
1056 void initHeaderSegment();
1060
1061public:
1062 BasicELFBuilder() : Obj(std::make_unique<Object>()) {}
1063};
1064
1066 MemoryBuffer *MemBuf;
1067 uint8_t NewSymbolVisibility;
1068 void addData(SymbolTableSection *SymTab);
1069
1070public:
1071 BinaryELFBuilder(MemoryBuffer *MB, uint8_t NewSymbolVisibility)
1072 : MemBuf(MB), NewSymbolVisibility(NewSymbolVisibility) {}
1073
1075};
1076
1078 const std::vector<IHexRecord> &Records;
1079
1080 void addDataSections();
1081
1082public:
1083 IHexELFBuilder(const std::vector<IHexRecord> &Records) : Records(Records) {}
1084
1086};
1087
1088template <class ELFT> class ELFBuilder {
1089private:
1090 using Elf_Addr = typename ELFT::Addr;
1091 using Elf_Shdr = typename ELFT::Shdr;
1092 using Elf_Word = typename ELFT::Word;
1093
1094 const ELFFile<ELFT> &ElfFile;
1095 Object &Obj;
1096 size_t EhdrOffset = 0;
1097 std::optional<StringRef> ExtractPartition;
1098
1099 void setParentSegment(Segment &Child);
1100 Error readProgramHeaders(const ELFFile<ELFT> &HeadersFile);
1101 Error initGroupSection(GroupSection *GroupSec);
1102 Error initSymbolTable(SymbolTableSection *SymTab);
1103 Error readSectionHeaders();
1104 Error readSections(bool EnsureSymtab);
1105 Error findEhdrOffset();
1106 Expected<SectionBase &> makeSection(const Elf_Shdr &Shdr);
1107
1108public:
1109 ELFBuilder(const ELFObjectFile<ELFT> &ElfObj, Object &Obj,
1110 std::optional<StringRef> ExtractPartition);
1111
1112 Error build(bool EnsureSymtab);
1113};
1114
1115class BinaryReader : public Reader {
1116 MemoryBuffer *MemBuf;
1117 uint8_t NewSymbolVisibility;
1118
1119public:
1120 BinaryReader(MemoryBuffer *MB, const uint8_t NewSymbolVisibility)
1121 : MemBuf(MB), NewSymbolVisibility(NewSymbolVisibility) {}
1122 Expected<std::unique_ptr<Object>> create(bool EnsureSymtab) const override;
1123};
1124
1125class IHexReader : public Reader {
1126 MemoryBuffer *MemBuf;
1127
1129 Error parseError(size_t LineNo, Error E) const {
1130 return LineNo == -1U
1131 ? createFileError(MemBuf->getBufferIdentifier(), std::move(E))
1132 : createFileError(MemBuf->getBufferIdentifier(), LineNo,
1133 std::move(E));
1134 }
1135 template <typename... Ts>
1136 Error parseError(size_t LineNo, char const *Fmt, const Ts &...Vals) const {
1138 return parseError(LineNo, std::move(E));
1139 }
1140
1141public:
1142 IHexReader(MemoryBuffer *MB) : MemBuf(MB) {}
1143
1144 Expected<std::unique_ptr<Object>> create(bool EnsureSymtab) const override;
1145};
1146
1147class ELFReader : public Reader {
1148 Binary *Bin;
1149 std::optional<StringRef> ExtractPartition;
1150
1151public:
1152 Expected<std::unique_ptr<Object>> create(bool EnsureSymtab) const override;
1153 explicit ELFReader(Binary *B, std::optional<StringRef> ExtractPartition)
1154 : Bin(B), ExtractPartition(ExtractPartition) {}
1155};
1156
1157class Object {
1158private:
1159 using SecPtr = std::unique_ptr<SectionBase>;
1160 using SegPtr = std::unique_ptr<Segment>;
1161
1162 std::vector<SecPtr> Sections;
1163 std::vector<SegPtr> Segments;
1164 std::vector<SecPtr> RemovedSections;
1166
1167 static bool sectionIsAlloc(const SectionBase &Sec) {
1168 return Sec.Flags & ELF::SHF_ALLOC;
1169 };
1170
1171 Error updateSectionData(SecPtr &Sec, ArrayRef<uint8_t> Data);
1172
1173public:
1174 template <class T>
1176 typename std::vector<std::unique_ptr<T>>::const_iterator>>;
1177
1178 // It is often the case that the ELF header and the program header table are
1179 // not present in any segment. This could be a problem during file layout,
1180 // because other segments may get assigned an offset where either of the
1181 // two should reside, which will effectively corrupt the resulting binary.
1182 // Other than that we use these segments to track program header offsets
1183 // when they may not follow the ELF header.
1186
1196
1197 bool HadShdrs = true;
1198 bool MustBeRelocatable = false;
1202
1203 bool IsMips64EL = false;
1204
1205 SectionTableRef sections() const { return SectionTableRef(Sections); }
1208 decltype(&sectionIsAlloc)>>
1210 return make_filter_range(make_pointee_range(Sections), sectionIsAlloc);
1211 }
1212
1213 const auto &getUpdatedSections() const { return UpdatedSections; }
1215 Error updateSectionData(SectionBase &S, ArrayRef<uint8_t> Data);
1216
1218 auto SecIt =
1219 find_if(Sections, [&](const SecPtr &Sec) { return Sec->Name == Name; });
1220 return SecIt == Sections.end() ? nullptr : SecIt->get();
1221 }
1222 SectionTableRef removedSections() { return SectionTableRef(RemovedSections); }
1223
1225
1226 Error removeSections(bool AllowBrokenLinks,
1227 std::function<bool(const SectionBase &)> ToRemove);
1231 template <class T, class... Ts> T &addSection(Ts &&...Args) {
1232 auto Sec = std::make_unique<T>(std::forward<Ts>(Args)...);
1233 auto Ptr = Sec.get();
1234 MustBeRelocatable |= isa<RelocationSection>(*Ptr);
1235 Sections.emplace_back(std::move(Sec));
1236 Ptr->Index = Sections.size();
1237 return *Ptr;
1238 }
1241 Segments.emplace_back(std::make_unique<Segment>(Data));
1242 return *Segments.back();
1243 }
1244 bool isRelocatable() const {
1245 return (Type != ELF::ET_DYN && Type != ELF::ET_EXEC) || MustBeRelocatable;
1246 }
1247};
1248
1249} // end namespace elf
1250} // end namespace objcopy
1251} // end namespace llvm
1252
1253#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
uint32_t Index
#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:168
const T * data() const
Definition: ArrayRef.h:165
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:413
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1196
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:51
std::string str() const
str - Get the contents as an std::string.
Definition: StringRef.h:229
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:498
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:2764
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:1281
SymbolTableSection * addSymTab(StringTableSection *StrTab)
Definition: ELFObject.cpp:1289
std::unique_ptr< Object > Obj
Definition: ELFObject.h:1053
BinaryELFBuilder(MemoryBuffer *MB, uint8_t NewSymbolVisibility)
Definition: ELFObject.h:1071
Expected< std::unique_ptr< Object > > build()
Definition: ELFObject.cpp:1335
BinaryReader(MemoryBuffer *MB, const uint8_t NewSymbolVisibility)
Definition: ELFObject.h:1120
Expected< std::unique_ptr< Object > > create(bool EnsureSymtab) const override
Definition: ELFObject.cpp:1954
Error visit(const SymbolTableSection &Sec) override
Definition: ELFObject.cpp:164
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:581
static bool classof(const SectionBase *S)
Definition: ELFObject.h:685
Error accept(SectionVisitor &Visitor) const override
Definition: ELFObject.cpp:502
DecompressedSection(const CompressedSection &Sec)
Definition: ELFObject.h:695
Error accept(SectionVisitor &) const override
Definition: ELFObject.cpp:1036
DynamicRelocationSection(ArrayRef< uint8_t > Data)
Definition: ELFObject.h:1009
static bool classof(const SectionBase *S)
Definition: ELFObject.h:1017
Error removeSectionReferences(bool AllowBrokenLinks, function_ref< bool(const SectionBase *)> ToRemove) override
Definition: ELFObject.cpp:1044
DynamicSection(ArrayRef< uint8_t > Data)
Definition: ELFObject.h:994
static bool classof(const SectionBase *S)
Definition: ELFObject.h:996
static bool classof(const SectionBase *S)
Definition: ELFObject.h:987
DynamicSymbolTableSection(ArrayRef< uint8_t > Data)
Definition: ELFObject.h:985
Error build(bool EnsureSymtab)
Definition: ELFObject.cpp:1920
ELFReader(Binary *B, std::optional< StringRef > ExtractPartition)
Definition: ELFObject.h:1153
Expected< std::unique_ptr< Object > > create(bool EnsureSymtab) const override
Definition: ELFObject.cpp:1993
Error visit(Section &Sec) override
Definition: ELFObject.cpp:82
ELFSectionWriter(WritableMemoryBuffer &Buf)
Definition: ELFObject.h:146
Error visit(const SymbolTableSection &Sec) override
Definition: ELFObject.cpp:862
GroupSection(ArrayRef< uint8_t > Data)
Definition: ELFObject.h:955
ConstRange< SectionBase > members() const
Definition: ELFObject.h:974
void setSymTab(const SymbolTableSection *SymTabSec)
Definition: ELFObject.h:957
void replaceSectionReferences(const DenseMap< SectionBase *, SectionBase * > &FromTo) override
Definition: ELFObject.cpp:1119
Error accept(SectionVisitor &) const override
Definition: ELFObject.cpp:1207
static bool classof(const SectionBase *S)
Definition: ELFObject.h:978
ArrayRef< uint8_t > Contents
Definition: ELFObject.h:953
void addMember(SectionBase *Sec)
Definition: ELFObject.h:960
Error removeSectionReferences(bool AllowBrokenLinks, function_ref< bool(const SectionBase *)> ToRemove) override
Definition: ELFObject.cpp:1089
void setFlagWord(ELF::Elf32_Word W)
Definition: ELFObject.h:959
Error removeSymbols(function_ref< bool(const Symbol &)> ToRemove) override
Definition: ELFObject.cpp:1105
IHexELFBuilder(const std::vector< IHexRecord > &Records)
Definition: ELFObject.h:1083
Expected< std::unique_ptr< Object > > build()
Definition: ELFObject.cpp:1395
IHexReader(MemoryBuffer *MB)
Definition: ELFObject.h:1142
Expected< std::unique_ptr< Object > > create(bool EnsureSymtab) const override
Definition: ELFObject.cpp:1985
IHexSectionWriterBase(WritableMemoryBuffer &Buf)
Definition: ELFObject.h:290
void writeSection(const SectionBase *Sec, ArrayRef< uint8_t > Data)
Definition: ELFObject.cpp:351
Error visit(const Section &Sec) final
Definition: ELFObject.cpp:400
virtual void writeData(uint8_t Type, uint16_t Addr, ArrayRef< uint8_t > Data)
Definition: ELFObject.cpp:395
IHexSectionWriter(WritableMemoryBuffer &Buf)
Definition: ELFObject.h:304
void writeData(uint8_t Type, uint16_t Addr, ArrayRef< uint8_t > Data) override
Definition: ELFObject.cpp:425
Error visit(const StringTableSection &Sec) override
Definition: ELFObject.cpp:432
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:1205
StringTableSection * SectionNames
Definition: ELFObject.h:1199
SectionTableRef removedSections()
Definition: ELFObject.h:1222
bool isRelocatable() const
Definition: ELFObject.h:1244
iterator_range< filter_iterator< pointee_iterator< std::vector< SecPtr >::const_iterator >, decltype(&sectionIsAlloc)> > allocSections() const
Definition: ELFObject.h:1209
Error updateSection(StringRef Name, ArrayRef< uint8_t > Data)
Definition: ELFObject.cpp:2181
SectionIndexSection * SectionIndexTable
Definition: ELFObject.h:1201
Error removeSymbols(function_ref< bool(const Symbol &)> ToRemove)
Definition: ELFObject.cpp:2282
T & addSection(Ts &&...Args)
Definition: ELFObject.h:1231
Error removeSections(bool AllowBrokenLinks, std::function< bool(const SectionBase &)> ToRemove)
Definition: ELFObject.cpp:2197
Segment & addSegment(ArrayRef< uint8_t > Data)
Definition: ELFObject.h:1240
ConstRange< Segment > segments() const
Definition: ELFObject.h:1224
SymbolTableSection * SymbolTable
Definition: ELFObject.h:1200
Error compressOrDecompressSections(const CommonConfig &Config)
Definition: ELFObjcopy.cpp:212
const auto & getUpdatedSections() const
Definition: ELFObject.h:1213
SectionBase * findSection(StringRef Name)
Definition: ELFObject.h:1217
Error replaceSections(const DenseMap< SectionBase *, SectionBase * > &FromTo)
Definition: ELFObject.cpp:2258
void appendHexData(StringRef HexData)
Definition: ELFObject.cpp:518
ArrayRef< uint8_t > getContents() const override
Definition: ELFObject.h:660
OwnedDataSection(const Twine &SecName, uint64_t SecAddr, uint64_t SecFlags, uint64_t SecOff)
Definition: ELFObject.h:642
Error accept(SectionVisitor &Sec) const override
Definition: ELFObject.cpp:510
OwnedDataSection(StringRef SecName, ArrayRef< uint8_t > Data)
Definition: ELFObject.h:634
OwnedDataSection(SectionBase &S, ArrayRef< uint8_t > Data)
Definition: ELFObject.h:651
bool hasContents() const override
Definition: ELFObject.h:659
virtual Expected< std::unique_ptr< Object > > create(bool EnsureSymtab) const =0
Error initialize(SectionTableRef SecTable) override
Definition: ELFObject.cpp:927
const SectionBase * getSection() const
Definition: ELFObject.h:882
static bool classof(const SectionBase *S)
Definition: ELFObject.h:887
const Object & getObject() const
Definition: ELFObject.h:928
void addRelocation(const Relocation &Rel)
Definition: ELFObject.h:918
Error accept(SectionVisitor &Visitor) const override
Definition: ELFObject.cpp:999
Error removeSymbols(function_ref< bool(const Symbol &)> ToRemove) override
Definition: ELFObject.cpp:1007
void replaceSectionReferences(const DenseMap< SectionBase *, SectionBase * > &FromTo) override
Definition: ELFObject.cpp:1024
static bool classof(const SectionBase *S)
Definition: ELFObject.h:930
Error removeSectionReferences(bool AllowBrokenLinks, function_ref< bool(const SectionBase *)> ToRemove) override
Definition: ELFObject.cpp:899
virtual void writeRecord(SRecord &Record, uint64_t Off)=0
void writeSection(const SectionBase &S, ArrayRef< uint8_t > Data)
Definition: ELFObject.cpp:2917
Error visit(const Section &S) override
Definition: ELFObject.cpp:2884
SRECSectionWriterBase(WritableMemoryBuffer &Buf, uint64_t StartOffset)
Definition: ELFObject.h:460
Error visit(const StringTableSection &Sec) override
Definition: ELFObject.cpp:2932
void writeRecord(SRecord &Record, uint64_t Off) override
Definition: ELFObject.cpp:2899
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:59
virtual Error removeSectionReferences(bool AllowBrokenLinks, function_ref< bool(const SectionBase *)> ToRemove)
Definition: ELFObject.cpp:50
virtual void restoreSymTabLink(SymbolTableSection &)
Definition: ELFObject.h:556
virtual ArrayRef< uint8_t > getContents() const
Definition: ELFObject.h:552
virtual void replaceSectionReferences(const DenseMap< SectionBase *, SectionBase * > &)
Definition: ELFObject.cpp:62
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:55
virtual Error accept(SectionVisitor &Visitor) const =0
void setSymTab(SymbolTableSection *SymTab)
Definition: ELFObject.h:797
Error accept(SectionVisitor &Visitor) const override
Definition: ELFObject.cpp:640
void reserve(size_t NumSymbols)
Definition: ELFObject.h:793
Error initialize(SectionTableRef SecTable) override
Definition: ELFObject.cpp:621
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:1690
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:1682
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:186
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:1064
Error initialize(SectionTableRef SecTable) override
Definition: ELFObject.cpp:1133
ArrayRef< uint8_t > getContents() const override
Definition: ELFObject.h:623
Section(ArrayRef< uint8_t > Data)
Definition: ELFObject.h:611
void restoreSymTabLink(SymbolTableSection &SymTab) override
Definition: ELFObject.cpp:448
bool hasContents() const override
Definition: ELFObject.h:620
Error accept(SectionVisitor &Visitor) const override
Definition: ELFObject.cpp:440
void addSection(const SectionBase *Sec)
Definition: ELFObject.h:598
Segment(ArrayRef< uint8_t > Data)
Definition: ELFObject.h:588
ArrayRef< uint8_t > Contents
Definition: ELFObject.h:585
void removeSection(const SectionBase *Sec)
Definition: ELFObject.h:597
const SectionBase * firstSection() const
Definition: ELFObject.h:591
ArrayRef< uint8_t > getContents() const
Definition: ELFObject.h:600
std::set< const SectionBase *, SectionCompare > Sections
Definition: ELFObject.h:586
static bool classof(const SectionBase *S)
Definition: ELFObject.h:730
uint32_t findIndex(StringRef Name) const
Definition: ELFObject.cpp:591
Error accept(SectionVisitor &Visitor) const override
Definition: ELFObject.cpp:606
const SectionBase * getStrTab() const
Definition: ELFObject.h:840
Error removeSectionReferences(bool AllowBrokenLinks, function_ref< bool(const SectionBase *)> ToRemove) override
Definition: ELFObject.cpp:739
const SectionIndexSection * getShndxTable() const
Definition: ELFObject.h:838
std::vector< std::unique_ptr< Symbol > > Symbols
Definition: ELFObject.h:818
SectionIndexSection * SectionIndexTable
Definition: ELFObject.h:820
Error accept(SectionVisitor &Visitor) const override
Definition: ELFObject.cpp:878
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:714
void updateSymbols(function_ref< void(Symbol &)> Callable)
Definition: ELFObject.cpp:756
static bool classof(const SectionBase *S)
Definition: ELFObject.h:856
Expected< const Symbol * > getSymbolByIndex(uint32_t Index) const
Definition: ELFObject.cpp:845
Error removeSymbols(function_ref< bool(const Symbol &)> ToRemove) override
Definition: ELFObject.cpp:765
Error initialize(SectionTableRef SecTable) override
Definition: ELFObject.cpp:786
void replaceSectionReferences(const DenseMap< SectionBase *, SectionBase * > &FromTo) override
Definition: ELFObject.cpp:779
std::unique_ptr< Symbol > SymPtr
Definition: ELFObject.h:823
void setShndxTable(SectionIndexSection *ShndxTable)
Definition: ELFObject.h:835
StringTableSection * SymbolNames
Definition: ELFObject.h:819
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_XINDEX
Definition: ELF.h:1091
@ SHN_HIOS
Definition: ELF.h:1088
@ SHN_ABS
Definition: ELF.h:1089
@ SHN_COMMON
Definition: ELF.h:1090
@ SHN_LOOS
Definition: ELF.h:1087
@ SHN_LOPROC
Definition: ELF.h:1085
@ SHN_UNDEF
Definition: ELF.h:1083
@ SHN_HIPROC
Definition: ELF.h:1086
@ SHT_STRTAB
Definition: ELF.h:1100
@ SHT_GROUP
Definition: ELF.h:1112
@ SHT_PROGBITS
Definition: ELF.h:1098
@ SHT_REL
Definition: ELF.h:1106
@ SHT_NULL
Definition: ELF.h:1097
@ SHT_NOBITS
Definition: ELF.h:1105
@ SHT_SYMTAB
Definition: ELF.h:1099
@ SHT_CREL
Definition: ELF.h:1119
@ SHT_DYNAMIC
Definition: ELF.h:1103
@ SHT_SYMTAB_SHNDX
Definition: ELF.h:1113
@ SHT_RELA
Definition: ELF.h:1101
@ SHT_DYNSYM
Definition: ELF.h:1108
@ SHN_HEXAGON_SCOMMON_2
Definition: ELF.h:662
@ SHN_HEXAGON_SCOMMON_4
Definition: ELF.h:663
@ SHN_HEXAGON_SCOMMON_8
Definition: ELF.h:664
@ SHN_HEXAGON_SCOMMON
Definition: ELF.h:660
@ SHF_ALLOC
Definition: ELF.h:1198
@ SHF_COMPRESSED
Definition: ELF.h:1226
@ ET_DYN
Definition: ELF.h:119
@ ET_EXEC
Definition: ELF.h:118
@ SHN_AMDGPU_LDS
Definition: ELF.h:1906
@ SHN_MIPS_TEXT
Definition: ELF.h:577
@ SHN_MIPS_DATA
Definition: ELF.h:578
@ SHN_MIPS_SUNDEFINED
Definition: ELF.h:580
@ SHN_MIPS_SCOMMON
Definition: ELF.h:579
@ SHN_MIPS_ACOMMON
Definition: ELF.h:576
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:1385
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
Definition: Error.h:1291
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:573
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:1766
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
Definition: STLExtras.h:1903
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:232
static uint8_t getChecksum(StringRef S)
Definition: ELFObject.cpp:222
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:2977
static SRecord getHeader(StringRef FileName)
Definition: ELFObject.cpp:3006
uint8_t getChecksum() const
Definition: ELFObject.cpp:2961
SRecLineData toString() const
Definition: ELFObject.cpp:2941
static uint8_t getType(uint32_t Address)
Definition: ELFObject.cpp:2998
ArrayRef< uint8_t > Data
Definition: ELFObject.h:424
uint16_t getShndx() const
Definition: ELFObject.cpp:684
SectionBase * DefinedIn
Definition: ELFObject.h:764
SymbolShndxType ShndxType
Definition: ELFObject.h:765
An iterator type that allows iterating over the pointees via some other iterator.
Definition: iterator.h:324
Definition: regcomp.c:192