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