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 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 ArrayRef<std::unique_ptr<SectionBase>> Sections; 52 53 public: 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 71 enum ElfType { ELFT_ELF32LE, ELFT_ELF64LE, ELFT_ELF32BE, ELFT_ELF64BE }; 72 73 class SectionVisitor { 74 public: 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 90 class MutableSectionVisitor { 91 public: 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 107 class SectionWriter : public SectionVisitor { 108 protected: 109 WritableMemoryBuffer &Out; 110 111 public: 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 129 template <class ELFT> class ELFSectionWriter : public SectionWriter { 130 private: 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 136 public: 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 149 template <class ELFT> class ELFSectionSizer : public MutableSectionVisitor { 150 private: 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 157 public: 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 181 class BinarySectionWriter : public SectionWriter { 182 public: 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 197 using IHexLineData = SmallVector<char, 64>; 198 199 struct 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. 271 class 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 282 protected: 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 289 public: 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 302 class IHexSectionWriter : public IHexSectionWriterBase { 303 public: 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 310 class Writer { 311 protected: 312 Object &Obj; 313 std::unique_ptr<WritableMemoryBuffer> Buf; 314 raw_ostream &Out; 315 316 public: 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 324 template <class ELFT> class ELFWriter : public Writer { 325 private: 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 348 public: 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 361 class BinaryWriter : public Writer { 362 private: 363 const uint8_t GapFill; 364 const uint64_t PadTo; 365 std::unique_ptr<BinarySectionWriter> SecWriter; 366 367 uint64_t TotalSize = 0; 368 369 public: 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. 378 class ASCIIHexWriter : public Writer { 379 public: 380 ASCIIHexWriter(Object &Obj, raw_ostream &OS, StringRef OutputFile) 381 : Writer(Obj, OS), OutputFileName(OutputFile) {} 382 Error finalize() override; 383 384 protected: 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 394 class IHexWriter : public ASCIIHexWriter { 395 public: 396 Error write() override; 397 IHexWriter(Object &Obj, raw_ostream &Out, StringRef OutputFile) 398 : ASCIIHexWriter(Obj, Out, OutputFile) {} 399 400 private: 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 407 class SRECWriter : public ASCIIHexWriter { 408 public: 409 SRECWriter(Object &Obj, raw_ostream &OS, StringRef OutputFile) 410 : ASCIIHexWriter(Obj, OS, OutputFile) {} 411 Error write() override; 412 413 private: 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 420 using SRecLineData = SmallVector<char, 64>; 421 struct 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 458 class SRECSectionWriterBase : public BinarySectionWriter { 459 public: 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 475 protected: 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. 490 class SRECSizeCalculator : public SRECSectionWriterBase { 491 public: 492 SRECSizeCalculator(WritableMemoryBuffer &EmptyBuffer, uint64_t Offset) 493 : SRECSectionWriterBase(EmptyBuffer, Offset) {} 494 495 protected: 496 void writeRecord(SRecord &Record, uint64_t Off) override {} 497 }; 498 499 class SRECSectionWriter : public SRECSectionWriterBase { 500 public: 501 SRECSectionWriter(WritableMemoryBuffer &Buf, uint64_t Offset) 502 : SRECSectionWriterBase(Buf, Offset) {} 503 Error visit(const StringTableSection &Sec) override; 504 505 protected: 506 void writeRecord(SRecord &Record, uint64_t Off) override; 507 }; 508 509 class SectionBase { 510 public: 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 559 class Segment { 560 private: 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 572 public: 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(Sec); } 598 void addSection(const SectionBase *Sec) { Sections.insert(Sec); } 599 600 ArrayRef<uint8_t> getContents() const { return Contents; } 601 }; 602 603 class Section : public SectionBase { 604 MAKE_SEC_WRITER_FRIEND 605 606 ArrayRef<uint8_t> Contents; 607 SectionBase *LinkSection = nullptr; 608 bool HasSymTabLink = false; 609 610 public: 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 628 class OwnedDataSection : public SectionBase { 629 MAKE_SEC_WRITER_FRIEND 630 631 std::vector<uint8_t> Data; 632 633 public: 634 OwnedDataSection(StringRef SecName, ArrayRef<uint8_t> Data) 635 : Data(std::begin(Data), std::end(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(Data), std::end(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 663 class 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 672 public: 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 690 class DecompressedSection : public SectionBase { 691 MAKE_SEC_WRITER_FRIEND 692 693 public: 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. 714 class StringTableSection : public SectionBase { 715 MAKE_SEC_WRITER_FRIEND 716 717 StringTableBuilder StrTabBuilder; 718 719 public: 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. 741 enum 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 762 struct 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 779 class SectionIndexSection : public SectionBase { 780 MAKE_SEC_WRITER_FRIEND 781 782 private: 783 std::vector<uint32_t> Indexes; 784 SymbolTableSection *Symbols = nullptr; 785 786 public: 787 virtual ~SectionIndexSection() {} 788 void addIndex(uint32_t Index) { 789 assert(Size > 0); 790 Indexes.push_back(Index); 791 } 792 793 void reserve(size_t NumSymbols) { 794 Indexes.reserve(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 811 class SymbolTableSection : public SectionBase { 812 MAKE_SEC_WRITER_FRIEND 813 814 void setStrTab(StringTableSection *StrTab) { SymbolNames = StrTab; } 815 void assignIndices(); 816 817 protected: 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 825 public: 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 861 struct 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). 877 class RelocationSectionBase : public SectionBase { 878 protected: 879 SectionBase *SecToApplyRel = nullptr; 880 881 public: 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({ELF::SHT_REL, ELF::SHT_RELA, ELF::SHT_CREL}, 889 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. 895 template <class SymTabType> 896 class RelocSectionWithSymtabBase : public RelocationSectionBase { 897 void setSymTab(SymTabType *SymTab) { Symbols = SymTab; } 898 899 protected: 900 RelocSectionWithSymtabBase() = default; 901 902 SymTabType *Symbols = nullptr; 903 904 public: 905 Error initialize(SectionTableRef SecTable) override; 906 void finalize() override; 907 }; 908 909 class RelocationSection 910 : public RelocSectionWithSymtabBase<SymbolTableSection> { 911 MAKE_SEC_WRITER_FRIEND 912 913 std::vector<Relocation> Relocations; 914 const Object &Obj; 915 916 public: 917 RelocationSection(const Object &O) : Obj(O) {} 918 void addRelocation(const Relocation &Rel) { Relocations.push_back(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 940 class 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 947 public: 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(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(GroupMembers); 976 } 977 978 static bool classof(const SectionBase *S) { 979 return S->OriginalType == ELF::SHT_GROUP; 980 } 981 }; 982 983 class DynamicSymbolTableSection : public Section { 984 public: 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 992 class DynamicSection : public Section { 993 public: 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 1001 class DynamicRelocationSection 1002 : public RelocSectionWithSymtabBase<DynamicSymbolTableSection> { 1003 MAKE_SEC_WRITER_FRIEND 1004 1005 private: 1006 ArrayRef<uint8_t> Contents; 1007 1008 public: 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 1024 class GnuDebugLinkSection : public SectionBase { 1025 MAKE_SEC_WRITER_FRIEND 1026 1027 private: 1028 StringRef FileName; 1029 uint32_t CRC32; 1030 1031 void init(StringRef File); 1032 1033 public: 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 1040 class Reader { 1041 public: 1042 virtual ~Reader(); 1043 virtual Expected<std::unique_ptr<Object>> create(bool EnsureSymtab) const = 0; 1044 }; 1045 1046 using object::Binary; 1047 using object::ELFFile; 1048 using object::ELFObjectFile; 1049 using object::OwningBinary; 1050 1051 class BasicELFBuilder { 1052 protected: 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 1061 public: 1062 BasicELFBuilder() : Obj(std::make_unique<Object>()) {} 1063 }; 1064 1065 class BinaryELFBuilder : public BasicELFBuilder { 1066 MemoryBuffer *MemBuf; 1067 uint8_t NewSymbolVisibility; 1068 void addData(SymbolTableSection *SymTab); 1069 1070 public: 1071 BinaryELFBuilder(MemoryBuffer *MB, uint8_t NewSymbolVisibility) 1072 : MemBuf(MB), NewSymbolVisibility(NewSymbolVisibility) {} 1073 1074 Expected<std::unique_ptr<Object>> build(); 1075 }; 1076 1077 class IHexELFBuilder : public BasicELFBuilder { 1078 const std::vector<IHexRecord> &Records; 1079 1080 void addDataSections(); 1081 1082 public: 1083 IHexELFBuilder(const std::vector<IHexRecord> &Records) : Records(Records) {} 1084 1085 Expected<std::unique_ptr<Object>> build(); 1086 }; 1087 1088 template <class ELFT> class ELFBuilder { 1089 private: 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 1108 public: 1109 ELFBuilder(const ELFObjectFile<ELFT> &ElfObj, Object &Obj, 1110 std::optional<StringRef> ExtractPartition); 1111 1112 Error build(bool EnsureSymtab); 1113 }; 1114 1115 class BinaryReader : public Reader { 1116 MemoryBuffer *MemBuf; 1117 uint8_t NewSymbolVisibility; 1118 1119 public: 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 1125 class 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(MemBuf->getBufferIdentifier(), std::move(E)) 1132 : createFileError(MemBuf->getBufferIdentifier(), LineNo, 1133 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, std::move(E)); 1139 } 1140 1141 public: 1142 IHexReader(MemoryBuffer *MB) : MemBuf(MB) {} 1143 1144 Expected<std::unique_ptr<Object>> create(bool EnsureSymtab) const override; 1145 }; 1146 1147 class ELFReader : public Reader { 1148 Binary *Bin; 1149 std::optional<StringRef> ExtractPartition; 1150 1151 public: 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 1157 class Object { 1158 private: 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 1173 public: 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(§ionIsAlloc)>> 1209 allocSections() const { 1210 return make_filter_range(make_pointee_range(Sections), 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(Sections, [&](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(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(std::make_unique<Segment>(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