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