LLVM 24.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;
43class GroupSection;
47class Segment;
48class Object;
49struct Symbol;
50
53
54public:
56
57 explicit SectionTableRef(ArrayRef<std::unique_ptr<SectionBase>> Secs)
58 : Sections(Secs) {}
59 SectionTableRef(const SectionTableRef &) = default;
60
61 iterator begin() const { return iterator(Sections.data()); }
62 iterator end() const { return iterator(Sections.data() + Sections.size()); }
63 size_t size() const { return Sections.size(); }
64
66
67 template <class T>
69 Twine TypeErrMsg);
70};
71
73
75public:
76 virtual ~SectionVisitor() = default;
77
78 virtual Error visit(const Section &Sec) = 0;
79 virtual Error visit(const OwnedDataSection &Sec) = 0;
80 virtual Error visit(const StringTableSection &Sec) = 0;
81 virtual Error visit(const SymbolTableSection &Sec) = 0;
82 virtual Error visit(const RelocationSection &Sec) = 0;
83 virtual Error visit(const DynamicRelocationSection &Sec) = 0;
84 virtual Error visit(const GnuDebugLinkSection &Sec) = 0;
85 virtual Error visit(const GroupSection &Sec) = 0;
86 virtual Error visit(const SectionIndexSection &Sec) = 0;
87 virtual Error visit(const CompressedSection &Sec) = 0;
88 virtual Error visit(const DecompressedSection &Sec) = 0;
89};
90
92public:
93 virtual ~MutableSectionVisitor() = default;
94
95 virtual Error visit(Section &Sec) = 0;
96 virtual Error visit(OwnedDataSection &Sec) = 0;
97 virtual Error visit(StringTableSection &Sec) = 0;
98 virtual Error visit(SymbolTableSection &Sec) = 0;
99 virtual Error visit(RelocationSection &Sec) = 0;
101 virtual Error visit(GnuDebugLinkSection &Sec) = 0;
102 virtual Error visit(GroupSection &Sec) = 0;
103 virtual Error visit(SectionIndexSection &Sec) = 0;
104 virtual Error visit(CompressedSection &Sec) = 0;
105 virtual Error visit(DecompressedSection &Sec) = 0;
106};
107
109protected:
111
112public:
113 ~SectionWriter() override = default;
114
115 Error visit(const Section &Sec) override;
116 Error visit(const OwnedDataSection &Sec) override;
117 Error visit(const StringTableSection &Sec) override;
118 Error visit(const DynamicRelocationSection &Sec) override;
119 Error visit(const SymbolTableSection &Sec) override = 0;
120 Error visit(const RelocationSection &Sec) override = 0;
121 Error visit(const GnuDebugLinkSection &Sec) override = 0;
122 Error visit(const GroupSection &Sec) override = 0;
123 Error visit(const SectionIndexSection &Sec) override = 0;
124 Error visit(const CompressedSection &Sec) override = 0;
125 Error visit(const DecompressedSection &Sec) override = 0;
126
127 explicit SectionWriter(WritableMemoryBuffer &Buf) : Out(Buf) {}
128};
129
130template <class ELFT> class ELFSectionWriter : public SectionWriter {
131private:
132 using Elf_Word = typename ELFT::Word;
133 using Elf_Rel = typename ELFT::Rel;
134 using Elf_Rela = typename ELFT::Rela;
135 using Elf_Sym = typename ELFT::Sym;
136
137public:
138 ~ELFSectionWriter() override = default;
139 Error visit(const SymbolTableSection &Sec) override;
140 Error visit(const RelocationSection &Sec) override;
141 Error visit(const GnuDebugLinkSection &Sec) override;
142 Error visit(const GroupSection &Sec) override;
143 Error visit(const SectionIndexSection &Sec) override;
144 Error visit(const CompressedSection &Sec) override;
145 Error visit(const DecompressedSection &Sec) override;
146
148};
149
150template <class ELFT> class ELFSectionSizer : public MutableSectionVisitor {
151private:
152 using Elf_Rel = typename ELFT::Rel;
153 using Elf_Rela = typename ELFT::Rela;
154 using Elf_Sym = typename ELFT::Sym;
155 using Elf_Word = typename ELFT::Word;
156 using Elf_Xword = typename ELFT::Xword;
157
158public:
159 Error visit(Section &Sec) override;
160 Error visit(OwnedDataSection &Sec) override;
161 Error visit(StringTableSection &Sec) override;
162 Error visit(DynamicRelocationSection &Sec) override;
163 Error visit(SymbolTableSection &Sec) override;
164 Error visit(RelocationSection &Sec) override;
165 Error visit(GnuDebugLinkSection &Sec) override;
166 Error visit(GroupSection &Sec) override;
167 Error visit(SectionIndexSection &Sec) override;
168 Error visit(CompressedSection &Sec) override;
169 Error visit(DecompressedSection &Sec) override;
170};
171
172#define MAKE_SEC_WRITER_FRIEND \
173 friend class SectionWriter; \
174 friend class IHexSectionWriterBase; \
175 friend class IHexSectionWriter; \
176 friend class SRECSectionWriter; \
177 friend class SRECSectionWriterBase; \
178 friend class SRECSizeCalculator; \
179 template <class ELFT> friend class ELFSectionWriter; \
180 template <class ELFT> friend class ELFSectionSizer;
181
183public:
184 ~BinarySectionWriter() override = default;
185
186 Error visit(const SymbolTableSection &Sec) override;
187 Error visit(const RelocationSection &Sec) override;
188 Error visit(const GnuDebugLinkSection &Sec) override;
189 Error visit(const GroupSection &Sec) override;
190 Error visit(const SectionIndexSection &Sec) override;
191 Error visit(const CompressedSection &Sec) override;
192 Error visit(const DecompressedSection &Sec) override;
193
196};
197
199
201 // Memory address of the record.
203 // Record type (see below).
205 // Record data in hexadecimal form.
207
208 // Helper method to get file length of the record
209 // including newline character
210 static size_t getLength(size_t DataSize) {
211 // :LLAAAATT[DD...DD]CC'
212 return DataSize * 2 + 11;
213 }
214
215 // Gets length of line in a file (getLength + CRLF).
216 static size_t getLineLength(size_t DataSize) {
217 return getLength(DataSize) + 2;
218 }
219
220 // Given type, address and data returns line which can
221 // be written to output file.
224
225 // Parses the line and returns record if possible.
226 // Line should be trimmed from whitespace characters.
228
229 // Calculates checksum of stringified record representation
230 // S must NOT contain leading ':' and trailing whitespace
231 // characters
232 static uint8_t getChecksum(StringRef S);
233
234 enum Type {
235 // Contains data and a 16-bit starting address for the data.
236 // The byte count specifies number of data bytes in the record.
237 Data = 0,
238 // Must occur exactly once per file in the last line of the file.
239 // The data field is empty (thus byte count is 00) and the address
240 // field is typically 0000.
242 // The data field contains a 16-bit segment base address (thus byte
243 // count is always 02) compatible with 80x86 real mode addressing.
244 // The address field (typically 0000) is ignored. The segment address
245 // from the most recent 02 record is multiplied by 16 and added to each
246 // subsequent data record address to form the physical starting address
247 // for the data. This allows addressing up to one megabyte of address
248 // space.
250 // or 80x86 processors, specifies the initial content of the CS:IP
251 // registers. The address field is 0000, the byte count is always 04,
252 // the first two data bytes are the CS value, the latter two are the
253 // IP value.
255 // Allows for 32 bit addressing (up to 4GiB). The record's address field
256 // is ignored (typically 0000) and its byte count is always 02. The two
257 // data bytes (big endian) specify the upper 16 bits of the 32 bit
258 // absolute address for all subsequent type 00 records
260 // The address field is 0000 (not used) and the byte count is always 04.
261 // The four data bytes represent a 32-bit address value. In the case of
262 // 80386 and higher CPUs, this address is loaded into the EIP register.
264 // We have no other valid types
266 };
267};
268
269// Base class for IHexSectionWriter. This class implements writing algorithm,
270// but doesn't actually write records. It is used for output buffer size
271// calculation in IHexWriter::finalize.
273 // 20-bit segment address
274 uint32_t SegmentAddr = 0;
275 // Extended linear address
276 uint32_t BaseAddr = 0;
277
278 // Write segment address corresponding to 'Addr'
279 uint64_t writeSegmentAddr(uint64_t Addr);
280 // Write extended linear (base) address corresponding to 'Addr'
281 uint64_t writeBaseAddr(uint64_t Addr);
282
283protected:
284 // Offset in the output buffer
286
289
290public:
293
294 uint64_t getBufferOffset() const { return Offset; }
295 Error visit(const Section &Sec) final;
296 Error visit(const OwnedDataSection &Sec) final;
297 Error visit(const StringTableSection &Sec) override;
298 Error visit(const DynamicRelocationSection &Sec) final;
300};
301
302// Real IHEX section writer
304public:
306
307 void writeData(uint8_t Type, uint16_t Addr, ArrayRef<uint8_t> Data) override;
308 Error visit(const StringTableSection &Sec) override;
309};
310
311class Writer {
312protected:
314 std::unique_ptr<WritableMemoryBuffer> Buf;
316
317public:
318 virtual ~Writer();
319 virtual Error finalize() = 0;
320 virtual Error write() = 0;
321
323};
324
325template <class ELFT> class ELFWriter : public Writer {
326private:
327 using Elf_Addr = typename ELFT::Addr;
328 using Elf_Shdr = typename ELFT::Shdr;
329 using Elf_Phdr = typename ELFT::Phdr;
330 using Elf_Ehdr = typename ELFT::Ehdr;
331
332 void initEhdrSegment();
333
334 void writeEhdr();
335 void writePhdr(const Segment &Seg);
336 void writeShdr(const SectionBase &Sec);
337
338 void writePhdrs();
339 void writeShdrs();
340 Error writeSectionData();
341 void writeSegmentData();
342
343 void assignOffsets();
344
345 std::unique_ptr<ELFSectionWriter<ELFT>> SecWriter;
346
347 size_t totalSize() const;
348
349public:
350 ~ELFWriter() override = default;
352
353 // For --only-keep-debug, select an alternative section/segment layout
354 // algorithm.
356
357 Error finalize() override;
358 Error write() override;
359 ELFWriter(Object &Obj, raw_ostream &Out, bool WSH, bool OnlyKeepDebug);
360};
361
362class BinaryWriter : public Writer {
363private:
364 const uint8_t GapFill;
365 const uint64_t PadTo;
366 std::unique_ptr<BinarySectionWriter> SecWriter;
367
368 uint64_t TotalSize = 0;
369
370public:
371 ~BinaryWriter() override = default;
372 Error finalize() override;
373 Error write() override;
375 : Writer(Obj, Out), GapFill(Config.GapFill), PadTo(Config.PadTo) {}
376};
377
378// A base class for writing ascii hex formats such as srec and ihex.
379class ASCIIHexWriter : public Writer {
380public:
382 : Writer(Obj, OS), OutputFileName(OutputFile) {}
383 Error finalize() override;
384
385protected:
387 size_t TotalSize = 0;
388 std::vector<const SectionBase *> Sections;
389
390 Error checkSection(const SectionBase &S) const;
391 virtual Expected<size_t>
392 getTotalSize(WritableMemoryBuffer &EmptyBuffer) const = 0;
393};
394
396public:
397 Error write() override;
399 : ASCIIHexWriter(Obj, Out, OutputFile) {}
400
401private:
402 uint64_t writeEntryPointRecord(uint8_t *Buf);
403 uint64_t writeEndOfFileRecord(uint8_t *Buf);
405 getTotalSize(WritableMemoryBuffer &EmptyBuffer) const override;
406};
407
409public:
411 : ASCIIHexWriter(Obj, OS, OutputFile) {}
412 Error write() override;
413
414private:
415 size_t writeHeader(uint8_t *Buf);
416 size_t writeTerminator(uint8_t *Buf, uint8_t Type);
418 getTotalSize(WritableMemoryBuffer &EmptyBuffer) const override;
419};
420
422struct SRecord {
426 SRecLineData toString() const;
427 uint8_t getCount() const;
428 // Get address size in characters.
429 uint8_t getAddressSize() const;
430 uint8_t getChecksum() const;
431 size_t getSize() const;
432 static SRecord getHeader(StringRef FileName);
434
435 enum Type : uint8_t {
436 // Vendor specific text comment.
437 S0 = 0,
438 // Data that starts at a 16 bit address.
439 S1 = 1,
440 // Data that starts at a 24 bit address.
441 S2 = 2,
442 // Data that starts at a 32 bit address.
443 S3 = 3,
444 // Reserved.
445 S4 = 4,
446 // 16 bit count of S1/S2/S3 records (optional).
447 S5 = 5,
448 // 32 bit count of S1/S2/S3 records (optional).
449 S6 = 6,
450 // Terminates a series of S3 records.
451 S7 = 7,
452 // Terminates a series of S2 records.
453 S8 = 8,
454 // Terminates a series of S1 records.
455 S9 = 9
456 };
457};
458
460public:
462 uint64_t StartOffset)
463 : BinarySectionWriter(Buf), Offset(StartOffset), HeaderSize(StartOffset) {
464 }
465
467
468 void writeRecords(uint32_t Entry);
469 uint64_t getBufferOffset() const { return Offset; }
470 Error visit(const Section &S) override;
471 Error visit(const OwnedDataSection &S) override;
472 Error visit(const StringTableSection &S) override;
473 Error visit(const DynamicRelocationSection &S) override;
474 uint8_t getType() const { return Type; };
475
476protected:
477 // Offset in the output buffer.
479 // Sections start after the header.
481 // Type of records to write.
483 std::vector<SRecord> Records;
484
486 virtual void writeRecord(SRecord &Record, uint64_t Off) = 0;
487};
488
489// An SRECSectionWriterBase that visits sections but does not write anything.
490// This class is only used to calculate the size of the output file.
492public:
495
496protected:
498};
499
501public:
504 Error visit(const StringTableSection &Sec) override;
505
506protected:
507 void writeRecord(SRecord &Record, uint64_t Off) override;
508};
509
511public:
512 std::string Name;
516
520 uint64_t OriginalOffset = std::numeric_limits<uint64_t>::max();
521
533 bool HasSymbol = false;
534
535 SectionBase() = default;
536 SectionBase(const SectionBase &) = default;
537
538 virtual ~SectionBase() = default;
539
540 virtual Error initialize(SectionTableRef SecTable);
541 virtual void finalize();
542 // Remove references to these sections. The list of sections must be sorted.
543 virtual Error
544 removeSectionReferences(bool AllowBrokenLinks,
545 function_ref<bool(const SectionBase *)> ToRemove);
546 virtual Error removeSymbols(function_ref<bool(const Symbol &)> ToRemove);
547 virtual Error accept(SectionVisitor &Visitor) const = 0;
548 virtual Error accept(MutableSectionVisitor &Visitor) = 0;
549 virtual void markSymbols();
550 virtual void
552 virtual bool hasContents() const { return false; }
553 virtual ArrayRef<uint8_t> getContents() const { return {}; }
554 // Notify the section that it is subject to removal.
555 virtual void onRemove();
556
558};
559
560class Segment {
561private:
562 struct SectionCompare {
563 bool operator()(const SectionBase *Lhs, const SectionBase *Rhs) const {
564 // Some sections might have the same address if one of them is empty. To
565 // fix this we can use the lexicographic ordering on ->Addr and the
566 // original index.
567 if (Lhs->OriginalOffset == Rhs->OriginalOffset)
568 return Lhs->OriginalIndex < Rhs->OriginalIndex;
569 return Lhs->OriginalOffset < Rhs->OriginalOffset;
570 }
571 };
572
573public:
582
587 std::set<const SectionBase *, SectionCompare> Sections;
588
590 Segment() = default;
591
592 const SectionBase *firstSection() const {
593 if (!Sections.empty())
594 return *Sections.begin();
595 return nullptr;
596 }
597
598 void removeSection(const SectionBase *Sec) { Sections.erase(Sec); }
599 void addSection(const SectionBase *Sec) { Sections.insert(Sec); }
600
602};
603
604class Section : public SectionBase {
606
607 ArrayRef<uint8_t> Contents;
608 SectionBase *LinkSection = nullptr;
609 bool HasSymTabLink = false;
610
611public:
612 explicit Section(ArrayRef<uint8_t> Data) : Contents(Data) {}
613
614 Error accept(SectionVisitor &Visitor) const override;
615 Error accept(MutableSectionVisitor &Visitor) override;
617 bool AllowBrokenLinks,
618 function_ref<bool(const SectionBase *)> ToRemove) override;
619 Error initialize(SectionTableRef SecTable) override;
620 void finalize() override;
621 bool hasContents() const override {
622 return Type != ELF::SHT_NOBITS && Type != ELF::SHT_NULL;
623 }
624 ArrayRef<uint8_t> getContents() const override { return Contents; }
625
626 void restoreSymTabLink(SymbolTableSection &SymTab) override;
627};
628
631
632 std::vector<uint8_t> Data;
633
634public:
636 : Data(std::begin(Data), std::end(Data)) {
637 Name = SecName.str();
639 Size = Data.size();
640 OriginalOffset = std::numeric_limits<uint64_t>::max();
641 }
642
643 OwnedDataSection(const Twine &SecName, uint64_t SecAddr, uint64_t SecFlags,
644 uint64_t SecOff) {
645 Name = SecName.str();
647 Addr = SecAddr;
648 Flags = OriginalFlags = SecFlags;
649 OriginalOffset = SecOff;
650 }
651
653 : SectionBase(S), Data(std::begin(Data), std::end(Data)) {
654 Size = Data.size();
655 }
656
657 void appendHexData(StringRef HexData);
658 Error accept(SectionVisitor &Sec) const override;
659 Error accept(MutableSectionVisitor &Visitor) override;
660 bool hasContents() const override { return true; }
661 ArrayRef<uint8_t> getContents() const override { return Data; }
662};
663
666
667 uint32_t ChType = 0;
668 DebugCompressionType CompressionType;
669 uint64_t DecompressedSize;
670 uint64_t DecompressedAlign;
671 SmallVector<uint8_t, 128> CompressedData;
672
673public:
675 DebugCompressionType CompressionType, bool Is64Bits);
676 CompressedSection(ArrayRef<uint8_t> CompressedData, uint32_t ChType,
677 uint64_t DecompressedSize, uint64_t DecompressedAlign);
678
679 uint64_t getDecompressedSize() const { return DecompressedSize; }
680 uint64_t getDecompressedAlign() const { return DecompressedAlign; }
681 uint64_t getChType() const { return ChType; }
682
683 Error accept(SectionVisitor &Visitor) const override;
684 Error accept(MutableSectionVisitor &Visitor) override;
685
686 static bool classof(const SectionBase *S) {
688 }
689};
690
693
694public:
697 : SectionBase(Sec), ChType(Sec.getChType()) {
700 Flags = OriginalFlags = (Flags & ~ELF::SHF_COMPRESSED);
701 }
702
703 Error accept(SectionVisitor &Visitor) const override;
704 Error accept(MutableSectionVisitor &Visitor) override;
705};
706
707// There are two types of string tables that can exist, dynamic and not dynamic.
708// In the dynamic case the string table is allocated. Changing a dynamic string
709// table would mean altering virtual addresses and thus the memory image. So
710// dynamic string tables should not have an interface to modify them or
711// reconstruct them. This type lets us reconstruct a string table. To avoid
712// this class being used for dynamic string tables (which has happened) the
713// classof method checks that the particular instance is not allocated. This
714// then agrees with the makeSection method used to construct most sections.
717
718 StringTableBuilder StrTabBuilder;
719
720public:
724
727 void prepareForLayout();
728 Error accept(SectionVisitor &Visitor) const override;
729 Error accept(MutableSectionVisitor &Visitor) override;
730
731 static bool classof(const SectionBase *S) {
733 return false;
734 return S->OriginalType == ELF::SHT_STRTAB;
735 }
736};
737
738// Symbols have a st_shndx field that normally stores an index but occasionally
739// stores a different special value. This enum keeps track of what the st_shndx
740// field means. Most of the values are just copies of the special SHN_* values.
741// SYMBOL_SIMPLE_INDEX means that the st_shndx is just an index of a section.
762
779
782
783private:
784 std::vector<uint32_t> Indexes;
785 SymbolTableSection *Symbols = nullptr;
786
787public:
788 ~SectionIndexSection() override = default;
790 assert(Size > 0);
791 Indexes.push_back(Index);
792 }
793
794 void reserve(size_t NumSymbols) {
795 Indexes.reserve(NumSymbols);
796 Size = NumSymbols * 4;
797 }
798 void setSymTab(SymbolTableSection *SymTab) { Symbols = SymTab; }
799 Error initialize(SectionTableRef SecTable) override;
800 void finalize() override;
801 Error accept(SectionVisitor &Visitor) const override;
802 Error accept(MutableSectionVisitor &Visitor) override;
803
805 Name = ".symtab_shndx";
806 Align = 4;
807 EntrySize = 4;
809 }
810};
811
814
815 void setStrTab(StringTableSection *StrTab) { SymbolNames = StrTab; }
816 void assignIndices();
817
818protected:
819 std::vector<std::unique_ptr<Symbol>> Symbols;
822 bool IndicesChanged = false;
823
824 using SymPtr = std::unique_ptr<Symbol>;
825
826public:
828
829 void addSymbol(Twine Name, uint8_t Bind, uint8_t Type, SectionBase *DefinedIn,
830 uint64_t Value, uint8_t Visibility, uint16_t Shndx,
831 uint64_t SymbolSize);
832 void prepareForLayout();
833 // An 'empty' symbol table still contains a null symbol.
834 bool empty() const { return Symbols.size() == 1; }
835 bool indicesChanged() const { return IndicesChanged; }
837 SectionIndexTable = ShndxTable;
838 }
840 void fillShndxTable();
841 const SectionBase *getStrTab() const { return SymbolNames; }
844 void updateSymbols(function_ref<void(Symbol &)> Callable);
845
847 bool AllowBrokenLinks,
848 function_ref<bool(const SectionBase *)> ToRemove) override;
849 Error initialize(SectionTableRef SecTable) override;
850 void finalize() override;
851 Error accept(SectionVisitor &Visitor) const override;
852 Error accept(MutableSectionVisitor &Visitor) override;
853 Error removeSymbols(function_ref<bool(const Symbol &)> ToRemove) override;
855 const DenseMap<SectionBase *, SectionBase *> &FromTo) override;
856
857 static bool classof(const SectionBase *S) {
858 return S->OriginalType == ELF::SHT_SYMTAB;
859 }
860};
861
868
869// All relocation sections denote relocations to apply to another section.
870// However, some relocation sections use a dynamic symbol table and others use
871// a regular symbol table. Because the types of the two symbol tables differ in
872// our system (because they should behave differently) we can't uniformly
873// represent all relocations with the same base class if we expose an interface
874// that mentions the symbol table type. So we split the two base types into two
875// different classes, one which handles the section the relocation is applied to
876// and another which handles the symbol table type. The symbol table type is
877// taken as a type parameter to the class (see RelocSectionWithSymtabBase).
879 const bool Dynamic;
880
881protected:
883
884 explicit RelocationSectionBase(bool Dynamic) : Dynamic(Dynamic) {}
885
886public:
887 bool isDynamic() const { return Dynamic; }
888 const SectionBase *getSection() const { return SecToApplyRel; }
890
891 StringRef getNamePrefix() const;
892
893 static bool classof(const SectionBase *S) {
895 S->OriginalType);
896 }
897};
898
899// Takes the symbol table type to use as a parameter so that we can deduplicate
900// that code between the two symbol table types.
901template <class SymTabType>
903 void setSymTab(SymTabType *SymTab) { Symbols = SymTab; }
904
905protected:
909
910 SymTabType *Symbols = nullptr;
911
912public:
913 Error initialize(SectionTableRef SecTable) override;
914 void finalize() override;
915};
916
918 : public RelocSectionWithSymtabBase<SymbolTableSection> {
920
921 std::vector<Relocation> Relocations;
922 const Object &Obj;
923
924public:
925 RelocationSection(const Object &O) : Obj(O) {}
926 void addRelocation(const Relocation &Rel) { Relocations.push_back(Rel); }
927 Error accept(SectionVisitor &Visitor) const override;
928 Error accept(MutableSectionVisitor &Visitor) override;
930 bool AllowBrokenLinks,
931 function_ref<bool(const SectionBase *)> ToRemove) override;
932 Error removeSymbols(function_ref<bool(const Symbol &)> ToRemove) override;
933 void markSymbols() override;
935 const DenseMap<SectionBase *, SectionBase *> &FromTo) override;
936 const Object &getObject() const { return Obj; }
937
938 static bool classof(const SectionBase *S) {
940 !static_cast<const RelocationSectionBase *>(S)->isDynamic();
941 }
942};
943
944// TODO: The way stripping and groups interact is complicated
945// and still needs to be worked on.
946
947class GroupSection : public SectionBase {
949 const SymbolTableSection *SymTab = nullptr;
950 Symbol *Sym = nullptr;
951 ELF::Elf32_Word FlagWord;
953
954public:
955 template <class T>
958 // TODO: Contents is present in several classes of the hierarchy.
959 // This needs to be refactored to avoid duplication.
961
963
964 void setSymTab(const SymbolTableSection *SymTabSec) { SymTab = SymTabSec; }
965 void setSymbol(Symbol *S) { Sym = S; }
966 void setFlagWord(ELF::Elf32_Word W) { FlagWord = W; }
967 void addMember(SectionBase *Sec) { GroupMembers.push_back(Sec); }
968
969 Error accept(SectionVisitor &) const override;
970 Error accept(MutableSectionVisitor &Visitor) override;
971 void finalize() override;
973 bool AllowBrokenLinks,
974 function_ref<bool(const SectionBase *)> ToRemove) override;
975 Error removeSymbols(function_ref<bool(const Symbol &)> ToRemove) override;
976 void markSymbols() override;
978 const DenseMap<SectionBase *, SectionBase *> &FromTo) override;
979 void onRemove() override;
980
982 return make_pointee_range(GroupMembers);
983 }
984
985 static bool classof(const SectionBase *S) {
986 return S->OriginalType == ELF::SHT_GROUP;
987 }
988};
989
991public:
993
994 static bool classof(const SectionBase *S) {
995 return S->OriginalType == ELF::SHT_DYNSYM;
996 }
997};
998
999class DynamicSection : public Section {
1000public:
1002
1003 static bool classof(const SectionBase *S) {
1004 return S->OriginalType == ELF::SHT_DYNAMIC;
1005 }
1006};
1007
1009 : public RelocSectionWithSymtabBase<DynamicSymbolTableSection> {
1011
1012private:
1013 ArrayRef<uint8_t> Contents;
1014
1015public:
1017
1018 Error accept(SectionVisitor &) const override;
1019 Error accept(MutableSectionVisitor &Visitor) override;
1021 bool AllowBrokenLinks,
1022 function_ref<bool(const SectionBase *)> ToRemove) override;
1023
1024 static bool classof(const SectionBase *S) {
1026 static_cast<const RelocationSectionBase *>(S)->isDynamic();
1027 }
1028};
1029
1032
1033private:
1034 StringRef FileName;
1035 uint32_t CRC32;
1036
1037 void init(StringRef File);
1038
1039public:
1040 // If we add this section from an external source we can use this ctor.
1041 explicit GnuDebugLinkSection(StringRef File, uint32_t PrecomputedCRC);
1042 Error accept(SectionVisitor &Visitor) const override;
1043 Error accept(MutableSectionVisitor &Visitor) override;
1044};
1045
1046class Reader {
1047public:
1048 virtual ~Reader();
1049 virtual Expected<std::unique_ptr<Object>> create(bool EnsureSymtab) const = 0;
1050};
1051
1052using object::Binary;
1053using object::ELFFile;
1056
1058protected:
1059 std::unique_ptr<Object> Obj;
1060
1061 void initFileHeader();
1062 void initHeaderSegment();
1066
1067public:
1070};
1071
1073 MemoryBuffer *MemBuf;
1074 uint8_t NewSymbolVisibility;
1075 void addData(SymbolTableSection *SymTab);
1076
1077public:
1078 BinaryELFBuilder(MemoryBuffer *MB, uint8_t NewSymbolVisibility)
1079 : MemBuf(MB), NewSymbolVisibility(NewSymbolVisibility) {}
1080
1082};
1083
1085 const std::vector<IHexRecord> &Records;
1086
1087 void addDataSections();
1088
1089public:
1090 IHexELFBuilder(const std::vector<IHexRecord> &Records) : Records(Records) {}
1091
1093};
1094
1095template <class ELFT> class ELFBuilder {
1096private:
1097 using Elf_Addr = typename ELFT::Addr;
1098 using Elf_Shdr = typename ELFT::Shdr;
1099 using Elf_Word = typename ELFT::Word;
1100
1101 const ELFFile<ELFT> &ElfFile;
1102 Object &Obj;
1103 size_t EhdrOffset = 0;
1104 std::optional<StringRef> ExtractPartition;
1105
1106 void setParentSegment(Segment &Child);
1107 Error readProgramHeaders(const ELFFile<ELFT> &HeadersFile);
1108 Error initGroupSection(GroupSection *GroupSec);
1109 Error initSymbolTable(SymbolTableSection *SymTab);
1110 Error readSectionHeaders();
1111 Error readSections(bool EnsureSymtab);
1112 Error findEhdrOffset();
1113 Expected<SectionBase &> makeSection(const Elf_Shdr &Shdr);
1114
1115public:
1116 ELFBuilder(const ELFObjectFile<ELFT> &ElfObj, Object &Obj,
1117 std::optional<StringRef> ExtractPartition);
1118
1119 Error build(bool EnsureSymtab);
1120};
1121
1122class BinaryReader : public Reader {
1123 MemoryBuffer *MemBuf;
1124 uint8_t NewSymbolVisibility;
1125
1126public:
1127 BinaryReader(MemoryBuffer *MB, const uint8_t NewSymbolVisibility)
1128 : MemBuf(MB), NewSymbolVisibility(NewSymbolVisibility) {}
1129 Expected<std::unique_ptr<Object>> create(bool EnsureSymtab) const override;
1130};
1131
1132class IHexReader : public Reader {
1133 MemoryBuffer *MemBuf;
1134
1135 Expected<std::vector<IHexRecord>> parse() const;
1136 Error parseError(size_t LineNo, Error E) const {
1137 return LineNo == -1U
1138 ? createFileError(MemBuf->getBufferIdentifier(), std::move(E))
1139 : createFileError(MemBuf->getBufferIdentifier(), LineNo,
1140 std::move(E));
1141 }
1142 template <typename... Ts>
1143 Error parseError(size_t LineNo, char const *Fmt, const Ts &...Vals) const {
1145 return parseError(LineNo, std::move(E));
1146 }
1147
1148public:
1149 IHexReader(MemoryBuffer *MB) : MemBuf(MB) {}
1150
1151 Expected<std::unique_ptr<Object>> create(bool EnsureSymtab) const override;
1152};
1153
1154class ELFReader : public Reader {
1155 Binary *Bin;
1156 std::optional<StringRef> ExtractPartition;
1157
1158public:
1159 Expected<std::unique_ptr<Object>> create(bool EnsureSymtab) const override;
1160 explicit ELFReader(Binary *B, std::optional<StringRef> ExtractPartition)
1161 : Bin(B), ExtractPartition(ExtractPartition) {}
1162};
1163
1164class Object {
1165private:
1166 using SecPtr = std::unique_ptr<SectionBase>;
1167 using SegPtr = std::unique_ptr<Segment>;
1168
1169 std::vector<SecPtr> Sections;
1170 std::vector<SegPtr> Segments;
1171 std::vector<SecPtr> RemovedSections;
1173
1174 static bool sectionIsAlloc(const SectionBase &Sec) {
1175 return Sec.Flags & ELF::SHF_ALLOC;
1176 };
1177
1178 Error updateSectionData(SecPtr &Sec, ArrayRef<uint8_t> Data);
1179
1180public:
1181 template <class T>
1183 typename std::vector<std::unique_ptr<T>>::const_iterator>>;
1184
1185 // It is often the case that the ELF header and the program header table are
1186 // not present in any segment. This could be a problem during file layout,
1187 // because other segments may get assigned an offset where either of the
1188 // two should reside, which will effectively corrupt the resulting binary.
1189 // Other than that we use these segments to track program header offsets
1190 // when they may not follow the ELF header.
1193
1203
1204 bool HadShdrs = true;
1205 bool MustBeRelocatable = false;
1209
1210 bool IsMips64EL = false;
1211
1212 SectionTableRef sections() const { return SectionTableRef(Sections); }
1215 decltype(&sectionIsAlloc)>>
1217 return make_filter_range(make_pointee_range(Sections), sectionIsAlloc);
1218 }
1219
1220 const auto &getUpdatedSections() const { return UpdatedSections; }
1222 Error updateSectionData(SectionBase &S, ArrayRef<uint8_t> Data);
1223
1225 auto SecIt =
1226 find_if(Sections, [&](const SecPtr &Sec) { return Sec->Name == Name; });
1227 return SecIt == Sections.end() ? nullptr : SecIt->get();
1228 }
1229 SectionTableRef removedSections() { return SectionTableRef(RemovedSections); }
1230
1232
1233 Error removeSections(bool AllowBrokenLinks,
1234 std::function<bool(const SectionBase &)> ToRemove);
1238 template <class T, class... Ts> T &addSection(Ts &&...Args) {
1239 auto Sec = std::make_unique<T>(std::forward<Ts>(Args)...);
1240 auto Ptr = Sec.get();
1242 Sections.emplace_back(std::move(Sec));
1243 Ptr->Index = Sections.size();
1244 return *Ptr;
1245 }
1248 Segments.emplace_back(std::make_unique<Segment>(Data));
1249 return *Segments.back();
1250 }
1251 bool isRelocatable() const {
1252 return (Type != ELF::ET_DYN && Type != ELF::ET_EXEC) || MustBeRelocatable;
1253 }
1254};
1255
1256} // end namespace elf
1257} // end namespace objcopy
1258} // end namespace llvm
1259
1260#endif // LLVM_LIB_OBJCOPY_ELF_ELFOBJECT_H
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
unsigned uint64_t
ReachingDefInfo InstSet & ToRemove
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
#define MAKE_SEC_WRITER_FRIEND
Definition ELFObject.h:172
#define T
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
Lightweight error class with error context and mandatory checking.
Definition Error.h:159
Tagged union holding either a T or a Error.
Definition Error.h:485
This interface provides simple read-only access to a block of memory, and provides simple methods for...
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
std::string str() const
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:82
LLVM_ABI 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:46
LLVM Value Representation.
Definition Value.h:75
This class is an extension of MemoryBuffer, which allows copy-on-write access to the underlying conte...
An efficient, type-erasing, non-owning reference to a callable.
A range adaptor for a pair of iterators.
Error checkSection(const SectionBase &S) const
ASCIIHexWriter(Object &Obj, raw_ostream &OS, StringRef OutputFile)
Definition ELFObject.h:381
std::vector< const SectionBase * > Sections
Definition ELFObject.h:388
virtual Expected< size_t > getTotalSize(WritableMemoryBuffer &EmptyBuffer) const =0
StringTableSection * addStrTab()
SymbolTableSection * addSymTab(StringTableSection *StrTab)
std::unique_ptr< Object > Obj
Definition ELFObject.h:1059
BinaryELFBuilder(MemoryBuffer *MB, uint8_t NewSymbolVisibility)
Definition ELFObject.h:1078
Expected< std::unique_ptr< Object > > build()
BinaryReader(MemoryBuffer *MB, const uint8_t NewSymbolVisibility)
Definition ELFObject.h:1127
Expected< std::unique_ptr< Object > > create(bool EnsureSymtab) const override
Error visit(const SymbolTableSection &Sec) override
BinarySectionWriter(WritableMemoryBuffer &Buf)
Definition ELFObject.h:194
BinaryWriter(Object &Obj, raw_ostream &Out, const CommonConfig &Config)
Definition ELFObject.h:374
~BinaryWriter() override=default
Error accept(SectionVisitor &Visitor) const override
CompressedSection(const SectionBase &Sec, DebugCompressionType CompressionType, bool Is64Bits)
static bool classof(const SectionBase *S)
Definition ELFObject.h:686
Error accept(SectionVisitor &Visitor) const override
DecompressedSection(const CompressedSection &Sec)
Definition ELFObject.h:696
Error accept(SectionVisitor &) const override
DynamicRelocationSection(ArrayRef< uint8_t > Data)
Definition ELFObject.h:1016
static bool classof(const SectionBase *S)
Definition ELFObject.h:1024
Error removeSectionReferences(bool AllowBrokenLinks, function_ref< bool(const SectionBase *)> ToRemove) override
DynamicSection(ArrayRef< uint8_t > Data)
Definition ELFObject.h:1001
static bool classof(const SectionBase *S)
Definition ELFObject.h:1003
static bool classof(const SectionBase *S)
Definition ELFObject.h:994
DynamicSymbolTableSection(ArrayRef< uint8_t > Data)
Definition ELFObject.h:992
ELFBuilder(const ELFObjectFile< ELFT > &ElfObj, Object &Obj, std::optional< StringRef > ExtractPartition)
Error build(bool EnsureSymtab)
ELFReader(Binary *B, std::optional< StringRef > ExtractPartition)
Definition ELFObject.h:1160
Expected< std::unique_ptr< Object > > create(bool EnsureSymtab) const override
Error visit(Section &Sec) override
Definition ELFObject.cpp:82
ELFSectionWriter(WritableMemoryBuffer &Buf)
Definition ELFObject.h:147
Error visit(const SymbolTableSection &Sec) override
~ELFWriter() override=default
ELFWriter(Object &Obj, raw_ostream &Out, bool WSH, bool OnlyKeepDebug)
GroupSection(ArrayRef< uint8_t > Data)
Definition ELFObject.h:962
ConstRange< SectionBase > members() const
Definition ELFObject.h:981
void setSymTab(const SymbolTableSection *SymTabSec)
Definition ELFObject.h:964
iterator_range< pointee_iterator< typename llvm::SmallVector< T *, 3 >::const_iterator > > ConstRange
Definition ELFObject.h:956
void replaceSectionReferences(const DenseMap< SectionBase *, SectionBase * > &FromTo) override
Error accept(SectionVisitor &) const override
static bool classof(const SectionBase *S)
Definition ELFObject.h:985
ArrayRef< uint8_t > Contents
Definition ELFObject.h:960
void addMember(SectionBase *Sec)
Definition ELFObject.h:967
Error removeSectionReferences(bool AllowBrokenLinks, function_ref< bool(const SectionBase *)> ToRemove) override
void setFlagWord(ELF::Elf32_Word W)
Definition ELFObject.h:966
Error removeSymbols(function_ref< bool(const Symbol &)> ToRemove) override
IHexELFBuilder(const std::vector< IHexRecord > &Records)
Definition ELFObject.h:1090
Expected< std::unique_ptr< Object > > build()
IHexReader(MemoryBuffer *MB)
Definition ELFObject.h:1149
Expected< std::unique_ptr< Object > > create(bool EnsureSymtab) const override
IHexSectionWriterBase(WritableMemoryBuffer &Buf)
Definition ELFObject.h:291
void writeSection(const SectionBase *Sec, ArrayRef< uint8_t > Data)
Error visit(const Section &Sec) final
virtual void writeData(uint8_t Type, uint16_t Addr, ArrayRef< uint8_t > Data)
IHexSectionWriter(WritableMemoryBuffer &Buf)
Definition ELFObject.h:305
void writeData(uint8_t Type, uint16_t Addr, ArrayRef< uint8_t > Data) override
Error visit(const StringTableSection &Sec) override
IHexWriter(Object &Obj, raw_ostream &Out, StringRef OutputFile)
Definition ELFObject.h:398
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
iterator_range< pointee_iterator< typename std::vector< std::unique_ptr< T > >::const_iterator > > ConstRange
Definition ELFObject.h:1182
SectionTableRef sections() const
Definition ELFObject.h:1212
StringTableSection * SectionNames
Definition ELFObject.h:1206
SectionTableRef removedSections()
Definition ELFObject.h:1229
iterator_range< filter_iterator< pointee_iterator< std::vector< SecPtr >::const_iterator >, decltype(&sectionIsAlloc)> > allocSections() const
Definition ELFObject.h:1216
Error updateSection(StringRef Name, ArrayRef< uint8_t > Data)
SectionIndexSection * SectionIndexTable
Definition ELFObject.h:1208
Error removeSymbols(function_ref< bool(const Symbol &)> ToRemove)
T & addSection(Ts &&...Args)
Definition ELFObject.h:1238
Error removeSections(bool AllowBrokenLinks, std::function< bool(const SectionBase &)> ToRemove)
Segment & addSegment(ArrayRef< uint8_t > Data)
Definition ELFObject.h:1247
ConstRange< Segment > segments() const
Definition ELFObject.h:1231
SymbolTableSection * SymbolTable
Definition ELFObject.h:1207
Error compressOrDecompressSections(const CommonConfig &Config)
const auto & getUpdatedSections() const
Definition ELFObject.h:1220
SectionBase * findSection(StringRef Name)
Definition ELFObject.h:1224
Error replaceSections(const DenseMap< SectionBase *, SectionBase * > &FromTo)
void appendHexData(StringRef HexData)
ArrayRef< uint8_t > getContents() const override
Definition ELFObject.h:661
OwnedDataSection(const Twine &SecName, uint64_t SecAddr, uint64_t SecFlags, uint64_t SecOff)
Definition ELFObject.h:643
Error accept(SectionVisitor &Sec) const override
OwnedDataSection(StringRef SecName, ArrayRef< uint8_t > Data)
Definition ELFObject.h:635
OwnedDataSection(SectionBase &S, ArrayRef< uint8_t > Data)
Definition ELFObject.h:652
bool hasContents() const override
Definition ELFObject.h:660
virtual Expected< std::unique_ptr< Object > > create(bool EnsureSymtab) const =0
Error initialize(SectionTableRef SecTable) override
const SectionBase * getSection() const
Definition ELFObject.h:888
static bool classof(const SectionBase *S)
Definition ELFObject.h:893
const Object & getObject() const
Definition ELFObject.h:936
void addRelocation(const Relocation &Rel)
Definition ELFObject.h:926
Error accept(SectionVisitor &Visitor) const override
Error removeSymbols(function_ref< bool(const Symbol &)> ToRemove) override
void replaceSectionReferences(const DenseMap< SectionBase *, SectionBase * > &FromTo) override
static bool classof(const SectionBase *S)
Definition ELFObject.h:938
Error removeSectionReferences(bool AllowBrokenLinks, function_ref< bool(const SectionBase *)> ToRemove) override
virtual void writeRecord(SRecord &Record, uint64_t Off)=0
void writeSection(const SectionBase &S, ArrayRef< uint8_t > Data)
Error visit(const Section &S) override
SRECSectionWriterBase(WritableMemoryBuffer &Buf, uint64_t StartOffset)
Definition ELFObject.h:461
Error visit(const StringTableSection &Sec) override
void writeRecord(SRecord &Record, uint64_t Off) override
SRECSectionWriter(WritableMemoryBuffer &Buf, uint64_t Offset)
Definition ELFObject.h:502
SRECSizeCalculator(WritableMemoryBuffer &EmptyBuffer, uint64_t Offset)
Definition ELFObject.h:493
void writeRecord(SRecord &Record, uint64_t Off) override
Definition ELFObject.h:497
SRECWriter(Object &Obj, raw_ostream &OS, StringRef OutputFile)
Definition ELFObject.h:410
ArrayRef< uint8_t > OriginalData
Definition ELFObject.h:532
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:557
virtual ArrayRef< uint8_t > getContents() const
Definition ELFObject.h:553
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:552
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:798
Error accept(SectionVisitor &Visitor) const override
void reserve(size_t NumSymbols)
Definition ELFObject.h:794
Error initialize(SectionTableRef SecTable) override
pointee_iterator< const std::unique_ptr< SectionBase > * > iterator
Definition ELFObject.h:55
Expected< T * > getSectionOfType(uint32_t Index, Twine IndexErrMsg, Twine TypeErrMsg)
SectionTableRef(ArrayRef< std::unique_ptr< SectionBase > > Secs)
Definition ELFObject.h:57
SectionTableRef(const SectionTableRef &)=default
Expected< SectionBase * > getSection(uint32_t Index, Twine ErrMsg)
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
Error visit(const GnuDebugLinkSection &Sec) override=0
Error visit(const SymbolTableSection &Sec) override=0
~SectionWriter() override=default
WritableMemoryBuffer & Out
Definition ELFObject.h:110
Error visit(const DecompressedSection &Sec) override=0
SectionWriter(WritableMemoryBuffer &Buf)
Definition ELFObject.h:127
Error removeSectionReferences(bool AllowBrokenLinks, function_ref< bool(const SectionBase *)> ToRemove) override
Error initialize(SectionTableRef SecTable) override
ArrayRef< uint8_t > getContents() const override
Definition ELFObject.h:624
Section(ArrayRef< uint8_t > Data)
Definition ELFObject.h:612
void restoreSymTabLink(SymbolTableSection &SymTab) override
bool hasContents() const override
Definition ELFObject.h:621
Error accept(SectionVisitor &Visitor) const override
void addSection(const SectionBase *Sec)
Definition ELFObject.h:599
Segment(ArrayRef< uint8_t > Data)
Definition ELFObject.h:589
ArrayRef< uint8_t > Contents
Definition ELFObject.h:586
void removeSection(const SectionBase *Sec)
Definition ELFObject.h:598
const SectionBase * firstSection() const
Definition ELFObject.h:592
ArrayRef< uint8_t > getContents() const
Definition ELFObject.h:601
std::set< const SectionBase *, SectionCompare > Sections
Definition ELFObject.h:587
static bool classof(const SectionBase *S)
Definition ELFObject.h:731
uint32_t findIndex(StringRef Name) const
Error accept(SectionVisitor &Visitor) const override
const SectionBase * getStrTab() const
Definition ELFObject.h:841
Error removeSectionReferences(bool AllowBrokenLinks, function_ref< bool(const SectionBase *)> ToRemove) override
const SectionIndexSection * getShndxTable() const
Definition ELFObject.h:839
std::vector< std::unique_ptr< Symbol > > Symbols
Definition ELFObject.h:819
SectionIndexSection * SectionIndexTable
Definition ELFObject.h:821
Error accept(SectionVisitor &Visitor) const override
void addSymbol(Twine Name, uint8_t Bind, uint8_t Type, SectionBase *DefinedIn, uint64_t Value, uint8_t Visibility, uint16_t Shndx, uint64_t SymbolSize)
void updateSymbols(function_ref< void(Symbol &)> Callable)
static bool classof(const SectionBase *S)
Definition ELFObject.h:857
Expected< const Symbol * > getSymbolByIndex(uint32_t Index) const
Error removeSymbols(function_ref< bool(const Symbol &)> ToRemove) override
Error initialize(SectionTableRef SecTable) override
void replaceSectionReferences(const DenseMap< SectionBase *, SectionBase * > &FromTo) override
std::unique_ptr< Symbol > SymPtr
Definition ELFObject.h:824
void setShndxTable(SectionIndexSection *ShndxTable)
Definition ELFObject.h:836
virtual Error finalize()=0
virtual Error write()=0
std::unique_ptr< WritableMemoryBuffer > Buf
Definition ELFObject.h:314
Writer(Object &O, raw_ostream &Out)
Definition ELFObject.h:322
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition raw_ostream.h:53
@ SHN_XINDEX
Definition ELF.h:1150
@ SHN_HIOS
Definition ELF.h:1147
@ SHN_ABS
Definition ELF.h:1148
@ SHN_COMMON
Definition ELF.h:1149
@ SHN_LOOS
Definition ELF.h:1146
@ SHN_LOPROC
Definition ELF.h:1144
@ SHN_UNDEF
Definition ELF.h:1142
@ SHN_HIPROC
Definition ELF.h:1145
@ SHN_AMDGPU_LDS
Definition ELF.h:1988
@ SHF_ALLOC
Definition ELF.h:1259
@ SHF_COMPRESSED
Definition ELF.h:1287
uint32_t Elf32_Word
Definition ELF.h:35
@ SHN_HEXAGON_SCOMMON_2
Definition ELF.h:695
@ SHN_HEXAGON_SCOMMON_4
Definition ELF.h:696
@ SHN_HEXAGON_SCOMMON_8
Definition ELF.h:697
@ SHN_HEXAGON_SCOMMON
Definition ELF.h:693
@ SHT_STRTAB
Definition ELF.h:1159
@ SHT_GROUP
Definition ELF.h:1171
@ SHT_PROGBITS
Definition ELF.h:1157
@ SHT_REL
Definition ELF.h:1165
@ SHT_NULL
Definition ELF.h:1156
@ SHT_NOBITS
Definition ELF.h:1164
@ SHT_SYMTAB
Definition ELF.h:1158
@ SHT_CREL
Definition ELF.h:1178
@ SHT_DYNAMIC
Definition ELF.h:1162
@ SHT_SYMTAB_SHNDX
Definition ELF.h:1172
@ SHT_RELA
Definition ELF.h:1160
@ SHT_DYNSYM
Definition ELF.h:1167
@ SHN_MIPS_TEXT
Definition ELF.h:586
@ SHN_MIPS_DATA
Definition ELF.h:587
@ SHN_MIPS_SUNDEFINED
Definition ELF.h:589
@ SHN_MIPS_SCOMMON
Definition ELF.h:588
@ SHN_MIPS_ACOMMON
Definition ELF.h:585
@ ET_DYN
Definition ELF.h:121
@ ET_EXEC
Definition ELF.h:120
SmallVector< char, 64 > IHexLineData
Definition ELFObject.h:198
SmallVector< char, 64 > SRecLineData
Definition ELFObject.h:421
This is an optimization pass for GlobalISel generic memory operations.
Error createFileError(const Twine &F, Error E)
Concatenate a source file path and/or name with an Error.
Definition Error.h:1415
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
Definition Error.h:1321
@ invalid_argument
Definition Errc.h:56
iterator_range< pointee_iterator< WrappedIteratorT > > make_pointee_range(RangeT &&Range)
Definition iterator.h:341
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:552
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
Definition Casting.h:547
DebugCompressionType
Definition Compression.h:28
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:1788
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
Definition STLExtras.h:1963
filter_iterator_impl< WrappedIteratorT, PredicateT, detail::fwd_or_bidi_tag< WrappedIteratorT > > filter_iterator
Defines filter_iterator to a suitable specialization of filter_iterator_impl, based on the underlying...
Definition STLExtras.h:539
Implement std::hash so that hash_code can be used in STL containers.
Definition BitVector.h:878
static IHexLineData getLine(uint8_t Type, uint16_t Addr, ArrayRef< uint8_t > Data)
static uint8_t getChecksum(StringRef S)
static Expected< IHexRecord > parse(StringRef Line)
static size_t getLength(size_t DataSize)
Definition ELFObject.h:210
static size_t getLineLength(size_t DataSize)
Definition ELFObject.h:216
uint8_t getAddressSize() const
static SRecord getHeader(StringRef FileName)
SRecLineData toString() const
static uint8_t getType(uint32_t Address)
ArrayRef< uint8_t > Data
Definition ELFObject.h:425
uint16_t getShndx() const
SymbolShndxType ShndxType
Definition ELFObject.h:766
An iterator type that allows iterating over the pointees via some other iterator.
Definition iterator.h:329