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