]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/llvm-objcopy/ELF/Object.h
Merge llvm, clang, compiler-rt, libc++, libunwind, lld, lldb and openmp
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / llvm-objcopy / ELF / Object.h
1 //===- Object.h -------------------------------------------------*- C++ -*-===//
2 //
3 //                      The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 #ifndef LLVM_TOOLS_OBJCOPY_OBJECT_H
11 #define LLVM_TOOLS_OBJCOPY_OBJECT_H
12
13 #include "Buffer.h"
14 #include "CopyConfig.h"
15 #include "llvm/ADT/ArrayRef.h"
16 #include "llvm/ADT/StringRef.h"
17 #include "llvm/ADT/Twine.h"
18 #include "llvm/BinaryFormat/ELF.h"
19 #include "llvm/MC/StringTableBuilder.h"
20 #include "llvm/Object/ELFObjectFile.h"
21 #include "llvm/Support/FileOutputBuffer.h"
22 #include "llvm/Support/JamCRC.h"
23 #include <cstddef>
24 #include <cstdint>
25 #include <functional>
26 #include <memory>
27 #include <set>
28 #include <vector>
29
30 namespace llvm {
31 enum class DebugCompressionType;
32 namespace objcopy {
33 namespace elf {
34
35 class SectionBase;
36 class Section;
37 class OwnedDataSection;
38 class StringTableSection;
39 class SymbolTableSection;
40 class RelocationSection;
41 class DynamicRelocationSection;
42 class GnuDebugLinkSection;
43 class GroupSection;
44 class SectionIndexSection;
45 class CompressedSection;
46 class DecompressedSection;
47 class Segment;
48 class Object;
49 struct Symbol;
50
51 class SectionTableRef {
52   MutableArrayRef<std::unique_ptr<SectionBase>> Sections;
53
54 public:
55   using iterator = pointee_iterator<std::unique_ptr<SectionBase> *>;
56
57   explicit SectionTableRef(MutableArrayRef<std::unique_ptr<SectionBase>> Secs)
58       : Sections(Secs) {}
59   SectionTableRef(const SectionTableRef &) = default;
60
61   iterator begin() { return iterator(Sections.data()); }
62   iterator end() { return iterator(Sections.data() + Sections.size()); }
63
64   SectionBase *getSection(uint32_t Index, Twine ErrMsg);
65
66   template <class T>
67   T *getSectionOfType(uint32_t Index, Twine IndexErrMsg, Twine TypeErrMsg);
68 };
69
70 enum ElfType { ELFT_ELF32LE, ELFT_ELF64LE, ELFT_ELF32BE, ELFT_ELF64BE };
71
72 class SectionVisitor {
73 public:
74   virtual ~SectionVisitor() = default;
75
76   virtual void visit(const Section &Sec) = 0;
77   virtual void visit(const OwnedDataSection &Sec) = 0;
78   virtual void visit(const StringTableSection &Sec) = 0;
79   virtual void visit(const SymbolTableSection &Sec) = 0;
80   virtual void visit(const RelocationSection &Sec) = 0;
81   virtual void visit(const DynamicRelocationSection &Sec) = 0;
82   virtual void visit(const GnuDebugLinkSection &Sec) = 0;
83   virtual void visit(const GroupSection &Sec) = 0;
84   virtual void visit(const SectionIndexSection &Sec) = 0;
85   virtual void visit(const CompressedSection &Sec) = 0;
86   virtual void visit(const DecompressedSection &Sec) = 0;
87 };
88
89 class MutableSectionVisitor {
90 public:
91   virtual ~MutableSectionVisitor() = default;
92
93   virtual void visit(Section &Sec) = 0;
94   virtual void visit(OwnedDataSection &Sec) = 0;
95   virtual void visit(StringTableSection &Sec) = 0;
96   virtual void visit(SymbolTableSection &Sec) = 0;
97   virtual void visit(RelocationSection &Sec) = 0;
98   virtual void visit(DynamicRelocationSection &Sec) = 0;
99   virtual void visit(GnuDebugLinkSection &Sec) = 0;
100   virtual void visit(GroupSection &Sec) = 0;
101   virtual void visit(SectionIndexSection &Sec) = 0;
102   virtual void visit(CompressedSection &Sec) = 0;
103   virtual void visit(DecompressedSection &Sec) = 0;
104 };
105
106 class SectionWriter : public SectionVisitor {
107 protected:
108   Buffer &Out;
109
110 public:
111   virtual ~SectionWriter(){};
112
113   void visit(const Section &Sec) override;
114   void visit(const OwnedDataSection &Sec) override;
115   void visit(const StringTableSection &Sec) override;
116   void visit(const DynamicRelocationSection &Sec) override;
117   virtual void visit(const SymbolTableSection &Sec) override = 0;
118   virtual void visit(const RelocationSection &Sec) override = 0;
119   virtual void visit(const GnuDebugLinkSection &Sec) override = 0;
120   virtual void visit(const GroupSection &Sec) override = 0;
121   virtual void visit(const SectionIndexSection &Sec) override = 0;
122   virtual void visit(const CompressedSection &Sec) override = 0;
123   virtual void visit(const DecompressedSection &Sec) override = 0;
124
125   explicit SectionWriter(Buffer &Buf) : Out(Buf) {}
126 };
127
128 template <class ELFT> class ELFSectionWriter : public SectionWriter {
129 private:
130   using Elf_Word = typename ELFT::Word;
131   using Elf_Rel = typename ELFT::Rel;
132   using Elf_Rela = typename ELFT::Rela;
133   using Elf_Sym = typename ELFT::Sym;
134
135 public:
136   virtual ~ELFSectionWriter() {}
137   void visit(const SymbolTableSection &Sec) override;
138   void visit(const RelocationSection &Sec) override;
139   void visit(const GnuDebugLinkSection &Sec) override;
140   void visit(const GroupSection &Sec) override;
141   void visit(const SectionIndexSection &Sec) override;
142   void visit(const CompressedSection &Sec) override;
143   void visit(const DecompressedSection &Sec) override;
144
145   explicit ELFSectionWriter(Buffer &Buf) : SectionWriter(Buf) {}
146 };
147
148 template <class ELFT> class ELFSectionSizer : public MutableSectionVisitor {
149 private:
150   using Elf_Rel = typename ELFT::Rel;
151   using Elf_Rela = typename ELFT::Rela;
152   using Elf_Sym = typename ELFT::Sym;
153   using Elf_Word = typename ELFT::Word;
154   using Elf_Xword = typename ELFT::Xword;
155
156 public:
157   void visit(Section &Sec) override;
158   void visit(OwnedDataSection &Sec) override;
159   void visit(StringTableSection &Sec) override;
160   void visit(DynamicRelocationSection &Sec) override;
161   void visit(SymbolTableSection &Sec) override;
162   void visit(RelocationSection &Sec) override;
163   void visit(GnuDebugLinkSection &Sec) override;
164   void visit(GroupSection &Sec) override;
165   void visit(SectionIndexSection &Sec) override;
166   void visit(CompressedSection &Sec) override;
167   void visit(DecompressedSection &Sec) override;
168 };
169
170 #define MAKE_SEC_WRITER_FRIEND                                                 \
171   friend class SectionWriter;                                                  \
172   template <class ELFT> friend class ELFSectionWriter;                         \
173   template <class ELFT> friend class ELFSectionSizer;
174
175 class BinarySectionWriter : public SectionWriter {
176 public:
177   virtual ~BinarySectionWriter() {}
178
179   void visit(const SymbolTableSection &Sec) override;
180   void visit(const RelocationSection &Sec) override;
181   void visit(const GnuDebugLinkSection &Sec) override;
182   void visit(const GroupSection &Sec) override;
183   void visit(const SectionIndexSection &Sec) override;
184   void visit(const CompressedSection &Sec) override;
185   void visit(const DecompressedSection &Sec) override;
186
187   explicit BinarySectionWriter(Buffer &Buf) : SectionWriter(Buf) {}
188 };
189
190 class Writer {
191 protected:
192   Object &Obj;
193   Buffer &Buf;
194
195 public:
196   virtual ~Writer();
197   virtual void finalize() = 0;
198   virtual void write() = 0;
199
200   Writer(Object &O, Buffer &B) : Obj(O), Buf(B) {}
201 };
202
203 template <class ELFT> class ELFWriter : public Writer {
204 private:
205   using Elf_Addr = typename ELFT::Addr;
206   using Elf_Shdr = typename ELFT::Shdr;
207   using Elf_Phdr = typename ELFT::Phdr;
208   using Elf_Ehdr = typename ELFT::Ehdr;
209
210   void initEhdrSegment();
211
212   void writeEhdr();
213   void writePhdr(const Segment &Seg);
214   void writeShdr(const SectionBase &Sec);
215
216   void writePhdrs();
217   void writeShdrs();
218   void writeSectionData();
219
220   void assignOffsets();
221
222   std::unique_ptr<ELFSectionWriter<ELFT>> SecWriter;
223
224   size_t totalSize() const;
225
226 public:
227   virtual ~ELFWriter() {}
228   bool WriteSectionHeaders = true;
229
230   void finalize() override;
231   void write() override;
232   ELFWriter(Object &Obj, Buffer &Buf, bool WSH)
233       : Writer(Obj, Buf), WriteSectionHeaders(WSH) {}
234 };
235
236 class BinaryWriter : public Writer {
237 private:
238   std::unique_ptr<BinarySectionWriter> SecWriter;
239
240   uint64_t TotalSize;
241
242 public:
243   ~BinaryWriter() {}
244   void finalize() override;
245   void write() override;
246   BinaryWriter(Object &Obj, Buffer &Buf) : Writer(Obj, Buf) {}
247 };
248
249 class SectionBase {
250 public:
251   std::string Name;
252   Segment *ParentSegment = nullptr;
253   uint64_t HeaderOffset;
254   uint64_t OriginalOffset = std::numeric_limits<uint64_t>::max();
255   uint32_t Index;
256   bool HasSymbol = false;
257
258   uint64_t Addr = 0;
259   uint64_t Align = 1;
260   uint32_t EntrySize = 0;
261   uint64_t Flags = 0;
262   uint64_t Info = 0;
263   uint64_t Link = ELF::SHN_UNDEF;
264   uint64_t NameIndex = 0;
265   uint64_t Offset = 0;
266   uint64_t Size = 0;
267   uint64_t Type = ELF::SHT_NULL;
268   ArrayRef<uint8_t> OriginalData;
269
270   SectionBase() = default;
271   SectionBase(const SectionBase &) = default;
272
273   virtual ~SectionBase() = default;
274
275   virtual void initialize(SectionTableRef SecTable);
276   virtual void finalize();
277   virtual void removeSectionReferences(const SectionBase *Sec);
278   virtual void removeSymbols(function_ref<bool(const Symbol &)> ToRemove);
279   virtual void accept(SectionVisitor &Visitor) const = 0;
280   virtual void accept(MutableSectionVisitor &Visitor) = 0;
281   virtual void markSymbols();
282 };
283
284 class Segment {
285 private:
286   struct SectionCompare {
287     bool operator()(const SectionBase *Lhs, const SectionBase *Rhs) const {
288       // Some sections might have the same address if one of them is empty. To
289       // fix this we can use the lexicographic ordering on ->Addr and the
290       // address of the actully stored section.
291       if (Lhs->OriginalOffset == Rhs->OriginalOffset)
292         return Lhs < Rhs;
293       return Lhs->OriginalOffset < Rhs->OriginalOffset;
294     }
295   };
296
297   std::set<const SectionBase *, SectionCompare> Sections;
298
299 public:
300   uint32_t Type;
301   uint32_t Flags;
302   uint64_t Offset;
303   uint64_t VAddr;
304   uint64_t PAddr;
305   uint64_t FileSize;
306   uint64_t MemSize;
307   uint64_t Align;
308
309   uint32_t Index;
310   uint64_t OriginalOffset;
311   Segment *ParentSegment = nullptr;
312   ArrayRef<uint8_t> Contents;
313
314   explicit Segment(ArrayRef<uint8_t> Data) : Contents(Data) {}
315   Segment() {}
316
317   const SectionBase *firstSection() const {
318     if (!Sections.empty())
319       return *Sections.begin();
320     return nullptr;
321   }
322
323   void removeSection(const SectionBase *Sec) { Sections.erase(Sec); }
324   void addSection(const SectionBase *Sec) { Sections.insert(Sec); }
325 };
326
327 class Section : public SectionBase {
328   MAKE_SEC_WRITER_FRIEND
329
330   ArrayRef<uint8_t> Contents;
331   SectionBase *LinkSection = nullptr;
332
333 public:
334   explicit Section(ArrayRef<uint8_t> Data) : Contents(Data) {}
335
336   void accept(SectionVisitor &Visitor) const override;
337   void accept(MutableSectionVisitor &Visitor) override;
338   void removeSectionReferences(const SectionBase *Sec) override;
339   void initialize(SectionTableRef SecTable) override;
340   void finalize() override;
341 };
342
343 class OwnedDataSection : public SectionBase {
344   MAKE_SEC_WRITER_FRIEND
345
346   std::vector<uint8_t> Data;
347
348 public:
349   OwnedDataSection(StringRef SecName, ArrayRef<uint8_t> Data)
350       : Data(std::begin(Data), std::end(Data)) {
351     Name = SecName.str();
352     Type = ELF::SHT_PROGBITS;
353     Size = Data.size();
354     OriginalOffset = std::numeric_limits<uint64_t>::max();
355   }
356
357   void accept(SectionVisitor &Sec) const override;
358   void accept(MutableSectionVisitor &Visitor) override;
359 };
360
361 class CompressedSection : public SectionBase {
362   MAKE_SEC_WRITER_FRIEND
363
364   DebugCompressionType CompressionType;
365   uint64_t DecompressedSize;
366   uint64_t DecompressedAlign;
367   SmallVector<char, 128> CompressedData;
368
369 public:
370   CompressedSection(const SectionBase &Sec,
371                     DebugCompressionType CompressionType);
372   CompressedSection(ArrayRef<uint8_t> CompressedData, uint64_t DecompressedSize,
373                     uint64_t DecompressedAlign);
374
375   uint64_t getDecompressedSize() const { return DecompressedSize; }
376   uint64_t getDecompressedAlign() const { return DecompressedAlign; }
377
378   void accept(SectionVisitor &Visitor) const override;
379   void accept(MutableSectionVisitor &Visitor) override;
380
381   static bool classof(const SectionBase *S) {
382     return (S->Flags & ELF::SHF_COMPRESSED) ||
383            (StringRef(S->Name).startswith(".zdebug"));
384   }
385 };
386
387 class DecompressedSection : public SectionBase {
388   MAKE_SEC_WRITER_FRIEND
389
390 public:
391   explicit DecompressedSection(const CompressedSection &Sec)
392       : SectionBase(Sec) {
393     Size = Sec.getDecompressedSize();
394     Align = Sec.getDecompressedAlign();
395     Flags = (Flags & ~ELF::SHF_COMPRESSED);
396     if (StringRef(Name).startswith(".zdebug"))
397       Name = "." + Name.substr(2);
398   }
399
400   void accept(SectionVisitor &Visitor) const override;
401   void accept(MutableSectionVisitor &Visitor) override;
402 };
403
404 // There are two types of string tables that can exist, dynamic and not dynamic.
405 // In the dynamic case the string table is allocated. Changing a dynamic string
406 // table would mean altering virtual addresses and thus the memory image. So
407 // dynamic string tables should not have an interface to modify them or
408 // reconstruct them. This type lets us reconstruct a string table. To avoid
409 // this class being used for dynamic string tables (which has happened) the
410 // classof method checks that the particular instance is not allocated. This
411 // then agrees with the makeSection method used to construct most sections.
412 class StringTableSection : public SectionBase {
413   MAKE_SEC_WRITER_FRIEND
414
415   StringTableBuilder StrTabBuilder;
416
417 public:
418   StringTableSection() : StrTabBuilder(StringTableBuilder::ELF) {
419     Type = ELF::SHT_STRTAB;
420   }
421
422   void addString(StringRef Name);
423   uint32_t findIndex(StringRef Name) const;
424   void finalize() override;
425   void accept(SectionVisitor &Visitor) const override;
426   void accept(MutableSectionVisitor &Visitor) override;
427
428   static bool classof(const SectionBase *S) {
429     if (S->Flags & ELF::SHF_ALLOC)
430       return false;
431     return S->Type == ELF::SHT_STRTAB;
432   }
433 };
434
435 // Symbols have a st_shndx field that normally stores an index but occasionally
436 // stores a different special value. This enum keeps track of what the st_shndx
437 // field means. Most of the values are just copies of the special SHN_* values.
438 // SYMBOL_SIMPLE_INDEX means that the st_shndx is just an index of a section.
439 enum SymbolShndxType {
440   SYMBOL_SIMPLE_INDEX = 0,
441   SYMBOL_ABS = ELF::SHN_ABS,
442   SYMBOL_COMMON = ELF::SHN_COMMON,
443   SYMBOL_HEXAGON_SCOMMON = ELF::SHN_HEXAGON_SCOMMON,
444   SYMBOL_HEXAGON_SCOMMON_2 = ELF::SHN_HEXAGON_SCOMMON_2,
445   SYMBOL_HEXAGON_SCOMMON_4 = ELF::SHN_HEXAGON_SCOMMON_4,
446   SYMBOL_HEXAGON_SCOMMON_8 = ELF::SHN_HEXAGON_SCOMMON_8,
447   SYMBOL_XINDEX = ELF::SHN_XINDEX,
448 };
449
450 struct Symbol {
451   uint8_t Binding;
452   SectionBase *DefinedIn = nullptr;
453   SymbolShndxType ShndxType;
454   uint32_t Index;
455   std::string Name;
456   uint32_t NameIndex;
457   uint64_t Size;
458   uint8_t Type;
459   uint64_t Value;
460   uint8_t Visibility;
461   bool Referenced = false;
462
463   uint16_t getShndx() const;
464   bool isCommon() const;
465 };
466
467 class SectionIndexSection : public SectionBase {
468   MAKE_SEC_WRITER_FRIEND
469
470 private:
471   std::vector<uint32_t> Indexes;
472   SymbolTableSection *Symbols = nullptr;
473
474 public:
475   virtual ~SectionIndexSection() {}
476   void addIndex(uint32_t Index) {
477     Indexes.push_back(Index);
478     Size += 4;
479   }
480   void setSymTab(SymbolTableSection *SymTab) { Symbols = SymTab; }
481   void initialize(SectionTableRef SecTable) override;
482   void finalize() override;
483   void accept(SectionVisitor &Visitor) const override;
484   void accept(MutableSectionVisitor &Visitor) override;
485
486   SectionIndexSection() {
487     Name = ".symtab_shndx";
488     Align = 4;
489     EntrySize = 4;
490     Type = ELF::SHT_SYMTAB_SHNDX;
491   }
492 };
493
494 class SymbolTableSection : public SectionBase {
495   MAKE_SEC_WRITER_FRIEND
496
497   void setStrTab(StringTableSection *StrTab) { SymbolNames = StrTab; }
498   void assignIndices();
499
500 protected:
501   std::vector<std::unique_ptr<Symbol>> Symbols;
502   StringTableSection *SymbolNames = nullptr;
503   SectionIndexSection *SectionIndexTable = nullptr;
504
505   using SymPtr = std::unique_ptr<Symbol>;
506
507 public:
508   SymbolTableSection() { Type = ELF::SHT_SYMTAB; }
509
510   void addSymbol(Twine Name, uint8_t Bind, uint8_t Type, SectionBase *DefinedIn,
511                  uint64_t Value, uint8_t Visibility, uint16_t Shndx,
512                  uint64_t Size);
513   void prepareForLayout();
514   // An 'empty' symbol table still contains a null symbol.
515   bool empty() const { return Symbols.size() == 1; }
516   void setShndxTable(SectionIndexSection *ShndxTable) {
517     SectionIndexTable = ShndxTable;
518   }
519   const SectionIndexSection *getShndxTable() const { return SectionIndexTable; }
520   const SectionBase *getStrTab() const { return SymbolNames; }
521   const Symbol *getSymbolByIndex(uint32_t Index) const;
522   Symbol *getSymbolByIndex(uint32_t Index);
523   void updateSymbols(function_ref<void(Symbol &)> Callable);
524
525   void removeSectionReferences(const SectionBase *Sec) override;
526   void initialize(SectionTableRef SecTable) override;
527   void finalize() override;
528   void accept(SectionVisitor &Visitor) const override;
529   void accept(MutableSectionVisitor &Visitor) override;
530   void removeSymbols(function_ref<bool(const Symbol &)> ToRemove) override;
531
532   static bool classof(const SectionBase *S) {
533     return S->Type == ELF::SHT_SYMTAB;
534   }
535 };
536
537 struct Relocation {
538   Symbol *RelocSymbol = nullptr;
539   uint64_t Offset;
540   uint64_t Addend;
541   uint32_t Type;
542 };
543
544 // All relocation sections denote relocations to apply to another section.
545 // However, some relocation sections use a dynamic symbol table and others use
546 // a regular symbol table. Because the types of the two symbol tables differ in
547 // our system (because they should behave differently) we can't uniformly
548 // represent all relocations with the same base class if we expose an interface
549 // that mentions the symbol table type. So we split the two base types into two
550 // different classes, one which handles the section the relocation is applied to
551 // and another which handles the symbol table type. The symbol table type is
552 // taken as a type parameter to the class (see RelocSectionWithSymtabBase).
553 class RelocationSectionBase : public SectionBase {
554 protected:
555   SectionBase *SecToApplyRel = nullptr;
556
557 public:
558   const SectionBase *getSection() const { return SecToApplyRel; }
559   void setSection(SectionBase *Sec) { SecToApplyRel = Sec; }
560
561   static bool classof(const SectionBase *S) {
562     return S->Type == ELF::SHT_REL || S->Type == ELF::SHT_RELA;
563   }
564 };
565
566 // Takes the symbol table type to use as a parameter so that we can deduplicate
567 // that code between the two symbol table types.
568 template <class SymTabType>
569 class RelocSectionWithSymtabBase : public RelocationSectionBase {
570   SymTabType *Symbols = nullptr;
571   void setSymTab(SymTabType *SymTab) { Symbols = SymTab; }
572
573 protected:
574   RelocSectionWithSymtabBase() = default;
575
576 public:
577   void removeSectionReferences(const SectionBase *Sec) override;
578   void initialize(SectionTableRef SecTable) override;
579   void finalize() override;
580 };
581
582 class RelocationSection
583     : public RelocSectionWithSymtabBase<SymbolTableSection> {
584   MAKE_SEC_WRITER_FRIEND
585
586   std::vector<Relocation> Relocations;
587
588 public:
589   void addRelocation(Relocation Rel) { Relocations.push_back(Rel); }
590   void accept(SectionVisitor &Visitor) const override;
591   void accept(MutableSectionVisitor &Visitor) override;
592   void removeSymbols(function_ref<bool(const Symbol &)> ToRemove) override;
593   void markSymbols() override;
594
595   static bool classof(const SectionBase *S) {
596     if (S->Flags & ELF::SHF_ALLOC)
597       return false;
598     return S->Type == ELF::SHT_REL || S->Type == ELF::SHT_RELA;
599   }
600 };
601
602 // TODO: The way stripping and groups interact is complicated
603 // and still needs to be worked on.
604
605 class GroupSection : public SectionBase {
606   MAKE_SEC_WRITER_FRIEND
607   const SymbolTableSection *SymTab = nullptr;
608   Symbol *Sym = nullptr;
609   ELF::Elf32_Word FlagWord;
610   SmallVector<SectionBase *, 3> GroupMembers;
611
612 public:
613   // TODO: Contents is present in several classes of the hierarchy.
614   // This needs to be refactored to avoid duplication.
615   ArrayRef<uint8_t> Contents;
616
617   explicit GroupSection(ArrayRef<uint8_t> Data) : Contents(Data) {}
618
619   void setSymTab(const SymbolTableSection *SymTabSec) { SymTab = SymTabSec; }
620   void setSymbol(Symbol *S) { Sym = S; }
621   void setFlagWord(ELF::Elf32_Word W) { FlagWord = W; }
622   void addMember(SectionBase *Sec) { GroupMembers.push_back(Sec); }
623
624   void accept(SectionVisitor &) const override;
625   void accept(MutableSectionVisitor &Visitor) override;
626   void finalize() override;
627   void removeSymbols(function_ref<bool(const Symbol &)> ToRemove) override;
628   void markSymbols() override;
629
630   static bool classof(const SectionBase *S) {
631     return S->Type == ELF::SHT_GROUP;
632   }
633 };
634
635 class DynamicSymbolTableSection : public Section {
636 public:
637   explicit DynamicSymbolTableSection(ArrayRef<uint8_t> Data) : Section(Data) {}
638
639   static bool classof(const SectionBase *S) {
640     return S->Type == ELF::SHT_DYNSYM;
641   }
642 };
643
644 class DynamicSection : public Section {
645 public:
646   explicit DynamicSection(ArrayRef<uint8_t> Data) : Section(Data) {}
647
648   static bool classof(const SectionBase *S) {
649     return S->Type == ELF::SHT_DYNAMIC;
650   }
651 };
652
653 class DynamicRelocationSection
654     : public RelocSectionWithSymtabBase<DynamicSymbolTableSection> {
655   MAKE_SEC_WRITER_FRIEND
656
657 private:
658   ArrayRef<uint8_t> Contents;
659
660 public:
661   explicit DynamicRelocationSection(ArrayRef<uint8_t> Data) : Contents(Data) {}
662
663   void accept(SectionVisitor &) const override;
664   void accept(MutableSectionVisitor &Visitor) override;
665
666   static bool classof(const SectionBase *S) {
667     if (!(S->Flags & ELF::SHF_ALLOC))
668       return false;
669     return S->Type == ELF::SHT_REL || S->Type == ELF::SHT_RELA;
670   }
671 };
672
673 class GnuDebugLinkSection : public SectionBase {
674   MAKE_SEC_WRITER_FRIEND
675
676 private:
677   StringRef FileName;
678   uint32_t CRC32;
679
680   void init(StringRef File, StringRef Data);
681
682 public:
683   // If we add this section from an external source we can use this ctor.
684   explicit GnuDebugLinkSection(StringRef File);
685   void accept(SectionVisitor &Visitor) const override;
686   void accept(MutableSectionVisitor &Visitor) override;
687 };
688
689 class Reader {
690 public:
691   virtual ~Reader();
692   virtual std::unique_ptr<Object> create() const = 0;
693 };
694
695 using object::Binary;
696 using object::ELFFile;
697 using object::ELFObjectFile;
698 using object::OwningBinary;
699
700 class BinaryELFBuilder {
701   uint16_t EMachine;
702   MemoryBuffer *MemBuf;
703   std::unique_ptr<Object> Obj;
704
705   void initFileHeader();
706   void initHeaderSegment();
707   StringTableSection *addStrTab();
708   SymbolTableSection *addSymTab(StringTableSection *StrTab);
709   void addData(SymbolTableSection *SymTab);
710   void initSections();
711
712 public:
713   BinaryELFBuilder(uint16_t EM, MemoryBuffer *MB)
714       : EMachine(EM), MemBuf(MB), Obj(llvm::make_unique<Object>()) {}
715
716   std::unique_ptr<Object> build();
717 };
718
719 template <class ELFT> class ELFBuilder {
720 private:
721   using Elf_Addr = typename ELFT::Addr;
722   using Elf_Shdr = typename ELFT::Shdr;
723   using Elf_Word = typename ELFT::Word;
724
725   const ELFFile<ELFT> &ElfFile;
726   Object &Obj;
727
728   void setParentSegment(Segment &Child);
729   void readProgramHeaders();
730   void initGroupSection(GroupSection *GroupSec);
731   void initSymbolTable(SymbolTableSection *SymTab);
732   void readSectionHeaders();
733   SectionBase &makeSection(const Elf_Shdr &Shdr);
734
735 public:
736   ELFBuilder(const ELFObjectFile<ELFT> &ElfObj, Object &Obj)
737       : ElfFile(*ElfObj.getELFFile()), Obj(Obj) {}
738
739   void build();
740 };
741
742 class BinaryReader : public Reader {
743   const MachineInfo &MInfo;
744   MemoryBuffer *MemBuf;
745
746 public:
747   BinaryReader(const MachineInfo &MI, MemoryBuffer *MB)
748       : MInfo(MI), MemBuf(MB) {}
749   std::unique_ptr<Object> create() const override;
750 };
751
752 class ELFReader : public Reader {
753   Binary *Bin;
754
755 public:
756   std::unique_ptr<Object> create() const override;
757   explicit ELFReader(Binary *B) : Bin(B) {}
758 };
759
760 class Object {
761 private:
762   using SecPtr = std::unique_ptr<SectionBase>;
763   using SegPtr = std::unique_ptr<Segment>;
764
765   std::vector<SecPtr> Sections;
766   std::vector<SegPtr> Segments;
767
768 public:
769   template <class T>
770   using Range = iterator_range<
771       pointee_iterator<typename std::vector<std::unique_ptr<T>>::iterator>>;
772
773   template <class T>
774   using ConstRange = iterator_range<pointee_iterator<
775       typename std::vector<std::unique_ptr<T>>::const_iterator>>;
776
777   // It is often the case that the ELF header and the program header table are
778   // not present in any segment. This could be a problem during file layout,
779   // because other segments may get assigned an offset where either of the
780   // two should reside, which will effectively corrupt the resulting binary.
781   // Other than that we use these segments to track program header offsets
782   // when they may not follow the ELF header.
783   Segment ElfHdrSegment;
784   Segment ProgramHdrSegment;
785
786   uint8_t OSABI;
787   uint8_t ABIVersion;
788   uint64_t Entry;
789   uint64_t SHOffset;
790   uint32_t Type;
791   uint32_t Machine;
792   uint32_t Version;
793   uint32_t Flags;
794
795   StringTableSection *SectionNames = nullptr;
796   SymbolTableSection *SymbolTable = nullptr;
797   SectionIndexSection *SectionIndexTable = nullptr;
798
799   void sortSections();
800   SectionTableRef sections() { return SectionTableRef(Sections); }
801   ConstRange<SectionBase> sections() const {
802     return make_pointee_range(Sections);
803   }
804   Range<Segment> segments() { return make_pointee_range(Segments); }
805   ConstRange<Segment> segments() const { return make_pointee_range(Segments); }
806
807   void removeSections(std::function<bool(const SectionBase &)> ToRemove);
808   void removeSymbols(function_ref<bool(const Symbol &)> ToRemove);
809   template <class T, class... Ts> T &addSection(Ts &&... Args) {
810     auto Sec = llvm::make_unique<T>(std::forward<Ts>(Args)...);
811     auto Ptr = Sec.get();
812     Sections.emplace_back(std::move(Sec));
813     Ptr->Index = Sections.size();
814     return *Ptr;
815   }
816   Segment &addSegment(ArrayRef<uint8_t> Data) {
817     Segments.emplace_back(llvm::make_unique<Segment>(Data));
818     return *Segments.back();
819   }
820 };
821
822 } // end namespace elf
823 } // end namespace objcopy
824 } // end namespace llvm
825
826 #endif // LLVM_TOOLS_OBJCOPY_OBJECT_H