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