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 5681ad6265SDimitry Andric explicit SectionTableRef(ArrayRef<std::unique_ptr<SectionBase>> Secs) 5781ad6265SDimitry Andric : Sections(Secs) {} 5881ad6265SDimitry Andric SectionTableRef(const SectionTableRef &) = default; 5981ad6265SDimitry Andric 6081ad6265SDimitry Andric iterator begin() const { return iterator(Sections.data()); } 6181ad6265SDimitry Andric iterator end() const { return iterator(Sections.data() + Sections.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 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: 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 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; \ 175*0fca6ea1SDimitry Andric friend class SRECSectionWriter; \ 176*0fca6ea1SDimitry Andric friend class SRECSectionWriterBase; \ 177*0fca6ea1SDimitry Andric friend class SRECSizeCalculator; \ 17881ad6265SDimitry Andric template <class ELFT> friend class ELFSectionWriter; \ 17981ad6265SDimitry Andric template <class ELFT> friend class ELFSectionSizer; 18081ad6265SDimitry Andric 18181ad6265SDimitry Andric class BinarySectionWriter : public SectionWriter { 18281ad6265SDimitry Andric public: 18381ad6265SDimitry Andric virtual ~BinarySectionWriter() {} 18481ad6265SDimitry Andric 18581ad6265SDimitry Andric Error visit(const SymbolTableSection &Sec) override; 18681ad6265SDimitry Andric Error visit(const RelocationSection &Sec) override; 18781ad6265SDimitry Andric Error visit(const GnuDebugLinkSection &Sec) override; 18881ad6265SDimitry Andric Error visit(const GroupSection &Sec) override; 18981ad6265SDimitry Andric Error visit(const SectionIndexSection &Sec) override; 19081ad6265SDimitry Andric Error visit(const CompressedSection &Sec) override; 19181ad6265SDimitry Andric Error visit(const DecompressedSection &Sec) override; 19281ad6265SDimitry Andric 19381ad6265SDimitry Andric explicit BinarySectionWriter(WritableMemoryBuffer &Buf) 19481ad6265SDimitry Andric : SectionWriter(Buf) {} 19581ad6265SDimitry Andric }; 19681ad6265SDimitry Andric 19781ad6265SDimitry Andric using IHexLineData = SmallVector<char, 64>; 19881ad6265SDimitry Andric 19981ad6265SDimitry Andric struct IHexRecord { 20081ad6265SDimitry Andric // Memory address of the record. 20181ad6265SDimitry Andric uint16_t Addr; 20281ad6265SDimitry Andric // Record type (see below). 20381ad6265SDimitry Andric uint16_t Type; 20481ad6265SDimitry Andric // Record data in hexadecimal form. 20581ad6265SDimitry Andric StringRef HexData; 20681ad6265SDimitry Andric 20781ad6265SDimitry Andric // Helper method to get file length of the record 20881ad6265SDimitry Andric // including newline character 20981ad6265SDimitry Andric static size_t getLength(size_t DataSize) { 21081ad6265SDimitry Andric // :LLAAAATT[DD...DD]CC' 21181ad6265SDimitry Andric return DataSize * 2 + 11; 21281ad6265SDimitry Andric } 21381ad6265SDimitry Andric 21481ad6265SDimitry Andric // Gets length of line in a file (getLength + CRLF). 21581ad6265SDimitry Andric static size_t getLineLength(size_t DataSize) { 21681ad6265SDimitry Andric return getLength(DataSize) + 2; 21781ad6265SDimitry Andric } 21881ad6265SDimitry Andric 21981ad6265SDimitry Andric // Given type, address and data returns line which can 22081ad6265SDimitry Andric // be written to output file. 22181ad6265SDimitry Andric static IHexLineData getLine(uint8_t Type, uint16_t Addr, 22281ad6265SDimitry Andric ArrayRef<uint8_t> Data); 22381ad6265SDimitry Andric 22481ad6265SDimitry Andric // Parses the line and returns record if possible. 22581ad6265SDimitry Andric // Line should be trimmed from whitespace characters. 22681ad6265SDimitry Andric static Expected<IHexRecord> parse(StringRef Line); 22781ad6265SDimitry Andric 22881ad6265SDimitry Andric // Calculates checksum of stringified record representation 22981ad6265SDimitry Andric // S must NOT contain leading ':' and trailing whitespace 23081ad6265SDimitry Andric // characters 23181ad6265SDimitry Andric static uint8_t getChecksum(StringRef S); 23281ad6265SDimitry Andric 23381ad6265SDimitry Andric enum Type { 23481ad6265SDimitry Andric // Contains data and a 16-bit starting address for the data. 23581ad6265SDimitry Andric // The byte count specifies number of data bytes in the record. 23681ad6265SDimitry Andric Data = 0, 23781ad6265SDimitry Andric // Must occur exactly once per file in the last line of the file. 23881ad6265SDimitry Andric // The data field is empty (thus byte count is 00) and the address 23981ad6265SDimitry Andric // field is typically 0000. 24081ad6265SDimitry Andric EndOfFile = 1, 24181ad6265SDimitry Andric // The data field contains a 16-bit segment base address (thus byte 24281ad6265SDimitry Andric // count is always 02) compatible with 80x86 real mode addressing. 24381ad6265SDimitry Andric // The address field (typically 0000) is ignored. The segment address 24481ad6265SDimitry Andric // from the most recent 02 record is multiplied by 16 and added to each 24581ad6265SDimitry Andric // subsequent data record address to form the physical starting address 24681ad6265SDimitry Andric // for the data. This allows addressing up to one megabyte of address 24781ad6265SDimitry Andric // space. 24881ad6265SDimitry Andric SegmentAddr = 2, 24981ad6265SDimitry Andric // or 80x86 processors, specifies the initial content of the CS:IP 25081ad6265SDimitry Andric // registers. The address field is 0000, the byte count is always 04, 25181ad6265SDimitry Andric // the first two data bytes are the CS value, the latter two are the 25281ad6265SDimitry Andric // IP value. 25381ad6265SDimitry Andric StartAddr80x86 = 3, 25481ad6265SDimitry Andric // Allows for 32 bit addressing (up to 4GiB). The record's address field 25581ad6265SDimitry Andric // is ignored (typically 0000) and its byte count is always 02. The two 25681ad6265SDimitry Andric // data bytes (big endian) specify the upper 16 bits of the 32 bit 25781ad6265SDimitry Andric // absolute address for all subsequent type 00 records 25881ad6265SDimitry Andric ExtendedAddr = 4, 25981ad6265SDimitry Andric // The address field is 0000 (not used) and the byte count is always 04. 26081ad6265SDimitry Andric // The four data bytes represent a 32-bit address value. In the case of 26181ad6265SDimitry Andric // 80386 and higher CPUs, this address is loaded into the EIP register. 26281ad6265SDimitry Andric StartAddr = 5, 26381ad6265SDimitry Andric // We have no other valid types 26481ad6265SDimitry Andric InvalidType = 6 26581ad6265SDimitry Andric }; 26681ad6265SDimitry Andric }; 26781ad6265SDimitry Andric 26881ad6265SDimitry Andric // Base class for IHexSectionWriter. This class implements writing algorithm, 26981ad6265SDimitry Andric // but doesn't actually write records. It is used for output buffer size 27081ad6265SDimitry Andric // calculation in IHexWriter::finalize. 27181ad6265SDimitry Andric class IHexSectionWriterBase : public BinarySectionWriter { 27281ad6265SDimitry Andric // 20-bit segment address 27381ad6265SDimitry Andric uint32_t SegmentAddr = 0; 27481ad6265SDimitry Andric // Extended linear address 27581ad6265SDimitry Andric uint32_t BaseAddr = 0; 27681ad6265SDimitry Andric 27781ad6265SDimitry Andric // Write segment address corresponding to 'Addr' 27881ad6265SDimitry Andric uint64_t writeSegmentAddr(uint64_t Addr); 27981ad6265SDimitry Andric // Write extended linear (base) address corresponding to 'Addr' 28081ad6265SDimitry Andric uint64_t writeBaseAddr(uint64_t Addr); 28181ad6265SDimitry Andric 28281ad6265SDimitry Andric protected: 28381ad6265SDimitry Andric // Offset in the output buffer 28481ad6265SDimitry Andric uint64_t Offset = 0; 28581ad6265SDimitry Andric 28681ad6265SDimitry Andric void writeSection(const SectionBase *Sec, ArrayRef<uint8_t> Data); 28781ad6265SDimitry Andric virtual void writeData(uint8_t Type, uint16_t Addr, ArrayRef<uint8_t> Data); 28881ad6265SDimitry Andric 28981ad6265SDimitry Andric public: 29081ad6265SDimitry Andric explicit IHexSectionWriterBase(WritableMemoryBuffer &Buf) 29181ad6265SDimitry Andric : BinarySectionWriter(Buf) {} 29281ad6265SDimitry Andric 29381ad6265SDimitry Andric uint64_t getBufferOffset() const { return Offset; } 29481ad6265SDimitry Andric Error visit(const Section &Sec) final; 29581ad6265SDimitry Andric Error visit(const OwnedDataSection &Sec) final; 29681ad6265SDimitry Andric Error visit(const StringTableSection &Sec) override; 29781ad6265SDimitry Andric Error visit(const DynamicRelocationSection &Sec) final; 29881ad6265SDimitry Andric using BinarySectionWriter::visit; 29981ad6265SDimitry Andric }; 30081ad6265SDimitry Andric 30181ad6265SDimitry Andric // Real IHEX section writer 30281ad6265SDimitry Andric class IHexSectionWriter : public IHexSectionWriterBase { 30381ad6265SDimitry Andric public: 30481ad6265SDimitry Andric IHexSectionWriter(WritableMemoryBuffer &Buf) : IHexSectionWriterBase(Buf) {} 30581ad6265SDimitry Andric 30681ad6265SDimitry Andric void writeData(uint8_t Type, uint16_t Addr, ArrayRef<uint8_t> Data) override; 30781ad6265SDimitry Andric Error visit(const StringTableSection &Sec) override; 30881ad6265SDimitry Andric }; 30981ad6265SDimitry Andric 31081ad6265SDimitry Andric class Writer { 31181ad6265SDimitry Andric protected: 31281ad6265SDimitry Andric Object &Obj; 31381ad6265SDimitry Andric std::unique_ptr<WritableMemoryBuffer> Buf; 31481ad6265SDimitry Andric raw_ostream &Out; 31581ad6265SDimitry Andric 31681ad6265SDimitry Andric public: 31781ad6265SDimitry Andric virtual ~Writer(); 31881ad6265SDimitry Andric virtual Error finalize() = 0; 31981ad6265SDimitry Andric virtual Error write() = 0; 32081ad6265SDimitry Andric 32181ad6265SDimitry Andric Writer(Object &O, raw_ostream &Out) : Obj(O), Out(Out) {} 32281ad6265SDimitry Andric }; 32381ad6265SDimitry Andric 32481ad6265SDimitry Andric template <class ELFT> class ELFWriter : public Writer { 32581ad6265SDimitry Andric private: 32681ad6265SDimitry Andric using Elf_Addr = typename ELFT::Addr; 32781ad6265SDimitry Andric using Elf_Shdr = typename ELFT::Shdr; 32881ad6265SDimitry Andric using Elf_Phdr = typename ELFT::Phdr; 32981ad6265SDimitry Andric using Elf_Ehdr = typename ELFT::Ehdr; 33081ad6265SDimitry Andric 33181ad6265SDimitry Andric void initEhdrSegment(); 33281ad6265SDimitry Andric 33381ad6265SDimitry Andric void writeEhdr(); 33481ad6265SDimitry Andric void writePhdr(const Segment &Seg); 33581ad6265SDimitry Andric void writeShdr(const SectionBase &Sec); 33681ad6265SDimitry Andric 33781ad6265SDimitry Andric void writePhdrs(); 33881ad6265SDimitry Andric void writeShdrs(); 33981ad6265SDimitry Andric Error writeSectionData(); 34081ad6265SDimitry Andric void writeSegmentData(); 34181ad6265SDimitry Andric 34281ad6265SDimitry Andric void assignOffsets(); 34381ad6265SDimitry Andric 34481ad6265SDimitry Andric std::unique_ptr<ELFSectionWriter<ELFT>> SecWriter; 34581ad6265SDimitry Andric 34681ad6265SDimitry Andric size_t totalSize() const; 34781ad6265SDimitry Andric 34881ad6265SDimitry Andric public: 34981ad6265SDimitry Andric virtual ~ELFWriter() {} 35081ad6265SDimitry Andric bool WriteSectionHeaders; 35181ad6265SDimitry Andric 35281ad6265SDimitry Andric // For --only-keep-debug, select an alternative section/segment layout 35381ad6265SDimitry Andric // algorithm. 35481ad6265SDimitry Andric bool OnlyKeepDebug; 35581ad6265SDimitry Andric 35681ad6265SDimitry Andric Error finalize() override; 35781ad6265SDimitry Andric Error write() override; 35881ad6265SDimitry Andric ELFWriter(Object &Obj, raw_ostream &Out, bool WSH, bool OnlyKeepDebug); 35981ad6265SDimitry Andric }; 36081ad6265SDimitry Andric 36181ad6265SDimitry Andric class BinaryWriter : public Writer { 36281ad6265SDimitry Andric private: 3635f757f3fSDimitry Andric const uint8_t GapFill; 3645f757f3fSDimitry Andric const uint64_t PadTo; 36581ad6265SDimitry Andric std::unique_ptr<BinarySectionWriter> SecWriter; 36681ad6265SDimitry Andric 36781ad6265SDimitry Andric uint64_t TotalSize = 0; 36881ad6265SDimitry Andric 36981ad6265SDimitry Andric public: 37081ad6265SDimitry Andric ~BinaryWriter() {} 37181ad6265SDimitry Andric Error finalize() override; 37281ad6265SDimitry Andric Error write() override; 3735f757f3fSDimitry Andric BinaryWriter(Object &Obj, raw_ostream &Out, const CommonConfig &Config) 3745f757f3fSDimitry Andric : Writer(Obj, Out), GapFill(Config.GapFill), PadTo(Config.PadTo) {} 37581ad6265SDimitry Andric }; 37681ad6265SDimitry Andric 377*0fca6ea1SDimitry Andric // A base class for writing ascii hex formats such as srec and ihex. 378*0fca6ea1SDimitry Andric class ASCIIHexWriter : public Writer { 379*0fca6ea1SDimitry Andric public: 380*0fca6ea1SDimitry Andric ASCIIHexWriter(Object &Obj, raw_ostream &OS, StringRef OutputFile) 381*0fca6ea1SDimitry Andric : Writer(Obj, OS), OutputFileName(OutputFile) {} 382*0fca6ea1SDimitry Andric Error finalize() override; 383*0fca6ea1SDimitry Andric 384*0fca6ea1SDimitry Andric protected: 385*0fca6ea1SDimitry Andric StringRef OutputFileName; 386*0fca6ea1SDimitry Andric size_t TotalSize = 0; 387*0fca6ea1SDimitry Andric std::vector<const SectionBase *> Sections; 388*0fca6ea1SDimitry Andric 389*0fca6ea1SDimitry Andric Error checkSection(const SectionBase &S) const; 390*0fca6ea1SDimitry Andric virtual Expected<size_t> 391*0fca6ea1SDimitry Andric getTotalSize(WritableMemoryBuffer &EmptyBuffer) const = 0; 39281ad6265SDimitry Andric }; 39381ad6265SDimitry Andric 394*0fca6ea1SDimitry Andric class IHexWriter : public ASCIIHexWriter { 395*0fca6ea1SDimitry Andric public: 396*0fca6ea1SDimitry Andric Error write() override; 397*0fca6ea1SDimitry Andric IHexWriter(Object &Obj, raw_ostream &Out, StringRef OutputFile) 398*0fca6ea1SDimitry Andric : ASCIIHexWriter(Obj, Out, OutputFile) {} 39981ad6265SDimitry Andric 400*0fca6ea1SDimitry Andric private: 40181ad6265SDimitry Andric uint64_t writeEntryPointRecord(uint8_t *Buf); 40281ad6265SDimitry Andric uint64_t writeEndOfFileRecord(uint8_t *Buf); 403*0fca6ea1SDimitry Andric Expected<size_t> 404*0fca6ea1SDimitry Andric getTotalSize(WritableMemoryBuffer &EmptyBuffer) const override; 405*0fca6ea1SDimitry Andric }; 40681ad6265SDimitry Andric 407*0fca6ea1SDimitry Andric class SRECWriter : public ASCIIHexWriter { 40881ad6265SDimitry Andric public: 409*0fca6ea1SDimitry Andric SRECWriter(Object &Obj, raw_ostream &OS, StringRef OutputFile) 410*0fca6ea1SDimitry Andric : ASCIIHexWriter(Obj, OS, OutputFile) {} 41181ad6265SDimitry Andric Error write() override; 412*0fca6ea1SDimitry Andric 413*0fca6ea1SDimitry Andric private: 414*0fca6ea1SDimitry Andric size_t writeHeader(uint8_t *Buf); 415*0fca6ea1SDimitry Andric size_t writeTerminator(uint8_t *Buf, uint8_t Type); 416*0fca6ea1SDimitry Andric Expected<size_t> 417*0fca6ea1SDimitry Andric getTotalSize(WritableMemoryBuffer &EmptyBuffer) const override; 418*0fca6ea1SDimitry Andric }; 419*0fca6ea1SDimitry Andric 420*0fca6ea1SDimitry Andric using SRecLineData = SmallVector<char, 64>; 421*0fca6ea1SDimitry Andric struct SRecord { 422*0fca6ea1SDimitry Andric uint8_t Type; 423*0fca6ea1SDimitry Andric uint32_t Address; 424*0fca6ea1SDimitry Andric ArrayRef<uint8_t> Data; 425*0fca6ea1SDimitry Andric SRecLineData toString() const; 426*0fca6ea1SDimitry Andric uint8_t getCount() const; 427*0fca6ea1SDimitry Andric // Get address size in characters. 428*0fca6ea1SDimitry Andric uint8_t getAddressSize() const; 429*0fca6ea1SDimitry Andric uint8_t getChecksum() const; 430*0fca6ea1SDimitry Andric size_t getSize() const; 431*0fca6ea1SDimitry Andric static SRecord getHeader(StringRef FileName); 432*0fca6ea1SDimitry Andric static uint8_t getType(uint32_t Address); 433*0fca6ea1SDimitry Andric 434*0fca6ea1SDimitry Andric enum Type : uint8_t { 435*0fca6ea1SDimitry Andric // Vendor specific text comment. 436*0fca6ea1SDimitry Andric S0 = 0, 437*0fca6ea1SDimitry Andric // Data that starts at a 16 bit address. 438*0fca6ea1SDimitry Andric S1 = 1, 439*0fca6ea1SDimitry Andric // Data that starts at a 24 bit address. 440*0fca6ea1SDimitry Andric S2 = 2, 441*0fca6ea1SDimitry Andric // Data that starts at a 32 bit address. 442*0fca6ea1SDimitry Andric S3 = 3, 443*0fca6ea1SDimitry Andric // Reserved. 444*0fca6ea1SDimitry Andric S4 = 4, 445*0fca6ea1SDimitry Andric // 16 bit count of S1/S2/S3 records (optional). 446*0fca6ea1SDimitry Andric S5 = 5, 447*0fca6ea1SDimitry Andric // 32 bit count of S1/S2/S3 records (optional). 448*0fca6ea1SDimitry Andric S6 = 6, 449*0fca6ea1SDimitry Andric // Terminates a series of S3 records. 450*0fca6ea1SDimitry Andric S7 = 7, 451*0fca6ea1SDimitry Andric // Terminates a series of S2 records. 452*0fca6ea1SDimitry Andric S8 = 8, 453*0fca6ea1SDimitry Andric // Terminates a series of S1 records. 454*0fca6ea1SDimitry Andric S9 = 9 455*0fca6ea1SDimitry Andric }; 456*0fca6ea1SDimitry Andric }; 457*0fca6ea1SDimitry Andric 458*0fca6ea1SDimitry Andric class SRECSectionWriterBase : public BinarySectionWriter { 459*0fca6ea1SDimitry Andric public: 460*0fca6ea1SDimitry Andric explicit SRECSectionWriterBase(WritableMemoryBuffer &Buf, 461*0fca6ea1SDimitry Andric uint64_t StartOffset) 462*0fca6ea1SDimitry Andric : BinarySectionWriter(Buf), Offset(StartOffset), HeaderSize(StartOffset) { 463*0fca6ea1SDimitry Andric } 464*0fca6ea1SDimitry Andric 465*0fca6ea1SDimitry Andric using BinarySectionWriter::visit; 466*0fca6ea1SDimitry Andric 467*0fca6ea1SDimitry Andric void writeRecords(uint32_t Entry); 468*0fca6ea1SDimitry Andric uint64_t getBufferOffset() const { return Offset; } 469*0fca6ea1SDimitry Andric Error visit(const Section &S) override; 470*0fca6ea1SDimitry Andric Error visit(const OwnedDataSection &S) override; 471*0fca6ea1SDimitry Andric Error visit(const StringTableSection &S) override; 472*0fca6ea1SDimitry Andric Error visit(const DynamicRelocationSection &S) override; 473*0fca6ea1SDimitry Andric uint8_t getType() const { return Type; }; 474*0fca6ea1SDimitry Andric 475*0fca6ea1SDimitry Andric protected: 476*0fca6ea1SDimitry Andric // Offset in the output buffer. 477*0fca6ea1SDimitry Andric uint64_t Offset; 478*0fca6ea1SDimitry Andric // Sections start after the header. 479*0fca6ea1SDimitry Andric uint64_t HeaderSize; 480*0fca6ea1SDimitry Andric // Type of records to write. 481*0fca6ea1SDimitry Andric uint8_t Type = SRecord::S1; 482*0fca6ea1SDimitry Andric std::vector<SRecord> Records; 483*0fca6ea1SDimitry Andric 484*0fca6ea1SDimitry Andric void writeSection(const SectionBase &S, ArrayRef<uint8_t> Data); 485*0fca6ea1SDimitry Andric virtual void writeRecord(SRecord &Record, uint64_t Off) = 0; 486*0fca6ea1SDimitry Andric }; 487*0fca6ea1SDimitry Andric 488*0fca6ea1SDimitry Andric // An SRECSectionWriterBase that visits sections but does not write anything. 489*0fca6ea1SDimitry Andric // This class is only used to calculate the size of the output file. 490*0fca6ea1SDimitry Andric class SRECSizeCalculator : public SRECSectionWriterBase { 491*0fca6ea1SDimitry Andric public: 492*0fca6ea1SDimitry Andric SRECSizeCalculator(WritableMemoryBuffer &EmptyBuffer, uint64_t Offset) 493*0fca6ea1SDimitry Andric : SRECSectionWriterBase(EmptyBuffer, Offset) {} 494*0fca6ea1SDimitry Andric 495*0fca6ea1SDimitry Andric protected: 496*0fca6ea1SDimitry Andric void writeRecord(SRecord &Record, uint64_t Off) override {} 497*0fca6ea1SDimitry Andric }; 498*0fca6ea1SDimitry Andric 499*0fca6ea1SDimitry Andric class SRECSectionWriter : public SRECSectionWriterBase { 500*0fca6ea1SDimitry Andric public: 501*0fca6ea1SDimitry Andric SRECSectionWriter(WritableMemoryBuffer &Buf, uint64_t Offset) 502*0fca6ea1SDimitry Andric : SRECSectionWriterBase(Buf, Offset) {} 503*0fca6ea1SDimitry Andric Error visit(const StringTableSection &Sec) override; 504*0fca6ea1SDimitry Andric 505*0fca6ea1SDimitry Andric protected: 506*0fca6ea1SDimitry Andric void writeRecord(SRecord &Record, uint64_t Off) override; 50781ad6265SDimitry Andric }; 50881ad6265SDimitry Andric 50981ad6265SDimitry Andric class SectionBase { 51081ad6265SDimitry Andric public: 51181ad6265SDimitry Andric std::string Name; 51281ad6265SDimitry Andric Segment *ParentSegment = nullptr; 51381ad6265SDimitry Andric uint64_t HeaderOffset = 0; 51481ad6265SDimitry Andric uint32_t Index = 0; 51581ad6265SDimitry Andric 51681ad6265SDimitry Andric uint32_t OriginalIndex = 0; 51781ad6265SDimitry Andric uint64_t OriginalFlags = 0; 51881ad6265SDimitry Andric uint64_t OriginalType = ELF::SHT_NULL; 51981ad6265SDimitry Andric uint64_t OriginalOffset = std::numeric_limits<uint64_t>::max(); 52081ad6265SDimitry Andric 52181ad6265SDimitry Andric uint64_t Addr = 0; 52281ad6265SDimitry Andric uint64_t Align = 1; 52381ad6265SDimitry Andric uint32_t EntrySize = 0; 52481ad6265SDimitry Andric uint64_t Flags = 0; 52581ad6265SDimitry Andric uint64_t Info = 0; 52681ad6265SDimitry Andric uint64_t Link = ELF::SHN_UNDEF; 52781ad6265SDimitry Andric uint64_t NameIndex = 0; 52881ad6265SDimitry Andric uint64_t Offset = 0; 52981ad6265SDimitry Andric uint64_t Size = 0; 53081ad6265SDimitry Andric uint64_t Type = ELF::SHT_NULL; 53181ad6265SDimitry Andric ArrayRef<uint8_t> OriginalData; 53281ad6265SDimitry Andric bool HasSymbol = false; 53381ad6265SDimitry Andric 53481ad6265SDimitry Andric SectionBase() = default; 53581ad6265SDimitry Andric SectionBase(const SectionBase &) = default; 53681ad6265SDimitry Andric 53781ad6265SDimitry Andric virtual ~SectionBase() = default; 53881ad6265SDimitry Andric 53981ad6265SDimitry Andric virtual Error initialize(SectionTableRef SecTable); 54081ad6265SDimitry Andric virtual void finalize(); 54181ad6265SDimitry Andric // Remove references to these sections. The list of sections must be sorted. 54281ad6265SDimitry Andric virtual Error 54381ad6265SDimitry Andric removeSectionReferences(bool AllowBrokenLinks, 54481ad6265SDimitry Andric function_ref<bool(const SectionBase *)> ToRemove); 54581ad6265SDimitry Andric virtual Error removeSymbols(function_ref<bool(const Symbol &)> ToRemove); 54681ad6265SDimitry Andric virtual Error accept(SectionVisitor &Visitor) const = 0; 54781ad6265SDimitry Andric virtual Error accept(MutableSectionVisitor &Visitor) = 0; 54881ad6265SDimitry Andric virtual void markSymbols(); 54981ad6265SDimitry Andric virtual void 55081ad6265SDimitry Andric replaceSectionReferences(const DenseMap<SectionBase *, SectionBase *> &); 55181ad6265SDimitry Andric virtual bool hasContents() const { return false; } 55281ad6265SDimitry Andric // Notify the section that it is subject to removal. 55381ad6265SDimitry Andric virtual void onRemove(); 55406c3fb27SDimitry Andric 55506c3fb27SDimitry Andric virtual void restoreSymTabLink(SymbolTableSection &) {} 55681ad6265SDimitry Andric }; 55781ad6265SDimitry Andric 55881ad6265SDimitry Andric class Segment { 55981ad6265SDimitry Andric private: 56081ad6265SDimitry Andric struct SectionCompare { 56181ad6265SDimitry Andric bool operator()(const SectionBase *Lhs, const SectionBase *Rhs) const { 56281ad6265SDimitry Andric // Some sections might have the same address if one of them is empty. To 56381ad6265SDimitry Andric // fix this we can use the lexicographic ordering on ->Addr and the 56481ad6265SDimitry Andric // original index. 56581ad6265SDimitry Andric if (Lhs->OriginalOffset == Rhs->OriginalOffset) 56681ad6265SDimitry Andric return Lhs->OriginalIndex < Rhs->OriginalIndex; 56781ad6265SDimitry Andric return Lhs->OriginalOffset < Rhs->OriginalOffset; 56881ad6265SDimitry Andric } 56981ad6265SDimitry Andric }; 57081ad6265SDimitry Andric 57181ad6265SDimitry Andric public: 57281ad6265SDimitry Andric uint32_t Type = 0; 57381ad6265SDimitry Andric uint32_t Flags = 0; 57481ad6265SDimitry Andric uint64_t Offset = 0; 57581ad6265SDimitry Andric uint64_t VAddr = 0; 57681ad6265SDimitry Andric uint64_t PAddr = 0; 57781ad6265SDimitry Andric uint64_t FileSize = 0; 57881ad6265SDimitry Andric uint64_t MemSize = 0; 57981ad6265SDimitry Andric uint64_t Align = 0; 58081ad6265SDimitry Andric 58181ad6265SDimitry Andric uint32_t Index = 0; 58281ad6265SDimitry Andric uint64_t OriginalOffset = 0; 58381ad6265SDimitry Andric Segment *ParentSegment = nullptr; 58481ad6265SDimitry Andric ArrayRef<uint8_t> Contents; 58581ad6265SDimitry Andric std::set<const SectionBase *, SectionCompare> Sections; 58681ad6265SDimitry Andric 58781ad6265SDimitry Andric explicit Segment(ArrayRef<uint8_t> Data) : Contents(Data) {} 58881ad6265SDimitry Andric Segment() = default; 58981ad6265SDimitry Andric 59081ad6265SDimitry Andric const SectionBase *firstSection() const { 59181ad6265SDimitry Andric if (!Sections.empty()) 59281ad6265SDimitry Andric return *Sections.begin(); 59381ad6265SDimitry Andric return nullptr; 59481ad6265SDimitry Andric } 59581ad6265SDimitry Andric 59681ad6265SDimitry Andric void removeSection(const SectionBase *Sec) { Sections.erase(Sec); } 59781ad6265SDimitry Andric void addSection(const SectionBase *Sec) { Sections.insert(Sec); } 59881ad6265SDimitry Andric 59981ad6265SDimitry Andric ArrayRef<uint8_t> getContents() const { return Contents; } 60081ad6265SDimitry Andric }; 60181ad6265SDimitry Andric 60281ad6265SDimitry Andric class Section : public SectionBase { 60381ad6265SDimitry Andric MAKE_SEC_WRITER_FRIEND 60481ad6265SDimitry Andric 60581ad6265SDimitry Andric ArrayRef<uint8_t> Contents; 60681ad6265SDimitry Andric SectionBase *LinkSection = nullptr; 60706c3fb27SDimitry Andric bool HasSymTabLink = false; 60881ad6265SDimitry Andric 60981ad6265SDimitry Andric public: 61081ad6265SDimitry Andric explicit Section(ArrayRef<uint8_t> Data) : Contents(Data) {} 61181ad6265SDimitry Andric 61281ad6265SDimitry Andric Error accept(SectionVisitor &Visitor) const override; 61381ad6265SDimitry Andric Error accept(MutableSectionVisitor &Visitor) override; 61481ad6265SDimitry Andric Error removeSectionReferences( 61581ad6265SDimitry Andric bool AllowBrokenLinks, 61681ad6265SDimitry Andric function_ref<bool(const SectionBase *)> ToRemove) override; 61781ad6265SDimitry Andric Error initialize(SectionTableRef SecTable) override; 61881ad6265SDimitry Andric void finalize() override; 61981ad6265SDimitry Andric bool hasContents() const override { 62081ad6265SDimitry Andric return Type != ELF::SHT_NOBITS && Type != ELF::SHT_NULL; 62181ad6265SDimitry Andric } 62206c3fb27SDimitry Andric void restoreSymTabLink(SymbolTableSection &SymTab) override; 62381ad6265SDimitry Andric }; 62481ad6265SDimitry Andric 62581ad6265SDimitry Andric class OwnedDataSection : public SectionBase { 62681ad6265SDimitry Andric MAKE_SEC_WRITER_FRIEND 62781ad6265SDimitry Andric 62881ad6265SDimitry Andric std::vector<uint8_t> Data; 62981ad6265SDimitry Andric 63081ad6265SDimitry Andric public: 63181ad6265SDimitry Andric OwnedDataSection(StringRef SecName, ArrayRef<uint8_t> Data) 63281ad6265SDimitry Andric : Data(std::begin(Data), std::end(Data)) { 63381ad6265SDimitry Andric Name = SecName.str(); 63481ad6265SDimitry Andric Type = OriginalType = ELF::SHT_PROGBITS; 63581ad6265SDimitry Andric Size = Data.size(); 63681ad6265SDimitry Andric OriginalOffset = std::numeric_limits<uint64_t>::max(); 63781ad6265SDimitry Andric } 63881ad6265SDimitry Andric 63981ad6265SDimitry Andric OwnedDataSection(const Twine &SecName, uint64_t SecAddr, uint64_t SecFlags, 64081ad6265SDimitry Andric uint64_t SecOff) { 64181ad6265SDimitry Andric Name = SecName.str(); 64281ad6265SDimitry Andric Type = OriginalType = ELF::SHT_PROGBITS; 64381ad6265SDimitry Andric Addr = SecAddr; 64481ad6265SDimitry Andric Flags = OriginalFlags = SecFlags; 64581ad6265SDimitry Andric OriginalOffset = SecOff; 64681ad6265SDimitry Andric } 64781ad6265SDimitry Andric 64881ad6265SDimitry Andric OwnedDataSection(SectionBase &S, ArrayRef<uint8_t> Data) 64981ad6265SDimitry Andric : SectionBase(S), Data(std::begin(Data), std::end(Data)) { 65081ad6265SDimitry Andric Size = Data.size(); 65181ad6265SDimitry Andric } 65281ad6265SDimitry Andric 65381ad6265SDimitry Andric void appendHexData(StringRef HexData); 65481ad6265SDimitry Andric Error accept(SectionVisitor &Sec) const override; 65581ad6265SDimitry Andric Error accept(MutableSectionVisitor &Visitor) override; 65681ad6265SDimitry Andric bool hasContents() const override { return true; } 65781ad6265SDimitry Andric }; 65881ad6265SDimitry Andric 65981ad6265SDimitry Andric class CompressedSection : public SectionBase { 66081ad6265SDimitry Andric MAKE_SEC_WRITER_FRIEND 66181ad6265SDimitry Andric 662bdd1243dSDimitry Andric uint32_t ChType = 0; 66381ad6265SDimitry Andric DebugCompressionType CompressionType; 66481ad6265SDimitry Andric uint64_t DecompressedSize; 66581ad6265SDimitry Andric uint64_t DecompressedAlign; 666753f127fSDimitry Andric SmallVector<uint8_t, 128> CompressedData; 66781ad6265SDimitry Andric 66881ad6265SDimitry Andric public: 66981ad6265SDimitry Andric CompressedSection(const SectionBase &Sec, 670bdd1243dSDimitry Andric DebugCompressionType CompressionType, bool Is64Bits); 671bdd1243dSDimitry Andric CompressedSection(ArrayRef<uint8_t> CompressedData, uint32_t ChType, 672bdd1243dSDimitry Andric uint64_t DecompressedSize, uint64_t DecompressedAlign); 67381ad6265SDimitry Andric 67481ad6265SDimitry Andric uint64_t getDecompressedSize() const { return DecompressedSize; } 67581ad6265SDimitry Andric uint64_t getDecompressedAlign() const { return DecompressedAlign; } 676bdd1243dSDimitry Andric uint64_t getChType() const { return ChType; } 67781ad6265SDimitry Andric 67881ad6265SDimitry Andric Error accept(SectionVisitor &Visitor) const override; 67981ad6265SDimitry Andric Error accept(MutableSectionVisitor &Visitor) override; 68081ad6265SDimitry Andric 68181ad6265SDimitry Andric static bool classof(const SectionBase *S) { 68281ad6265SDimitry Andric return S->OriginalFlags & ELF::SHF_COMPRESSED; 68381ad6265SDimitry Andric } 68481ad6265SDimitry Andric }; 68581ad6265SDimitry Andric 68681ad6265SDimitry Andric class DecompressedSection : public SectionBase { 68781ad6265SDimitry Andric MAKE_SEC_WRITER_FRIEND 68881ad6265SDimitry Andric 68981ad6265SDimitry Andric public: 690bdd1243dSDimitry Andric uint32_t ChType; 69181ad6265SDimitry Andric explicit DecompressedSection(const CompressedSection &Sec) 692bdd1243dSDimitry Andric : SectionBase(Sec), ChType(Sec.getChType()) { 69381ad6265SDimitry Andric Size = Sec.getDecompressedSize(); 69481ad6265SDimitry Andric Align = Sec.getDecompressedAlign(); 69581ad6265SDimitry Andric Flags = OriginalFlags = (Flags & ~ELF::SHF_COMPRESSED); 69681ad6265SDimitry Andric } 69781ad6265SDimitry Andric 69881ad6265SDimitry Andric Error accept(SectionVisitor &Visitor) const override; 69981ad6265SDimitry Andric Error accept(MutableSectionVisitor &Visitor) override; 70081ad6265SDimitry Andric }; 70181ad6265SDimitry Andric 70281ad6265SDimitry Andric // There are two types of string tables that can exist, dynamic and not dynamic. 70381ad6265SDimitry Andric // In the dynamic case the string table is allocated. Changing a dynamic string 70481ad6265SDimitry Andric // table would mean altering virtual addresses and thus the memory image. So 70581ad6265SDimitry Andric // dynamic string tables should not have an interface to modify them or 70681ad6265SDimitry Andric // reconstruct them. This type lets us reconstruct a string table. To avoid 70781ad6265SDimitry Andric // this class being used for dynamic string tables (which has happened) the 70881ad6265SDimitry Andric // classof method checks that the particular instance is not allocated. This 70981ad6265SDimitry Andric // then agrees with the makeSection method used to construct most sections. 71081ad6265SDimitry Andric class StringTableSection : public SectionBase { 71181ad6265SDimitry Andric MAKE_SEC_WRITER_FRIEND 71281ad6265SDimitry Andric 71381ad6265SDimitry Andric StringTableBuilder StrTabBuilder; 71481ad6265SDimitry Andric 71581ad6265SDimitry Andric public: 71681ad6265SDimitry Andric StringTableSection() : StrTabBuilder(StringTableBuilder::ELF) { 71781ad6265SDimitry Andric Type = OriginalType = ELF::SHT_STRTAB; 71881ad6265SDimitry Andric } 71981ad6265SDimitry Andric 72081ad6265SDimitry Andric void addString(StringRef Name); 72181ad6265SDimitry Andric uint32_t findIndex(StringRef Name) const; 72281ad6265SDimitry Andric void prepareForLayout(); 72381ad6265SDimitry Andric Error accept(SectionVisitor &Visitor) const override; 72481ad6265SDimitry Andric Error accept(MutableSectionVisitor &Visitor) override; 72581ad6265SDimitry Andric 72681ad6265SDimitry Andric static bool classof(const SectionBase *S) { 72781ad6265SDimitry Andric if (S->OriginalFlags & ELF::SHF_ALLOC) 72881ad6265SDimitry Andric return false; 72981ad6265SDimitry Andric return S->OriginalType == ELF::SHT_STRTAB; 73081ad6265SDimitry Andric } 73181ad6265SDimitry Andric }; 73281ad6265SDimitry Andric 73381ad6265SDimitry Andric // Symbols have a st_shndx field that normally stores an index but occasionally 73481ad6265SDimitry Andric // stores a different special value. This enum keeps track of what the st_shndx 73581ad6265SDimitry Andric // field means. Most of the values are just copies of the special SHN_* values. 73681ad6265SDimitry Andric // SYMBOL_SIMPLE_INDEX means that the st_shndx is just an index of a section. 73781ad6265SDimitry Andric enum SymbolShndxType { 73881ad6265SDimitry Andric SYMBOL_SIMPLE_INDEX = 0, 73981ad6265SDimitry Andric SYMBOL_ABS = ELF::SHN_ABS, 74081ad6265SDimitry Andric SYMBOL_COMMON = ELF::SHN_COMMON, 74181ad6265SDimitry Andric SYMBOL_LOPROC = ELF::SHN_LOPROC, 74281ad6265SDimitry Andric SYMBOL_AMDGPU_LDS = ELF::SHN_AMDGPU_LDS, 74381ad6265SDimitry Andric SYMBOL_HEXAGON_SCOMMON = ELF::SHN_HEXAGON_SCOMMON, 74481ad6265SDimitry Andric SYMBOL_HEXAGON_SCOMMON_2 = ELF::SHN_HEXAGON_SCOMMON_2, 74581ad6265SDimitry Andric SYMBOL_HEXAGON_SCOMMON_4 = ELF::SHN_HEXAGON_SCOMMON_4, 74681ad6265SDimitry Andric SYMBOL_HEXAGON_SCOMMON_8 = ELF::SHN_HEXAGON_SCOMMON_8, 74781ad6265SDimitry Andric SYMBOL_MIPS_ACOMMON = ELF::SHN_MIPS_ACOMMON, 74881ad6265SDimitry Andric SYMBOL_MIPS_TEXT = ELF::SHN_MIPS_TEXT, 74981ad6265SDimitry Andric SYMBOL_MIPS_DATA = ELF::SHN_MIPS_DATA, 75081ad6265SDimitry Andric SYMBOL_MIPS_SCOMMON = ELF::SHN_MIPS_SCOMMON, 75181ad6265SDimitry Andric SYMBOL_MIPS_SUNDEFINED = ELF::SHN_MIPS_SUNDEFINED, 75281ad6265SDimitry Andric SYMBOL_HIPROC = ELF::SHN_HIPROC, 75381ad6265SDimitry Andric SYMBOL_LOOS = ELF::SHN_LOOS, 75481ad6265SDimitry Andric SYMBOL_HIOS = ELF::SHN_HIOS, 75581ad6265SDimitry Andric SYMBOL_XINDEX = ELF::SHN_XINDEX, 75681ad6265SDimitry Andric }; 75781ad6265SDimitry Andric 75881ad6265SDimitry Andric struct Symbol { 75981ad6265SDimitry Andric uint8_t Binding; 76081ad6265SDimitry Andric SectionBase *DefinedIn = nullptr; 76181ad6265SDimitry Andric SymbolShndxType ShndxType; 76281ad6265SDimitry Andric uint32_t Index; 76381ad6265SDimitry Andric std::string Name; 76481ad6265SDimitry Andric uint32_t NameIndex; 76581ad6265SDimitry Andric uint64_t Size; 76681ad6265SDimitry Andric uint8_t Type; 76781ad6265SDimitry Andric uint64_t Value; 76881ad6265SDimitry Andric uint8_t Visibility; 76981ad6265SDimitry Andric bool Referenced = false; 77081ad6265SDimitry Andric 77181ad6265SDimitry Andric uint16_t getShndx() const; 77281ad6265SDimitry Andric bool isCommon() const; 77381ad6265SDimitry Andric }; 77481ad6265SDimitry Andric 77581ad6265SDimitry Andric class SectionIndexSection : public SectionBase { 77681ad6265SDimitry Andric MAKE_SEC_WRITER_FRIEND 77781ad6265SDimitry Andric 77881ad6265SDimitry Andric private: 77981ad6265SDimitry Andric std::vector<uint32_t> Indexes; 78081ad6265SDimitry Andric SymbolTableSection *Symbols = nullptr; 78181ad6265SDimitry Andric 78281ad6265SDimitry Andric public: 78381ad6265SDimitry Andric virtual ~SectionIndexSection() {} 78481ad6265SDimitry Andric void addIndex(uint32_t Index) { 78581ad6265SDimitry Andric assert(Size > 0); 78681ad6265SDimitry Andric Indexes.push_back(Index); 78781ad6265SDimitry Andric } 78881ad6265SDimitry Andric 78981ad6265SDimitry Andric void reserve(size_t NumSymbols) { 79081ad6265SDimitry Andric Indexes.reserve(NumSymbols); 79181ad6265SDimitry Andric Size = NumSymbols * 4; 79281ad6265SDimitry Andric } 79381ad6265SDimitry Andric void setSymTab(SymbolTableSection *SymTab) { Symbols = SymTab; } 79481ad6265SDimitry Andric Error initialize(SectionTableRef SecTable) override; 79581ad6265SDimitry Andric void finalize() override; 79681ad6265SDimitry Andric Error accept(SectionVisitor &Visitor) const override; 79781ad6265SDimitry Andric Error accept(MutableSectionVisitor &Visitor) override; 79881ad6265SDimitry Andric 79981ad6265SDimitry Andric SectionIndexSection() { 80081ad6265SDimitry Andric Name = ".symtab_shndx"; 80181ad6265SDimitry Andric Align = 4; 80281ad6265SDimitry Andric EntrySize = 4; 80381ad6265SDimitry Andric Type = OriginalType = ELF::SHT_SYMTAB_SHNDX; 80481ad6265SDimitry Andric } 80581ad6265SDimitry Andric }; 80681ad6265SDimitry Andric 80781ad6265SDimitry Andric class SymbolTableSection : public SectionBase { 80881ad6265SDimitry Andric MAKE_SEC_WRITER_FRIEND 80981ad6265SDimitry Andric 81081ad6265SDimitry Andric void setStrTab(StringTableSection *StrTab) { SymbolNames = StrTab; } 81181ad6265SDimitry Andric void assignIndices(); 81281ad6265SDimitry Andric 81381ad6265SDimitry Andric protected: 81481ad6265SDimitry Andric std::vector<std::unique_ptr<Symbol>> Symbols; 81581ad6265SDimitry Andric StringTableSection *SymbolNames = nullptr; 81681ad6265SDimitry Andric SectionIndexSection *SectionIndexTable = nullptr; 81706c3fb27SDimitry Andric bool IndicesChanged = false; 81881ad6265SDimitry Andric 81981ad6265SDimitry Andric using SymPtr = std::unique_ptr<Symbol>; 82081ad6265SDimitry Andric 82181ad6265SDimitry Andric public: 82281ad6265SDimitry Andric SymbolTableSection() { Type = OriginalType = ELF::SHT_SYMTAB; } 82381ad6265SDimitry Andric 82481ad6265SDimitry Andric void addSymbol(Twine Name, uint8_t Bind, uint8_t Type, SectionBase *DefinedIn, 82581ad6265SDimitry Andric uint64_t Value, uint8_t Visibility, uint16_t Shndx, 82681ad6265SDimitry Andric uint64_t SymbolSize); 82781ad6265SDimitry Andric void prepareForLayout(); 82881ad6265SDimitry Andric // An 'empty' symbol table still contains a null symbol. 82981ad6265SDimitry Andric bool empty() const { return Symbols.size() == 1; } 83006c3fb27SDimitry Andric bool indicesChanged() const { return IndicesChanged; } 83181ad6265SDimitry Andric void setShndxTable(SectionIndexSection *ShndxTable) { 83281ad6265SDimitry Andric SectionIndexTable = ShndxTable; 83381ad6265SDimitry Andric } 83481ad6265SDimitry Andric const SectionIndexSection *getShndxTable() const { return SectionIndexTable; } 83581ad6265SDimitry Andric void fillShndxTable(); 83681ad6265SDimitry Andric const SectionBase *getStrTab() const { return SymbolNames; } 83781ad6265SDimitry Andric Expected<const Symbol *> getSymbolByIndex(uint32_t Index) const; 83881ad6265SDimitry Andric Expected<Symbol *> getSymbolByIndex(uint32_t Index); 83981ad6265SDimitry Andric void updateSymbols(function_ref<void(Symbol &)> Callable); 84081ad6265SDimitry Andric 84181ad6265SDimitry Andric Error removeSectionReferences( 84281ad6265SDimitry Andric bool AllowBrokenLinks, 84381ad6265SDimitry Andric function_ref<bool(const SectionBase *)> ToRemove) override; 84481ad6265SDimitry Andric Error initialize(SectionTableRef SecTable) override; 84581ad6265SDimitry Andric void finalize() override; 84681ad6265SDimitry Andric Error accept(SectionVisitor &Visitor) const override; 84781ad6265SDimitry Andric Error accept(MutableSectionVisitor &Visitor) override; 84881ad6265SDimitry Andric Error removeSymbols(function_ref<bool(const Symbol &)> ToRemove) override; 84981ad6265SDimitry Andric void replaceSectionReferences( 85081ad6265SDimitry Andric const DenseMap<SectionBase *, SectionBase *> &FromTo) override; 85181ad6265SDimitry Andric 85281ad6265SDimitry Andric static bool classof(const SectionBase *S) { 85381ad6265SDimitry Andric return S->OriginalType == ELF::SHT_SYMTAB; 85481ad6265SDimitry Andric } 85581ad6265SDimitry Andric }; 85681ad6265SDimitry Andric 85781ad6265SDimitry Andric struct Relocation { 85881ad6265SDimitry Andric Symbol *RelocSymbol = nullptr; 85981ad6265SDimitry Andric uint64_t Offset; 86081ad6265SDimitry Andric uint64_t Addend; 86181ad6265SDimitry Andric uint32_t Type; 86281ad6265SDimitry Andric }; 86381ad6265SDimitry Andric 86481ad6265SDimitry Andric // All relocation sections denote relocations to apply to another section. 86581ad6265SDimitry Andric // However, some relocation sections use a dynamic symbol table and others use 86681ad6265SDimitry Andric // a regular symbol table. Because the types of the two symbol tables differ in 86781ad6265SDimitry Andric // our system (because they should behave differently) we can't uniformly 86881ad6265SDimitry Andric // represent all relocations with the same base class if we expose an interface 86981ad6265SDimitry Andric // that mentions the symbol table type. So we split the two base types into two 87081ad6265SDimitry Andric // different classes, one which handles the section the relocation is applied to 87181ad6265SDimitry Andric // and another which handles the symbol table type. The symbol table type is 87281ad6265SDimitry Andric // taken as a type parameter to the class (see RelocSectionWithSymtabBase). 87381ad6265SDimitry Andric class RelocationSectionBase : public SectionBase { 87481ad6265SDimitry Andric protected: 87581ad6265SDimitry Andric SectionBase *SecToApplyRel = nullptr; 87681ad6265SDimitry Andric 87781ad6265SDimitry Andric public: 87881ad6265SDimitry Andric const SectionBase *getSection() const { return SecToApplyRel; } 87981ad6265SDimitry Andric void setSection(SectionBase *Sec) { SecToApplyRel = Sec; } 88081ad6265SDimitry Andric 88181ad6265SDimitry Andric StringRef getNamePrefix() const; 88281ad6265SDimitry Andric 88381ad6265SDimitry Andric static bool classof(const SectionBase *S) { 884*0fca6ea1SDimitry Andric return is_contained({ELF::SHT_REL, ELF::SHT_RELA, ELF::SHT_CREL}, 885*0fca6ea1SDimitry Andric S->OriginalType); 88681ad6265SDimitry Andric } 88781ad6265SDimitry Andric }; 88881ad6265SDimitry Andric 88981ad6265SDimitry Andric // Takes the symbol table type to use as a parameter so that we can deduplicate 89081ad6265SDimitry Andric // that code between the two symbol table types. 89181ad6265SDimitry Andric template <class SymTabType> 89281ad6265SDimitry Andric class RelocSectionWithSymtabBase : public RelocationSectionBase { 89381ad6265SDimitry Andric void setSymTab(SymTabType *SymTab) { Symbols = SymTab; } 89481ad6265SDimitry Andric 89581ad6265SDimitry Andric protected: 89681ad6265SDimitry Andric RelocSectionWithSymtabBase() = default; 89781ad6265SDimitry Andric 89881ad6265SDimitry Andric SymTabType *Symbols = nullptr; 89981ad6265SDimitry Andric 90081ad6265SDimitry Andric public: 90181ad6265SDimitry Andric Error initialize(SectionTableRef SecTable) override; 90281ad6265SDimitry Andric void finalize() override; 90381ad6265SDimitry Andric }; 90481ad6265SDimitry Andric 90581ad6265SDimitry Andric class RelocationSection 90681ad6265SDimitry Andric : public RelocSectionWithSymtabBase<SymbolTableSection> { 90781ad6265SDimitry Andric MAKE_SEC_WRITER_FRIEND 90881ad6265SDimitry Andric 90981ad6265SDimitry Andric std::vector<Relocation> Relocations; 91081ad6265SDimitry Andric const Object &Obj; 91181ad6265SDimitry Andric 91281ad6265SDimitry Andric public: 91381ad6265SDimitry Andric RelocationSection(const Object &O) : Obj(O) {} 914*0fca6ea1SDimitry Andric void addRelocation(const Relocation &Rel) { Relocations.push_back(Rel); } 91581ad6265SDimitry Andric Error accept(SectionVisitor &Visitor) const override; 91681ad6265SDimitry Andric Error accept(MutableSectionVisitor &Visitor) override; 91781ad6265SDimitry Andric Error removeSectionReferences( 91881ad6265SDimitry Andric bool AllowBrokenLinks, 91981ad6265SDimitry Andric function_ref<bool(const SectionBase *)> ToRemove) override; 92081ad6265SDimitry Andric Error removeSymbols(function_ref<bool(const Symbol &)> ToRemove) override; 92181ad6265SDimitry Andric void markSymbols() override; 92281ad6265SDimitry Andric void replaceSectionReferences( 92381ad6265SDimitry Andric const DenseMap<SectionBase *, SectionBase *> &FromTo) override; 92481ad6265SDimitry Andric const Object &getObject() const { return Obj; } 92581ad6265SDimitry Andric 92681ad6265SDimitry Andric static bool classof(const SectionBase *S) { 92781ad6265SDimitry Andric if (S->OriginalFlags & ELF::SHF_ALLOC) 92881ad6265SDimitry Andric return false; 929*0fca6ea1SDimitry Andric return RelocationSectionBase::classof(S); 93081ad6265SDimitry Andric } 93181ad6265SDimitry Andric }; 93281ad6265SDimitry Andric 93381ad6265SDimitry Andric // TODO: The way stripping and groups interact is complicated 93481ad6265SDimitry Andric // and still needs to be worked on. 93581ad6265SDimitry Andric 93681ad6265SDimitry Andric class GroupSection : public SectionBase { 93781ad6265SDimitry Andric MAKE_SEC_WRITER_FRIEND 93881ad6265SDimitry Andric const SymbolTableSection *SymTab = nullptr; 93981ad6265SDimitry Andric Symbol *Sym = nullptr; 94081ad6265SDimitry Andric ELF::Elf32_Word FlagWord; 94181ad6265SDimitry Andric SmallVector<SectionBase *, 3> GroupMembers; 94281ad6265SDimitry Andric 94381ad6265SDimitry Andric public: 944*0fca6ea1SDimitry Andric template <class T> 945*0fca6ea1SDimitry Andric using ConstRange = iterator_range< 946*0fca6ea1SDimitry Andric pointee_iterator<typename llvm::SmallVector<T *, 3>::const_iterator>>; 94781ad6265SDimitry Andric // TODO: Contents is present in several classes of the hierarchy. 94881ad6265SDimitry Andric // This needs to be refactored to avoid duplication. 94981ad6265SDimitry Andric ArrayRef<uint8_t> Contents; 95081ad6265SDimitry Andric 95181ad6265SDimitry Andric explicit GroupSection(ArrayRef<uint8_t> Data) : Contents(Data) {} 95281ad6265SDimitry Andric 95381ad6265SDimitry Andric void setSymTab(const SymbolTableSection *SymTabSec) { SymTab = SymTabSec; } 95481ad6265SDimitry Andric void setSymbol(Symbol *S) { Sym = S; } 95581ad6265SDimitry Andric void setFlagWord(ELF::Elf32_Word W) { FlagWord = W; } 95681ad6265SDimitry Andric void addMember(SectionBase *Sec) { GroupMembers.push_back(Sec); } 95781ad6265SDimitry Andric 95881ad6265SDimitry Andric Error accept(SectionVisitor &) const override; 95981ad6265SDimitry Andric Error accept(MutableSectionVisitor &Visitor) override; 96081ad6265SDimitry Andric void finalize() override; 96181ad6265SDimitry Andric Error removeSectionReferences( 96281ad6265SDimitry Andric bool AllowBrokenLinks, 96381ad6265SDimitry Andric function_ref<bool(const SectionBase *)> ToRemove) override; 96481ad6265SDimitry Andric Error removeSymbols(function_ref<bool(const Symbol &)> ToRemove) override; 96581ad6265SDimitry Andric void markSymbols() override; 96681ad6265SDimitry Andric void replaceSectionReferences( 96781ad6265SDimitry Andric const DenseMap<SectionBase *, SectionBase *> &FromTo) override; 96881ad6265SDimitry Andric void onRemove() override; 96981ad6265SDimitry Andric 970*0fca6ea1SDimitry Andric ConstRange<SectionBase> members() const { 971*0fca6ea1SDimitry Andric return make_pointee_range(GroupMembers); 972*0fca6ea1SDimitry Andric } 973*0fca6ea1SDimitry Andric 97481ad6265SDimitry Andric static bool classof(const SectionBase *S) { 97581ad6265SDimitry Andric return S->OriginalType == ELF::SHT_GROUP; 97681ad6265SDimitry Andric } 97781ad6265SDimitry Andric }; 97881ad6265SDimitry Andric 97981ad6265SDimitry Andric class DynamicSymbolTableSection : public Section { 98081ad6265SDimitry Andric public: 98181ad6265SDimitry Andric explicit DynamicSymbolTableSection(ArrayRef<uint8_t> Data) : Section(Data) {} 98281ad6265SDimitry Andric 98381ad6265SDimitry Andric static bool classof(const SectionBase *S) { 98481ad6265SDimitry Andric return S->OriginalType == ELF::SHT_DYNSYM; 98581ad6265SDimitry Andric } 98681ad6265SDimitry Andric }; 98781ad6265SDimitry Andric 98881ad6265SDimitry Andric class DynamicSection : public Section { 98981ad6265SDimitry Andric public: 99081ad6265SDimitry Andric explicit DynamicSection(ArrayRef<uint8_t> Data) : Section(Data) {} 99181ad6265SDimitry Andric 99281ad6265SDimitry Andric static bool classof(const SectionBase *S) { 99381ad6265SDimitry Andric return S->OriginalType == ELF::SHT_DYNAMIC; 99481ad6265SDimitry Andric } 99581ad6265SDimitry Andric }; 99681ad6265SDimitry Andric 99781ad6265SDimitry Andric class DynamicRelocationSection 99881ad6265SDimitry Andric : public RelocSectionWithSymtabBase<DynamicSymbolTableSection> { 99981ad6265SDimitry Andric MAKE_SEC_WRITER_FRIEND 100081ad6265SDimitry Andric 100181ad6265SDimitry Andric private: 100281ad6265SDimitry Andric ArrayRef<uint8_t> Contents; 100381ad6265SDimitry Andric 100481ad6265SDimitry Andric public: 100581ad6265SDimitry Andric explicit DynamicRelocationSection(ArrayRef<uint8_t> Data) : Contents(Data) {} 100681ad6265SDimitry Andric 100781ad6265SDimitry Andric Error accept(SectionVisitor &) const override; 100881ad6265SDimitry Andric Error accept(MutableSectionVisitor &Visitor) override; 100981ad6265SDimitry Andric Error removeSectionReferences( 101081ad6265SDimitry Andric bool AllowBrokenLinks, 101181ad6265SDimitry Andric function_ref<bool(const SectionBase *)> ToRemove) override; 101281ad6265SDimitry Andric 101381ad6265SDimitry Andric static bool classof(const SectionBase *S) { 101481ad6265SDimitry Andric if (!(S->OriginalFlags & ELF::SHF_ALLOC)) 101581ad6265SDimitry Andric return false; 101681ad6265SDimitry Andric return S->OriginalType == ELF::SHT_REL || S->OriginalType == ELF::SHT_RELA; 101781ad6265SDimitry Andric } 101881ad6265SDimitry Andric }; 101981ad6265SDimitry Andric 102081ad6265SDimitry Andric class GnuDebugLinkSection : public SectionBase { 102181ad6265SDimitry Andric MAKE_SEC_WRITER_FRIEND 102281ad6265SDimitry Andric 102381ad6265SDimitry Andric private: 102481ad6265SDimitry Andric StringRef FileName; 102581ad6265SDimitry Andric uint32_t CRC32; 102681ad6265SDimitry Andric 102781ad6265SDimitry Andric void init(StringRef File); 102881ad6265SDimitry Andric 102981ad6265SDimitry Andric public: 103081ad6265SDimitry Andric // If we add this section from an external source we can use this ctor. 103181ad6265SDimitry Andric explicit GnuDebugLinkSection(StringRef File, uint32_t PrecomputedCRC); 103281ad6265SDimitry Andric Error accept(SectionVisitor &Visitor) const override; 103381ad6265SDimitry Andric Error accept(MutableSectionVisitor &Visitor) override; 103481ad6265SDimitry Andric }; 103581ad6265SDimitry Andric 103681ad6265SDimitry Andric class Reader { 103781ad6265SDimitry Andric public: 103881ad6265SDimitry Andric virtual ~Reader(); 103981ad6265SDimitry Andric virtual Expected<std::unique_ptr<Object>> create(bool EnsureSymtab) const = 0; 104081ad6265SDimitry Andric }; 104181ad6265SDimitry Andric 104281ad6265SDimitry Andric using object::Binary; 104381ad6265SDimitry Andric using object::ELFFile; 104481ad6265SDimitry Andric using object::ELFObjectFile; 104581ad6265SDimitry Andric using object::OwningBinary; 104681ad6265SDimitry Andric 104781ad6265SDimitry Andric class BasicELFBuilder { 104881ad6265SDimitry Andric protected: 104981ad6265SDimitry Andric std::unique_ptr<Object> Obj; 105081ad6265SDimitry Andric 105181ad6265SDimitry Andric void initFileHeader(); 105281ad6265SDimitry Andric void initHeaderSegment(); 105381ad6265SDimitry Andric StringTableSection *addStrTab(); 105481ad6265SDimitry Andric SymbolTableSection *addSymTab(StringTableSection *StrTab); 105581ad6265SDimitry Andric Error initSections(); 105681ad6265SDimitry Andric 105781ad6265SDimitry Andric public: 105881ad6265SDimitry Andric BasicELFBuilder() : Obj(std::make_unique<Object>()) {} 105981ad6265SDimitry Andric }; 106081ad6265SDimitry Andric 106181ad6265SDimitry Andric class BinaryELFBuilder : public BasicELFBuilder { 106281ad6265SDimitry Andric MemoryBuffer *MemBuf; 106381ad6265SDimitry Andric uint8_t NewSymbolVisibility; 106481ad6265SDimitry Andric void addData(SymbolTableSection *SymTab); 106581ad6265SDimitry Andric 106681ad6265SDimitry Andric public: 106781ad6265SDimitry Andric BinaryELFBuilder(MemoryBuffer *MB, uint8_t NewSymbolVisibility) 106881ad6265SDimitry Andric : MemBuf(MB), NewSymbolVisibility(NewSymbolVisibility) {} 106981ad6265SDimitry Andric 107081ad6265SDimitry Andric Expected<std::unique_ptr<Object>> build(); 107181ad6265SDimitry Andric }; 107281ad6265SDimitry Andric 107381ad6265SDimitry Andric class IHexELFBuilder : public BasicELFBuilder { 107481ad6265SDimitry Andric const std::vector<IHexRecord> &Records; 107581ad6265SDimitry Andric 107681ad6265SDimitry Andric void addDataSections(); 107781ad6265SDimitry Andric 107881ad6265SDimitry Andric public: 107981ad6265SDimitry Andric IHexELFBuilder(const std::vector<IHexRecord> &Records) : Records(Records) {} 108081ad6265SDimitry Andric 108181ad6265SDimitry Andric Expected<std::unique_ptr<Object>> build(); 108281ad6265SDimitry Andric }; 108381ad6265SDimitry Andric 108481ad6265SDimitry Andric template <class ELFT> class ELFBuilder { 108581ad6265SDimitry Andric private: 108681ad6265SDimitry Andric using Elf_Addr = typename ELFT::Addr; 108781ad6265SDimitry Andric using Elf_Shdr = typename ELFT::Shdr; 108881ad6265SDimitry Andric using Elf_Word = typename ELFT::Word; 108981ad6265SDimitry Andric 109081ad6265SDimitry Andric const ELFFile<ELFT> &ElfFile; 109181ad6265SDimitry Andric Object &Obj; 109281ad6265SDimitry Andric size_t EhdrOffset = 0; 1093bdd1243dSDimitry Andric std::optional<StringRef> ExtractPartition; 109481ad6265SDimitry Andric 109581ad6265SDimitry Andric void setParentSegment(Segment &Child); 109681ad6265SDimitry Andric Error readProgramHeaders(const ELFFile<ELFT> &HeadersFile); 109781ad6265SDimitry Andric Error initGroupSection(GroupSection *GroupSec); 109881ad6265SDimitry Andric Error initSymbolTable(SymbolTableSection *SymTab); 109981ad6265SDimitry Andric Error readSectionHeaders(); 110081ad6265SDimitry Andric Error readSections(bool EnsureSymtab); 110181ad6265SDimitry Andric Error findEhdrOffset(); 110281ad6265SDimitry Andric Expected<SectionBase &> makeSection(const Elf_Shdr &Shdr); 110381ad6265SDimitry Andric 110481ad6265SDimitry Andric public: 110581ad6265SDimitry Andric ELFBuilder(const ELFObjectFile<ELFT> &ElfObj, Object &Obj, 1106bdd1243dSDimitry Andric std::optional<StringRef> ExtractPartition); 110781ad6265SDimitry Andric 110881ad6265SDimitry Andric Error build(bool EnsureSymtab); 110981ad6265SDimitry Andric }; 111081ad6265SDimitry Andric 111181ad6265SDimitry Andric class BinaryReader : public Reader { 111281ad6265SDimitry Andric MemoryBuffer *MemBuf; 111381ad6265SDimitry Andric uint8_t NewSymbolVisibility; 111481ad6265SDimitry Andric 111581ad6265SDimitry Andric public: 111681ad6265SDimitry Andric BinaryReader(MemoryBuffer *MB, const uint8_t NewSymbolVisibility) 111781ad6265SDimitry Andric : MemBuf(MB), NewSymbolVisibility(NewSymbolVisibility) {} 111881ad6265SDimitry Andric Expected<std::unique_ptr<Object>> create(bool EnsureSymtab) const override; 111981ad6265SDimitry Andric }; 112081ad6265SDimitry Andric 112181ad6265SDimitry Andric class IHexReader : public Reader { 112281ad6265SDimitry Andric MemoryBuffer *MemBuf; 112381ad6265SDimitry Andric 112481ad6265SDimitry Andric Expected<std::vector<IHexRecord>> parse() const; 112581ad6265SDimitry Andric Error parseError(size_t LineNo, Error E) const { 112681ad6265SDimitry Andric return LineNo == -1U 112781ad6265SDimitry Andric ? createFileError(MemBuf->getBufferIdentifier(), std::move(E)) 112881ad6265SDimitry Andric : createFileError(MemBuf->getBufferIdentifier(), LineNo, 112981ad6265SDimitry Andric std::move(E)); 113081ad6265SDimitry Andric } 113181ad6265SDimitry Andric template <typename... Ts> 113281ad6265SDimitry Andric Error parseError(size_t LineNo, char const *Fmt, const Ts &...Vals) const { 113381ad6265SDimitry Andric Error E = createStringError(errc::invalid_argument, Fmt, Vals...); 113481ad6265SDimitry Andric return parseError(LineNo, std::move(E)); 113581ad6265SDimitry Andric } 113681ad6265SDimitry Andric 113781ad6265SDimitry Andric public: 113881ad6265SDimitry Andric IHexReader(MemoryBuffer *MB) : MemBuf(MB) {} 113981ad6265SDimitry Andric 114081ad6265SDimitry Andric Expected<std::unique_ptr<Object>> create(bool EnsureSymtab) const override; 114181ad6265SDimitry Andric }; 114281ad6265SDimitry Andric 114381ad6265SDimitry Andric class ELFReader : public Reader { 114481ad6265SDimitry Andric Binary *Bin; 1145bdd1243dSDimitry Andric std::optional<StringRef> ExtractPartition; 114681ad6265SDimitry Andric 114781ad6265SDimitry Andric public: 114881ad6265SDimitry Andric Expected<std::unique_ptr<Object>> create(bool EnsureSymtab) const override; 1149bdd1243dSDimitry Andric explicit ELFReader(Binary *B, std::optional<StringRef> ExtractPartition) 115081ad6265SDimitry Andric : Bin(B), ExtractPartition(ExtractPartition) {} 115181ad6265SDimitry Andric }; 115281ad6265SDimitry Andric 115381ad6265SDimitry Andric class Object { 115481ad6265SDimitry Andric private: 115581ad6265SDimitry Andric using SecPtr = std::unique_ptr<SectionBase>; 115681ad6265SDimitry Andric using SegPtr = std::unique_ptr<Segment>; 115781ad6265SDimitry Andric 115881ad6265SDimitry Andric std::vector<SecPtr> Sections; 115981ad6265SDimitry Andric std::vector<SegPtr> Segments; 116081ad6265SDimitry Andric std::vector<SecPtr> RemovedSections; 116181ad6265SDimitry Andric DenseMap<SectionBase *, std::vector<uint8_t>> UpdatedSections; 116281ad6265SDimitry Andric 116381ad6265SDimitry Andric static bool sectionIsAlloc(const SectionBase &Sec) { 116481ad6265SDimitry Andric return Sec.Flags & ELF::SHF_ALLOC; 116581ad6265SDimitry Andric }; 116681ad6265SDimitry Andric 116781ad6265SDimitry Andric public: 116881ad6265SDimitry Andric template <class T> 116981ad6265SDimitry Andric using ConstRange = iterator_range<pointee_iterator< 117081ad6265SDimitry Andric typename std::vector<std::unique_ptr<T>>::const_iterator>>; 117181ad6265SDimitry Andric 117281ad6265SDimitry Andric // It is often the case that the ELF header and the program header table are 117381ad6265SDimitry Andric // not present in any segment. This could be a problem during file layout, 117481ad6265SDimitry Andric // because other segments may get assigned an offset where either of the 117581ad6265SDimitry Andric // two should reside, which will effectively corrupt the resulting binary. 117681ad6265SDimitry Andric // Other than that we use these segments to track program header offsets 117781ad6265SDimitry Andric // when they may not follow the ELF header. 117881ad6265SDimitry Andric Segment ElfHdrSegment; 117981ad6265SDimitry Andric Segment ProgramHdrSegment; 118081ad6265SDimitry Andric 1181bdd1243dSDimitry Andric bool Is64Bits; 118281ad6265SDimitry Andric uint8_t OSABI; 118381ad6265SDimitry Andric uint8_t ABIVersion; 118481ad6265SDimitry Andric uint64_t Entry; 118581ad6265SDimitry Andric uint64_t SHOff; 118681ad6265SDimitry Andric uint32_t Type; 118781ad6265SDimitry Andric uint32_t Machine; 118881ad6265SDimitry Andric uint32_t Version; 118981ad6265SDimitry Andric uint32_t Flags; 119081ad6265SDimitry Andric 119181ad6265SDimitry Andric bool HadShdrs = true; 119281ad6265SDimitry Andric bool MustBeRelocatable = false; 119381ad6265SDimitry Andric StringTableSection *SectionNames = nullptr; 119481ad6265SDimitry Andric SymbolTableSection *SymbolTable = nullptr; 119581ad6265SDimitry Andric SectionIndexSection *SectionIndexTable = nullptr; 119681ad6265SDimitry Andric 119781ad6265SDimitry Andric bool IsMips64EL = false; 119881ad6265SDimitry Andric 119981ad6265SDimitry Andric SectionTableRef sections() const { return SectionTableRef(Sections); } 120081ad6265SDimitry Andric iterator_range< 120181ad6265SDimitry Andric filter_iterator<pointee_iterator<std::vector<SecPtr>::const_iterator>, 120281ad6265SDimitry Andric decltype(§ionIsAlloc)>> 120381ad6265SDimitry Andric allocSections() const { 120481ad6265SDimitry Andric return make_filter_range(make_pointee_range(Sections), sectionIsAlloc); 120581ad6265SDimitry Andric } 120681ad6265SDimitry Andric 120781ad6265SDimitry Andric const auto &getUpdatedSections() const { return UpdatedSections; } 120881ad6265SDimitry Andric Error updateSection(StringRef Name, ArrayRef<uint8_t> Data); 120981ad6265SDimitry Andric 121081ad6265SDimitry Andric SectionBase *findSection(StringRef Name) { 121181ad6265SDimitry Andric auto SecIt = 121281ad6265SDimitry Andric find_if(Sections, [&](const SecPtr &Sec) { return Sec->Name == Name; }); 121381ad6265SDimitry Andric return SecIt == Sections.end() ? nullptr : SecIt->get(); 121481ad6265SDimitry Andric } 121581ad6265SDimitry Andric SectionTableRef removedSections() { return SectionTableRef(RemovedSections); } 121681ad6265SDimitry Andric 121781ad6265SDimitry Andric ConstRange<Segment> segments() const { return make_pointee_range(Segments); } 121881ad6265SDimitry Andric 121981ad6265SDimitry Andric Error removeSections(bool AllowBrokenLinks, 122081ad6265SDimitry Andric std::function<bool(const SectionBase &)> ToRemove); 1221*0fca6ea1SDimitry Andric Error compressOrDecompressSections(const CommonConfig &Config); 122281ad6265SDimitry Andric Error replaceSections(const DenseMap<SectionBase *, SectionBase *> &FromTo); 122381ad6265SDimitry Andric Error removeSymbols(function_ref<bool(const Symbol &)> ToRemove); 122481ad6265SDimitry Andric template <class T, class... Ts> T &addSection(Ts &&...Args) { 122581ad6265SDimitry Andric auto Sec = std::make_unique<T>(std::forward<Ts>(Args)...); 122681ad6265SDimitry Andric auto Ptr = Sec.get(); 122781ad6265SDimitry Andric MustBeRelocatable |= isa<RelocationSection>(*Ptr); 122881ad6265SDimitry Andric Sections.emplace_back(std::move(Sec)); 122981ad6265SDimitry Andric Ptr->Index = Sections.size(); 123081ad6265SDimitry Andric return *Ptr; 123181ad6265SDimitry Andric } 123281ad6265SDimitry Andric Error addNewSymbolTable(); 123381ad6265SDimitry Andric Segment &addSegment(ArrayRef<uint8_t> Data) { 123481ad6265SDimitry Andric Segments.emplace_back(std::make_unique<Segment>(Data)); 123581ad6265SDimitry Andric return *Segments.back(); 123681ad6265SDimitry Andric } 123781ad6265SDimitry Andric bool isRelocatable() const { 123881ad6265SDimitry Andric return (Type != ELF::ET_DYN && Type != ELF::ET_EXEC) || MustBeRelocatable; 123981ad6265SDimitry Andric } 124081ad6265SDimitry Andric }; 124181ad6265SDimitry Andric 124281ad6265SDimitry Andric } // end namespace elf 124381ad6265SDimitry Andric } // end namespace objcopy 124481ad6265SDimitry Andric } // end namespace llvm 124581ad6265SDimitry Andric 124681ad6265SDimitry Andric #endif // LLVM_LIB_OBJCOPY_ELF_ELFOBJECT_H 1247