181ad6265SDimitry Andric //===- ELFObject.h ----------------------------------------------*- C++ -*-===// 281ad6265SDimitry Andric // 381ad6265SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 481ad6265SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 581ad6265SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 681ad6265SDimitry Andric // 781ad6265SDimitry Andric //===----------------------------------------------------------------------===// 881ad6265SDimitry Andric 981ad6265SDimitry Andric #ifndef LLVM_LIB_OBJCOPY_ELF_ELFOBJECT_H 1081ad6265SDimitry Andric #define LLVM_LIB_OBJCOPY_ELF_ELFOBJECT_H 1181ad6265SDimitry Andric 1281ad6265SDimitry Andric #include "llvm/ADT/ArrayRef.h" 1381ad6265SDimitry Andric #include "llvm/ADT/StringRef.h" 1481ad6265SDimitry Andric #include "llvm/ADT/Twine.h" 1581ad6265SDimitry Andric #include "llvm/BinaryFormat/ELF.h" 1681ad6265SDimitry Andric #include "llvm/MC/StringTableBuilder.h" 1781ad6265SDimitry Andric #include "llvm/ObjCopy/CommonConfig.h" 1881ad6265SDimitry Andric #include "llvm/Object/ELFObjectFile.h" 1981ad6265SDimitry Andric #include "llvm/Support/Errc.h" 2081ad6265SDimitry Andric #include "llvm/Support/FileOutputBuffer.h" 2181ad6265SDimitry Andric #include "llvm/Support/MemoryBuffer.h" 2281ad6265SDimitry Andric #include <cstddef> 2381ad6265SDimitry Andric #include <cstdint> 2481ad6265SDimitry Andric #include <functional> 2581ad6265SDimitry Andric #include <memory> 2681ad6265SDimitry Andric #include <set> 2781ad6265SDimitry Andric #include <vector> 2881ad6265SDimitry Andric 2981ad6265SDimitry Andric namespace llvm { 3081ad6265SDimitry Andric enum class DebugCompressionType; 3181ad6265SDimitry Andric namespace objcopy { 3281ad6265SDimitry Andric namespace elf { 3381ad6265SDimitry Andric 3481ad6265SDimitry Andric class SectionBase; 3581ad6265SDimitry Andric class Section; 3681ad6265SDimitry Andric class OwnedDataSection; 3781ad6265SDimitry Andric class StringTableSection; 3881ad6265SDimitry Andric class SymbolTableSection; 3981ad6265SDimitry Andric class RelocationSection; 4081ad6265SDimitry Andric class DynamicRelocationSection; 4181ad6265SDimitry Andric class GnuDebugLinkSection; 4281ad6265SDimitry Andric class GroupSection; 4381ad6265SDimitry Andric class SectionIndexSection; 4481ad6265SDimitry Andric class CompressedSection; 4581ad6265SDimitry Andric class DecompressedSection; 4681ad6265SDimitry Andric class Segment; 4781ad6265SDimitry Andric class Object; 4881ad6265SDimitry Andric struct Symbol; 4981ad6265SDimitry Andric 5081ad6265SDimitry Andric class SectionTableRef { 5181ad6265SDimitry Andric ArrayRef<std::unique_ptr<SectionBase>> Sections; 5281ad6265SDimitry Andric 5381ad6265SDimitry Andric public: 5481ad6265SDimitry Andric using iterator = pointee_iterator<const std::unique_ptr<SectionBase> *>; 5581ad6265SDimitry Andric SectionTableRef(ArrayRef<std::unique_ptr<SectionBase>> Secs)5681ad6265SDimitry Andric explicit SectionTableRef(ArrayRef<std::unique_ptr<SectionBase>> Secs) 5781ad6265SDimitry Andric : Sections(Secs) {} 5881ad6265SDimitry Andric SectionTableRef(const SectionTableRef &) = default; 5981ad6265SDimitry Andric begin()6081ad6265SDimitry Andric iterator begin() const { return iterator(Sections.data()); } end()6181ad6265SDimitry Andric iterator end() const { return iterator(Sections.data() + Sections.size()); } size()6281ad6265SDimitry Andric size_t size() const { return Sections.size(); } 6381ad6265SDimitry Andric 6481ad6265SDimitry Andric Expected<SectionBase *> getSection(uint32_t Index, Twine ErrMsg); 6581ad6265SDimitry Andric 6681ad6265SDimitry Andric template <class T> 6781ad6265SDimitry Andric Expected<T *> getSectionOfType(uint32_t Index, Twine IndexErrMsg, 6881ad6265SDimitry Andric Twine TypeErrMsg); 6981ad6265SDimitry Andric }; 7081ad6265SDimitry Andric 7181ad6265SDimitry Andric enum ElfType { ELFT_ELF32LE, ELFT_ELF64LE, ELFT_ELF32BE, ELFT_ELF64BE }; 7281ad6265SDimitry Andric 7381ad6265SDimitry Andric class SectionVisitor { 7481ad6265SDimitry Andric public: 7581ad6265SDimitry Andric virtual ~SectionVisitor() = default; 7681ad6265SDimitry Andric 7781ad6265SDimitry Andric virtual Error visit(const Section &Sec) = 0; 7881ad6265SDimitry Andric virtual Error visit(const OwnedDataSection &Sec) = 0; 7981ad6265SDimitry Andric virtual Error visit(const StringTableSection &Sec) = 0; 8081ad6265SDimitry Andric virtual Error visit(const SymbolTableSection &Sec) = 0; 8181ad6265SDimitry Andric virtual Error visit(const RelocationSection &Sec) = 0; 8281ad6265SDimitry Andric virtual Error visit(const DynamicRelocationSection &Sec) = 0; 8381ad6265SDimitry Andric virtual Error visit(const GnuDebugLinkSection &Sec) = 0; 8481ad6265SDimitry Andric virtual Error visit(const GroupSection &Sec) = 0; 8581ad6265SDimitry Andric virtual Error visit(const SectionIndexSection &Sec) = 0; 8681ad6265SDimitry Andric virtual Error visit(const CompressedSection &Sec) = 0; 8781ad6265SDimitry Andric virtual Error visit(const DecompressedSection &Sec) = 0; 8881ad6265SDimitry Andric }; 8981ad6265SDimitry Andric 9081ad6265SDimitry Andric class MutableSectionVisitor { 9181ad6265SDimitry Andric public: 9281ad6265SDimitry Andric virtual ~MutableSectionVisitor() = default; 9381ad6265SDimitry Andric 9481ad6265SDimitry Andric virtual Error visit(Section &Sec) = 0; 9581ad6265SDimitry Andric virtual Error visit(OwnedDataSection &Sec) = 0; 9681ad6265SDimitry Andric virtual Error visit(StringTableSection &Sec) = 0; 9781ad6265SDimitry Andric virtual Error visit(SymbolTableSection &Sec) = 0; 9881ad6265SDimitry Andric virtual Error visit(RelocationSection &Sec) = 0; 9981ad6265SDimitry Andric virtual Error visit(DynamicRelocationSection &Sec) = 0; 10081ad6265SDimitry Andric virtual Error visit(GnuDebugLinkSection &Sec) = 0; 10181ad6265SDimitry Andric virtual Error visit(GroupSection &Sec) = 0; 10281ad6265SDimitry Andric virtual Error visit(SectionIndexSection &Sec) = 0; 10381ad6265SDimitry Andric virtual Error visit(CompressedSection &Sec) = 0; 10481ad6265SDimitry Andric virtual Error visit(DecompressedSection &Sec) = 0; 10581ad6265SDimitry Andric }; 10681ad6265SDimitry Andric 10781ad6265SDimitry Andric class SectionWriter : public SectionVisitor { 10881ad6265SDimitry Andric protected: 10981ad6265SDimitry Andric WritableMemoryBuffer &Out; 11081ad6265SDimitry Andric 11181ad6265SDimitry Andric public: 11281ad6265SDimitry Andric virtual ~SectionWriter() = default; 11381ad6265SDimitry Andric 11481ad6265SDimitry Andric Error visit(const Section &Sec) override; 11581ad6265SDimitry Andric Error visit(const OwnedDataSection &Sec) override; 11681ad6265SDimitry Andric Error visit(const StringTableSection &Sec) override; 11781ad6265SDimitry Andric Error visit(const DynamicRelocationSection &Sec) override; 118972a253aSDimitry Andric Error visit(const SymbolTableSection &Sec) override = 0; 119972a253aSDimitry Andric Error visit(const RelocationSection &Sec) override = 0; 120972a253aSDimitry Andric Error visit(const GnuDebugLinkSection &Sec) override = 0; 121972a253aSDimitry Andric Error visit(const GroupSection &Sec) override = 0; 122972a253aSDimitry Andric Error visit(const SectionIndexSection &Sec) override = 0; 123972a253aSDimitry Andric Error visit(const CompressedSection &Sec) override = 0; 124972a253aSDimitry Andric Error visit(const DecompressedSection &Sec) override = 0; 12581ad6265SDimitry Andric SectionWriter(WritableMemoryBuffer & Buf)12681ad6265SDimitry Andric explicit SectionWriter(WritableMemoryBuffer &Buf) : Out(Buf) {} 12781ad6265SDimitry Andric }; 12881ad6265SDimitry Andric 12981ad6265SDimitry Andric template <class ELFT> class ELFSectionWriter : public SectionWriter { 13081ad6265SDimitry Andric private: 13181ad6265SDimitry Andric using Elf_Word = typename ELFT::Word; 13281ad6265SDimitry Andric using Elf_Rel = typename ELFT::Rel; 13381ad6265SDimitry Andric using Elf_Rela = typename ELFT::Rela; 13481ad6265SDimitry Andric using Elf_Sym = typename ELFT::Sym; 13581ad6265SDimitry Andric 13681ad6265SDimitry Andric public: ~ELFSectionWriter()13781ad6265SDimitry Andric virtual ~ELFSectionWriter() {} 13881ad6265SDimitry Andric Error visit(const SymbolTableSection &Sec) override; 13981ad6265SDimitry Andric Error visit(const RelocationSection &Sec) override; 14081ad6265SDimitry Andric Error visit(const GnuDebugLinkSection &Sec) override; 14181ad6265SDimitry Andric Error visit(const GroupSection &Sec) override; 14281ad6265SDimitry Andric Error visit(const SectionIndexSection &Sec) override; 14381ad6265SDimitry Andric Error visit(const CompressedSection &Sec) override; 14481ad6265SDimitry Andric Error visit(const DecompressedSection &Sec) override; 14581ad6265SDimitry Andric ELFSectionWriter(WritableMemoryBuffer & Buf)14681ad6265SDimitry Andric explicit ELFSectionWriter(WritableMemoryBuffer &Buf) : SectionWriter(Buf) {} 14781ad6265SDimitry Andric }; 14881ad6265SDimitry Andric 14981ad6265SDimitry Andric template <class ELFT> class ELFSectionSizer : public MutableSectionVisitor { 15081ad6265SDimitry Andric private: 15181ad6265SDimitry Andric using Elf_Rel = typename ELFT::Rel; 15281ad6265SDimitry Andric using Elf_Rela = typename ELFT::Rela; 15381ad6265SDimitry Andric using Elf_Sym = typename ELFT::Sym; 15481ad6265SDimitry Andric using Elf_Word = typename ELFT::Word; 15581ad6265SDimitry Andric using Elf_Xword = typename ELFT::Xword; 15681ad6265SDimitry Andric 15781ad6265SDimitry Andric public: 15881ad6265SDimitry Andric Error visit(Section &Sec) override; 15981ad6265SDimitry Andric Error visit(OwnedDataSection &Sec) override; 16081ad6265SDimitry Andric Error visit(StringTableSection &Sec) override; 16181ad6265SDimitry Andric Error visit(DynamicRelocationSection &Sec) override; 16281ad6265SDimitry Andric Error visit(SymbolTableSection &Sec) override; 16381ad6265SDimitry Andric Error visit(RelocationSection &Sec) override; 16481ad6265SDimitry Andric Error visit(GnuDebugLinkSection &Sec) override; 16581ad6265SDimitry Andric Error visit(GroupSection &Sec) override; 16681ad6265SDimitry Andric Error visit(SectionIndexSection &Sec) override; 16781ad6265SDimitry Andric Error visit(CompressedSection &Sec) override; 16881ad6265SDimitry Andric Error visit(DecompressedSection &Sec) override; 16981ad6265SDimitry Andric }; 17081ad6265SDimitry Andric 17181ad6265SDimitry Andric #define MAKE_SEC_WRITER_FRIEND \ 17281ad6265SDimitry Andric friend class SectionWriter; \ 17381ad6265SDimitry Andric friend class IHexSectionWriterBase; \ 17481ad6265SDimitry Andric friend class IHexSectionWriter; \ 17581ad6265SDimitry Andric template <class ELFT> friend class ELFSectionWriter; \ 17681ad6265SDimitry Andric template <class ELFT> friend class ELFSectionSizer; 17781ad6265SDimitry Andric 17881ad6265SDimitry Andric class BinarySectionWriter : public SectionWriter { 17981ad6265SDimitry Andric public: ~BinarySectionWriter()18081ad6265SDimitry Andric virtual ~BinarySectionWriter() {} 18181ad6265SDimitry Andric 18281ad6265SDimitry Andric Error visit(const SymbolTableSection &Sec) override; 18381ad6265SDimitry Andric Error visit(const RelocationSection &Sec) override; 18481ad6265SDimitry Andric Error visit(const GnuDebugLinkSection &Sec) override; 18581ad6265SDimitry Andric Error visit(const GroupSection &Sec) override; 18681ad6265SDimitry Andric Error visit(const SectionIndexSection &Sec) override; 18781ad6265SDimitry Andric Error visit(const CompressedSection &Sec) override; 18881ad6265SDimitry Andric Error visit(const DecompressedSection &Sec) override; 18981ad6265SDimitry Andric BinarySectionWriter(WritableMemoryBuffer & Buf)19081ad6265SDimitry Andric explicit BinarySectionWriter(WritableMemoryBuffer &Buf) 19181ad6265SDimitry Andric : SectionWriter(Buf) {} 19281ad6265SDimitry Andric }; 19381ad6265SDimitry Andric 19481ad6265SDimitry Andric using IHexLineData = SmallVector<char, 64>; 19581ad6265SDimitry Andric 19681ad6265SDimitry Andric struct IHexRecord { 19781ad6265SDimitry Andric // Memory address of the record. 19881ad6265SDimitry Andric uint16_t Addr; 19981ad6265SDimitry Andric // Record type (see below). 20081ad6265SDimitry Andric uint16_t Type; 20181ad6265SDimitry Andric // Record data in hexadecimal form. 20281ad6265SDimitry Andric StringRef HexData; 20381ad6265SDimitry Andric 20481ad6265SDimitry Andric // Helper method to get file length of the record 20581ad6265SDimitry Andric // including newline character getLengthIHexRecord20681ad6265SDimitry Andric static size_t getLength(size_t DataSize) { 20781ad6265SDimitry Andric // :LLAAAATT[DD...DD]CC' 20881ad6265SDimitry Andric return DataSize * 2 + 11; 20981ad6265SDimitry Andric } 21081ad6265SDimitry Andric 21181ad6265SDimitry Andric // Gets length of line in a file (getLength + CRLF). getLineLengthIHexRecord21281ad6265SDimitry Andric static size_t getLineLength(size_t DataSize) { 21381ad6265SDimitry Andric return getLength(DataSize) + 2; 21481ad6265SDimitry Andric } 21581ad6265SDimitry Andric 21681ad6265SDimitry Andric // Given type, address and data returns line which can 21781ad6265SDimitry Andric // be written to output file. 21881ad6265SDimitry Andric static IHexLineData getLine(uint8_t Type, uint16_t Addr, 21981ad6265SDimitry Andric ArrayRef<uint8_t> Data); 22081ad6265SDimitry Andric 22181ad6265SDimitry Andric // Parses the line and returns record if possible. 22281ad6265SDimitry Andric // Line should be trimmed from whitespace characters. 22381ad6265SDimitry Andric static Expected<IHexRecord> parse(StringRef Line); 22481ad6265SDimitry Andric 22581ad6265SDimitry Andric // Calculates checksum of stringified record representation 22681ad6265SDimitry Andric // S must NOT contain leading ':' and trailing whitespace 22781ad6265SDimitry Andric // characters 22881ad6265SDimitry Andric static uint8_t getChecksum(StringRef S); 22981ad6265SDimitry Andric 23081ad6265SDimitry Andric enum Type { 23181ad6265SDimitry Andric // Contains data and a 16-bit starting address for the data. 23281ad6265SDimitry Andric // The byte count specifies number of data bytes in the record. 23381ad6265SDimitry Andric Data = 0, 23481ad6265SDimitry Andric // Must occur exactly once per file in the last line of the file. 23581ad6265SDimitry Andric // The data field is empty (thus byte count is 00) and the address 23681ad6265SDimitry Andric // field is typically 0000. 23781ad6265SDimitry Andric EndOfFile = 1, 23881ad6265SDimitry Andric // The data field contains a 16-bit segment base address (thus byte 23981ad6265SDimitry Andric // count is always 02) compatible with 80x86 real mode addressing. 24081ad6265SDimitry Andric // The address field (typically 0000) is ignored. The segment address 24181ad6265SDimitry Andric // from the most recent 02 record is multiplied by 16 and added to each 24281ad6265SDimitry Andric // subsequent data record address to form the physical starting address 24381ad6265SDimitry Andric // for the data. This allows addressing up to one megabyte of address 24481ad6265SDimitry Andric // space. 24581ad6265SDimitry Andric SegmentAddr = 2, 24681ad6265SDimitry Andric // or 80x86 processors, specifies the initial content of the CS:IP 24781ad6265SDimitry Andric // registers. The address field is 0000, the byte count is always 04, 24881ad6265SDimitry Andric // the first two data bytes are the CS value, the latter two are the 24981ad6265SDimitry Andric // IP value. 25081ad6265SDimitry Andric StartAddr80x86 = 3, 25181ad6265SDimitry Andric // Allows for 32 bit addressing (up to 4GiB). The record's address field 25281ad6265SDimitry Andric // is ignored (typically 0000) and its byte count is always 02. The two 25381ad6265SDimitry Andric // data bytes (big endian) specify the upper 16 bits of the 32 bit 25481ad6265SDimitry Andric // absolute address for all subsequent type 00 records 25581ad6265SDimitry Andric ExtendedAddr = 4, 25681ad6265SDimitry Andric // The address field is 0000 (not used) and the byte count is always 04. 25781ad6265SDimitry Andric // The four data bytes represent a 32-bit address value. In the case of 25881ad6265SDimitry Andric // 80386 and higher CPUs, this address is loaded into the EIP register. 25981ad6265SDimitry Andric StartAddr = 5, 26081ad6265SDimitry Andric // We have no other valid types 26181ad6265SDimitry Andric InvalidType = 6 26281ad6265SDimitry Andric }; 26381ad6265SDimitry Andric }; 26481ad6265SDimitry Andric 26581ad6265SDimitry Andric // Base class for IHexSectionWriter. This class implements writing algorithm, 26681ad6265SDimitry Andric // but doesn't actually write records. It is used for output buffer size 26781ad6265SDimitry Andric // calculation in IHexWriter::finalize. 26881ad6265SDimitry Andric class IHexSectionWriterBase : public BinarySectionWriter { 26981ad6265SDimitry Andric // 20-bit segment address 27081ad6265SDimitry Andric uint32_t SegmentAddr = 0; 27181ad6265SDimitry Andric // Extended linear address 27281ad6265SDimitry Andric uint32_t BaseAddr = 0; 27381ad6265SDimitry Andric 27481ad6265SDimitry Andric // Write segment address corresponding to 'Addr' 27581ad6265SDimitry Andric uint64_t writeSegmentAddr(uint64_t Addr); 27681ad6265SDimitry Andric // Write extended linear (base) address corresponding to 'Addr' 27781ad6265SDimitry Andric uint64_t writeBaseAddr(uint64_t Addr); 27881ad6265SDimitry Andric 27981ad6265SDimitry Andric protected: 28081ad6265SDimitry Andric // Offset in the output buffer 28181ad6265SDimitry Andric uint64_t Offset = 0; 28281ad6265SDimitry Andric 28381ad6265SDimitry Andric void writeSection(const SectionBase *Sec, ArrayRef<uint8_t> Data); 28481ad6265SDimitry Andric virtual void writeData(uint8_t Type, uint16_t Addr, ArrayRef<uint8_t> Data); 28581ad6265SDimitry Andric 28681ad6265SDimitry Andric public: IHexSectionWriterBase(WritableMemoryBuffer & Buf)28781ad6265SDimitry Andric explicit IHexSectionWriterBase(WritableMemoryBuffer &Buf) 28881ad6265SDimitry Andric : BinarySectionWriter(Buf) {} 28981ad6265SDimitry Andric getBufferOffset()29081ad6265SDimitry Andric uint64_t getBufferOffset() const { return Offset; } 29181ad6265SDimitry Andric Error visit(const Section &Sec) final; 29281ad6265SDimitry Andric Error visit(const OwnedDataSection &Sec) final; 29381ad6265SDimitry Andric Error visit(const StringTableSection &Sec) override; 29481ad6265SDimitry Andric Error visit(const DynamicRelocationSection &Sec) final; 29581ad6265SDimitry Andric using BinarySectionWriter::visit; 29681ad6265SDimitry Andric }; 29781ad6265SDimitry Andric 29881ad6265SDimitry Andric // Real IHEX section writer 29981ad6265SDimitry Andric class IHexSectionWriter : public IHexSectionWriterBase { 30081ad6265SDimitry Andric public: IHexSectionWriter(WritableMemoryBuffer & Buf)30181ad6265SDimitry Andric IHexSectionWriter(WritableMemoryBuffer &Buf) : IHexSectionWriterBase(Buf) {} 30281ad6265SDimitry Andric 30381ad6265SDimitry Andric void writeData(uint8_t Type, uint16_t Addr, ArrayRef<uint8_t> Data) override; 30481ad6265SDimitry Andric Error visit(const StringTableSection &Sec) override; 30581ad6265SDimitry Andric }; 30681ad6265SDimitry Andric 30781ad6265SDimitry Andric class Writer { 30881ad6265SDimitry Andric protected: 30981ad6265SDimitry Andric Object &Obj; 31081ad6265SDimitry Andric std::unique_ptr<WritableMemoryBuffer> Buf; 31181ad6265SDimitry Andric raw_ostream &Out; 31281ad6265SDimitry Andric 31381ad6265SDimitry Andric public: 31481ad6265SDimitry Andric virtual ~Writer(); 31581ad6265SDimitry Andric virtual Error finalize() = 0; 31681ad6265SDimitry Andric virtual Error write() = 0; 31781ad6265SDimitry Andric Writer(Object & O,raw_ostream & Out)31881ad6265SDimitry Andric Writer(Object &O, raw_ostream &Out) : Obj(O), Out(Out) {} 31981ad6265SDimitry Andric }; 32081ad6265SDimitry Andric 32181ad6265SDimitry Andric template <class ELFT> class ELFWriter : public Writer { 32281ad6265SDimitry Andric private: 32381ad6265SDimitry Andric using Elf_Addr = typename ELFT::Addr; 32481ad6265SDimitry Andric using Elf_Shdr = typename ELFT::Shdr; 32581ad6265SDimitry Andric using Elf_Phdr = typename ELFT::Phdr; 32681ad6265SDimitry Andric using Elf_Ehdr = typename ELFT::Ehdr; 32781ad6265SDimitry Andric 32881ad6265SDimitry Andric void initEhdrSegment(); 32981ad6265SDimitry Andric 33081ad6265SDimitry Andric void writeEhdr(); 33181ad6265SDimitry Andric void writePhdr(const Segment &Seg); 33281ad6265SDimitry Andric void writeShdr(const SectionBase &Sec); 33381ad6265SDimitry Andric 33481ad6265SDimitry Andric void writePhdrs(); 33581ad6265SDimitry Andric void writeShdrs(); 33681ad6265SDimitry Andric Error writeSectionData(); 33781ad6265SDimitry Andric void writeSegmentData(); 33881ad6265SDimitry Andric 33981ad6265SDimitry Andric void assignOffsets(); 34081ad6265SDimitry Andric 34181ad6265SDimitry Andric std::unique_ptr<ELFSectionWriter<ELFT>> SecWriter; 34281ad6265SDimitry Andric 34381ad6265SDimitry Andric size_t totalSize() const; 34481ad6265SDimitry Andric 34581ad6265SDimitry Andric public: ~ELFWriter()34681ad6265SDimitry Andric virtual ~ELFWriter() {} 34781ad6265SDimitry Andric bool WriteSectionHeaders; 34881ad6265SDimitry Andric 34981ad6265SDimitry Andric // For --only-keep-debug, select an alternative section/segment layout 35081ad6265SDimitry Andric // algorithm. 35181ad6265SDimitry Andric bool OnlyKeepDebug; 35281ad6265SDimitry Andric 35381ad6265SDimitry Andric Error finalize() override; 35481ad6265SDimitry Andric Error write() override; 35581ad6265SDimitry Andric ELFWriter(Object &Obj, raw_ostream &Out, bool WSH, bool OnlyKeepDebug); 35681ad6265SDimitry Andric }; 35781ad6265SDimitry Andric 35881ad6265SDimitry Andric class BinaryWriter : public Writer { 35981ad6265SDimitry Andric private: 360*5f757f3fSDimitry Andric const uint8_t GapFill; 361*5f757f3fSDimitry Andric const uint64_t PadTo; 36281ad6265SDimitry Andric std::unique_ptr<BinarySectionWriter> SecWriter; 36381ad6265SDimitry Andric 36481ad6265SDimitry Andric uint64_t TotalSize = 0; 36581ad6265SDimitry Andric 36681ad6265SDimitry Andric public: ~BinaryWriter()36781ad6265SDimitry Andric ~BinaryWriter() {} 36881ad6265SDimitry Andric Error finalize() override; 36981ad6265SDimitry Andric Error write() override; BinaryWriter(Object & Obj,raw_ostream & Out,const CommonConfig & Config)370*5f757f3fSDimitry Andric BinaryWriter(Object &Obj, raw_ostream &Out, const CommonConfig &Config) 371*5f757f3fSDimitry Andric : Writer(Obj, Out), GapFill(Config.GapFill), PadTo(Config.PadTo) {} 37281ad6265SDimitry Andric }; 37381ad6265SDimitry Andric 37481ad6265SDimitry Andric class IHexWriter : public Writer { 37581ad6265SDimitry Andric struct SectionCompare { 37681ad6265SDimitry Andric bool operator()(const SectionBase *Lhs, const SectionBase *Rhs) const; 37781ad6265SDimitry Andric }; 37881ad6265SDimitry Andric 37981ad6265SDimitry Andric std::set<const SectionBase *, SectionCompare> Sections; 38081ad6265SDimitry Andric size_t TotalSize = 0; 38181ad6265SDimitry Andric 38281ad6265SDimitry Andric Error checkSection(const SectionBase &Sec); 38381ad6265SDimitry Andric uint64_t writeEntryPointRecord(uint8_t *Buf); 38481ad6265SDimitry Andric uint64_t writeEndOfFileRecord(uint8_t *Buf); 38581ad6265SDimitry Andric 38681ad6265SDimitry Andric public: ~IHexWriter()38781ad6265SDimitry Andric ~IHexWriter() {} 38881ad6265SDimitry Andric Error finalize() override; 38981ad6265SDimitry Andric Error write() override; IHexWriter(Object & Obj,raw_ostream & Out)39081ad6265SDimitry Andric IHexWriter(Object &Obj, raw_ostream &Out) : Writer(Obj, Out) {} 39181ad6265SDimitry Andric }; 39281ad6265SDimitry Andric 39381ad6265SDimitry Andric class SectionBase { 39481ad6265SDimitry Andric public: 39581ad6265SDimitry Andric std::string Name; 39681ad6265SDimitry Andric Segment *ParentSegment = nullptr; 39781ad6265SDimitry Andric uint64_t HeaderOffset = 0; 39881ad6265SDimitry Andric uint32_t Index = 0; 39981ad6265SDimitry Andric 40081ad6265SDimitry Andric uint32_t OriginalIndex = 0; 40181ad6265SDimitry Andric uint64_t OriginalFlags = 0; 40281ad6265SDimitry Andric uint64_t OriginalType = ELF::SHT_NULL; 40381ad6265SDimitry Andric uint64_t OriginalOffset = std::numeric_limits<uint64_t>::max(); 40481ad6265SDimitry Andric 40581ad6265SDimitry Andric uint64_t Addr = 0; 40681ad6265SDimitry Andric uint64_t Align = 1; 40781ad6265SDimitry Andric uint32_t EntrySize = 0; 40881ad6265SDimitry Andric uint64_t Flags = 0; 40981ad6265SDimitry Andric uint64_t Info = 0; 41081ad6265SDimitry Andric uint64_t Link = ELF::SHN_UNDEF; 41181ad6265SDimitry Andric uint64_t NameIndex = 0; 41281ad6265SDimitry Andric uint64_t Offset = 0; 41381ad6265SDimitry Andric uint64_t Size = 0; 41481ad6265SDimitry Andric uint64_t Type = ELF::SHT_NULL; 41581ad6265SDimitry Andric ArrayRef<uint8_t> OriginalData; 41681ad6265SDimitry Andric bool HasSymbol = false; 41781ad6265SDimitry Andric 41881ad6265SDimitry Andric SectionBase() = default; 41981ad6265SDimitry Andric SectionBase(const SectionBase &) = default; 42081ad6265SDimitry Andric 42181ad6265SDimitry Andric virtual ~SectionBase() = default; 42281ad6265SDimitry Andric 42381ad6265SDimitry Andric virtual Error initialize(SectionTableRef SecTable); 42481ad6265SDimitry Andric virtual void finalize(); 42581ad6265SDimitry Andric // Remove references to these sections. The list of sections must be sorted. 42681ad6265SDimitry Andric virtual Error 42781ad6265SDimitry Andric removeSectionReferences(bool AllowBrokenLinks, 42881ad6265SDimitry Andric function_ref<bool(const SectionBase *)> ToRemove); 42981ad6265SDimitry Andric virtual Error removeSymbols(function_ref<bool(const Symbol &)> ToRemove); 43081ad6265SDimitry Andric virtual Error accept(SectionVisitor &Visitor) const = 0; 43181ad6265SDimitry Andric virtual Error accept(MutableSectionVisitor &Visitor) = 0; 43281ad6265SDimitry Andric virtual void markSymbols(); 43381ad6265SDimitry Andric virtual void 43481ad6265SDimitry Andric replaceSectionReferences(const DenseMap<SectionBase *, SectionBase *> &); hasContents()43581ad6265SDimitry Andric virtual bool hasContents() const { return false; } 43681ad6265SDimitry Andric // Notify the section that it is subject to removal. 43781ad6265SDimitry Andric virtual void onRemove(); 43806c3fb27SDimitry Andric restoreSymTabLink(SymbolTableSection &)43906c3fb27SDimitry Andric virtual void restoreSymTabLink(SymbolTableSection &) {} 44081ad6265SDimitry Andric }; 44181ad6265SDimitry Andric 44281ad6265SDimitry Andric class Segment { 44381ad6265SDimitry Andric private: 44481ad6265SDimitry Andric struct SectionCompare { operatorSectionCompare44581ad6265SDimitry Andric bool operator()(const SectionBase *Lhs, const SectionBase *Rhs) const { 44681ad6265SDimitry Andric // Some sections might have the same address if one of them is empty. To 44781ad6265SDimitry Andric // fix this we can use the lexicographic ordering on ->Addr and the 44881ad6265SDimitry Andric // original index. 44981ad6265SDimitry Andric if (Lhs->OriginalOffset == Rhs->OriginalOffset) 45081ad6265SDimitry Andric return Lhs->OriginalIndex < Rhs->OriginalIndex; 45181ad6265SDimitry Andric return Lhs->OriginalOffset < Rhs->OriginalOffset; 45281ad6265SDimitry Andric } 45381ad6265SDimitry Andric }; 45481ad6265SDimitry Andric 45581ad6265SDimitry Andric public: 45681ad6265SDimitry Andric uint32_t Type = 0; 45781ad6265SDimitry Andric uint32_t Flags = 0; 45881ad6265SDimitry Andric uint64_t Offset = 0; 45981ad6265SDimitry Andric uint64_t VAddr = 0; 46081ad6265SDimitry Andric uint64_t PAddr = 0; 46181ad6265SDimitry Andric uint64_t FileSize = 0; 46281ad6265SDimitry Andric uint64_t MemSize = 0; 46381ad6265SDimitry Andric uint64_t Align = 0; 46481ad6265SDimitry Andric 46581ad6265SDimitry Andric uint32_t Index = 0; 46681ad6265SDimitry Andric uint64_t OriginalOffset = 0; 46781ad6265SDimitry Andric Segment *ParentSegment = nullptr; 46881ad6265SDimitry Andric ArrayRef<uint8_t> Contents; 46981ad6265SDimitry Andric std::set<const SectionBase *, SectionCompare> Sections; 47081ad6265SDimitry Andric Segment(ArrayRef<uint8_t> Data)47181ad6265SDimitry Andric explicit Segment(ArrayRef<uint8_t> Data) : Contents(Data) {} 47281ad6265SDimitry Andric Segment() = default; 47381ad6265SDimitry Andric firstSection()47481ad6265SDimitry Andric const SectionBase *firstSection() const { 47581ad6265SDimitry Andric if (!Sections.empty()) 47681ad6265SDimitry Andric return *Sections.begin(); 47781ad6265SDimitry Andric return nullptr; 47881ad6265SDimitry Andric } 47981ad6265SDimitry Andric removeSection(const SectionBase * Sec)48081ad6265SDimitry Andric void removeSection(const SectionBase *Sec) { Sections.erase(Sec); } addSection(const SectionBase * Sec)48181ad6265SDimitry Andric void addSection(const SectionBase *Sec) { Sections.insert(Sec); } 48281ad6265SDimitry Andric getContents()48381ad6265SDimitry Andric ArrayRef<uint8_t> getContents() const { return Contents; } 48481ad6265SDimitry Andric }; 48581ad6265SDimitry Andric 48681ad6265SDimitry Andric class Section : public SectionBase { 48781ad6265SDimitry Andric MAKE_SEC_WRITER_FRIEND 48881ad6265SDimitry Andric 48981ad6265SDimitry Andric ArrayRef<uint8_t> Contents; 49081ad6265SDimitry Andric SectionBase *LinkSection = nullptr; 49106c3fb27SDimitry Andric bool HasSymTabLink = false; 49281ad6265SDimitry Andric 49381ad6265SDimitry Andric public: Section(ArrayRef<uint8_t> Data)49481ad6265SDimitry Andric explicit Section(ArrayRef<uint8_t> Data) : Contents(Data) {} 49581ad6265SDimitry Andric 49681ad6265SDimitry Andric Error accept(SectionVisitor &Visitor) const override; 49781ad6265SDimitry Andric Error accept(MutableSectionVisitor &Visitor) override; 49881ad6265SDimitry Andric Error removeSectionReferences( 49981ad6265SDimitry Andric bool AllowBrokenLinks, 50081ad6265SDimitry Andric function_ref<bool(const SectionBase *)> ToRemove) override; 50181ad6265SDimitry Andric Error initialize(SectionTableRef SecTable) override; 50281ad6265SDimitry Andric void finalize() override; hasContents()50381ad6265SDimitry Andric bool hasContents() const override { 50481ad6265SDimitry Andric return Type != ELF::SHT_NOBITS && Type != ELF::SHT_NULL; 50581ad6265SDimitry Andric } 50606c3fb27SDimitry Andric void restoreSymTabLink(SymbolTableSection &SymTab) override; 50781ad6265SDimitry Andric }; 50881ad6265SDimitry Andric 50981ad6265SDimitry Andric class OwnedDataSection : public SectionBase { 51081ad6265SDimitry Andric MAKE_SEC_WRITER_FRIEND 51181ad6265SDimitry Andric 51281ad6265SDimitry Andric std::vector<uint8_t> Data; 51381ad6265SDimitry Andric 51481ad6265SDimitry Andric public: OwnedDataSection(StringRef SecName,ArrayRef<uint8_t> Data)51581ad6265SDimitry Andric OwnedDataSection(StringRef SecName, ArrayRef<uint8_t> Data) 51681ad6265SDimitry Andric : Data(std::begin(Data), std::end(Data)) { 51781ad6265SDimitry Andric Name = SecName.str(); 51881ad6265SDimitry Andric Type = OriginalType = ELF::SHT_PROGBITS; 51981ad6265SDimitry Andric Size = Data.size(); 52081ad6265SDimitry Andric OriginalOffset = std::numeric_limits<uint64_t>::max(); 52181ad6265SDimitry Andric } 52281ad6265SDimitry Andric OwnedDataSection(const Twine & SecName,uint64_t SecAddr,uint64_t SecFlags,uint64_t SecOff)52381ad6265SDimitry Andric OwnedDataSection(const Twine &SecName, uint64_t SecAddr, uint64_t SecFlags, 52481ad6265SDimitry Andric uint64_t SecOff) { 52581ad6265SDimitry Andric Name = SecName.str(); 52681ad6265SDimitry Andric Type = OriginalType = ELF::SHT_PROGBITS; 52781ad6265SDimitry Andric Addr = SecAddr; 52881ad6265SDimitry Andric Flags = OriginalFlags = SecFlags; 52981ad6265SDimitry Andric OriginalOffset = SecOff; 53081ad6265SDimitry Andric } 53181ad6265SDimitry Andric OwnedDataSection(SectionBase & S,ArrayRef<uint8_t> Data)53281ad6265SDimitry Andric OwnedDataSection(SectionBase &S, ArrayRef<uint8_t> Data) 53381ad6265SDimitry Andric : SectionBase(S), Data(std::begin(Data), std::end(Data)) { 53481ad6265SDimitry Andric Size = Data.size(); 53581ad6265SDimitry Andric } 53681ad6265SDimitry Andric 53781ad6265SDimitry Andric void appendHexData(StringRef HexData); 53881ad6265SDimitry Andric Error accept(SectionVisitor &Sec) const override; 53981ad6265SDimitry Andric Error accept(MutableSectionVisitor &Visitor) override; hasContents()54081ad6265SDimitry Andric bool hasContents() const override { return true; } 54181ad6265SDimitry Andric }; 54281ad6265SDimitry Andric 54381ad6265SDimitry Andric class CompressedSection : public SectionBase { 54481ad6265SDimitry Andric MAKE_SEC_WRITER_FRIEND 54581ad6265SDimitry Andric 546bdd1243dSDimitry Andric uint32_t ChType = 0; 54781ad6265SDimitry Andric DebugCompressionType CompressionType; 54881ad6265SDimitry Andric uint64_t DecompressedSize; 54981ad6265SDimitry Andric uint64_t DecompressedAlign; 550753f127fSDimitry Andric SmallVector<uint8_t, 128> CompressedData; 55181ad6265SDimitry Andric 55281ad6265SDimitry Andric public: 55381ad6265SDimitry Andric CompressedSection(const SectionBase &Sec, 554bdd1243dSDimitry Andric DebugCompressionType CompressionType, bool Is64Bits); 555bdd1243dSDimitry Andric CompressedSection(ArrayRef<uint8_t> CompressedData, uint32_t ChType, 556bdd1243dSDimitry Andric uint64_t DecompressedSize, uint64_t DecompressedAlign); 55781ad6265SDimitry Andric getDecompressedSize()55881ad6265SDimitry Andric uint64_t getDecompressedSize() const { return DecompressedSize; } getDecompressedAlign()55981ad6265SDimitry Andric uint64_t getDecompressedAlign() const { return DecompressedAlign; } getChType()560bdd1243dSDimitry Andric uint64_t getChType() const { return ChType; } 56181ad6265SDimitry Andric 56281ad6265SDimitry Andric Error accept(SectionVisitor &Visitor) const override; 56381ad6265SDimitry Andric Error accept(MutableSectionVisitor &Visitor) override; 56481ad6265SDimitry Andric classof(const SectionBase * S)56581ad6265SDimitry Andric static bool classof(const SectionBase *S) { 56681ad6265SDimitry Andric return S->OriginalFlags & ELF::SHF_COMPRESSED; 56781ad6265SDimitry Andric } 56881ad6265SDimitry Andric }; 56981ad6265SDimitry Andric 57081ad6265SDimitry Andric class DecompressedSection : public SectionBase { 57181ad6265SDimitry Andric MAKE_SEC_WRITER_FRIEND 57281ad6265SDimitry Andric 57381ad6265SDimitry Andric public: 574bdd1243dSDimitry Andric uint32_t ChType; DecompressedSection(const CompressedSection & Sec)57581ad6265SDimitry Andric explicit DecompressedSection(const CompressedSection &Sec) 576bdd1243dSDimitry Andric : SectionBase(Sec), ChType(Sec.getChType()) { 57781ad6265SDimitry Andric Size = Sec.getDecompressedSize(); 57881ad6265SDimitry Andric Align = Sec.getDecompressedAlign(); 57981ad6265SDimitry Andric Flags = OriginalFlags = (Flags & ~ELF::SHF_COMPRESSED); 58081ad6265SDimitry Andric } 58181ad6265SDimitry Andric 58281ad6265SDimitry Andric Error accept(SectionVisitor &Visitor) const override; 58381ad6265SDimitry Andric Error accept(MutableSectionVisitor &Visitor) override; 58481ad6265SDimitry Andric }; 58581ad6265SDimitry Andric 58681ad6265SDimitry Andric // There are two types of string tables that can exist, dynamic and not dynamic. 58781ad6265SDimitry Andric // In the dynamic case the string table is allocated. Changing a dynamic string 58881ad6265SDimitry Andric // table would mean altering virtual addresses and thus the memory image. So 58981ad6265SDimitry Andric // dynamic string tables should not have an interface to modify them or 59081ad6265SDimitry Andric // reconstruct them. This type lets us reconstruct a string table. To avoid 59181ad6265SDimitry Andric // this class being used for dynamic string tables (which has happened) the 59281ad6265SDimitry Andric // classof method checks that the particular instance is not allocated. This 59381ad6265SDimitry Andric // then agrees with the makeSection method used to construct most sections. 59481ad6265SDimitry Andric class StringTableSection : public SectionBase { 59581ad6265SDimitry Andric MAKE_SEC_WRITER_FRIEND 59681ad6265SDimitry Andric 59781ad6265SDimitry Andric StringTableBuilder StrTabBuilder; 59881ad6265SDimitry Andric 59981ad6265SDimitry Andric public: StringTableSection()60081ad6265SDimitry Andric StringTableSection() : StrTabBuilder(StringTableBuilder::ELF) { 60181ad6265SDimitry Andric Type = OriginalType = ELF::SHT_STRTAB; 60281ad6265SDimitry Andric } 60381ad6265SDimitry Andric 60481ad6265SDimitry Andric void addString(StringRef Name); 60581ad6265SDimitry Andric uint32_t findIndex(StringRef Name) const; 60681ad6265SDimitry Andric void prepareForLayout(); 60781ad6265SDimitry Andric Error accept(SectionVisitor &Visitor) const override; 60881ad6265SDimitry Andric Error accept(MutableSectionVisitor &Visitor) override; 60981ad6265SDimitry Andric classof(const SectionBase * S)61081ad6265SDimitry Andric static bool classof(const SectionBase *S) { 61181ad6265SDimitry Andric if (S->OriginalFlags & ELF::SHF_ALLOC) 61281ad6265SDimitry Andric return false; 61381ad6265SDimitry Andric return S->OriginalType == ELF::SHT_STRTAB; 61481ad6265SDimitry Andric } 61581ad6265SDimitry Andric }; 61681ad6265SDimitry Andric 61781ad6265SDimitry Andric // Symbols have a st_shndx field that normally stores an index but occasionally 61881ad6265SDimitry Andric // stores a different special value. This enum keeps track of what the st_shndx 61981ad6265SDimitry Andric // field means. Most of the values are just copies of the special SHN_* values. 62081ad6265SDimitry Andric // SYMBOL_SIMPLE_INDEX means that the st_shndx is just an index of a section. 62181ad6265SDimitry Andric enum SymbolShndxType { 62281ad6265SDimitry Andric SYMBOL_SIMPLE_INDEX = 0, 62381ad6265SDimitry Andric SYMBOL_ABS = ELF::SHN_ABS, 62481ad6265SDimitry Andric SYMBOL_COMMON = ELF::SHN_COMMON, 62581ad6265SDimitry Andric SYMBOL_LOPROC = ELF::SHN_LOPROC, 62681ad6265SDimitry Andric SYMBOL_AMDGPU_LDS = ELF::SHN_AMDGPU_LDS, 62781ad6265SDimitry Andric SYMBOL_HEXAGON_SCOMMON = ELF::SHN_HEXAGON_SCOMMON, 62881ad6265SDimitry Andric SYMBOL_HEXAGON_SCOMMON_2 = ELF::SHN_HEXAGON_SCOMMON_2, 62981ad6265SDimitry Andric SYMBOL_HEXAGON_SCOMMON_4 = ELF::SHN_HEXAGON_SCOMMON_4, 63081ad6265SDimitry Andric SYMBOL_HEXAGON_SCOMMON_8 = ELF::SHN_HEXAGON_SCOMMON_8, 63181ad6265SDimitry Andric SYMBOL_MIPS_ACOMMON = ELF::SHN_MIPS_ACOMMON, 63281ad6265SDimitry Andric SYMBOL_MIPS_TEXT = ELF::SHN_MIPS_TEXT, 63381ad6265SDimitry Andric SYMBOL_MIPS_DATA = ELF::SHN_MIPS_DATA, 63481ad6265SDimitry Andric SYMBOL_MIPS_SCOMMON = ELF::SHN_MIPS_SCOMMON, 63581ad6265SDimitry Andric SYMBOL_MIPS_SUNDEFINED = ELF::SHN_MIPS_SUNDEFINED, 63681ad6265SDimitry Andric SYMBOL_HIPROC = ELF::SHN_HIPROC, 63781ad6265SDimitry Andric SYMBOL_LOOS = ELF::SHN_LOOS, 63881ad6265SDimitry Andric SYMBOL_HIOS = ELF::SHN_HIOS, 63981ad6265SDimitry Andric SYMBOL_XINDEX = ELF::SHN_XINDEX, 64081ad6265SDimitry Andric }; 64181ad6265SDimitry Andric 64281ad6265SDimitry Andric struct Symbol { 64381ad6265SDimitry Andric uint8_t Binding; 64481ad6265SDimitry Andric SectionBase *DefinedIn = nullptr; 64581ad6265SDimitry Andric SymbolShndxType ShndxType; 64681ad6265SDimitry Andric uint32_t Index; 64781ad6265SDimitry Andric std::string Name; 64881ad6265SDimitry Andric uint32_t NameIndex; 64981ad6265SDimitry Andric uint64_t Size; 65081ad6265SDimitry Andric uint8_t Type; 65181ad6265SDimitry Andric uint64_t Value; 65281ad6265SDimitry Andric uint8_t Visibility; 65381ad6265SDimitry Andric bool Referenced = false; 65481ad6265SDimitry Andric 65581ad6265SDimitry Andric uint16_t getShndx() const; 65681ad6265SDimitry Andric bool isCommon() const; 65781ad6265SDimitry Andric }; 65881ad6265SDimitry Andric 65981ad6265SDimitry Andric class SectionIndexSection : public SectionBase { 66081ad6265SDimitry Andric MAKE_SEC_WRITER_FRIEND 66181ad6265SDimitry Andric 66281ad6265SDimitry Andric private: 66381ad6265SDimitry Andric std::vector<uint32_t> Indexes; 66481ad6265SDimitry Andric SymbolTableSection *Symbols = nullptr; 66581ad6265SDimitry Andric 66681ad6265SDimitry Andric public: ~SectionIndexSection()66781ad6265SDimitry Andric virtual ~SectionIndexSection() {} addIndex(uint32_t Index)66881ad6265SDimitry Andric void addIndex(uint32_t Index) { 66981ad6265SDimitry Andric assert(Size > 0); 67081ad6265SDimitry Andric Indexes.push_back(Index); 67181ad6265SDimitry Andric } 67281ad6265SDimitry Andric reserve(size_t NumSymbols)67381ad6265SDimitry Andric void reserve(size_t NumSymbols) { 67481ad6265SDimitry Andric Indexes.reserve(NumSymbols); 67581ad6265SDimitry Andric Size = NumSymbols * 4; 67681ad6265SDimitry Andric } setSymTab(SymbolTableSection * SymTab)67781ad6265SDimitry Andric void setSymTab(SymbolTableSection *SymTab) { Symbols = SymTab; } 67881ad6265SDimitry Andric Error initialize(SectionTableRef SecTable) override; 67981ad6265SDimitry Andric void finalize() override; 68081ad6265SDimitry Andric Error accept(SectionVisitor &Visitor) const override; 68181ad6265SDimitry Andric Error accept(MutableSectionVisitor &Visitor) override; 68281ad6265SDimitry Andric SectionIndexSection()68381ad6265SDimitry Andric SectionIndexSection() { 68481ad6265SDimitry Andric Name = ".symtab_shndx"; 68581ad6265SDimitry Andric Align = 4; 68681ad6265SDimitry Andric EntrySize = 4; 68781ad6265SDimitry Andric Type = OriginalType = ELF::SHT_SYMTAB_SHNDX; 68881ad6265SDimitry Andric } 68981ad6265SDimitry Andric }; 69081ad6265SDimitry Andric 69181ad6265SDimitry Andric class SymbolTableSection : public SectionBase { 69281ad6265SDimitry Andric MAKE_SEC_WRITER_FRIEND 69381ad6265SDimitry Andric setStrTab(StringTableSection * StrTab)69481ad6265SDimitry Andric void setStrTab(StringTableSection *StrTab) { SymbolNames = StrTab; } 69581ad6265SDimitry Andric void assignIndices(); 69681ad6265SDimitry Andric 69781ad6265SDimitry Andric protected: 69881ad6265SDimitry Andric std::vector<std::unique_ptr<Symbol>> Symbols; 69981ad6265SDimitry Andric StringTableSection *SymbolNames = nullptr; 70081ad6265SDimitry Andric SectionIndexSection *SectionIndexTable = nullptr; 70106c3fb27SDimitry Andric bool IndicesChanged = false; 70281ad6265SDimitry Andric 70381ad6265SDimitry Andric using SymPtr = std::unique_ptr<Symbol>; 70481ad6265SDimitry Andric 70581ad6265SDimitry Andric public: SymbolTableSection()70681ad6265SDimitry Andric SymbolTableSection() { Type = OriginalType = ELF::SHT_SYMTAB; } 70781ad6265SDimitry Andric 70881ad6265SDimitry Andric void addSymbol(Twine Name, uint8_t Bind, uint8_t Type, SectionBase *DefinedIn, 70981ad6265SDimitry Andric uint64_t Value, uint8_t Visibility, uint16_t Shndx, 71081ad6265SDimitry Andric uint64_t SymbolSize); 71181ad6265SDimitry Andric void prepareForLayout(); 71281ad6265SDimitry Andric // An 'empty' symbol table still contains a null symbol. empty()71381ad6265SDimitry Andric bool empty() const { return Symbols.size() == 1; } indicesChanged()71406c3fb27SDimitry Andric bool indicesChanged() const { return IndicesChanged; } setShndxTable(SectionIndexSection * ShndxTable)71581ad6265SDimitry Andric void setShndxTable(SectionIndexSection *ShndxTable) { 71681ad6265SDimitry Andric SectionIndexTable = ShndxTable; 71781ad6265SDimitry Andric } getShndxTable()71881ad6265SDimitry Andric const SectionIndexSection *getShndxTable() const { return SectionIndexTable; } 71981ad6265SDimitry Andric void fillShndxTable(); getStrTab()72081ad6265SDimitry Andric const SectionBase *getStrTab() const { return SymbolNames; } 72181ad6265SDimitry Andric Expected<const Symbol *> getSymbolByIndex(uint32_t Index) const; 72281ad6265SDimitry Andric Expected<Symbol *> getSymbolByIndex(uint32_t Index); 72381ad6265SDimitry Andric void updateSymbols(function_ref<void(Symbol &)> Callable); 72481ad6265SDimitry Andric 72581ad6265SDimitry Andric Error removeSectionReferences( 72681ad6265SDimitry Andric bool AllowBrokenLinks, 72781ad6265SDimitry Andric function_ref<bool(const SectionBase *)> ToRemove) override; 72881ad6265SDimitry Andric Error initialize(SectionTableRef SecTable) override; 72981ad6265SDimitry Andric void finalize() override; 73081ad6265SDimitry Andric Error accept(SectionVisitor &Visitor) const override; 73181ad6265SDimitry Andric Error accept(MutableSectionVisitor &Visitor) override; 73281ad6265SDimitry Andric Error removeSymbols(function_ref<bool(const Symbol &)> ToRemove) override; 73381ad6265SDimitry Andric void replaceSectionReferences( 73481ad6265SDimitry Andric const DenseMap<SectionBase *, SectionBase *> &FromTo) override; 73581ad6265SDimitry Andric classof(const SectionBase * S)73681ad6265SDimitry Andric static bool classof(const SectionBase *S) { 73781ad6265SDimitry Andric return S->OriginalType == ELF::SHT_SYMTAB; 73881ad6265SDimitry Andric } 73981ad6265SDimitry Andric }; 74081ad6265SDimitry Andric 74181ad6265SDimitry Andric struct Relocation { 74281ad6265SDimitry Andric Symbol *RelocSymbol = nullptr; 74381ad6265SDimitry Andric uint64_t Offset; 74481ad6265SDimitry Andric uint64_t Addend; 74581ad6265SDimitry Andric uint32_t Type; 74681ad6265SDimitry Andric }; 74781ad6265SDimitry Andric 74881ad6265SDimitry Andric // All relocation sections denote relocations to apply to another section. 74981ad6265SDimitry Andric // However, some relocation sections use a dynamic symbol table and others use 75081ad6265SDimitry Andric // a regular symbol table. Because the types of the two symbol tables differ in 75181ad6265SDimitry Andric // our system (because they should behave differently) we can't uniformly 75281ad6265SDimitry Andric // represent all relocations with the same base class if we expose an interface 75381ad6265SDimitry Andric // that mentions the symbol table type. So we split the two base types into two 75481ad6265SDimitry Andric // different classes, one which handles the section the relocation is applied to 75581ad6265SDimitry Andric // and another which handles the symbol table type. The symbol table type is 75681ad6265SDimitry Andric // taken as a type parameter to the class (see RelocSectionWithSymtabBase). 75781ad6265SDimitry Andric class RelocationSectionBase : public SectionBase { 75881ad6265SDimitry Andric protected: 75981ad6265SDimitry Andric SectionBase *SecToApplyRel = nullptr; 76081ad6265SDimitry Andric 76181ad6265SDimitry Andric public: getSection()76281ad6265SDimitry Andric const SectionBase *getSection() const { return SecToApplyRel; } setSection(SectionBase * Sec)76381ad6265SDimitry Andric void setSection(SectionBase *Sec) { SecToApplyRel = Sec; } 76481ad6265SDimitry Andric 76581ad6265SDimitry Andric StringRef getNamePrefix() const; 76681ad6265SDimitry Andric classof(const SectionBase * S)76781ad6265SDimitry Andric static bool classof(const SectionBase *S) { 76881ad6265SDimitry Andric return S->OriginalType == ELF::SHT_REL || S->OriginalType == ELF::SHT_RELA; 76981ad6265SDimitry Andric } 77081ad6265SDimitry Andric }; 77181ad6265SDimitry Andric 77281ad6265SDimitry Andric // Takes the symbol table type to use as a parameter so that we can deduplicate 77381ad6265SDimitry Andric // that code between the two symbol table types. 77481ad6265SDimitry Andric template <class SymTabType> 77581ad6265SDimitry Andric class RelocSectionWithSymtabBase : public RelocationSectionBase { setSymTab(SymTabType * SymTab)77681ad6265SDimitry Andric void setSymTab(SymTabType *SymTab) { Symbols = SymTab; } 77781ad6265SDimitry Andric 77881ad6265SDimitry Andric protected: 77981ad6265SDimitry Andric RelocSectionWithSymtabBase() = default; 78081ad6265SDimitry Andric 78181ad6265SDimitry Andric SymTabType *Symbols = nullptr; 78281ad6265SDimitry Andric 78381ad6265SDimitry Andric public: 78481ad6265SDimitry Andric Error initialize(SectionTableRef SecTable) override; 78581ad6265SDimitry Andric void finalize() override; 78681ad6265SDimitry Andric }; 78781ad6265SDimitry Andric 78881ad6265SDimitry Andric class RelocationSection 78981ad6265SDimitry Andric : public RelocSectionWithSymtabBase<SymbolTableSection> { 79081ad6265SDimitry Andric MAKE_SEC_WRITER_FRIEND 79181ad6265SDimitry Andric 79281ad6265SDimitry Andric std::vector<Relocation> Relocations; 79381ad6265SDimitry Andric const Object &Obj; 79481ad6265SDimitry Andric 79581ad6265SDimitry Andric public: RelocationSection(const Object & O)79681ad6265SDimitry Andric RelocationSection(const Object &O) : Obj(O) {} addRelocation(Relocation Rel)79781ad6265SDimitry Andric void addRelocation(Relocation Rel) { Relocations.push_back(Rel); } 79881ad6265SDimitry Andric Error accept(SectionVisitor &Visitor) const override; 79981ad6265SDimitry Andric Error accept(MutableSectionVisitor &Visitor) override; 80081ad6265SDimitry Andric Error removeSectionReferences( 80181ad6265SDimitry Andric bool AllowBrokenLinks, 80281ad6265SDimitry Andric function_ref<bool(const SectionBase *)> ToRemove) override; 80381ad6265SDimitry Andric Error removeSymbols(function_ref<bool(const Symbol &)> ToRemove) override; 80481ad6265SDimitry Andric void markSymbols() override; 80581ad6265SDimitry Andric void replaceSectionReferences( 80681ad6265SDimitry Andric const DenseMap<SectionBase *, SectionBase *> &FromTo) override; getObject()80781ad6265SDimitry Andric const Object &getObject() const { return Obj; } 80881ad6265SDimitry Andric classof(const SectionBase * S)80981ad6265SDimitry Andric static bool classof(const SectionBase *S) { 81081ad6265SDimitry Andric if (S->OriginalFlags & ELF::SHF_ALLOC) 81181ad6265SDimitry Andric return false; 81281ad6265SDimitry Andric return S->OriginalType == ELF::SHT_REL || S->OriginalType == ELF::SHT_RELA; 81381ad6265SDimitry Andric } 81481ad6265SDimitry Andric }; 81581ad6265SDimitry Andric 81681ad6265SDimitry Andric // TODO: The way stripping and groups interact is complicated 81781ad6265SDimitry Andric // and still needs to be worked on. 81881ad6265SDimitry Andric 81981ad6265SDimitry Andric class GroupSection : public SectionBase { 82081ad6265SDimitry Andric MAKE_SEC_WRITER_FRIEND 82181ad6265SDimitry Andric const SymbolTableSection *SymTab = nullptr; 82281ad6265SDimitry Andric Symbol *Sym = nullptr; 82381ad6265SDimitry Andric ELF::Elf32_Word FlagWord; 82481ad6265SDimitry Andric SmallVector<SectionBase *, 3> GroupMembers; 82581ad6265SDimitry Andric 82681ad6265SDimitry Andric public: 82781ad6265SDimitry Andric // TODO: Contents is present in several classes of the hierarchy. 82881ad6265SDimitry Andric // This needs to be refactored to avoid duplication. 82981ad6265SDimitry Andric ArrayRef<uint8_t> Contents; 83081ad6265SDimitry Andric GroupSection(ArrayRef<uint8_t> Data)83181ad6265SDimitry Andric explicit GroupSection(ArrayRef<uint8_t> Data) : Contents(Data) {} 83281ad6265SDimitry Andric setSymTab(const SymbolTableSection * SymTabSec)83381ad6265SDimitry Andric void setSymTab(const SymbolTableSection *SymTabSec) { SymTab = SymTabSec; } setSymbol(Symbol * S)83481ad6265SDimitry Andric void setSymbol(Symbol *S) { Sym = S; } setFlagWord(ELF::Elf32_Word W)83581ad6265SDimitry Andric void setFlagWord(ELF::Elf32_Word W) { FlagWord = W; } addMember(SectionBase * Sec)83681ad6265SDimitry Andric void addMember(SectionBase *Sec) { GroupMembers.push_back(Sec); } 83781ad6265SDimitry Andric 83881ad6265SDimitry Andric Error accept(SectionVisitor &) const override; 83981ad6265SDimitry Andric Error accept(MutableSectionVisitor &Visitor) override; 84081ad6265SDimitry Andric void finalize() override; 84181ad6265SDimitry Andric Error removeSectionReferences( 84281ad6265SDimitry Andric bool AllowBrokenLinks, 84381ad6265SDimitry Andric function_ref<bool(const SectionBase *)> ToRemove) override; 84481ad6265SDimitry Andric Error removeSymbols(function_ref<bool(const Symbol &)> ToRemove) override; 84581ad6265SDimitry Andric void markSymbols() override; 84681ad6265SDimitry Andric void replaceSectionReferences( 84781ad6265SDimitry Andric const DenseMap<SectionBase *, SectionBase *> &FromTo) override; 84881ad6265SDimitry Andric void onRemove() override; 84981ad6265SDimitry Andric classof(const SectionBase * S)85081ad6265SDimitry Andric static bool classof(const SectionBase *S) { 85181ad6265SDimitry Andric return S->OriginalType == ELF::SHT_GROUP; 85281ad6265SDimitry Andric } 85381ad6265SDimitry Andric }; 85481ad6265SDimitry Andric 85581ad6265SDimitry Andric class DynamicSymbolTableSection : public Section { 85681ad6265SDimitry Andric public: DynamicSymbolTableSection(ArrayRef<uint8_t> Data)85781ad6265SDimitry Andric explicit DynamicSymbolTableSection(ArrayRef<uint8_t> Data) : Section(Data) {} 85881ad6265SDimitry Andric classof(const SectionBase * S)85981ad6265SDimitry Andric static bool classof(const SectionBase *S) { 86081ad6265SDimitry Andric return S->OriginalType == ELF::SHT_DYNSYM; 86181ad6265SDimitry Andric } 86281ad6265SDimitry Andric }; 86381ad6265SDimitry Andric 86481ad6265SDimitry Andric class DynamicSection : public Section { 86581ad6265SDimitry Andric public: DynamicSection(ArrayRef<uint8_t> Data)86681ad6265SDimitry Andric explicit DynamicSection(ArrayRef<uint8_t> Data) : Section(Data) {} 86781ad6265SDimitry Andric classof(const SectionBase * S)86881ad6265SDimitry Andric static bool classof(const SectionBase *S) { 86981ad6265SDimitry Andric return S->OriginalType == ELF::SHT_DYNAMIC; 87081ad6265SDimitry Andric } 87181ad6265SDimitry Andric }; 87281ad6265SDimitry Andric 87381ad6265SDimitry Andric class DynamicRelocationSection 87481ad6265SDimitry Andric : public RelocSectionWithSymtabBase<DynamicSymbolTableSection> { 87581ad6265SDimitry Andric MAKE_SEC_WRITER_FRIEND 87681ad6265SDimitry Andric 87781ad6265SDimitry Andric private: 87881ad6265SDimitry Andric ArrayRef<uint8_t> Contents; 87981ad6265SDimitry Andric 88081ad6265SDimitry Andric public: DynamicRelocationSection(ArrayRef<uint8_t> Data)88181ad6265SDimitry Andric explicit DynamicRelocationSection(ArrayRef<uint8_t> Data) : Contents(Data) {} 88281ad6265SDimitry Andric 88381ad6265SDimitry Andric Error accept(SectionVisitor &) const override; 88481ad6265SDimitry Andric Error accept(MutableSectionVisitor &Visitor) override; 88581ad6265SDimitry Andric Error removeSectionReferences( 88681ad6265SDimitry Andric bool AllowBrokenLinks, 88781ad6265SDimitry Andric function_ref<bool(const SectionBase *)> ToRemove) override; 88881ad6265SDimitry Andric classof(const SectionBase * S)88981ad6265SDimitry Andric static bool classof(const SectionBase *S) { 89081ad6265SDimitry Andric if (!(S->OriginalFlags & ELF::SHF_ALLOC)) 89181ad6265SDimitry Andric return false; 89281ad6265SDimitry Andric return S->OriginalType == ELF::SHT_REL || S->OriginalType == ELF::SHT_RELA; 89381ad6265SDimitry Andric } 89481ad6265SDimitry Andric }; 89581ad6265SDimitry Andric 89681ad6265SDimitry Andric class GnuDebugLinkSection : public SectionBase { 89781ad6265SDimitry Andric MAKE_SEC_WRITER_FRIEND 89881ad6265SDimitry Andric 89981ad6265SDimitry Andric private: 90081ad6265SDimitry Andric StringRef FileName; 90181ad6265SDimitry Andric uint32_t CRC32; 90281ad6265SDimitry Andric 90381ad6265SDimitry Andric void init(StringRef File); 90481ad6265SDimitry Andric 90581ad6265SDimitry Andric public: 90681ad6265SDimitry Andric // If we add this section from an external source we can use this ctor. 90781ad6265SDimitry Andric explicit GnuDebugLinkSection(StringRef File, uint32_t PrecomputedCRC); 90881ad6265SDimitry Andric Error accept(SectionVisitor &Visitor) const override; 90981ad6265SDimitry Andric Error accept(MutableSectionVisitor &Visitor) override; 91081ad6265SDimitry Andric }; 91181ad6265SDimitry Andric 91281ad6265SDimitry Andric class Reader { 91381ad6265SDimitry Andric public: 91481ad6265SDimitry Andric virtual ~Reader(); 91581ad6265SDimitry Andric virtual Expected<std::unique_ptr<Object>> create(bool EnsureSymtab) const = 0; 91681ad6265SDimitry Andric }; 91781ad6265SDimitry Andric 91881ad6265SDimitry Andric using object::Binary; 91981ad6265SDimitry Andric using object::ELFFile; 92081ad6265SDimitry Andric using object::ELFObjectFile; 92181ad6265SDimitry Andric using object::OwningBinary; 92281ad6265SDimitry Andric 92381ad6265SDimitry Andric class BasicELFBuilder { 92481ad6265SDimitry Andric protected: 92581ad6265SDimitry Andric std::unique_ptr<Object> Obj; 92681ad6265SDimitry Andric 92781ad6265SDimitry Andric void initFileHeader(); 92881ad6265SDimitry Andric void initHeaderSegment(); 92981ad6265SDimitry Andric StringTableSection *addStrTab(); 93081ad6265SDimitry Andric SymbolTableSection *addSymTab(StringTableSection *StrTab); 93181ad6265SDimitry Andric Error initSections(); 93281ad6265SDimitry Andric 93381ad6265SDimitry Andric public: BasicELFBuilder()93481ad6265SDimitry Andric BasicELFBuilder() : Obj(std::make_unique<Object>()) {} 93581ad6265SDimitry Andric }; 93681ad6265SDimitry Andric 93781ad6265SDimitry Andric class BinaryELFBuilder : public BasicELFBuilder { 93881ad6265SDimitry Andric MemoryBuffer *MemBuf; 93981ad6265SDimitry Andric uint8_t NewSymbolVisibility; 94081ad6265SDimitry Andric void addData(SymbolTableSection *SymTab); 94181ad6265SDimitry Andric 94281ad6265SDimitry Andric public: BinaryELFBuilder(MemoryBuffer * MB,uint8_t NewSymbolVisibility)94381ad6265SDimitry Andric BinaryELFBuilder(MemoryBuffer *MB, uint8_t NewSymbolVisibility) 94481ad6265SDimitry Andric : MemBuf(MB), NewSymbolVisibility(NewSymbolVisibility) {} 94581ad6265SDimitry Andric 94681ad6265SDimitry Andric Expected<std::unique_ptr<Object>> build(); 94781ad6265SDimitry Andric }; 94881ad6265SDimitry Andric 94981ad6265SDimitry Andric class IHexELFBuilder : public BasicELFBuilder { 95081ad6265SDimitry Andric const std::vector<IHexRecord> &Records; 95181ad6265SDimitry Andric 95281ad6265SDimitry Andric void addDataSections(); 95381ad6265SDimitry Andric 95481ad6265SDimitry Andric public: IHexELFBuilder(const std::vector<IHexRecord> & Records)95581ad6265SDimitry Andric IHexELFBuilder(const std::vector<IHexRecord> &Records) : Records(Records) {} 95681ad6265SDimitry Andric 95781ad6265SDimitry Andric Expected<std::unique_ptr<Object>> build(); 95881ad6265SDimitry Andric }; 95981ad6265SDimitry Andric 96081ad6265SDimitry Andric template <class ELFT> class ELFBuilder { 96181ad6265SDimitry Andric private: 96281ad6265SDimitry Andric using Elf_Addr = typename ELFT::Addr; 96381ad6265SDimitry Andric using Elf_Shdr = typename ELFT::Shdr; 96481ad6265SDimitry Andric using Elf_Word = typename ELFT::Word; 96581ad6265SDimitry Andric 96681ad6265SDimitry Andric const ELFFile<ELFT> &ElfFile; 96781ad6265SDimitry Andric Object &Obj; 96881ad6265SDimitry Andric size_t EhdrOffset = 0; 969bdd1243dSDimitry Andric std::optional<StringRef> ExtractPartition; 97081ad6265SDimitry Andric 97181ad6265SDimitry Andric void setParentSegment(Segment &Child); 97281ad6265SDimitry Andric Error readProgramHeaders(const ELFFile<ELFT> &HeadersFile); 97381ad6265SDimitry Andric Error initGroupSection(GroupSection *GroupSec); 97481ad6265SDimitry Andric Error initSymbolTable(SymbolTableSection *SymTab); 97581ad6265SDimitry Andric Error readSectionHeaders(); 97681ad6265SDimitry Andric Error readSections(bool EnsureSymtab); 97781ad6265SDimitry Andric Error findEhdrOffset(); 97881ad6265SDimitry Andric Expected<SectionBase &> makeSection(const Elf_Shdr &Shdr); 97981ad6265SDimitry Andric 98081ad6265SDimitry Andric public: 98181ad6265SDimitry Andric ELFBuilder(const ELFObjectFile<ELFT> &ElfObj, Object &Obj, 982bdd1243dSDimitry Andric std::optional<StringRef> ExtractPartition); 98381ad6265SDimitry Andric 98481ad6265SDimitry Andric Error build(bool EnsureSymtab); 98581ad6265SDimitry Andric }; 98681ad6265SDimitry Andric 98781ad6265SDimitry Andric class BinaryReader : public Reader { 98881ad6265SDimitry Andric MemoryBuffer *MemBuf; 98981ad6265SDimitry Andric uint8_t NewSymbolVisibility; 99081ad6265SDimitry Andric 99181ad6265SDimitry Andric public: BinaryReader(MemoryBuffer * MB,const uint8_t NewSymbolVisibility)99281ad6265SDimitry Andric BinaryReader(MemoryBuffer *MB, const uint8_t NewSymbolVisibility) 99381ad6265SDimitry Andric : MemBuf(MB), NewSymbolVisibility(NewSymbolVisibility) {} 99481ad6265SDimitry Andric Expected<std::unique_ptr<Object>> create(bool EnsureSymtab) const override; 99581ad6265SDimitry Andric }; 99681ad6265SDimitry Andric 99781ad6265SDimitry Andric class IHexReader : public Reader { 99881ad6265SDimitry Andric MemoryBuffer *MemBuf; 99981ad6265SDimitry Andric 100081ad6265SDimitry Andric Expected<std::vector<IHexRecord>> parse() const; parseError(size_t LineNo,Error E)100181ad6265SDimitry Andric Error parseError(size_t LineNo, Error E) const { 100281ad6265SDimitry Andric return LineNo == -1U 100381ad6265SDimitry Andric ? createFileError(MemBuf->getBufferIdentifier(), std::move(E)) 100481ad6265SDimitry Andric : createFileError(MemBuf->getBufferIdentifier(), LineNo, 100581ad6265SDimitry Andric std::move(E)); 100681ad6265SDimitry Andric } 100781ad6265SDimitry Andric template <typename... Ts> parseError(size_t LineNo,char const * Fmt,const Ts &...Vals)100881ad6265SDimitry Andric Error parseError(size_t LineNo, char const *Fmt, const Ts &...Vals) const { 100981ad6265SDimitry Andric Error E = createStringError(errc::invalid_argument, Fmt, Vals...); 101081ad6265SDimitry Andric return parseError(LineNo, std::move(E)); 101181ad6265SDimitry Andric } 101281ad6265SDimitry Andric 101381ad6265SDimitry Andric public: IHexReader(MemoryBuffer * MB)101481ad6265SDimitry Andric IHexReader(MemoryBuffer *MB) : MemBuf(MB) {} 101581ad6265SDimitry Andric 101681ad6265SDimitry Andric Expected<std::unique_ptr<Object>> create(bool EnsureSymtab) const override; 101781ad6265SDimitry Andric }; 101881ad6265SDimitry Andric 101981ad6265SDimitry Andric class ELFReader : public Reader { 102081ad6265SDimitry Andric Binary *Bin; 1021bdd1243dSDimitry Andric std::optional<StringRef> ExtractPartition; 102281ad6265SDimitry Andric 102381ad6265SDimitry Andric public: 102481ad6265SDimitry Andric Expected<std::unique_ptr<Object>> create(bool EnsureSymtab) const override; ELFReader(Binary * B,std::optional<StringRef> ExtractPartition)1025bdd1243dSDimitry Andric explicit ELFReader(Binary *B, std::optional<StringRef> ExtractPartition) 102681ad6265SDimitry Andric : Bin(B), ExtractPartition(ExtractPartition) {} 102781ad6265SDimitry Andric }; 102881ad6265SDimitry Andric 102981ad6265SDimitry Andric class Object { 103081ad6265SDimitry Andric private: 103181ad6265SDimitry Andric using SecPtr = std::unique_ptr<SectionBase>; 103281ad6265SDimitry Andric using SegPtr = std::unique_ptr<Segment>; 103381ad6265SDimitry Andric 103481ad6265SDimitry Andric std::vector<SecPtr> Sections; 103581ad6265SDimitry Andric std::vector<SegPtr> Segments; 103681ad6265SDimitry Andric std::vector<SecPtr> RemovedSections; 103781ad6265SDimitry Andric DenseMap<SectionBase *, std::vector<uint8_t>> UpdatedSections; 103881ad6265SDimitry Andric sectionIsAlloc(const SectionBase & Sec)103981ad6265SDimitry Andric static bool sectionIsAlloc(const SectionBase &Sec) { 104081ad6265SDimitry Andric return Sec.Flags & ELF::SHF_ALLOC; 104181ad6265SDimitry Andric }; 104281ad6265SDimitry Andric 104381ad6265SDimitry Andric public: 104481ad6265SDimitry Andric template <class T> 104581ad6265SDimitry Andric using ConstRange = iterator_range<pointee_iterator< 104681ad6265SDimitry Andric typename std::vector<std::unique_ptr<T>>::const_iterator>>; 104781ad6265SDimitry Andric 104881ad6265SDimitry Andric // It is often the case that the ELF header and the program header table are 104981ad6265SDimitry Andric // not present in any segment. This could be a problem during file layout, 105081ad6265SDimitry Andric // because other segments may get assigned an offset where either of the 105181ad6265SDimitry Andric // two should reside, which will effectively corrupt the resulting binary. 105281ad6265SDimitry Andric // Other than that we use these segments to track program header offsets 105381ad6265SDimitry Andric // when they may not follow the ELF header. 105481ad6265SDimitry Andric Segment ElfHdrSegment; 105581ad6265SDimitry Andric Segment ProgramHdrSegment; 105681ad6265SDimitry Andric 1057bdd1243dSDimitry Andric bool Is64Bits; 105881ad6265SDimitry Andric uint8_t OSABI; 105981ad6265SDimitry Andric uint8_t ABIVersion; 106081ad6265SDimitry Andric uint64_t Entry; 106181ad6265SDimitry Andric uint64_t SHOff; 106281ad6265SDimitry Andric uint32_t Type; 106381ad6265SDimitry Andric uint32_t Machine; 106481ad6265SDimitry Andric uint32_t Version; 106581ad6265SDimitry Andric uint32_t Flags; 106681ad6265SDimitry Andric 106781ad6265SDimitry Andric bool HadShdrs = true; 106881ad6265SDimitry Andric bool MustBeRelocatable = false; 106981ad6265SDimitry Andric StringTableSection *SectionNames = nullptr; 107081ad6265SDimitry Andric SymbolTableSection *SymbolTable = nullptr; 107181ad6265SDimitry Andric SectionIndexSection *SectionIndexTable = nullptr; 107281ad6265SDimitry Andric 107381ad6265SDimitry Andric bool IsMips64EL = false; 107481ad6265SDimitry Andric sections()107581ad6265SDimitry Andric SectionTableRef sections() const { return SectionTableRef(Sections); } 107681ad6265SDimitry Andric iterator_range< 107781ad6265SDimitry Andric filter_iterator<pointee_iterator<std::vector<SecPtr>::const_iterator>, 107881ad6265SDimitry Andric decltype(§ionIsAlloc)>> allocSections()107981ad6265SDimitry Andric allocSections() const { 108081ad6265SDimitry Andric return make_filter_range(make_pointee_range(Sections), sectionIsAlloc); 108181ad6265SDimitry Andric } 108281ad6265SDimitry Andric getUpdatedSections()108381ad6265SDimitry Andric const auto &getUpdatedSections() const { return UpdatedSections; } 108481ad6265SDimitry Andric Error updateSection(StringRef Name, ArrayRef<uint8_t> Data); 108581ad6265SDimitry Andric findSection(StringRef Name)108681ad6265SDimitry Andric SectionBase *findSection(StringRef Name) { 108781ad6265SDimitry Andric auto SecIt = 108881ad6265SDimitry Andric find_if(Sections, [&](const SecPtr &Sec) { return Sec->Name == Name; }); 108981ad6265SDimitry Andric return SecIt == Sections.end() ? nullptr : SecIt->get(); 109081ad6265SDimitry Andric } removedSections()109181ad6265SDimitry Andric SectionTableRef removedSections() { return SectionTableRef(RemovedSections); } 109281ad6265SDimitry Andric segments()109381ad6265SDimitry Andric ConstRange<Segment> segments() const { return make_pointee_range(Segments); } 109481ad6265SDimitry Andric 109581ad6265SDimitry Andric Error removeSections(bool AllowBrokenLinks, 109681ad6265SDimitry Andric std::function<bool(const SectionBase &)> ToRemove); 109781ad6265SDimitry Andric Error replaceSections(const DenseMap<SectionBase *, SectionBase *> &FromTo); 109881ad6265SDimitry Andric Error removeSymbols(function_ref<bool(const Symbol &)> ToRemove); addSection(Ts &&...Args)109981ad6265SDimitry Andric template <class T, class... Ts> T &addSection(Ts &&...Args) { 110081ad6265SDimitry Andric auto Sec = std::make_unique<T>(std::forward<Ts>(Args)...); 110181ad6265SDimitry Andric auto Ptr = Sec.get(); 110281ad6265SDimitry Andric MustBeRelocatable |= isa<RelocationSection>(*Ptr); 110381ad6265SDimitry Andric Sections.emplace_back(std::move(Sec)); 110481ad6265SDimitry Andric Ptr->Index = Sections.size(); 110581ad6265SDimitry Andric return *Ptr; 110681ad6265SDimitry Andric } 110781ad6265SDimitry Andric Error addNewSymbolTable(); addSegment(ArrayRef<uint8_t> Data)110881ad6265SDimitry Andric Segment &addSegment(ArrayRef<uint8_t> Data) { 110981ad6265SDimitry Andric Segments.emplace_back(std::make_unique<Segment>(Data)); 111081ad6265SDimitry Andric return *Segments.back(); 111181ad6265SDimitry Andric } isRelocatable()111281ad6265SDimitry Andric bool isRelocatable() const { 111381ad6265SDimitry Andric return (Type != ELF::ET_DYN && Type != ELF::ET_EXEC) || MustBeRelocatable; 111481ad6265SDimitry Andric } 111581ad6265SDimitry Andric }; 111681ad6265SDimitry Andric 111781ad6265SDimitry Andric } // end namespace elf 111881ad6265SDimitry Andric } // end namespace objcopy 111981ad6265SDimitry Andric } // end namespace llvm 112081ad6265SDimitry Andric 112181ad6265SDimitry Andric #endif // LLVM_LIB_OBJCOPY_ELF_ELFOBJECT_H 1122