]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm-project/llvm/tools/llvm-objcopy/ELF/Object.h
Move all sources from the llvm project into contrib/llvm-project.
[FreeBSD/FreeBSD.git] / contrib / llvm-project / llvm / tools / llvm-objcopy / ELF / Object.h
1 //===- Object.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_TOOLS_OBJCOPY_OBJECT_H
10 #define LLVM_TOOLS_OBJCOPY_OBJECT_H
11
12 #include "Buffer.h"
13 #include "CopyConfig.h"
14 #include "llvm/ADT/ArrayRef.h"
15 #include "llvm/ADT/StringRef.h"
16 #include "llvm/ADT/Twine.h"
17 #include "llvm/BinaryFormat/ELF.h"
18 #include "llvm/MC/StringTableBuilder.h"
19 #include "llvm/Object/ELFObjectFile.h"
20 #include "llvm/Support/Errc.h"
21 #include "llvm/Support/FileOutputBuffer.h"
22 #include <cstddef>
23 #include <cstdint>
24 #include <functional>
25 #include <memory>
26 #include <set>
27 #include <vector>
28
29 namespace llvm {
30 enum class DebugCompressionType;
31 namespace objcopy {
32 namespace elf {
33
34 class SectionBase;
35 class Section;
36 class OwnedDataSection;
37 class StringTableSection;
38 class SymbolTableSection;
39 class RelocationSection;
40 class DynamicRelocationSection;
41 class GnuDebugLinkSection;
42 class GroupSection;
43 class SectionIndexSection;
44 class CompressedSection;
45 class DecompressedSection;
46 class Segment;
47 class Object;
48 struct Symbol;
49
50 class SectionTableRef {
51   MutableArrayRef<std::unique_ptr<SectionBase>> Sections;
52
53 public:
54   using iterator = pointee_iterator<std::unique_ptr<SectionBase> *>;
55
56   explicit SectionTableRef(MutableArrayRef<std::unique_ptr<SectionBase>> Secs)
57       : Sections(Secs) {}
58   SectionTableRef(const SectionTableRef &) = default;
59
60   iterator begin() { return iterator(Sections.data()); }
61   iterator end() { return iterator(Sections.data() + Sections.size()); }
62   size_t size() const { return 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() = default;
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   friend class IHexSectionWriterBase;                                          \
173   friend class IHexSectionWriter;                                              \
174   template <class ELFT> friend class ELFSectionWriter;                         \
175   template <class ELFT> friend class ELFSectionSizer;
176
177 class BinarySectionWriter : public SectionWriter {
178 public:
179   virtual ~BinarySectionWriter() {}
180
181   void visit(const SymbolTableSection &Sec) override;
182   void visit(const RelocationSection &Sec) override;
183   void visit(const GnuDebugLinkSection &Sec) override;
184   void visit(const GroupSection &Sec) override;
185   void visit(const SectionIndexSection &Sec) override;
186   void visit(const CompressedSection &Sec) override;
187   void visit(const DecompressedSection &Sec) override;
188
189   explicit BinarySectionWriter(Buffer &Buf) : SectionWriter(Buf) {}
190 };
191
192 using IHexLineData = SmallVector<char, 64>;
193
194 struct IHexRecord {
195   // Memory address of the record.
196   uint16_t Addr;
197   // Record type (see below).
198   uint16_t Type;
199   // Record data in hexadecimal form.
200   StringRef HexData;
201
202   // Helper method to get file length of the record
203   // including newline character
204   static size_t getLength(size_t DataSize) {
205     // :LLAAAATT[DD...DD]CC'
206     return DataSize * 2 + 11;
207   }
208
209   // Gets length of line in a file (getLength + CRLF).
210   static size_t getLineLength(size_t DataSize) {
211     return getLength(DataSize) + 2;
212   }
213
214   // Given type, address and data returns line which can
215   // be written to output file.
216   static IHexLineData getLine(uint8_t Type, uint16_t Addr,
217                               ArrayRef<uint8_t> Data);
218
219   // Parses the line and returns record if possible.
220   // Line should be trimmed from whitespace characters.
221   static Expected<IHexRecord> parse(StringRef Line);
222
223   // Calculates checksum of stringified record representation
224   // S must NOT contain leading ':' and trailing whitespace
225   // characters
226   static uint8_t getChecksum(StringRef S);
227
228   enum Type {
229     // Contains data and a 16-bit starting address for the data.
230     // The byte count specifies number of data bytes in the record.
231     Data = 0,
232     // Must occur exactly once per file in the last line of the file.
233     // The data field is empty (thus byte count is 00) and the address
234     // field is typically 0000.
235     EndOfFile = 1,
236     // The data field contains a 16-bit segment base address (thus byte
237     // count is always 02) compatible with 80x86 real mode addressing.
238     // The address field (typically 0000) is ignored. The segment address
239     // from the most recent 02 record is multiplied by 16 and added to each
240     // subsequent data record address to form the physical starting address
241     // for the data. This allows addressing up to one megabyte of address
242     // space.
243     SegmentAddr = 2,
244     // or 80x86 processors, specifies the initial content of the CS:IP
245     // registers. The address field is 0000, the byte count is always 04,
246     // the first two data bytes are the CS value, the latter two are the
247     // IP value.
248     StartAddr80x86 = 3,
249     // Allows for 32 bit addressing (up to 4GiB). The record's address field
250     // is ignored (typically 0000) and its byte count is always 02. The two
251     // data bytes (big endian) specify the upper 16 bits of the 32 bit
252     // absolute address for all subsequent type 00 records
253     ExtendedAddr = 4,
254     // The address field is 0000 (not used) and the byte count is always 04.
255     // The four data bytes represent a 32-bit address value. In the case of
256     // 80386 and higher CPUs, this address is loaded into the EIP register.
257     StartAddr = 5,
258     // We have no other valid types
259     InvalidType = 6
260   };
261 };
262
263 // Base class for IHexSectionWriter. This class implements writing algorithm,
264 // but doesn't actually write records. It is used for output buffer size
265 // calculation in IHexWriter::finalize.
266 class IHexSectionWriterBase : public BinarySectionWriter {
267   // 20-bit segment address
268   uint32_t SegmentAddr = 0;
269   // Extended linear address
270   uint32_t BaseAddr = 0;
271
272   // Write segment address corresponding to 'Addr'
273   uint64_t writeSegmentAddr(uint64_t Addr);
274   // Write extended linear (base) address corresponding to 'Addr'
275   uint64_t writeBaseAddr(uint64_t Addr);
276
277 protected:
278   // Offset in the output buffer
279   uint64_t Offset = 0;
280
281   void writeSection(const SectionBase *Sec, ArrayRef<uint8_t> Data);
282   virtual void writeData(uint8_t Type, uint16_t Addr, ArrayRef<uint8_t> Data);
283
284 public:
285   explicit IHexSectionWriterBase(Buffer &Buf) : BinarySectionWriter(Buf) {}
286
287   uint64_t getBufferOffset() const { return Offset; }
288   void visit(const Section &Sec) final;
289   void visit(const OwnedDataSection &Sec) final;
290   void visit(const StringTableSection &Sec) override;
291   void visit(const DynamicRelocationSection &Sec) final;
292   using BinarySectionWriter::visit;
293 };
294
295 // Real IHEX section writer
296 class IHexSectionWriter : public IHexSectionWriterBase {
297 public:
298   IHexSectionWriter(Buffer &Buf) : IHexSectionWriterBase(Buf) {}
299
300   void writeData(uint8_t Type, uint16_t Addr, ArrayRef<uint8_t> Data) override;
301   void visit(const StringTableSection &Sec) override;
302 };
303
304 class Writer {
305 protected:
306   Object &Obj;
307   Buffer &Buf;
308
309 public:
310   virtual ~Writer();
311   virtual Error finalize() = 0;
312   virtual Error write() = 0;
313
314   Writer(Object &O, Buffer &B) : Obj(O), Buf(B) {}
315 };
316
317 template <class ELFT> class ELFWriter : public Writer {
318 private:
319   using Elf_Addr = typename ELFT::Addr;
320   using Elf_Shdr = typename ELFT::Shdr;
321   using Elf_Phdr = typename ELFT::Phdr;
322   using Elf_Ehdr = typename ELFT::Ehdr;
323
324   void initEhdrSegment();
325
326   void writeEhdr();
327   void writePhdr(const Segment &Seg);
328   void writeShdr(const SectionBase &Sec);
329
330   void writePhdrs();
331   void writeShdrs();
332   void writeSectionData();
333   void writeSegmentData();
334
335   void assignOffsets();
336
337   std::unique_ptr<ELFSectionWriter<ELFT>> SecWriter;
338
339   size_t totalSize() const;
340
341 public:
342   virtual ~ELFWriter() {}
343   bool WriteSectionHeaders;
344
345   Error finalize() override;
346   Error write() override;
347   ELFWriter(Object &Obj, Buffer &Buf, bool WSH);
348 };
349
350 class BinaryWriter : public Writer {
351 private:
352   std::unique_ptr<BinarySectionWriter> SecWriter;
353
354   uint64_t TotalSize;
355
356 public:
357   ~BinaryWriter() {}
358   Error finalize() override;
359   Error write() override;
360   BinaryWriter(Object &Obj, Buffer &Buf) : Writer(Obj, Buf) {}
361 };
362
363 class IHexWriter : public Writer {
364   struct SectionCompare {
365     bool operator()(const SectionBase *Lhs, const SectionBase *Rhs) const;
366   };
367
368   std::set<const SectionBase *, SectionCompare> Sections;
369   size_t TotalSize;
370
371   Error checkSection(const SectionBase &Sec);
372   uint64_t writeEntryPointRecord(uint8_t *Buf);
373   uint64_t writeEndOfFileRecord(uint8_t *Buf);
374
375 public:
376   ~IHexWriter() {}
377   Error finalize() override;
378   Error write() override;
379   IHexWriter(Object &Obj, Buffer &Buf) : Writer(Obj, Buf) {}
380 };
381
382 class SectionBase {
383 public:
384   std::string Name;
385   Segment *ParentSegment = nullptr;
386   uint64_t HeaderOffset;
387   uint64_t OriginalOffset = std::numeric_limits<uint64_t>::max();
388   uint32_t Index;
389   bool HasSymbol = false;
390
391   uint64_t Addr = 0;
392   uint64_t Align = 1;
393   uint32_t EntrySize = 0;
394   uint64_t Flags = 0;
395   uint64_t Info = 0;
396   uint64_t Link = ELF::SHN_UNDEF;
397   uint64_t NameIndex = 0;
398   uint64_t Offset = 0;
399   uint64_t Size = 0;
400   uint64_t Type = ELF::SHT_NULL;
401   ArrayRef<uint8_t> OriginalData;
402
403   SectionBase() = default;
404   SectionBase(const SectionBase &) = default;
405
406   virtual ~SectionBase() = default;
407
408   virtual void initialize(SectionTableRef SecTable);
409   virtual void finalize();
410   // Remove references to these sections. The list of sections must be sorted.
411   virtual Error
412   removeSectionReferences(bool AllowBrokenLinks,
413                           function_ref<bool(const SectionBase *)> ToRemove);
414   virtual Error removeSymbols(function_ref<bool(const Symbol &)> ToRemove);
415   virtual void accept(SectionVisitor &Visitor) const = 0;
416   virtual void accept(MutableSectionVisitor &Visitor) = 0;
417   virtual void markSymbols();
418   virtual void
419   replaceSectionReferences(const DenseMap<SectionBase *, SectionBase *> &);
420 };
421
422 class Segment {
423 private:
424   struct SectionCompare {
425     bool operator()(const SectionBase *Lhs, const SectionBase *Rhs) const {
426       // Some sections might have the same address if one of them is empty. To
427       // fix this we can use the lexicographic ordering on ->Addr and the
428       // address of the actully stored section.
429       if (Lhs->OriginalOffset == Rhs->OriginalOffset)
430         return Lhs < Rhs;
431       return Lhs->OriginalOffset < Rhs->OriginalOffset;
432     }
433   };
434
435   std::set<const SectionBase *, SectionCompare> Sections;
436
437 public:
438   uint32_t Type;
439   uint32_t Flags;
440   uint64_t Offset;
441   uint64_t VAddr;
442   uint64_t PAddr;
443   uint64_t FileSize;
444   uint64_t MemSize;
445   uint64_t Align;
446
447   uint32_t Index;
448   uint64_t OriginalOffset;
449   Segment *ParentSegment = nullptr;
450   ArrayRef<uint8_t> Contents;
451
452   explicit Segment(ArrayRef<uint8_t> Data) : Contents(Data) {}
453   Segment() {}
454
455   const SectionBase *firstSection() const {
456     if (!Sections.empty())
457       return *Sections.begin();
458     return nullptr;
459   }
460
461   void removeSection(const SectionBase *Sec) { Sections.erase(Sec); }
462   void addSection(const SectionBase *Sec) { Sections.insert(Sec); }
463
464   ArrayRef<uint8_t> getContents() const { return Contents; }
465 };
466
467 class Section : public SectionBase {
468   MAKE_SEC_WRITER_FRIEND
469
470   ArrayRef<uint8_t> Contents;
471   SectionBase *LinkSection = nullptr;
472
473 public:
474   explicit Section(ArrayRef<uint8_t> Data) : Contents(Data) {}
475
476   void accept(SectionVisitor &Visitor) const override;
477   void accept(MutableSectionVisitor &Visitor) override;
478   Error removeSectionReferences(bool AllowBrokenLinks,
479       function_ref<bool(const SectionBase *)> ToRemove) override;
480   void initialize(SectionTableRef SecTable) override;
481   void finalize() override;
482 };
483
484 class OwnedDataSection : public SectionBase {
485   MAKE_SEC_WRITER_FRIEND
486
487   std::vector<uint8_t> Data;
488
489 public:
490   OwnedDataSection(StringRef SecName, ArrayRef<uint8_t> Data)
491       : Data(std::begin(Data), std::end(Data)) {
492     Name = SecName.str();
493     Type = ELF::SHT_PROGBITS;
494     Size = Data.size();
495     OriginalOffset = std::numeric_limits<uint64_t>::max();
496   }
497
498   OwnedDataSection(const Twine &SecName, uint64_t SecAddr, uint64_t SecFlags,
499                    uint64_t SecOff) {
500     Name = SecName.str();
501     Type = ELF::SHT_PROGBITS;
502     Addr = SecAddr;
503     Flags = SecFlags;
504     OriginalOffset = SecOff;
505   }
506
507   void appendHexData(StringRef HexData);
508   void accept(SectionVisitor &Sec) const override;
509   void accept(MutableSectionVisitor &Visitor) override;
510 };
511
512 class CompressedSection : public SectionBase {
513   MAKE_SEC_WRITER_FRIEND
514
515   DebugCompressionType CompressionType;
516   uint64_t DecompressedSize;
517   uint64_t DecompressedAlign;
518   SmallVector<char, 128> CompressedData;
519
520 public:
521   CompressedSection(const SectionBase &Sec,
522                     DebugCompressionType CompressionType);
523   CompressedSection(ArrayRef<uint8_t> CompressedData, uint64_t DecompressedSize,
524                     uint64_t DecompressedAlign);
525
526   uint64_t getDecompressedSize() const { return DecompressedSize; }
527   uint64_t getDecompressedAlign() const { return DecompressedAlign; }
528
529   void accept(SectionVisitor &Visitor) const override;
530   void accept(MutableSectionVisitor &Visitor) override;
531
532   static bool classof(const SectionBase *S) {
533     return (S->Flags & ELF::SHF_COMPRESSED) ||
534            (StringRef(S->Name).startswith(".zdebug"));
535   }
536 };
537
538 class DecompressedSection : public SectionBase {
539   MAKE_SEC_WRITER_FRIEND
540
541 public:
542   explicit DecompressedSection(const CompressedSection &Sec)
543       : SectionBase(Sec) {
544     Size = Sec.getDecompressedSize();
545     Align = Sec.getDecompressedAlign();
546     Flags = (Flags & ~ELF::SHF_COMPRESSED);
547     if (StringRef(Name).startswith(".zdebug"))
548       Name = "." + Name.substr(2);
549   }
550
551   void accept(SectionVisitor &Visitor) const override;
552   void accept(MutableSectionVisitor &Visitor) override;
553 };
554
555 // There are two types of string tables that can exist, dynamic and not dynamic.
556 // In the dynamic case the string table is allocated. Changing a dynamic string
557 // table would mean altering virtual addresses and thus the memory image. So
558 // dynamic string tables should not have an interface to modify them or
559 // reconstruct them. This type lets us reconstruct a string table. To avoid
560 // this class being used for dynamic string tables (which has happened) the
561 // classof method checks that the particular instance is not allocated. This
562 // then agrees with the makeSection method used to construct most sections.
563 class StringTableSection : public SectionBase {
564   MAKE_SEC_WRITER_FRIEND
565
566   StringTableBuilder StrTabBuilder;
567
568 public:
569   StringTableSection() : StrTabBuilder(StringTableBuilder::ELF) {
570     Type = ELF::SHT_STRTAB;
571   }
572
573   void addString(StringRef Name);
574   uint32_t findIndex(StringRef Name) const;
575   void prepareForLayout();
576   void accept(SectionVisitor &Visitor) const override;
577   void accept(MutableSectionVisitor &Visitor) override;
578
579   static bool classof(const SectionBase *S) {
580     if (S->Flags & ELF::SHF_ALLOC)
581       return false;
582     return S->Type == ELF::SHT_STRTAB;
583   }
584 };
585
586 // Symbols have a st_shndx field that normally stores an index but occasionally
587 // stores a different special value. This enum keeps track of what the st_shndx
588 // field means. Most of the values are just copies of the special SHN_* values.
589 // SYMBOL_SIMPLE_INDEX means that the st_shndx is just an index of a section.
590 enum SymbolShndxType {
591   SYMBOL_SIMPLE_INDEX = 0,
592   SYMBOL_ABS = ELF::SHN_ABS,
593   SYMBOL_COMMON = ELF::SHN_COMMON,
594   SYMBOL_LOPROC = ELF::SHN_LOPROC,
595   SYMBOL_AMDGPU_LDS = ELF::SHN_AMDGPU_LDS,
596   SYMBOL_HEXAGON_SCOMMON = ELF::SHN_HEXAGON_SCOMMON,
597   SYMBOL_HEXAGON_SCOMMON_2 = ELF::SHN_HEXAGON_SCOMMON_2,
598   SYMBOL_HEXAGON_SCOMMON_4 = ELF::SHN_HEXAGON_SCOMMON_4,
599   SYMBOL_HEXAGON_SCOMMON_8 = ELF::SHN_HEXAGON_SCOMMON_8,
600   SYMBOL_HIPROC = ELF::SHN_HIPROC,
601   SYMBOL_LOOS = ELF::SHN_LOOS,
602   SYMBOL_HIOS = ELF::SHN_HIOS,
603   SYMBOL_XINDEX = ELF::SHN_XINDEX,
604 };
605
606 struct Symbol {
607   uint8_t Binding;
608   SectionBase *DefinedIn = nullptr;
609   SymbolShndxType ShndxType;
610   uint32_t Index;
611   std::string Name;
612   uint32_t NameIndex;
613   uint64_t Size;
614   uint8_t Type;
615   uint64_t Value;
616   uint8_t Visibility;
617   bool Referenced = false;
618
619   uint16_t getShndx() const;
620   bool isCommon() const;
621 };
622
623 class SectionIndexSection : public SectionBase {
624   MAKE_SEC_WRITER_FRIEND
625
626 private:
627   std::vector<uint32_t> Indexes;
628   SymbolTableSection *Symbols = nullptr;
629
630 public:
631   virtual ~SectionIndexSection() {}
632   void addIndex(uint32_t Index) {
633     assert(Size > 0);
634     Indexes.push_back(Index);    
635   }
636
637   void reserve(size_t NumSymbols) {
638     Indexes.reserve(NumSymbols);
639     Size = NumSymbols * 4;
640   }  
641   void setSymTab(SymbolTableSection *SymTab) { Symbols = SymTab; }
642   void initialize(SectionTableRef SecTable) override;
643   void finalize() override;
644   void accept(SectionVisitor &Visitor) const override;
645   void accept(MutableSectionVisitor &Visitor) override;
646
647   SectionIndexSection() {
648     Name = ".symtab_shndx";
649     Align = 4;
650     EntrySize = 4;
651     Type = ELF::SHT_SYMTAB_SHNDX;
652   }
653 };
654
655 class SymbolTableSection : public SectionBase {
656   MAKE_SEC_WRITER_FRIEND
657
658   void setStrTab(StringTableSection *StrTab) { SymbolNames = StrTab; }
659   void assignIndices();
660
661 protected:
662   std::vector<std::unique_ptr<Symbol>> Symbols;
663   StringTableSection *SymbolNames = nullptr;
664   SectionIndexSection *SectionIndexTable = nullptr;
665
666   using SymPtr = std::unique_ptr<Symbol>;
667
668 public:
669   SymbolTableSection() { Type = ELF::SHT_SYMTAB; }
670
671   void addSymbol(Twine Name, uint8_t Bind, uint8_t Type, SectionBase *DefinedIn,
672                  uint64_t Value, uint8_t Visibility, uint16_t Shndx,
673                  uint64_t SymbolSize);
674   void prepareForLayout();
675   // An 'empty' symbol table still contains a null symbol.
676   bool empty() const { return Symbols.size() == 1; }
677   void setShndxTable(SectionIndexSection *ShndxTable) {
678     SectionIndexTable = ShndxTable;
679   }
680   const SectionIndexSection *getShndxTable() const { return SectionIndexTable; }
681   void fillShndxTable();
682   const SectionBase *getStrTab() const { return SymbolNames; }
683   const Symbol *getSymbolByIndex(uint32_t Index) const;
684   Symbol *getSymbolByIndex(uint32_t Index);
685   void updateSymbols(function_ref<void(Symbol &)> Callable);
686
687   Error removeSectionReferences(bool AllowBrokenLinks,
688       function_ref<bool(const SectionBase *)> ToRemove) override;
689   void initialize(SectionTableRef SecTable) override;
690   void finalize() override;
691   void accept(SectionVisitor &Visitor) const override;
692   void accept(MutableSectionVisitor &Visitor) override;
693   Error removeSymbols(function_ref<bool(const Symbol &)> ToRemove) override;
694   void replaceSectionReferences(
695       const DenseMap<SectionBase *, SectionBase *> &FromTo) override;
696
697   static bool classof(const SectionBase *S) {
698     return S->Type == ELF::SHT_SYMTAB;
699   }
700 };
701
702 struct Relocation {
703   Symbol *RelocSymbol = nullptr;
704   uint64_t Offset;
705   uint64_t Addend;
706   uint32_t Type;
707 };
708
709 // All relocation sections denote relocations to apply to another section.
710 // However, some relocation sections use a dynamic symbol table and others use
711 // a regular symbol table. Because the types of the two symbol tables differ in
712 // our system (because they should behave differently) we can't uniformly
713 // represent all relocations with the same base class if we expose an interface
714 // that mentions the symbol table type. So we split the two base types into two
715 // different classes, one which handles the section the relocation is applied to
716 // and another which handles the symbol table type. The symbol table type is
717 // taken as a type parameter to the class (see RelocSectionWithSymtabBase).
718 class RelocationSectionBase : public SectionBase {
719 protected:
720   SectionBase *SecToApplyRel = nullptr;
721
722 public:
723   const SectionBase *getSection() const { return SecToApplyRel; }
724   void setSection(SectionBase *Sec) { SecToApplyRel = Sec; }
725
726   static bool classof(const SectionBase *S) {
727     return S->Type == ELF::SHT_REL || S->Type == ELF::SHT_RELA;
728   }
729 };
730
731 // Takes the symbol table type to use as a parameter so that we can deduplicate
732 // that code between the two symbol table types.
733 template <class SymTabType>
734 class RelocSectionWithSymtabBase : public RelocationSectionBase {
735   void setSymTab(SymTabType *SymTab) { Symbols = SymTab; }
736
737 protected:
738   RelocSectionWithSymtabBase() = default;
739
740   SymTabType *Symbols = nullptr;
741
742 public:
743   void initialize(SectionTableRef SecTable) override;
744   void finalize() override;
745 };
746
747 class RelocationSection
748     : public RelocSectionWithSymtabBase<SymbolTableSection> {
749   MAKE_SEC_WRITER_FRIEND
750
751   std::vector<Relocation> Relocations;
752
753 public:
754   void addRelocation(Relocation Rel) { Relocations.push_back(Rel); }
755   void accept(SectionVisitor &Visitor) const override;
756   void accept(MutableSectionVisitor &Visitor) override;
757   Error removeSectionReferences(bool AllowBrokenLinks,
758       function_ref<bool(const SectionBase *)> ToRemove) override;
759   Error removeSymbols(function_ref<bool(const Symbol &)> ToRemove) override;
760   void markSymbols() override;
761   void replaceSectionReferences(
762       const DenseMap<SectionBase *, SectionBase *> &FromTo) override;
763
764   static bool classof(const SectionBase *S) {
765     if (S->Flags & ELF::SHF_ALLOC)
766       return false;
767     return S->Type == ELF::SHT_REL || S->Type == ELF::SHT_RELA;
768   }
769 };
770
771 // TODO: The way stripping and groups interact is complicated
772 // and still needs to be worked on.
773
774 class GroupSection : public SectionBase {
775   MAKE_SEC_WRITER_FRIEND
776   const SymbolTableSection *SymTab = nullptr;
777   Symbol *Sym = nullptr;
778   ELF::Elf32_Word FlagWord;
779   SmallVector<SectionBase *, 3> GroupMembers;
780
781 public:
782   // TODO: Contents is present in several classes of the hierarchy.
783   // This needs to be refactored to avoid duplication.
784   ArrayRef<uint8_t> Contents;
785
786   explicit GroupSection(ArrayRef<uint8_t> Data) : Contents(Data) {}
787
788   void setSymTab(const SymbolTableSection *SymTabSec) { SymTab = SymTabSec; }
789   void setSymbol(Symbol *S) { Sym = S; }
790   void setFlagWord(ELF::Elf32_Word W) { FlagWord = W; }
791   void addMember(SectionBase *Sec) { GroupMembers.push_back(Sec); }
792
793   void accept(SectionVisitor &) const override;
794   void accept(MutableSectionVisitor &Visitor) override;
795   void finalize() override;
796   Error removeSymbols(function_ref<bool(const Symbol &)> ToRemove) override;
797   void markSymbols() override;
798   void replaceSectionReferences(
799       const DenseMap<SectionBase *, SectionBase *> &FromTo) override;
800
801   static bool classof(const SectionBase *S) {
802     return S->Type == ELF::SHT_GROUP;
803   }
804 };
805
806 class DynamicSymbolTableSection : public Section {
807 public:
808   explicit DynamicSymbolTableSection(ArrayRef<uint8_t> Data) : Section(Data) {}
809
810   static bool classof(const SectionBase *S) {
811     return S->Type == ELF::SHT_DYNSYM;
812   }
813 };
814
815 class DynamicSection : public Section {
816 public:
817   explicit DynamicSection(ArrayRef<uint8_t> Data) : Section(Data) {}
818
819   static bool classof(const SectionBase *S) {
820     return S->Type == ELF::SHT_DYNAMIC;
821   }
822 };
823
824 class DynamicRelocationSection
825     : public RelocSectionWithSymtabBase<DynamicSymbolTableSection> {
826   MAKE_SEC_WRITER_FRIEND
827
828 private:
829   ArrayRef<uint8_t> Contents;
830
831 public:
832   explicit DynamicRelocationSection(ArrayRef<uint8_t> Data) : Contents(Data) {}
833
834   void accept(SectionVisitor &) const override;
835   void accept(MutableSectionVisitor &Visitor) override;
836   Error removeSectionReferences(
837       bool AllowBrokenLinks,
838       function_ref<bool(const SectionBase *)> ToRemove) override;
839
840   static bool classof(const SectionBase *S) {
841     if (!(S->Flags & ELF::SHF_ALLOC))
842       return false;
843     return S->Type == ELF::SHT_REL || S->Type == ELF::SHT_RELA;
844   }
845 };
846
847 class GnuDebugLinkSection : public SectionBase {
848   MAKE_SEC_WRITER_FRIEND
849
850 private:
851   StringRef FileName;
852   uint32_t CRC32;
853
854   void init(StringRef File);
855
856 public:
857   // If we add this section from an external source we can use this ctor.
858   explicit GnuDebugLinkSection(StringRef File, uint32_t PrecomputedCRC);
859   void accept(SectionVisitor &Visitor) const override;
860   void accept(MutableSectionVisitor &Visitor) override;
861 };
862
863 class Reader {
864 public:
865   virtual ~Reader();
866   virtual std::unique_ptr<Object> create() const = 0;
867 };
868
869 using object::Binary;
870 using object::ELFFile;
871 using object::ELFObjectFile;
872 using object::OwningBinary;
873
874 class BasicELFBuilder {
875 protected:
876   uint16_t EMachine;
877   std::unique_ptr<Object> Obj;
878
879   void initFileHeader();
880   void initHeaderSegment();
881   StringTableSection *addStrTab();
882   SymbolTableSection *addSymTab(StringTableSection *StrTab);
883   void initSections();
884
885 public:
886   BasicELFBuilder(uint16_t EM)
887       : EMachine(EM), Obj(llvm::make_unique<Object>()) {}
888 };
889
890 class BinaryELFBuilder : public BasicELFBuilder {
891   MemoryBuffer *MemBuf;
892   void addData(SymbolTableSection *SymTab);
893
894 public:
895   BinaryELFBuilder(uint16_t EM, MemoryBuffer *MB)
896       : BasicELFBuilder(EM), MemBuf(MB) {}
897
898   std::unique_ptr<Object> build();
899 };
900
901 class IHexELFBuilder : public BasicELFBuilder {
902   const std::vector<IHexRecord> &Records;
903
904   void addDataSections();
905
906 public:
907   IHexELFBuilder(const std::vector<IHexRecord> &Records)
908       : BasicELFBuilder(ELF::EM_386), Records(Records) {}
909
910   std::unique_ptr<Object> build();
911 };
912
913 template <class ELFT> class ELFBuilder {
914 private:
915   using Elf_Addr = typename ELFT::Addr;
916   using Elf_Shdr = typename ELFT::Shdr;
917   using Elf_Word = typename ELFT::Word;
918
919   const ELFFile<ELFT> &ElfFile;
920   Object &Obj;
921   size_t EhdrOffset = 0;
922   Optional<StringRef> ExtractPartition;
923
924   void setParentSegment(Segment &Child);
925   void readProgramHeaders(const ELFFile<ELFT> &HeadersFile);
926   void initGroupSection(GroupSection *GroupSec);
927   void initSymbolTable(SymbolTableSection *SymTab);
928   void readSectionHeaders();
929   void readSections();
930   void findEhdrOffset();
931   SectionBase &makeSection(const Elf_Shdr &Shdr);
932
933 public:
934   ELFBuilder(const ELFObjectFile<ELFT> &ElfObj, Object &Obj,
935              Optional<StringRef> ExtractPartition)
936       : ElfFile(*ElfObj.getELFFile()), Obj(Obj),
937         ExtractPartition(ExtractPartition) {}
938
939   void build();
940 };
941
942 class BinaryReader : public Reader {
943   const MachineInfo &MInfo;
944   MemoryBuffer *MemBuf;
945
946 public:
947   BinaryReader(const MachineInfo &MI, MemoryBuffer *MB)
948       : MInfo(MI), MemBuf(MB) {}
949   std::unique_ptr<Object> create() const override;
950 };
951
952 class IHexReader : public Reader {
953   MemoryBuffer *MemBuf;
954
955   Expected<std::vector<IHexRecord>> parse() const;
956   Error parseError(size_t LineNo, Error E) const {
957     return LineNo == -1U
958                ? createFileError(MemBuf->getBufferIdentifier(), std::move(E))
959                : createFileError(MemBuf->getBufferIdentifier(), LineNo,
960                                  std::move(E));
961   }
962   template <typename... Ts>
963   Error parseError(size_t LineNo, char const *Fmt, const Ts &... Vals) const {
964     Error E = createStringError(errc::invalid_argument, Fmt, Vals...);
965     return parseError(LineNo, std::move(E));
966   }
967
968 public:
969   IHexReader(MemoryBuffer *MB) : MemBuf(MB) {}
970
971   std::unique_ptr<Object> create() const override;
972 };
973
974 class ELFReader : public Reader {
975   Binary *Bin;
976   Optional<StringRef> ExtractPartition;
977
978 public:
979   std::unique_ptr<Object> create() const override;
980   explicit ELFReader(Binary *B, Optional<StringRef> ExtractPartition)
981       : Bin(B), ExtractPartition(ExtractPartition) {}
982 };
983
984 class Object {
985 private:
986   using SecPtr = std::unique_ptr<SectionBase>;
987   using SegPtr = std::unique_ptr<Segment>;
988
989   std::vector<SecPtr> Sections;
990   std::vector<SegPtr> Segments;
991   std::vector<SecPtr> RemovedSections;
992
993 public:
994   template <class T>
995   using Range = iterator_range<
996       pointee_iterator<typename std::vector<std::unique_ptr<T>>::iterator>>;
997
998   template <class T>
999   using ConstRange = iterator_range<pointee_iterator<
1000       typename std::vector<std::unique_ptr<T>>::const_iterator>>;
1001
1002   // It is often the case that the ELF header and the program header table are
1003   // not present in any segment. This could be a problem during file layout,
1004   // because other segments may get assigned an offset where either of the
1005   // two should reside, which will effectively corrupt the resulting binary.
1006   // Other than that we use these segments to track program header offsets
1007   // when they may not follow the ELF header.
1008   Segment ElfHdrSegment;
1009   Segment ProgramHdrSegment;
1010
1011   uint8_t OSABI;
1012   uint8_t ABIVersion;
1013   uint64_t Entry;
1014   uint64_t SHOffset;
1015   uint32_t Type;
1016   uint32_t Machine;
1017   uint32_t Version;
1018   uint32_t Flags;
1019
1020   bool HadShdrs = true;
1021   StringTableSection *SectionNames = nullptr;
1022   SymbolTableSection *SymbolTable = nullptr;
1023   SectionIndexSection *SectionIndexTable = nullptr;
1024
1025   void sortSections();
1026   SectionTableRef sections() { return SectionTableRef(Sections); }
1027   ConstRange<SectionBase> sections() const {
1028     return make_pointee_range(Sections);
1029   }
1030   SectionBase *findSection(StringRef Name) {
1031     auto SecIt =
1032         find_if(Sections, [&](const SecPtr &Sec) { return Sec->Name == Name; });
1033     return SecIt == Sections.end() ? nullptr : SecIt->get();
1034   }
1035   SectionTableRef removedSections() { return SectionTableRef(RemovedSections); }
1036
1037   Range<Segment> segments() { return make_pointee_range(Segments); }
1038   ConstRange<Segment> segments() const { return make_pointee_range(Segments); }
1039
1040   Error removeSections(bool AllowBrokenLinks,
1041                        std::function<bool(const SectionBase &)> ToRemove);
1042   Error removeSymbols(function_ref<bool(const Symbol &)> ToRemove);
1043   template <class T, class... Ts> T &addSection(Ts &&... Args) {
1044     auto Sec = llvm::make_unique<T>(std::forward<Ts>(Args)...);
1045     auto Ptr = Sec.get();
1046     Sections.emplace_back(std::move(Sec));
1047     Ptr->Index = Sections.size();
1048     return *Ptr;
1049   }
1050   Segment &addSegment(ArrayRef<uint8_t> Data) {
1051     Segments.emplace_back(llvm::make_unique<Segment>(Data));
1052     return *Segments.back();
1053   }
1054 };
1055
1056 } // end namespace elf
1057 } // end namespace objcopy
1058 } // end namespace llvm
1059
1060 #endif // LLVM_TOOLS_OBJCOPY_OBJECT_H