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