10b57cec5SDimitry Andric //===- lib/MC/ELFObjectWriter.cpp - ELF File Writer -----------------------===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 90b57cec5SDimitry Andric // This file implements ELF object file writer information. 100b57cec5SDimitry Andric // 110b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 120b57cec5SDimitry Andric 130b57cec5SDimitry Andric #include "llvm/ADT/ArrayRef.h" 140b57cec5SDimitry Andric #include "llvm/ADT/DenseMap.h" 150b57cec5SDimitry Andric #include "llvm/ADT/STLExtras.h" 160b57cec5SDimitry Andric #include "llvm/ADT/SmallVector.h" 1706c3fb27SDimitry Andric #include "llvm/ADT/StringExtras.h" 180b57cec5SDimitry Andric #include "llvm/ADT/StringRef.h" 190b57cec5SDimitry Andric #include "llvm/ADT/Twine.h" 2081ad6265SDimitry Andric #include "llvm/ADT/iterator.h" 210b57cec5SDimitry Andric #include "llvm/BinaryFormat/ELF.h" 220b57cec5SDimitry Andric #include "llvm/MC/MCAsmBackend.h" 230b57cec5SDimitry Andric #include "llvm/MC/MCAsmInfo.h" 240b57cec5SDimitry Andric #include "llvm/MC/MCAssembler.h" 250b57cec5SDimitry Andric #include "llvm/MC/MCContext.h" 26*0fca6ea1SDimitry Andric #include "llvm/MC/MCELFExtras.h" 270b57cec5SDimitry Andric #include "llvm/MC/MCELFObjectWriter.h" 280b57cec5SDimitry Andric #include "llvm/MC/MCExpr.h" 290b57cec5SDimitry Andric #include "llvm/MC/MCFixup.h" 300b57cec5SDimitry Andric #include "llvm/MC/MCFixupKindInfo.h" 310b57cec5SDimitry Andric #include "llvm/MC/MCFragment.h" 320b57cec5SDimitry Andric #include "llvm/MC/MCObjectWriter.h" 330b57cec5SDimitry Andric #include "llvm/MC/MCSection.h" 340b57cec5SDimitry Andric #include "llvm/MC/MCSectionELF.h" 350b57cec5SDimitry Andric #include "llvm/MC/MCSymbol.h" 360b57cec5SDimitry Andric #include "llvm/MC/MCSymbolELF.h" 3781ad6265SDimitry Andric #include "llvm/MC/MCTargetOptions.h" 380b57cec5SDimitry Andric #include "llvm/MC/MCValue.h" 390b57cec5SDimitry Andric #include "llvm/MC/StringTableBuilder.h" 408bcb0991SDimitry Andric #include "llvm/Support/Alignment.h" 410b57cec5SDimitry Andric #include "llvm/Support/Casting.h" 42*0fca6ea1SDimitry Andric #include "llvm/Support/CommandLine.h" 430b57cec5SDimitry Andric #include "llvm/Support/Compression.h" 4481ad6265SDimitry Andric #include "llvm/Support/Endian.h" 455ffd83dbSDimitry Andric #include "llvm/Support/EndianStream.h" 460b57cec5SDimitry Andric #include "llvm/Support/Error.h" 470b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h" 480b57cec5SDimitry Andric #include "llvm/Support/LEB128.h" 490b57cec5SDimitry Andric #include "llvm/Support/MathExtras.h" 500b57cec5SDimitry Andric #include "llvm/Support/SMLoc.h" 510b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h" 5206c3fb27SDimitry Andric #include "llvm/TargetParser/Host.h" 530b57cec5SDimitry Andric #include <algorithm> 540b57cec5SDimitry Andric #include <cassert> 550b57cec5SDimitry Andric #include <cstddef> 560b57cec5SDimitry Andric #include <cstdint> 570b57cec5SDimitry Andric #include <map> 580b57cec5SDimitry Andric #include <memory> 590b57cec5SDimitry Andric #include <string> 600b57cec5SDimitry Andric #include <utility> 610b57cec5SDimitry Andric #include <vector> 620b57cec5SDimitry Andric 630b57cec5SDimitry Andric using namespace llvm; 640b57cec5SDimitry Andric 650b57cec5SDimitry Andric #undef DEBUG_TYPE 660b57cec5SDimitry Andric #define DEBUG_TYPE "reloc-info" 670b57cec5SDimitry Andric 680b57cec5SDimitry Andric namespace { 690b57cec5SDimitry Andric 700b57cec5SDimitry Andric struct ELFWriter; 710b57cec5SDimitry Andric 720b57cec5SDimitry Andric bool isDwoSection(const MCSectionELF &Sec) { 735f757f3fSDimitry Andric return Sec.getName().ends_with(".dwo"); 740b57cec5SDimitry Andric } 750b57cec5SDimitry Andric 760b57cec5SDimitry Andric class SymbolTableWriter { 770b57cec5SDimitry Andric ELFWriter &EWriter; 780b57cec5SDimitry Andric bool Is64Bit; 790b57cec5SDimitry Andric 800b57cec5SDimitry Andric // indexes we are going to write to .symtab_shndx. 810b57cec5SDimitry Andric std::vector<uint32_t> ShndxIndexes; 820b57cec5SDimitry Andric 830b57cec5SDimitry Andric // The numbel of symbols written so far. 840b57cec5SDimitry Andric unsigned NumWritten; 850b57cec5SDimitry Andric 860b57cec5SDimitry Andric void createSymtabShndx(); 870b57cec5SDimitry Andric 880b57cec5SDimitry Andric template <typename T> void write(T Value); 890b57cec5SDimitry Andric 900b57cec5SDimitry Andric public: 910b57cec5SDimitry Andric SymbolTableWriter(ELFWriter &EWriter, bool Is64Bit); 920b57cec5SDimitry Andric 930b57cec5SDimitry Andric void writeSymbol(uint32_t name, uint8_t info, uint64_t value, uint64_t size, 940b57cec5SDimitry Andric uint8_t other, uint32_t shndx, bool Reserved); 950b57cec5SDimitry Andric 960b57cec5SDimitry Andric ArrayRef<uint32_t> getShndxIndexes() const { return ShndxIndexes; } 970b57cec5SDimitry Andric }; 980b57cec5SDimitry Andric 990b57cec5SDimitry Andric struct ELFWriter { 1000b57cec5SDimitry Andric ELFObjectWriter &OWriter; 1010b57cec5SDimitry Andric support::endian::Writer W; 1020b57cec5SDimitry Andric 1030b57cec5SDimitry Andric enum DwoMode { 1040b57cec5SDimitry Andric AllSections, 1050b57cec5SDimitry Andric NonDwoOnly, 1060b57cec5SDimitry Andric DwoOnly, 1070b57cec5SDimitry Andric } Mode; 1080b57cec5SDimitry Andric 109*0fca6ea1SDimitry Andric static uint64_t symbolValue(const MCAssembler &Asm, const MCSymbol &Sym); 110*0fca6ea1SDimitry Andric static bool isInSymtab(const MCAssembler &Asm, const MCSymbolELF &Symbol, 1110b57cec5SDimitry Andric bool Used, bool Renamed); 1120b57cec5SDimitry Andric 1130b57cec5SDimitry Andric /// Helper struct for containing some precomputed information on symbols. 1140b57cec5SDimitry Andric struct ELFSymbolData { 1150b57cec5SDimitry Andric const MCSymbolELF *Symbol; 1160b57cec5SDimitry Andric StringRef Name; 117fe6060f1SDimitry Andric uint32_t SectionIndex; 118fe6060f1SDimitry Andric uint32_t Order; 1190b57cec5SDimitry Andric }; 1200b57cec5SDimitry Andric 1210b57cec5SDimitry Andric /// @} 1220b57cec5SDimitry Andric /// @name Symbol Table Data 1230b57cec5SDimitry Andric /// @{ 1240b57cec5SDimitry Andric 1250b57cec5SDimitry Andric StringTableBuilder StrTabBuilder{StringTableBuilder::ELF}; 1260b57cec5SDimitry Andric 1270b57cec5SDimitry Andric /// @} 1280b57cec5SDimitry Andric 1290b57cec5SDimitry Andric // This holds the symbol table index of the last local symbol. 13006c3fb27SDimitry Andric unsigned LastLocalSymbolIndex = ~0u; 1310b57cec5SDimitry Andric // This holds the .strtab section index. 13206c3fb27SDimitry Andric unsigned StringTableIndex = ~0u; 1330b57cec5SDimitry Andric // This holds the .symtab section index. 13406c3fb27SDimitry Andric unsigned SymbolTableIndex = ~0u; 1350b57cec5SDimitry Andric 1360b57cec5SDimitry Andric // Sections in the order they are to be output in the section table. 137*0fca6ea1SDimitry Andric std::vector<MCSectionELF *> SectionTable; 138*0fca6ea1SDimitry Andric unsigned addToSectionTable(MCSectionELF *Sec); 1390b57cec5SDimitry Andric 1400b57cec5SDimitry Andric // TargetObjectWriter wrappers. 1410b57cec5SDimitry Andric bool is64Bit() const; 1420b57cec5SDimitry Andric 143bdd1243dSDimitry Andric uint64_t align(Align Alignment); 1440b57cec5SDimitry Andric 145fcaf7f86SDimitry Andric bool maybeWriteCompression(uint32_t ChType, uint64_t Size, 146753f127fSDimitry Andric SmallVectorImpl<uint8_t> &CompressedContents, 147bdd1243dSDimitry Andric Align Alignment); 1480b57cec5SDimitry Andric 1490b57cec5SDimitry Andric public: 1500b57cec5SDimitry Andric ELFWriter(ELFObjectWriter &OWriter, raw_pwrite_stream &OS, 1510b57cec5SDimitry Andric bool IsLittleEndian, DwoMode Mode) 1525f757f3fSDimitry Andric : OWriter(OWriter), W(OS, IsLittleEndian ? llvm::endianness::little 1535f757f3fSDimitry Andric : llvm::endianness::big), 1545f757f3fSDimitry Andric Mode(Mode) {} 1550b57cec5SDimitry Andric 1560b57cec5SDimitry Andric void WriteWord(uint64_t Word) { 1570b57cec5SDimitry Andric if (is64Bit()) 1580b57cec5SDimitry Andric W.write<uint64_t>(Word); 1590b57cec5SDimitry Andric else 1600b57cec5SDimitry Andric W.write<uint32_t>(Word); 1610b57cec5SDimitry Andric } 1620b57cec5SDimitry Andric 1630b57cec5SDimitry Andric template <typename T> void write(T Val) { 1640b57cec5SDimitry Andric W.write(Val); 1650b57cec5SDimitry Andric } 1660b57cec5SDimitry Andric 1670b57cec5SDimitry Andric void writeHeader(const MCAssembler &Asm); 1680b57cec5SDimitry Andric 169*0fca6ea1SDimitry Andric void writeSymbol(const MCAssembler &Asm, SymbolTableWriter &Writer, 170*0fca6ea1SDimitry Andric uint32_t StringIndex, ELFSymbolData &MSD); 1710b57cec5SDimitry Andric 1720b57cec5SDimitry Andric // Map from a signature symbol to the group section index 1730b57cec5SDimitry Andric using RevGroupMapTy = DenseMap<const MCSymbol *, unsigned>; 1740b57cec5SDimitry Andric 1750b57cec5SDimitry Andric /// Compute the symbol table data 1760b57cec5SDimitry Andric /// 1770b57cec5SDimitry Andric /// \param Asm - The assembler. 1780b57cec5SDimitry Andric /// \param RevGroupMap - Maps a signature symbol to the group section. 179*0fca6ea1SDimitry Andric void computeSymbolTable(MCAssembler &Asm, const RevGroupMapTy &RevGroupMap); 1800b57cec5SDimitry Andric 1810b57cec5SDimitry Andric void writeAddrsigSection(); 1820b57cec5SDimitry Andric 1830b57cec5SDimitry Andric MCSectionELF *createRelocationSection(MCContext &Ctx, 1840b57cec5SDimitry Andric const MCSectionELF &Sec); 1850b57cec5SDimitry Andric 186*0fca6ea1SDimitry Andric void writeSectionHeader(const MCAssembler &Asm); 187bdd1243dSDimitry Andric 188*0fca6ea1SDimitry Andric void writeSectionData(const MCAssembler &Asm, MCSection &Sec); 1890b57cec5SDimitry Andric 1900b57cec5SDimitry Andric void WriteSecHdrEntry(uint32_t Name, uint32_t Type, uint64_t Flags, 1910b57cec5SDimitry Andric uint64_t Address, uint64_t Offset, uint64_t Size, 192bdd1243dSDimitry Andric uint32_t Link, uint32_t Info, MaybeAlign Alignment, 1930b57cec5SDimitry Andric uint64_t EntrySize); 1940b57cec5SDimitry Andric 1950b57cec5SDimitry Andric void writeRelocations(const MCAssembler &Asm, const MCSectionELF &Sec); 1960b57cec5SDimitry Andric 197*0fca6ea1SDimitry Andric uint64_t writeObject(MCAssembler &Asm); 198*0fca6ea1SDimitry Andric void writeSection(uint32_t GroupSymbolIndex, uint64_t Offset, uint64_t Size, 1990b57cec5SDimitry Andric const MCSectionELF &Section); 2000b57cec5SDimitry Andric }; 2010b57cec5SDimitry Andric } // end anonymous namespace 2020b57cec5SDimitry Andric 203bdd1243dSDimitry Andric uint64_t ELFWriter::align(Align Alignment) { 204bdd1243dSDimitry Andric uint64_t Offset = W.OS.tell(); 205bdd1243dSDimitry Andric uint64_t NewOffset = alignTo(Offset, Alignment); 206fe6060f1SDimitry Andric W.OS.write_zeros(NewOffset - Offset); 207fe6060f1SDimitry Andric return NewOffset; 2080b57cec5SDimitry Andric } 2090b57cec5SDimitry Andric 210*0fca6ea1SDimitry Andric unsigned ELFWriter::addToSectionTable(MCSectionELF *Sec) { 2110b57cec5SDimitry Andric SectionTable.push_back(Sec); 2125ffd83dbSDimitry Andric StrTabBuilder.add(Sec->getName()); 2130b57cec5SDimitry Andric return SectionTable.size(); 2140b57cec5SDimitry Andric } 2150b57cec5SDimitry Andric 2160b57cec5SDimitry Andric void SymbolTableWriter::createSymtabShndx() { 2170b57cec5SDimitry Andric if (!ShndxIndexes.empty()) 2180b57cec5SDimitry Andric return; 2190b57cec5SDimitry Andric 2200b57cec5SDimitry Andric ShndxIndexes.resize(NumWritten); 2210b57cec5SDimitry Andric } 2220b57cec5SDimitry Andric 2230b57cec5SDimitry Andric template <typename T> void SymbolTableWriter::write(T Value) { 2240b57cec5SDimitry Andric EWriter.write(Value); 2250b57cec5SDimitry Andric } 2260b57cec5SDimitry Andric 2270b57cec5SDimitry Andric SymbolTableWriter::SymbolTableWriter(ELFWriter &EWriter, bool Is64Bit) 2280b57cec5SDimitry Andric : EWriter(EWriter), Is64Bit(Is64Bit), NumWritten(0) {} 2290b57cec5SDimitry Andric 2300b57cec5SDimitry Andric void SymbolTableWriter::writeSymbol(uint32_t name, uint8_t info, uint64_t value, 2310b57cec5SDimitry Andric uint64_t size, uint8_t other, 2320b57cec5SDimitry Andric uint32_t shndx, bool Reserved) { 2330b57cec5SDimitry Andric bool LargeIndex = shndx >= ELF::SHN_LORESERVE && !Reserved; 2340b57cec5SDimitry Andric 2350b57cec5SDimitry Andric if (LargeIndex) 2360b57cec5SDimitry Andric createSymtabShndx(); 2370b57cec5SDimitry Andric 2380b57cec5SDimitry Andric if (!ShndxIndexes.empty()) { 2390b57cec5SDimitry Andric if (LargeIndex) 2400b57cec5SDimitry Andric ShndxIndexes.push_back(shndx); 2410b57cec5SDimitry Andric else 2420b57cec5SDimitry Andric ShndxIndexes.push_back(0); 2430b57cec5SDimitry Andric } 2440b57cec5SDimitry Andric 2450b57cec5SDimitry Andric uint16_t Index = LargeIndex ? uint16_t(ELF::SHN_XINDEX) : shndx; 2460b57cec5SDimitry Andric 2470b57cec5SDimitry Andric if (Is64Bit) { 2480b57cec5SDimitry Andric write(name); // st_name 2490b57cec5SDimitry Andric write(info); // st_info 2500b57cec5SDimitry Andric write(other); // st_other 2510b57cec5SDimitry Andric write(Index); // st_shndx 2520b57cec5SDimitry Andric write(value); // st_value 2530b57cec5SDimitry Andric write(size); // st_size 2540b57cec5SDimitry Andric } else { 2550b57cec5SDimitry Andric write(name); // st_name 2560b57cec5SDimitry Andric write(uint32_t(value)); // st_value 2570b57cec5SDimitry Andric write(uint32_t(size)); // st_size 2580b57cec5SDimitry Andric write(info); // st_info 2590b57cec5SDimitry Andric write(other); // st_other 2600b57cec5SDimitry Andric write(Index); // st_shndx 2610b57cec5SDimitry Andric } 2620b57cec5SDimitry Andric 2630b57cec5SDimitry Andric ++NumWritten; 2640b57cec5SDimitry Andric } 2650b57cec5SDimitry Andric 2660b57cec5SDimitry Andric bool ELFWriter::is64Bit() const { 2670b57cec5SDimitry Andric return OWriter.TargetObjectWriter->is64Bit(); 2680b57cec5SDimitry Andric } 2690b57cec5SDimitry Andric 2700b57cec5SDimitry Andric // Emit the ELF header. 2710b57cec5SDimitry Andric void ELFWriter::writeHeader(const MCAssembler &Asm) { 2720b57cec5SDimitry Andric // ELF Header 2730b57cec5SDimitry Andric // ---------- 2740b57cec5SDimitry Andric // 2750b57cec5SDimitry Andric // Note 2760b57cec5SDimitry Andric // ---- 2770b57cec5SDimitry Andric // emitWord method behaves differently for ELF32 and ELF64, writing 2780b57cec5SDimitry Andric // 4 bytes in the former and 8 in the latter. 2790b57cec5SDimitry Andric 2800b57cec5SDimitry Andric W.OS << ELF::ElfMagic; // e_ident[EI_MAG0] to e_ident[EI_MAG3] 2810b57cec5SDimitry Andric 2820b57cec5SDimitry Andric W.OS << char(is64Bit() ? ELF::ELFCLASS64 : ELF::ELFCLASS32); // e_ident[EI_CLASS] 2830b57cec5SDimitry Andric 2840b57cec5SDimitry Andric // e_ident[EI_DATA] 2855f757f3fSDimitry Andric W.OS << char(W.Endian == llvm::endianness::little ? ELF::ELFDATA2LSB 2860b57cec5SDimitry Andric : ELF::ELFDATA2MSB); 2870b57cec5SDimitry Andric 2880b57cec5SDimitry Andric W.OS << char(ELF::EV_CURRENT); // e_ident[EI_VERSION] 2890b57cec5SDimitry Andric // e_ident[EI_OSABI] 290fe6060f1SDimitry Andric uint8_t OSABI = OWriter.TargetObjectWriter->getOSABI(); 291fe6060f1SDimitry Andric W.OS << char(OSABI == ELF::ELFOSABI_NONE && OWriter.seenGnuAbi() 292fe6060f1SDimitry Andric ? int(ELF::ELFOSABI_GNU) 293fe6060f1SDimitry Andric : OSABI); 2940b57cec5SDimitry Andric // e_ident[EI_ABIVERSION] 295*0fca6ea1SDimitry Andric W.OS << char(OWriter.OverrideABIVersion 296*0fca6ea1SDimitry Andric ? *OWriter.OverrideABIVersion 2977a6dacacSDimitry Andric : OWriter.TargetObjectWriter->getABIVersion()); 2980b57cec5SDimitry Andric 2990b57cec5SDimitry Andric W.OS.write_zeros(ELF::EI_NIDENT - ELF::EI_PAD); 3000b57cec5SDimitry Andric 3010b57cec5SDimitry Andric W.write<uint16_t>(ELF::ET_REL); // e_type 3020b57cec5SDimitry Andric 3030b57cec5SDimitry Andric W.write<uint16_t>(OWriter.TargetObjectWriter->getEMachine()); // e_machine = target 3040b57cec5SDimitry Andric 3050b57cec5SDimitry Andric W.write<uint32_t>(ELF::EV_CURRENT); // e_version 3060b57cec5SDimitry Andric WriteWord(0); // e_entry, no entry point in .o file 3070b57cec5SDimitry Andric WriteWord(0); // e_phoff, no program header for .o 3080b57cec5SDimitry Andric WriteWord(0); // e_shoff = sec hdr table off in bytes 3090b57cec5SDimitry Andric 3100b57cec5SDimitry Andric // e_flags = whatever the target wants 311*0fca6ea1SDimitry Andric W.write<uint32_t>(OWriter.getELFHeaderEFlags()); 3120b57cec5SDimitry Andric 3130b57cec5SDimitry Andric // e_ehsize = ELF header size 3140b57cec5SDimitry Andric W.write<uint16_t>(is64Bit() ? sizeof(ELF::Elf64_Ehdr) 3150b57cec5SDimitry Andric : sizeof(ELF::Elf32_Ehdr)); 3160b57cec5SDimitry Andric 3170b57cec5SDimitry Andric W.write<uint16_t>(0); // e_phentsize = prog header entry size 3180b57cec5SDimitry Andric W.write<uint16_t>(0); // e_phnum = # prog header entries = 0 3190b57cec5SDimitry Andric 3200b57cec5SDimitry Andric // e_shentsize = Section header entry size 3210b57cec5SDimitry Andric W.write<uint16_t>(is64Bit() ? sizeof(ELF::Elf64_Shdr) 3220b57cec5SDimitry Andric : sizeof(ELF::Elf32_Shdr)); 3230b57cec5SDimitry Andric 3240b57cec5SDimitry Andric // e_shnum = # of section header ents 3250b57cec5SDimitry Andric W.write<uint16_t>(0); 3260b57cec5SDimitry Andric 327fe6060f1SDimitry Andric // e_shstrndx = Section # of '.strtab' 3280b57cec5SDimitry Andric assert(StringTableIndex < ELF::SHN_LORESERVE); 3290b57cec5SDimitry Andric W.write<uint16_t>(StringTableIndex); 3300b57cec5SDimitry Andric } 3310b57cec5SDimitry Andric 332*0fca6ea1SDimitry Andric uint64_t ELFWriter::symbolValue(const MCAssembler &Asm, const MCSymbol &Sym) { 333e8d8bef9SDimitry Andric if (Sym.isCommon()) 334bdd1243dSDimitry Andric return Sym.getCommonAlignment()->value(); 3350b57cec5SDimitry Andric 3360b57cec5SDimitry Andric uint64_t Res; 337*0fca6ea1SDimitry Andric if (!Asm.getSymbolOffset(Sym, Res)) 3380b57cec5SDimitry Andric return 0; 3390b57cec5SDimitry Andric 340*0fca6ea1SDimitry Andric if (Asm.isThumbFunc(&Sym)) 3410b57cec5SDimitry Andric Res |= 1; 3420b57cec5SDimitry Andric 3430b57cec5SDimitry Andric return Res; 3440b57cec5SDimitry Andric } 3450b57cec5SDimitry Andric 3460b57cec5SDimitry Andric static uint8_t mergeTypeForSet(uint8_t origType, uint8_t newType) { 3470b57cec5SDimitry Andric uint8_t Type = newType; 3480b57cec5SDimitry Andric 3490b57cec5SDimitry Andric // Propagation rules: 3500b57cec5SDimitry Andric // IFUNC > FUNC > OBJECT > NOTYPE 3510b57cec5SDimitry Andric // TLS_OBJECT > OBJECT > NOTYPE 3520b57cec5SDimitry Andric // 3530b57cec5SDimitry Andric // dont let the new type degrade the old type 3540b57cec5SDimitry Andric switch (origType) { 3550b57cec5SDimitry Andric default: 3560b57cec5SDimitry Andric break; 3570b57cec5SDimitry Andric case ELF::STT_GNU_IFUNC: 3580b57cec5SDimitry Andric if (Type == ELF::STT_FUNC || Type == ELF::STT_OBJECT || 3590b57cec5SDimitry Andric Type == ELF::STT_NOTYPE || Type == ELF::STT_TLS) 3600b57cec5SDimitry Andric Type = ELF::STT_GNU_IFUNC; 3610b57cec5SDimitry Andric break; 3620b57cec5SDimitry Andric case ELF::STT_FUNC: 3630b57cec5SDimitry Andric if (Type == ELF::STT_OBJECT || Type == ELF::STT_NOTYPE || 3640b57cec5SDimitry Andric Type == ELF::STT_TLS) 3650b57cec5SDimitry Andric Type = ELF::STT_FUNC; 3660b57cec5SDimitry Andric break; 3670b57cec5SDimitry Andric case ELF::STT_OBJECT: 3680b57cec5SDimitry Andric if (Type == ELF::STT_NOTYPE) 3690b57cec5SDimitry Andric Type = ELF::STT_OBJECT; 3700b57cec5SDimitry Andric break; 3710b57cec5SDimitry Andric case ELF::STT_TLS: 3720b57cec5SDimitry Andric if (Type == ELF::STT_OBJECT || Type == ELF::STT_NOTYPE || 3730b57cec5SDimitry Andric Type == ELF::STT_GNU_IFUNC || Type == ELF::STT_FUNC) 3740b57cec5SDimitry Andric Type = ELF::STT_TLS; 3750b57cec5SDimitry Andric break; 3760b57cec5SDimitry Andric } 3770b57cec5SDimitry Andric 3780b57cec5SDimitry Andric return Type; 3790b57cec5SDimitry Andric } 3800b57cec5SDimitry Andric 3818bcb0991SDimitry Andric static bool isIFunc(const MCSymbolELF *Symbol) { 3828bcb0991SDimitry Andric while (Symbol->getType() != ELF::STT_GNU_IFUNC) { 3838bcb0991SDimitry Andric const MCSymbolRefExpr *Value; 3848bcb0991SDimitry Andric if (!Symbol->isVariable() || 3858bcb0991SDimitry Andric !(Value = dyn_cast<MCSymbolRefExpr>(Symbol->getVariableValue())) || 3868bcb0991SDimitry Andric Value->getKind() != MCSymbolRefExpr::VK_None || 3878bcb0991SDimitry Andric mergeTypeForSet(Symbol->getType(), ELF::STT_GNU_IFUNC) != ELF::STT_GNU_IFUNC) 3888bcb0991SDimitry Andric return false; 3898bcb0991SDimitry Andric Symbol = &cast<MCSymbolELF>(Value->getSymbol()); 3908bcb0991SDimitry Andric } 3918bcb0991SDimitry Andric return true; 3928bcb0991SDimitry Andric } 3938bcb0991SDimitry Andric 394*0fca6ea1SDimitry Andric void ELFWriter::writeSymbol(const MCAssembler &Asm, SymbolTableWriter &Writer, 395*0fca6ea1SDimitry Andric uint32_t StringIndex, ELFSymbolData &MSD) { 3960b57cec5SDimitry Andric const auto &Symbol = cast<MCSymbolELF>(*MSD.Symbol); 3970b57cec5SDimitry Andric const MCSymbolELF *Base = 398*0fca6ea1SDimitry Andric cast_or_null<MCSymbolELF>(Asm.getBaseSymbol(Symbol)); 3990b57cec5SDimitry Andric 4000b57cec5SDimitry Andric // This has to be in sync with when computeSymbolTable uses SHN_ABS or 4010b57cec5SDimitry Andric // SHN_COMMON. 4020b57cec5SDimitry Andric bool IsReserved = !Base || Symbol.isCommon(); 4030b57cec5SDimitry Andric 4040b57cec5SDimitry Andric // Binding and Type share the same byte as upper and lower nibbles 4050b57cec5SDimitry Andric uint8_t Binding = Symbol.getBinding(); 4060b57cec5SDimitry Andric uint8_t Type = Symbol.getType(); 4078bcb0991SDimitry Andric if (isIFunc(&Symbol)) 4088bcb0991SDimitry Andric Type = ELF::STT_GNU_IFUNC; 4090b57cec5SDimitry Andric if (Base) { 4100b57cec5SDimitry Andric Type = mergeTypeForSet(Type, Base->getType()); 4110b57cec5SDimitry Andric } 4120b57cec5SDimitry Andric uint8_t Info = (Binding << 4) | Type; 4130b57cec5SDimitry Andric 4140b57cec5SDimitry Andric // Other and Visibility share the same byte with Visibility using the lower 4150b57cec5SDimitry Andric // 2 bits 4160b57cec5SDimitry Andric uint8_t Visibility = Symbol.getVisibility(); 4170b57cec5SDimitry Andric uint8_t Other = Symbol.getOther() | Visibility; 4180b57cec5SDimitry Andric 419*0fca6ea1SDimitry Andric uint64_t Value = symbolValue(Asm, *MSD.Symbol); 4200b57cec5SDimitry Andric uint64_t Size = 0; 4210b57cec5SDimitry Andric 4220b57cec5SDimitry Andric const MCExpr *ESize = MSD.Symbol->getSize(); 4232a66634dSDimitry Andric if (!ESize && Base) { 4242a66634dSDimitry Andric // For expressions like .set y, x+1, if y's size is unset, inherit from x. 4250b57cec5SDimitry Andric ESize = Base->getSize(); 4260b57cec5SDimitry Andric 4272a66634dSDimitry Andric // For `.size x, 2; y = x; .size y, 1; z = y; z1 = z; .symver y, y@v1`, z, 4282a66634dSDimitry Andric // z1, and y@v1's st_size equals y's. However, `Base` is `x` which will give 4292a66634dSDimitry Andric // us 2. Follow the MCSymbolRefExpr assignment chain, which covers most 4302a66634dSDimitry Andric // needs. MCBinaryExpr is not handled. 4312a66634dSDimitry Andric const MCSymbolELF *Sym = &Symbol; 4322a66634dSDimitry Andric while (Sym->isVariable()) { 4332a66634dSDimitry Andric if (auto *Expr = 4342a66634dSDimitry Andric dyn_cast<MCSymbolRefExpr>(Sym->getVariableValue(false))) { 4352a66634dSDimitry Andric Sym = cast<MCSymbolELF>(&Expr->getSymbol()); 4362a66634dSDimitry Andric if (!Sym->getSize()) 4372a66634dSDimitry Andric continue; 4382a66634dSDimitry Andric ESize = Sym->getSize(); 4392a66634dSDimitry Andric } 4402a66634dSDimitry Andric break; 4412a66634dSDimitry Andric } 4422a66634dSDimitry Andric } 4432a66634dSDimitry Andric 4440b57cec5SDimitry Andric if (ESize) { 4450b57cec5SDimitry Andric int64_t Res; 446*0fca6ea1SDimitry Andric if (!ESize->evaluateKnownAbsolute(Res, Asm)) 4470b57cec5SDimitry Andric report_fatal_error("Size expression must be absolute."); 4480b57cec5SDimitry Andric Size = Res; 4490b57cec5SDimitry Andric } 4500b57cec5SDimitry Andric 4510b57cec5SDimitry Andric // Write out the symbol table entry 4520b57cec5SDimitry Andric Writer.writeSymbol(StringIndex, Info, Value, Size, Other, MSD.SectionIndex, 4530b57cec5SDimitry Andric IsReserved); 4540b57cec5SDimitry Andric } 4550b57cec5SDimitry Andric 456*0fca6ea1SDimitry Andric bool ELFWriter::isInSymtab(const MCAssembler &Asm, const MCSymbolELF &Symbol, 4570b57cec5SDimitry Andric bool Used, bool Renamed) { 4580b57cec5SDimitry Andric if (Symbol.isVariable()) { 4590b57cec5SDimitry Andric const MCExpr *Expr = Symbol.getVariableValue(); 4600b57cec5SDimitry Andric // Target Expressions that are always inlined do not appear in the symtab 4610b57cec5SDimitry Andric if (const auto *T = dyn_cast<MCTargetExpr>(Expr)) 4620b57cec5SDimitry Andric if (T->inlineAssignedExpr()) 4630b57cec5SDimitry Andric return false; 4640b57cec5SDimitry Andric if (const MCSymbolRefExpr *Ref = dyn_cast<MCSymbolRefExpr>(Expr)) { 4650b57cec5SDimitry Andric if (Ref->getKind() == MCSymbolRefExpr::VK_WEAKREF) 4660b57cec5SDimitry Andric return false; 4670b57cec5SDimitry Andric } 4680b57cec5SDimitry Andric } 4690b57cec5SDimitry Andric 4700b57cec5SDimitry Andric if (Used) 4710b57cec5SDimitry Andric return true; 4720b57cec5SDimitry Andric 4730b57cec5SDimitry Andric if (Renamed) 4740b57cec5SDimitry Andric return false; 4750b57cec5SDimitry Andric 4760b57cec5SDimitry Andric if (Symbol.isVariable() && Symbol.isUndefined()) { 4770b57cec5SDimitry Andric // FIXME: this is here just to diagnose the case of a var = commmon_sym. 478*0fca6ea1SDimitry Andric Asm.getBaseSymbol(Symbol); 4790b57cec5SDimitry Andric return false; 4800b57cec5SDimitry Andric } 4810b57cec5SDimitry Andric 4820b57cec5SDimitry Andric if (Symbol.isTemporary()) 4830b57cec5SDimitry Andric return false; 4840b57cec5SDimitry Andric 4850b57cec5SDimitry Andric if (Symbol.getType() == ELF::STT_SECTION) 4860b57cec5SDimitry Andric return false; 4870b57cec5SDimitry Andric 4880b57cec5SDimitry Andric return true; 4890b57cec5SDimitry Andric } 4900b57cec5SDimitry Andric 491*0fca6ea1SDimitry Andric void ELFWriter::computeSymbolTable(MCAssembler &Asm, 492*0fca6ea1SDimitry Andric const RevGroupMapTy &RevGroupMap) { 4930b57cec5SDimitry Andric MCContext &Ctx = Asm.getContext(); 4940b57cec5SDimitry Andric SymbolTableWriter Writer(*this, is64Bit()); 4950b57cec5SDimitry Andric 4960b57cec5SDimitry Andric // Symbol table 4970b57cec5SDimitry Andric unsigned EntrySize = is64Bit() ? ELF::SYMENTRY_SIZE64 : ELF::SYMENTRY_SIZE32; 4980b57cec5SDimitry Andric MCSectionELF *SymtabSection = 499fe6060f1SDimitry Andric Ctx.getELFSection(".symtab", ELF::SHT_SYMTAB, 0, EntrySize); 5008bcb0991SDimitry Andric SymtabSection->setAlignment(is64Bit() ? Align(8) : Align(4)); 5010b57cec5SDimitry Andric SymbolTableIndex = addToSectionTable(SymtabSection); 5020b57cec5SDimitry Andric 503bdd1243dSDimitry Andric uint64_t SecStart = align(SymtabSection->getAlign()); 5040b57cec5SDimitry Andric 5050b57cec5SDimitry Andric // The first entry is the undefined symbol entry. 5060b57cec5SDimitry Andric Writer.writeSymbol(0, 0, 0, 0, 0, 0, false); 5070b57cec5SDimitry Andric 5080b57cec5SDimitry Andric std::vector<ELFSymbolData> LocalSymbolData; 5090b57cec5SDimitry Andric std::vector<ELFSymbolData> ExternalSymbolData; 510fe6060f1SDimitry Andric MutableArrayRef<std::pair<std::string, size_t>> FileNames = 511*0fca6ea1SDimitry Andric OWriter.getFileNames(); 512fe6060f1SDimitry Andric for (const std::pair<std::string, size_t> &F : FileNames) 513fe6060f1SDimitry Andric StrTabBuilder.add(F.first); 5140b57cec5SDimitry Andric 5150b57cec5SDimitry Andric // Add the data for the symbols. 5160b57cec5SDimitry Andric bool HasLargeSectionIndex = false; 517fe6060f1SDimitry Andric for (auto It : llvm::enumerate(Asm.symbols())) { 518fe6060f1SDimitry Andric const auto &Symbol = cast<MCSymbolELF>(It.value()); 5190b57cec5SDimitry Andric bool Used = Symbol.isUsedInReloc(); 5200b57cec5SDimitry Andric bool WeakrefUsed = Symbol.isWeakrefUsedInReloc(); 5210b57cec5SDimitry Andric bool isSignature = Symbol.isSignature(); 5220b57cec5SDimitry Andric 523*0fca6ea1SDimitry Andric if (!isInSymtab(Asm, Symbol, Used || WeakrefUsed || isSignature, 5240b57cec5SDimitry Andric OWriter.Renames.count(&Symbol))) 5250b57cec5SDimitry Andric continue; 5260b57cec5SDimitry Andric 5270b57cec5SDimitry Andric if (Symbol.isTemporary() && Symbol.isUndefined()) { 5285ffd83dbSDimitry Andric Ctx.reportError(SMLoc(), "Undefined temporary symbol " + Symbol.getName()); 5290b57cec5SDimitry Andric continue; 5300b57cec5SDimitry Andric } 5310b57cec5SDimitry Andric 5320b57cec5SDimitry Andric ELFSymbolData MSD; 5330b57cec5SDimitry Andric MSD.Symbol = cast<MCSymbolELF>(&Symbol); 534fe6060f1SDimitry Andric MSD.Order = It.index(); 5350b57cec5SDimitry Andric 5360b57cec5SDimitry Andric bool Local = Symbol.getBinding() == ELF::STB_LOCAL; 5370b57cec5SDimitry Andric assert(Local || !Symbol.isTemporary()); 5380b57cec5SDimitry Andric 5390b57cec5SDimitry Andric if (Symbol.isAbsolute()) { 5400b57cec5SDimitry Andric MSD.SectionIndex = ELF::SHN_ABS; 5410b57cec5SDimitry Andric } else if (Symbol.isCommon()) { 5420b57cec5SDimitry Andric if (Symbol.isTargetCommon()) { 5430b57cec5SDimitry Andric MSD.SectionIndex = Symbol.getIndex(); 5440b57cec5SDimitry Andric } else { 5450b57cec5SDimitry Andric assert(!Local); 5460b57cec5SDimitry Andric MSD.SectionIndex = ELF::SHN_COMMON; 5470b57cec5SDimitry Andric } 5480b57cec5SDimitry Andric } else if (Symbol.isUndefined()) { 5490b57cec5SDimitry Andric if (isSignature && !Used) { 5500b57cec5SDimitry Andric MSD.SectionIndex = RevGroupMap.lookup(&Symbol); 5510b57cec5SDimitry Andric if (MSD.SectionIndex >= ELF::SHN_LORESERVE) 5520b57cec5SDimitry Andric HasLargeSectionIndex = true; 5530b57cec5SDimitry Andric } else { 5540b57cec5SDimitry Andric MSD.SectionIndex = ELF::SHN_UNDEF; 5550b57cec5SDimitry Andric } 5560b57cec5SDimitry Andric } else { 5570b57cec5SDimitry Andric const MCSectionELF &Section = 5580b57cec5SDimitry Andric static_cast<const MCSectionELF &>(Symbol.getSection()); 5590b57cec5SDimitry Andric 5600b57cec5SDimitry Andric // We may end up with a situation when section symbol is technically 5610b57cec5SDimitry Andric // defined, but should not be. That happens because we explicitly 5620b57cec5SDimitry Andric // pre-create few .debug_* sections to have accessors. 5630b57cec5SDimitry Andric // And if these sections were not really defined in the code, but were 5640b57cec5SDimitry Andric // referenced, we simply error out. 5650b57cec5SDimitry Andric if (!Section.isRegistered()) { 5660b57cec5SDimitry Andric assert(static_cast<const MCSymbolELF &>(Symbol).getType() == 5670b57cec5SDimitry Andric ELF::STT_SECTION); 5680b57cec5SDimitry Andric Ctx.reportError(SMLoc(), 5690b57cec5SDimitry Andric "Undefined section reference: " + Symbol.getName()); 5700b57cec5SDimitry Andric continue; 5710b57cec5SDimitry Andric } 5720b57cec5SDimitry Andric 5730b57cec5SDimitry Andric if (Mode == NonDwoOnly && isDwoSection(Section)) 5740b57cec5SDimitry Andric continue; 575*0fca6ea1SDimitry Andric MSD.SectionIndex = Section.getOrdinal(); 5760b57cec5SDimitry Andric assert(MSD.SectionIndex && "Invalid section index!"); 5770b57cec5SDimitry Andric if (MSD.SectionIndex >= ELF::SHN_LORESERVE) 5780b57cec5SDimitry Andric HasLargeSectionIndex = true; 5790b57cec5SDimitry Andric } 5800b57cec5SDimitry Andric 581*0fca6ea1SDimitry Andric // Temporary symbols generated for certain assembler features (.eh_frame, 582*0fca6ea1SDimitry Andric // .debug_line) of an empty name may be referenced by relocations due to 583*0fca6ea1SDimitry Andric // linker relaxation. Rename them to ".L0 " to match the gas fake label name 584*0fca6ea1SDimitry Andric // and allow ld/objcopy --discard-locals to discard such symbols. 5850b57cec5SDimitry Andric StringRef Name = Symbol.getName(); 586*0fca6ea1SDimitry Andric if (Name.empty()) 587*0fca6ea1SDimitry Andric Name = ".L0 "; 5880b57cec5SDimitry Andric 5890b57cec5SDimitry Andric // Sections have their own string table 5900b57cec5SDimitry Andric if (Symbol.getType() != ELF::STT_SECTION) { 5910b57cec5SDimitry Andric MSD.Name = Name; 5920b57cec5SDimitry Andric StrTabBuilder.add(Name); 5930b57cec5SDimitry Andric } 5940b57cec5SDimitry Andric 5950b57cec5SDimitry Andric if (Local) 5960b57cec5SDimitry Andric LocalSymbolData.push_back(MSD); 5970b57cec5SDimitry Andric else 5980b57cec5SDimitry Andric ExternalSymbolData.push_back(MSD); 5990b57cec5SDimitry Andric } 6000b57cec5SDimitry Andric 6010b57cec5SDimitry Andric // This holds the .symtab_shndx section index. 6020b57cec5SDimitry Andric unsigned SymtabShndxSectionIndex = 0; 6030b57cec5SDimitry Andric 6040b57cec5SDimitry Andric if (HasLargeSectionIndex) { 6050b57cec5SDimitry Andric MCSectionELF *SymtabShndxSection = 606fe6060f1SDimitry Andric Ctx.getELFSection(".symtab_shndx", ELF::SHT_SYMTAB_SHNDX, 0, 4); 6070b57cec5SDimitry Andric SymtabShndxSectionIndex = addToSectionTable(SymtabShndxSection); 6088bcb0991SDimitry Andric SymtabShndxSection->setAlignment(Align(4)); 6090b57cec5SDimitry Andric } 6100b57cec5SDimitry Andric 6110b57cec5SDimitry Andric StrTabBuilder.finalize(); 6120b57cec5SDimitry Andric 613fe6060f1SDimitry Andric // Make the first STT_FILE precede previous local symbols. 614fe6060f1SDimitry Andric unsigned Index = 1; 615fe6060f1SDimitry Andric auto FileNameIt = FileNames.begin(); 616fe6060f1SDimitry Andric if (!FileNames.empty()) 617fe6060f1SDimitry Andric FileNames[0].second = 0; 6180b57cec5SDimitry Andric 6190b57cec5SDimitry Andric for (ELFSymbolData &MSD : LocalSymbolData) { 620fe6060f1SDimitry Andric // Emit STT_FILE symbols before their associated local symbols. 621fe6060f1SDimitry Andric for (; FileNameIt != FileNames.end() && FileNameIt->second <= MSD.Order; 622fe6060f1SDimitry Andric ++FileNameIt) { 623fe6060f1SDimitry Andric Writer.writeSymbol(StrTabBuilder.getOffset(FileNameIt->first), 624fe6060f1SDimitry Andric ELF::STT_FILE | ELF::STB_LOCAL, 0, 0, ELF::STV_DEFAULT, 625fe6060f1SDimitry Andric ELF::SHN_ABS, true); 626fe6060f1SDimitry Andric ++Index; 627fe6060f1SDimitry Andric } 628fe6060f1SDimitry Andric 6290b57cec5SDimitry Andric unsigned StringIndex = MSD.Symbol->getType() == ELF::STT_SECTION 6300b57cec5SDimitry Andric ? 0 6310b57cec5SDimitry Andric : StrTabBuilder.getOffset(MSD.Name); 6320b57cec5SDimitry Andric MSD.Symbol->setIndex(Index++); 633*0fca6ea1SDimitry Andric writeSymbol(Asm, Writer, StringIndex, MSD); 6340b57cec5SDimitry Andric } 635fe6060f1SDimitry Andric for (; FileNameIt != FileNames.end(); ++FileNameIt) { 636fe6060f1SDimitry Andric Writer.writeSymbol(StrTabBuilder.getOffset(FileNameIt->first), 637fe6060f1SDimitry Andric ELF::STT_FILE | ELF::STB_LOCAL, 0, 0, ELF::STV_DEFAULT, 638fe6060f1SDimitry Andric ELF::SHN_ABS, true); 639fe6060f1SDimitry Andric ++Index; 640fe6060f1SDimitry Andric } 6410b57cec5SDimitry Andric 6420b57cec5SDimitry Andric // Write the symbol table entries. 6430b57cec5SDimitry Andric LastLocalSymbolIndex = Index; 6440b57cec5SDimitry Andric 6450b57cec5SDimitry Andric for (ELFSymbolData &MSD : ExternalSymbolData) { 6460b57cec5SDimitry Andric unsigned StringIndex = StrTabBuilder.getOffset(MSD.Name); 6470b57cec5SDimitry Andric MSD.Symbol->setIndex(Index++); 648*0fca6ea1SDimitry Andric writeSymbol(Asm, Writer, StringIndex, MSD); 6490b57cec5SDimitry Andric assert(MSD.Symbol->getBinding() != ELF::STB_LOCAL); 6500b57cec5SDimitry Andric } 6510b57cec5SDimitry Andric 6520b57cec5SDimitry Andric uint64_t SecEnd = W.OS.tell(); 653*0fca6ea1SDimitry Andric SymtabSection->setOffsets(SecStart, SecEnd); 6540b57cec5SDimitry Andric 6550b57cec5SDimitry Andric ArrayRef<uint32_t> ShndxIndexes = Writer.getShndxIndexes(); 6560b57cec5SDimitry Andric if (ShndxIndexes.empty()) { 6570b57cec5SDimitry Andric assert(SymtabShndxSectionIndex == 0); 6580b57cec5SDimitry Andric return; 6590b57cec5SDimitry Andric } 6600b57cec5SDimitry Andric assert(SymtabShndxSectionIndex != 0); 6610b57cec5SDimitry Andric 6620b57cec5SDimitry Andric SecStart = W.OS.tell(); 663*0fca6ea1SDimitry Andric MCSectionELF *SymtabShndxSection = SectionTable[SymtabShndxSectionIndex - 1]; 6640b57cec5SDimitry Andric for (uint32_t Index : ShndxIndexes) 6650b57cec5SDimitry Andric write(Index); 6660b57cec5SDimitry Andric SecEnd = W.OS.tell(); 667*0fca6ea1SDimitry Andric SymtabShndxSection->setOffsets(SecStart, SecEnd); 6680b57cec5SDimitry Andric } 6690b57cec5SDimitry Andric 6700b57cec5SDimitry Andric void ELFWriter::writeAddrsigSection() { 671*0fca6ea1SDimitry Andric for (const MCSymbol *Sym : OWriter.getAddrsigSyms()) 672bdd1243dSDimitry Andric if (Sym->getIndex() != 0) 6730b57cec5SDimitry Andric encodeULEB128(Sym->getIndex(), W.OS); 6740b57cec5SDimitry Andric } 6750b57cec5SDimitry Andric 6760b57cec5SDimitry Andric MCSectionELF *ELFWriter::createRelocationSection(MCContext &Ctx, 6770b57cec5SDimitry Andric const MCSectionELF &Sec) { 6780b57cec5SDimitry Andric if (OWriter.Relocations[&Sec].empty()) 6790b57cec5SDimitry Andric return nullptr; 6800b57cec5SDimitry Andric 681*0fca6ea1SDimitry Andric unsigned Flags = ELF::SHF_INFO_LINK; 682*0fca6ea1SDimitry Andric if (Sec.getFlags() & ELF::SHF_GROUP) 683*0fca6ea1SDimitry Andric Flags = ELF::SHF_GROUP; 6840b57cec5SDimitry Andric 685*0fca6ea1SDimitry Andric const StringRef SectionName = Sec.getName(); 686*0fca6ea1SDimitry Andric const MCTargetOptions *TO = Ctx.getTargetOptions(); 687*0fca6ea1SDimitry Andric if (TO && TO->Crel) { 688*0fca6ea1SDimitry Andric MCSectionELF *RelaSection = 689*0fca6ea1SDimitry Andric Ctx.createELFRelSection(".crel" + SectionName, ELF::SHT_CREL, Flags, 690*0fca6ea1SDimitry Andric /*EntrySize=*/1, Sec.getGroup(), &Sec); 691*0fca6ea1SDimitry Andric return RelaSection; 692*0fca6ea1SDimitry Andric } 693*0fca6ea1SDimitry Andric 694*0fca6ea1SDimitry Andric const bool Rela = OWriter.usesRela(TO, Sec); 6950b57cec5SDimitry Andric unsigned EntrySize; 696fe6060f1SDimitry Andric if (Rela) 6970b57cec5SDimitry Andric EntrySize = is64Bit() ? sizeof(ELF::Elf64_Rela) : sizeof(ELF::Elf32_Rela); 6980b57cec5SDimitry Andric else 6990b57cec5SDimitry Andric EntrySize = is64Bit() ? sizeof(ELF::Elf64_Rel) : sizeof(ELF::Elf32_Rel); 7000b57cec5SDimitry Andric 701*0fca6ea1SDimitry Andric MCSectionELF *RelaSection = 702*0fca6ea1SDimitry Andric Ctx.createELFRelSection(((Rela ? ".rela" : ".rel") + SectionName), 703*0fca6ea1SDimitry Andric Rela ? ELF::SHT_RELA : ELF::SHT_REL, Flags, 704*0fca6ea1SDimitry Andric EntrySize, Sec.getGroup(), &Sec); 7058bcb0991SDimitry Andric RelaSection->setAlignment(is64Bit() ? Align(8) : Align(4)); 7060b57cec5SDimitry Andric return RelaSection; 7070b57cec5SDimitry Andric } 7080b57cec5SDimitry Andric 7090b57cec5SDimitry Andric // Include the debug info compression header. 7100b57cec5SDimitry Andric bool ELFWriter::maybeWriteCompression( 711fcaf7f86SDimitry Andric uint32_t ChType, uint64_t Size, 712bdd1243dSDimitry Andric SmallVectorImpl<uint8_t> &CompressedContents, Align Alignment) { 7130b57cec5SDimitry Andric uint64_t HdrSize = 7145f757f3fSDimitry Andric is64Bit() ? sizeof(ELF::Elf64_Chdr) : sizeof(ELF::Elf32_Chdr); 7150b57cec5SDimitry Andric if (Size <= HdrSize + CompressedContents.size()) 7160b57cec5SDimitry Andric return false; 7170b57cec5SDimitry Andric // Platform specific header is followed by compressed data. 7180b57cec5SDimitry Andric if (is64Bit()) { 7190b57cec5SDimitry Andric // Write Elf64_Chdr header. 720fcaf7f86SDimitry Andric write(static_cast<ELF::Elf64_Word>(ChType)); 7210b57cec5SDimitry Andric write(static_cast<ELF::Elf64_Word>(0)); // ch_reserved field. 7220b57cec5SDimitry Andric write(static_cast<ELF::Elf64_Xword>(Size)); 723bdd1243dSDimitry Andric write(static_cast<ELF::Elf64_Xword>(Alignment.value())); 7240b57cec5SDimitry Andric } else { 7250b57cec5SDimitry Andric // Write Elf32_Chdr header otherwise. 726fcaf7f86SDimitry Andric write(static_cast<ELF::Elf32_Word>(ChType)); 7270b57cec5SDimitry Andric write(static_cast<ELF::Elf32_Word>(Size)); 728bdd1243dSDimitry Andric write(static_cast<ELF::Elf32_Word>(Alignment.value())); 7290b57cec5SDimitry Andric } 7300b57cec5SDimitry Andric return true; 7310b57cec5SDimitry Andric } 7320b57cec5SDimitry Andric 733*0fca6ea1SDimitry Andric void ELFWriter::writeSectionData(const MCAssembler &Asm, MCSection &Sec) { 7340b57cec5SDimitry Andric MCSectionELF &Section = static_cast<MCSectionELF &>(Sec); 7355ffd83dbSDimitry Andric StringRef SectionName = Section.getName(); 736*0fca6ea1SDimitry Andric auto &Ctx = Asm.getContext(); 737*0fca6ea1SDimitry Andric const DebugCompressionType CompressionType = 738*0fca6ea1SDimitry Andric Ctx.getTargetOptions() ? Ctx.getTargetOptions()->CompressDebugSections 739*0fca6ea1SDimitry Andric : DebugCompressionType::None; 740bdd1243dSDimitry Andric if (CompressionType == DebugCompressionType::None || 7415f757f3fSDimitry Andric !SectionName.starts_with(".debug_")) { 742*0fca6ea1SDimitry Andric Asm.writeSectionData(W.OS, &Section); 7430b57cec5SDimitry Andric return; 7440b57cec5SDimitry Andric } 7450b57cec5SDimitry Andric 7460b57cec5SDimitry Andric SmallVector<char, 128> UncompressedData; 7470b57cec5SDimitry Andric raw_svector_ostream VecOS(UncompressedData); 748*0fca6ea1SDimitry Andric Asm.writeSectionData(VecOS, &Section); 749bdd1243dSDimitry Andric ArrayRef<uint8_t> Uncompressed = 750bdd1243dSDimitry Andric ArrayRef(reinterpret_cast<uint8_t *>(UncompressedData.data()), 751bdd1243dSDimitry Andric UncompressedData.size()); 7520b57cec5SDimitry Andric 753fcaf7f86SDimitry Andric SmallVector<uint8_t, 128> Compressed; 754bdd1243dSDimitry Andric uint32_t ChType; 755bdd1243dSDimitry Andric switch (CompressionType) { 756bdd1243dSDimitry Andric case DebugCompressionType::None: 757bdd1243dSDimitry Andric llvm_unreachable("has been handled"); 758bdd1243dSDimitry Andric case DebugCompressionType::Zlib: 759bdd1243dSDimitry Andric ChType = ELF::ELFCOMPRESS_ZLIB; 760bdd1243dSDimitry Andric break; 761bdd1243dSDimitry Andric case DebugCompressionType::Zstd: 762bdd1243dSDimitry Andric ChType = ELF::ELFCOMPRESS_ZSTD; 763bdd1243dSDimitry Andric break; 764bdd1243dSDimitry Andric } 765bdd1243dSDimitry Andric compression::compress(compression::Params(CompressionType), Uncompressed, 766fcaf7f86SDimitry Andric Compressed); 767fcaf7f86SDimitry Andric if (!maybeWriteCompression(ChType, UncompressedData.size(), Compressed, 768bdd1243dSDimitry Andric Sec.getAlign())) { 7690b57cec5SDimitry Andric W.OS << UncompressedData; 7700b57cec5SDimitry Andric return; 7710b57cec5SDimitry Andric } 7720b57cec5SDimitry Andric 7730b57cec5SDimitry Andric Section.setFlags(Section.getFlags() | ELF::SHF_COMPRESSED); 7740b57cec5SDimitry Andric // Alignment field should reflect the requirements of 7750b57cec5SDimitry Andric // the compressed section header. 7768bcb0991SDimitry Andric Section.setAlignment(is64Bit() ? Align(8) : Align(4)); 777fcaf7f86SDimitry Andric W.OS << toStringRef(Compressed); 7780b57cec5SDimitry Andric } 7790b57cec5SDimitry Andric 7800b57cec5SDimitry Andric void ELFWriter::WriteSecHdrEntry(uint32_t Name, uint32_t Type, uint64_t Flags, 7810b57cec5SDimitry Andric uint64_t Address, uint64_t Offset, 7820b57cec5SDimitry Andric uint64_t Size, uint32_t Link, uint32_t Info, 783bdd1243dSDimitry Andric MaybeAlign Alignment, uint64_t EntrySize) { 7840b57cec5SDimitry Andric W.write<uint32_t>(Name); // sh_name: index into string table 7850b57cec5SDimitry Andric W.write<uint32_t>(Type); // sh_type 7860b57cec5SDimitry Andric WriteWord(Flags); // sh_flags 7870b57cec5SDimitry Andric WriteWord(Address); // sh_addr 7880b57cec5SDimitry Andric WriteWord(Offset); // sh_offset 7890b57cec5SDimitry Andric WriteWord(Size); // sh_size 7900b57cec5SDimitry Andric W.write<uint32_t>(Link); // sh_link 7910b57cec5SDimitry Andric W.write<uint32_t>(Info); // sh_info 792bdd1243dSDimitry Andric WriteWord(Alignment ? Alignment->value() : 0); // sh_addralign 7930b57cec5SDimitry Andric WriteWord(EntrySize); // sh_entsize 7940b57cec5SDimitry Andric } 7950b57cec5SDimitry Andric 796*0fca6ea1SDimitry Andric template <bool Is64> 797*0fca6ea1SDimitry Andric static void encodeCrel(ArrayRef<ELFRelocationEntry> Relocs, raw_ostream &OS) { 798*0fca6ea1SDimitry Andric using uint = std::conditional_t<Is64, uint64_t, uint32_t>; 799*0fca6ea1SDimitry Andric ELF::encodeCrel<Is64>(OS, Relocs, [&](const ELFRelocationEntry &R) { 800*0fca6ea1SDimitry Andric uint32_t SymIdx = R.Symbol ? R.Symbol->getIndex() : 0; 801*0fca6ea1SDimitry Andric return ELF::Elf_Crel<Is64>{static_cast<uint>(R.Offset), SymIdx, R.Type, 802*0fca6ea1SDimitry Andric std::make_signed_t<uint>(R.Addend)}; 803*0fca6ea1SDimitry Andric }); 804*0fca6ea1SDimitry Andric } 805*0fca6ea1SDimitry Andric 8060b57cec5SDimitry Andric void ELFWriter::writeRelocations(const MCAssembler &Asm, 8070b57cec5SDimitry Andric const MCSectionELF &Sec) { 8080b57cec5SDimitry Andric std::vector<ELFRelocationEntry> &Relocs = OWriter.Relocations[&Sec]; 809*0fca6ea1SDimitry Andric const MCTargetOptions *TO = Asm.getContext().getTargetOptions(); 810*0fca6ea1SDimitry Andric const bool Rela = OWriter.usesRela(TO, Sec); 8110b57cec5SDimitry Andric 8120b57cec5SDimitry Andric // Sort the relocation entries. MIPS needs this. 8130b57cec5SDimitry Andric OWriter.TargetObjectWriter->sortRelocs(Asm, Relocs); 8140b57cec5SDimitry Andric 815*0fca6ea1SDimitry Andric if (OWriter.TargetObjectWriter->getEMachine() == ELF::EM_MIPS) { 816*0fca6ea1SDimitry Andric for (const ELFRelocationEntry &Entry : Relocs) { 817*0fca6ea1SDimitry Andric uint32_t SymIdx = Entry.Symbol ? Entry.Symbol->getIndex() : 0; 8180b57cec5SDimitry Andric if (is64Bit()) { 8190b57cec5SDimitry Andric write(Entry.Offset); 820*0fca6ea1SDimitry Andric write(uint32_t(SymIdx)); 8210b57cec5SDimitry Andric write(OWriter.TargetObjectWriter->getRSsym(Entry.Type)); 8220b57cec5SDimitry Andric write(OWriter.TargetObjectWriter->getRType3(Entry.Type)); 8230b57cec5SDimitry Andric write(OWriter.TargetObjectWriter->getRType2(Entry.Type)); 8240b57cec5SDimitry Andric write(OWriter.TargetObjectWriter->getRType(Entry.Type)); 825fe6060f1SDimitry Andric if (Rela) 8260b57cec5SDimitry Andric write(Entry.Addend); 8270b57cec5SDimitry Andric } else { 8280b57cec5SDimitry Andric write(uint32_t(Entry.Offset)); 829*0fca6ea1SDimitry Andric ELF::Elf32_Rela ERE32; 830*0fca6ea1SDimitry Andric ERE32.setSymbolAndType(SymIdx, Entry.Type); 8310b57cec5SDimitry Andric write(ERE32.r_info); 832fe6060f1SDimitry Andric if (Rela) 8330b57cec5SDimitry Andric write(uint32_t(Entry.Addend)); 8340b57cec5SDimitry Andric if (uint32_t RType = 8350b57cec5SDimitry Andric OWriter.TargetObjectWriter->getRType2(Entry.Type)) { 8360b57cec5SDimitry Andric write(uint32_t(Entry.Offset)); 8370b57cec5SDimitry Andric ERE32.setSymbolAndType(0, RType); 8380b57cec5SDimitry Andric write(ERE32.r_info); 8390b57cec5SDimitry Andric write(uint32_t(0)); 8400b57cec5SDimitry Andric } 8410b57cec5SDimitry Andric if (uint32_t RType = 8420b57cec5SDimitry Andric OWriter.TargetObjectWriter->getRType3(Entry.Type)) { 8430b57cec5SDimitry Andric write(uint32_t(Entry.Offset)); 8440b57cec5SDimitry Andric ERE32.setSymbolAndType(0, RType); 8450b57cec5SDimitry Andric write(ERE32.r_info); 8460b57cec5SDimitry Andric write(uint32_t(0)); 8470b57cec5SDimitry Andric } 8480b57cec5SDimitry Andric } 8490b57cec5SDimitry Andric } 850*0fca6ea1SDimitry Andric } else if (TO && TO->Crel) { 851*0fca6ea1SDimitry Andric if (is64Bit()) 852*0fca6ea1SDimitry Andric encodeCrel<true>(Relocs, W.OS); 853*0fca6ea1SDimitry Andric else 854*0fca6ea1SDimitry Andric encodeCrel<false>(Relocs, W.OS); 855*0fca6ea1SDimitry Andric } else { 856*0fca6ea1SDimitry Andric for (const ELFRelocationEntry &Entry : Relocs) { 857*0fca6ea1SDimitry Andric uint32_t Symidx = Entry.Symbol ? Entry.Symbol->getIndex() : 0; 858*0fca6ea1SDimitry Andric if (is64Bit()) { 859*0fca6ea1SDimitry Andric write(Entry.Offset); 860*0fca6ea1SDimitry Andric ELF::Elf64_Rela ERE; 861*0fca6ea1SDimitry Andric ERE.setSymbolAndType(Symidx, Entry.Type); 862*0fca6ea1SDimitry Andric write(ERE.r_info); 863*0fca6ea1SDimitry Andric if (Rela) 864*0fca6ea1SDimitry Andric write(Entry.Addend); 865*0fca6ea1SDimitry Andric } else { 866*0fca6ea1SDimitry Andric write(uint32_t(Entry.Offset)); 867*0fca6ea1SDimitry Andric ELF::Elf32_Rela ERE; 868*0fca6ea1SDimitry Andric ERE.setSymbolAndType(Symidx, Entry.Type); 869*0fca6ea1SDimitry Andric write(ERE.r_info); 870*0fca6ea1SDimitry Andric if (Rela) 871*0fca6ea1SDimitry Andric write(uint32_t(Entry.Addend)); 872*0fca6ea1SDimitry Andric } 873*0fca6ea1SDimitry Andric } 8740b57cec5SDimitry Andric } 8750b57cec5SDimitry Andric } 8760b57cec5SDimitry Andric 877*0fca6ea1SDimitry Andric void ELFWriter::writeSection(uint32_t GroupSymbolIndex, uint64_t Offset, 8780b57cec5SDimitry Andric uint64_t Size, const MCSectionELF &Section) { 8790b57cec5SDimitry Andric uint64_t sh_link = 0; 8800b57cec5SDimitry Andric uint64_t sh_info = 0; 8810b57cec5SDimitry Andric 8820b57cec5SDimitry Andric switch(Section.getType()) { 8830b57cec5SDimitry Andric default: 8840b57cec5SDimitry Andric // Nothing to do. 8850b57cec5SDimitry Andric break; 8860b57cec5SDimitry Andric 8870b57cec5SDimitry Andric case ELF::SHT_DYNAMIC: 8880b57cec5SDimitry Andric llvm_unreachable("SHT_DYNAMIC in a relocatable object"); 8890b57cec5SDimitry Andric 8900b57cec5SDimitry Andric case ELF::SHT_REL: 891*0fca6ea1SDimitry Andric case ELF::SHT_RELA: 892*0fca6ea1SDimitry Andric case ELF::SHT_CREL: { 8930b57cec5SDimitry Andric sh_link = SymbolTableIndex; 8940b57cec5SDimitry Andric assert(sh_link && ".symtab not found"); 8955ffd83dbSDimitry Andric const MCSection *InfoSection = Section.getLinkedToSection(); 896*0fca6ea1SDimitry Andric sh_info = InfoSection->getOrdinal(); 8970b57cec5SDimitry Andric break; 8980b57cec5SDimitry Andric } 8990b57cec5SDimitry Andric 9000b57cec5SDimitry Andric case ELF::SHT_SYMTAB: 9010b57cec5SDimitry Andric sh_link = StringTableIndex; 9020b57cec5SDimitry Andric sh_info = LastLocalSymbolIndex; 9030b57cec5SDimitry Andric break; 9040b57cec5SDimitry Andric 9050b57cec5SDimitry Andric case ELF::SHT_SYMTAB_SHNDX: 9060b57cec5SDimitry Andric case ELF::SHT_LLVM_CALL_GRAPH_PROFILE: 9070b57cec5SDimitry Andric case ELF::SHT_LLVM_ADDRSIG: 9080b57cec5SDimitry Andric sh_link = SymbolTableIndex; 9090b57cec5SDimitry Andric break; 9100b57cec5SDimitry Andric 9110b57cec5SDimitry Andric case ELF::SHT_GROUP: 9120b57cec5SDimitry Andric sh_link = SymbolTableIndex; 9130b57cec5SDimitry Andric sh_info = GroupSymbolIndex; 9140b57cec5SDimitry Andric break; 9150b57cec5SDimitry Andric } 9160b57cec5SDimitry Andric 9170b57cec5SDimitry Andric if (Section.getFlags() & ELF::SHF_LINK_ORDER) { 918e8d8bef9SDimitry Andric // If the value in the associated metadata is not a definition, Sym will be 919e8d8bef9SDimitry Andric // undefined. Represent this with sh_link=0. 9205ffd83dbSDimitry Andric const MCSymbol *Sym = Section.getLinkedToSymbol(); 921*0fca6ea1SDimitry Andric if (Sym && Sym->isInSection()) 922*0fca6ea1SDimitry Andric sh_link = Sym->getSection().getOrdinal(); 923e8d8bef9SDimitry Andric } 9240b57cec5SDimitry Andric 9255ffd83dbSDimitry Andric WriteSecHdrEntry(StrTabBuilder.getOffset(Section.getName()), 9260b57cec5SDimitry Andric Section.getType(), Section.getFlags(), 0, Offset, Size, 927bdd1243dSDimitry Andric sh_link, sh_info, Section.getAlign(), 9280b57cec5SDimitry Andric Section.getEntrySize()); 9290b57cec5SDimitry Andric } 9300b57cec5SDimitry Andric 931*0fca6ea1SDimitry Andric void ELFWriter::writeSectionHeader(const MCAssembler &Asm) { 9320b57cec5SDimitry Andric const unsigned NumSections = SectionTable.size(); 9330b57cec5SDimitry Andric 9340b57cec5SDimitry Andric // Null section first. 9350b57cec5SDimitry Andric uint64_t FirstSectionSize = 9360b57cec5SDimitry Andric (NumSections + 1) >= ELF::SHN_LORESERVE ? NumSections + 1 : 0; 937bdd1243dSDimitry Andric WriteSecHdrEntry(0, 0, 0, 0, 0, FirstSectionSize, 0, 0, std::nullopt, 0); 9380b57cec5SDimitry Andric 9390b57cec5SDimitry Andric for (const MCSectionELF *Section : SectionTable) { 9400b57cec5SDimitry Andric uint32_t GroupSymbolIndex; 9410b57cec5SDimitry Andric unsigned Type = Section->getType(); 9420b57cec5SDimitry Andric if (Type != ELF::SHT_GROUP) 9430b57cec5SDimitry Andric GroupSymbolIndex = 0; 9440b57cec5SDimitry Andric else 9450b57cec5SDimitry Andric GroupSymbolIndex = Section->getGroup()->getIndex(); 9460b57cec5SDimitry Andric 947*0fca6ea1SDimitry Andric std::pair<uint64_t, uint64_t> Offsets = Section->getOffsets(); 9480b57cec5SDimitry Andric uint64_t Size; 9490b57cec5SDimitry Andric if (Type == ELF::SHT_NOBITS) 950*0fca6ea1SDimitry Andric Size = Asm.getSectionAddressSize(*Section); 9510b57cec5SDimitry Andric else 9520b57cec5SDimitry Andric Size = Offsets.second - Offsets.first; 9530b57cec5SDimitry Andric 954*0fca6ea1SDimitry Andric writeSection(GroupSymbolIndex, Offsets.first, Size, *Section); 9550b57cec5SDimitry Andric } 9560b57cec5SDimitry Andric } 9570b57cec5SDimitry Andric 958*0fca6ea1SDimitry Andric uint64_t ELFWriter::writeObject(MCAssembler &Asm) { 9590b57cec5SDimitry Andric uint64_t StartOffset = W.OS.tell(); 9600b57cec5SDimitry Andric 9610b57cec5SDimitry Andric MCContext &Ctx = Asm.getContext(); 9620b57cec5SDimitry Andric MCSectionELF *StrtabSection = 9630b57cec5SDimitry Andric Ctx.getELFSection(".strtab", ELF::SHT_STRTAB, 0); 9640b57cec5SDimitry Andric StringTableIndex = addToSectionTable(StrtabSection); 9650b57cec5SDimitry Andric 9660b57cec5SDimitry Andric RevGroupMapTy RevGroupMap; 9670b57cec5SDimitry Andric 9680b57cec5SDimitry Andric // Write out the ELF header ... 9690b57cec5SDimitry Andric writeHeader(Asm); 9700b57cec5SDimitry Andric 9710b57cec5SDimitry Andric // ... then the sections ... 972*0fca6ea1SDimitry Andric SmallVector<std::pair<MCSectionELF *, SmallVector<unsigned>>, 0> Groups; 973*0fca6ea1SDimitry Andric // Map from group section index to group 974*0fca6ea1SDimitry Andric SmallVector<unsigned, 0> GroupMap; 975*0fca6ea1SDimitry Andric SmallVector<MCSectionELF *> Relocations; 9760b57cec5SDimitry Andric for (MCSection &Sec : Asm) { 9770b57cec5SDimitry Andric MCSectionELF &Section = static_cast<MCSectionELF &>(Sec); 9780b57cec5SDimitry Andric if (Mode == NonDwoOnly && isDwoSection(Section)) 9790b57cec5SDimitry Andric continue; 9800b57cec5SDimitry Andric if (Mode == DwoOnly && !isDwoSection(Section)) 9810b57cec5SDimitry Andric continue; 9820b57cec5SDimitry Andric 9830b57cec5SDimitry Andric // Remember the offset into the file for this section. 984bdd1243dSDimitry Andric const uint64_t SecStart = align(Section.getAlign()); 9850b57cec5SDimitry Andric 9860b57cec5SDimitry Andric const MCSymbolELF *SignatureSymbol = Section.getGroup(); 987*0fca6ea1SDimitry Andric writeSectionData(Asm, Section); 9880b57cec5SDimitry Andric 9890b57cec5SDimitry Andric uint64_t SecEnd = W.OS.tell(); 990*0fca6ea1SDimitry Andric Section.setOffsets(SecStart, SecEnd); 9910b57cec5SDimitry Andric 9920b57cec5SDimitry Andric MCSectionELF *RelSection = createRelocationSection(Ctx, Section); 9930b57cec5SDimitry Andric 994*0fca6ea1SDimitry Andric unsigned *GroupIdxEntry = nullptr; 9950b57cec5SDimitry Andric if (SignatureSymbol) { 996*0fca6ea1SDimitry Andric GroupIdxEntry = &RevGroupMap[SignatureSymbol]; 997*0fca6ea1SDimitry Andric if (!*GroupIdxEntry) { 998fe6060f1SDimitry Andric MCSectionELF *Group = 999fe6060f1SDimitry Andric Ctx.createELFGroupSection(SignatureSymbol, Section.isComdat()); 1000*0fca6ea1SDimitry Andric *GroupIdxEntry = addToSectionTable(Group); 10018bcb0991SDimitry Andric Group->setAlignment(Align(4)); 1002*0fca6ea1SDimitry Andric 1003*0fca6ea1SDimitry Andric GroupMap.resize(*GroupIdxEntry + 1); 1004*0fca6ea1SDimitry Andric GroupMap[*GroupIdxEntry] = Groups.size(); 1005*0fca6ea1SDimitry Andric Groups.emplace_back(Group, SmallVector<unsigned>{}); 10060b57cec5SDimitry Andric } 10070b57cec5SDimitry Andric } 10080b57cec5SDimitry Andric 1009*0fca6ea1SDimitry Andric Section.setOrdinal(addToSectionTable(&Section)); 10100b57cec5SDimitry Andric if (RelSection) { 1011*0fca6ea1SDimitry Andric RelSection->setOrdinal(addToSectionTable(RelSection)); 10120b57cec5SDimitry Andric Relocations.push_back(RelSection); 10130b57cec5SDimitry Andric } 10140b57cec5SDimitry Andric 1015*0fca6ea1SDimitry Andric if (GroupIdxEntry) { 1016*0fca6ea1SDimitry Andric auto &Members = Groups[GroupMap[*GroupIdxEntry]]; 1017*0fca6ea1SDimitry Andric Members.second.push_back(Section.getOrdinal()); 1018*0fca6ea1SDimitry Andric if (RelSection) 1019*0fca6ea1SDimitry Andric Members.second.push_back(RelSection->getOrdinal()); 1020*0fca6ea1SDimitry Andric } 1021*0fca6ea1SDimitry Andric 10220b57cec5SDimitry Andric OWriter.TargetObjectWriter->addTargetSectionFlags(Ctx, Section); 10230b57cec5SDimitry Andric } 10240b57cec5SDimitry Andric 1025*0fca6ea1SDimitry Andric for (auto &[Group, Members] : Groups) { 10260b57cec5SDimitry Andric // Remember the offset into the file for this section. 1027bdd1243dSDimitry Andric const uint64_t SecStart = align(Group->getAlign()); 10280b57cec5SDimitry Andric 1029fe6060f1SDimitry Andric write(uint32_t(Group->isComdat() ? unsigned(ELF::GRP_COMDAT) : 0)); 1030*0fca6ea1SDimitry Andric W.write<unsigned>(Members); 10310b57cec5SDimitry Andric 10320b57cec5SDimitry Andric uint64_t SecEnd = W.OS.tell(); 1033*0fca6ea1SDimitry Andric Group->setOffsets(SecStart, SecEnd); 10340b57cec5SDimitry Andric } 10350b57cec5SDimitry Andric 10360b57cec5SDimitry Andric if (Mode == DwoOnly) { 10370b57cec5SDimitry Andric // dwo files don't have symbol tables or relocations, but they do have 10380b57cec5SDimitry Andric // string tables. 10390b57cec5SDimitry Andric StrTabBuilder.finalize(); 10400b57cec5SDimitry Andric } else { 10410b57cec5SDimitry Andric MCSectionELF *AddrsigSection; 1042*0fca6ea1SDimitry Andric if (OWriter.getEmitAddrsigSection()) { 10430b57cec5SDimitry Andric AddrsigSection = Ctx.getELFSection(".llvm_addrsig", ELF::SHT_LLVM_ADDRSIG, 10440b57cec5SDimitry Andric ELF::SHF_EXCLUDE); 10450b57cec5SDimitry Andric addToSectionTable(AddrsigSection); 10460b57cec5SDimitry Andric } 10470b57cec5SDimitry Andric 10480b57cec5SDimitry Andric // Compute symbol table information. 1049*0fca6ea1SDimitry Andric computeSymbolTable(Asm, RevGroupMap); 10500b57cec5SDimitry Andric 10510b57cec5SDimitry Andric for (MCSectionELF *RelSection : Relocations) { 10520b57cec5SDimitry Andric // Remember the offset into the file for this section. 1053bdd1243dSDimitry Andric const uint64_t SecStart = align(RelSection->getAlign()); 10540b57cec5SDimitry Andric 10550b57cec5SDimitry Andric writeRelocations(Asm, 10565ffd83dbSDimitry Andric cast<MCSectionELF>(*RelSection->getLinkedToSection())); 10570b57cec5SDimitry Andric 10580b57cec5SDimitry Andric uint64_t SecEnd = W.OS.tell(); 1059*0fca6ea1SDimitry Andric RelSection->setOffsets(SecStart, SecEnd); 10600b57cec5SDimitry Andric } 10610b57cec5SDimitry Andric 1062*0fca6ea1SDimitry Andric if (OWriter.getEmitAddrsigSection()) { 10630b57cec5SDimitry Andric uint64_t SecStart = W.OS.tell(); 10640b57cec5SDimitry Andric writeAddrsigSection(); 10650b57cec5SDimitry Andric uint64_t SecEnd = W.OS.tell(); 1066*0fca6ea1SDimitry Andric AddrsigSection->setOffsets(SecStart, SecEnd); 10670b57cec5SDimitry Andric } 10680b57cec5SDimitry Andric } 10690b57cec5SDimitry Andric 10700b57cec5SDimitry Andric { 10710b57cec5SDimitry Andric uint64_t SecStart = W.OS.tell(); 1072fe6060f1SDimitry Andric StrTabBuilder.write(W.OS); 1073*0fca6ea1SDimitry Andric StrtabSection->setOffsets(SecStart, W.OS.tell()); 10740b57cec5SDimitry Andric } 10750b57cec5SDimitry Andric 1076bdd1243dSDimitry Andric const uint64_t SectionHeaderOffset = align(is64Bit() ? Align(8) : Align(4)); 10770b57cec5SDimitry Andric 10780b57cec5SDimitry Andric // ... then the section header table ... 1079*0fca6ea1SDimitry Andric writeSectionHeader(Asm); 10800b57cec5SDimitry Andric 10810b57cec5SDimitry Andric uint16_t NumSections = support::endian::byte_swap<uint16_t>( 10820b57cec5SDimitry Andric (SectionTable.size() + 1 >= ELF::SHN_LORESERVE) ? (uint16_t)ELF::SHN_UNDEF 10830b57cec5SDimitry Andric : SectionTable.size() + 1, 10840b57cec5SDimitry Andric W.Endian); 10850b57cec5SDimitry Andric unsigned NumSectionsOffset; 10860b57cec5SDimitry Andric 10870b57cec5SDimitry Andric auto &Stream = static_cast<raw_pwrite_stream &>(W.OS); 10880b57cec5SDimitry Andric if (is64Bit()) { 10890b57cec5SDimitry Andric uint64_t Val = 10900b57cec5SDimitry Andric support::endian::byte_swap<uint64_t>(SectionHeaderOffset, W.Endian); 10910b57cec5SDimitry Andric Stream.pwrite(reinterpret_cast<char *>(&Val), sizeof(Val), 10920b57cec5SDimitry Andric offsetof(ELF::Elf64_Ehdr, e_shoff)); 10930b57cec5SDimitry Andric NumSectionsOffset = offsetof(ELF::Elf64_Ehdr, e_shnum); 10940b57cec5SDimitry Andric } else { 10950b57cec5SDimitry Andric uint32_t Val = 10960b57cec5SDimitry Andric support::endian::byte_swap<uint32_t>(SectionHeaderOffset, W.Endian); 10970b57cec5SDimitry Andric Stream.pwrite(reinterpret_cast<char *>(&Val), sizeof(Val), 10980b57cec5SDimitry Andric offsetof(ELF::Elf32_Ehdr, e_shoff)); 10990b57cec5SDimitry Andric NumSectionsOffset = offsetof(ELF::Elf32_Ehdr, e_shnum); 11000b57cec5SDimitry Andric } 11010b57cec5SDimitry Andric Stream.pwrite(reinterpret_cast<char *>(&NumSections), sizeof(NumSections), 11020b57cec5SDimitry Andric NumSectionsOffset); 11030b57cec5SDimitry Andric 11040b57cec5SDimitry Andric return W.OS.tell() - StartOffset; 11050b57cec5SDimitry Andric } 11060b57cec5SDimitry Andric 1107*0fca6ea1SDimitry Andric ELFObjectWriter::ELFObjectWriter(std::unique_ptr<MCELFObjectTargetWriter> MOTW, 1108*0fca6ea1SDimitry Andric raw_pwrite_stream &OS, bool IsLittleEndian) 1109*0fca6ea1SDimitry Andric : TargetObjectWriter(std::move(MOTW)), OS(OS), 1110*0fca6ea1SDimitry Andric IsLittleEndian(IsLittleEndian) {} 1111*0fca6ea1SDimitry Andric ELFObjectWriter::ELFObjectWriter(std::unique_ptr<MCELFObjectTargetWriter> MOTW, 1112*0fca6ea1SDimitry Andric raw_pwrite_stream &OS, 1113*0fca6ea1SDimitry Andric raw_pwrite_stream &DwoOS, bool IsLittleEndian) 1114*0fca6ea1SDimitry Andric : TargetObjectWriter(std::move(MOTW)), OS(OS), DwoOS(&DwoOS), 1115*0fca6ea1SDimitry Andric IsLittleEndian(IsLittleEndian) {} 1116*0fca6ea1SDimitry Andric 1117*0fca6ea1SDimitry Andric void ELFObjectWriter::reset() { 1118*0fca6ea1SDimitry Andric ELFHeaderEFlags = 0; 1119*0fca6ea1SDimitry Andric SeenGnuAbi = false; 1120*0fca6ea1SDimitry Andric OverrideABIVersion.reset(); 1121*0fca6ea1SDimitry Andric Relocations.clear(); 1122*0fca6ea1SDimitry Andric Renames.clear(); 1123*0fca6ea1SDimitry Andric Symvers.clear(); 1124*0fca6ea1SDimitry Andric MCObjectWriter::reset(); 1125*0fca6ea1SDimitry Andric } 1126*0fca6ea1SDimitry Andric 11270b57cec5SDimitry Andric bool ELFObjectWriter::hasRelocationAddend() const { 11280b57cec5SDimitry Andric return TargetObjectWriter->hasRelocationAddend(); 11290b57cec5SDimitry Andric } 11300b57cec5SDimitry Andric 1131*0fca6ea1SDimitry Andric void ELFObjectWriter::executePostLayoutBinding(MCAssembler &Asm) { 11320b57cec5SDimitry Andric // The presence of symbol versions causes undefined symbols and 11330b57cec5SDimitry Andric // versions declared with @@@ to be renamed. 1134*0fca6ea1SDimitry Andric for (const Symver &S : Symvers) { 1135e8d8bef9SDimitry Andric StringRef AliasName = S.Name; 1136e8d8bef9SDimitry Andric const auto &Symbol = cast<MCSymbolELF>(*S.Sym); 11370b57cec5SDimitry Andric size_t Pos = AliasName.find('@'); 11380b57cec5SDimitry Andric assert(Pos != StringRef::npos); 11390b57cec5SDimitry Andric 11400b57cec5SDimitry Andric StringRef Prefix = AliasName.substr(0, Pos); 11410b57cec5SDimitry Andric StringRef Rest = AliasName.substr(Pos); 11420b57cec5SDimitry Andric StringRef Tail = Rest; 11435f757f3fSDimitry Andric if (Rest.starts_with("@@@")) 11440b57cec5SDimitry Andric Tail = Rest.substr(Symbol.isUndefined() ? 2 : 1); 11450b57cec5SDimitry Andric 11460b57cec5SDimitry Andric auto *Alias = 11470b57cec5SDimitry Andric cast<MCSymbolELF>(Asm.getContext().getOrCreateSymbol(Prefix + Tail)); 11480b57cec5SDimitry Andric Asm.registerSymbol(*Alias); 11490b57cec5SDimitry Andric const MCExpr *Value = MCSymbolRefExpr::create(&Symbol, Asm.getContext()); 11500b57cec5SDimitry Andric Alias->setVariableValue(Value); 11510b57cec5SDimitry Andric 11520b57cec5SDimitry Andric // Aliases defined with .symvar copy the binding from the symbol they alias. 11530b57cec5SDimitry Andric // This is the first place we are able to copy this information. 11540b57cec5SDimitry Andric Alias->setBinding(Symbol.getBinding()); 1155e8d8bef9SDimitry Andric Alias->setVisibility(Symbol.getVisibility()); 11560b57cec5SDimitry Andric Alias->setOther(Symbol.getOther()); 11570b57cec5SDimitry Andric 1158fe6060f1SDimitry Andric if (!Symbol.isUndefined() && S.KeepOriginalSym) 11590b57cec5SDimitry Andric continue; 11600b57cec5SDimitry Andric 11615f757f3fSDimitry Andric if (Symbol.isUndefined() && Rest.starts_with("@@") && 11625f757f3fSDimitry Andric !Rest.starts_with("@@@")) { 1163e8d8bef9SDimitry Andric Asm.getContext().reportError(S.Loc, "default version symbol " + 1164e8d8bef9SDimitry Andric AliasName + " must be defined"); 11650b57cec5SDimitry Andric continue; 11660b57cec5SDimitry Andric } 11670b57cec5SDimitry Andric 11680b57cec5SDimitry Andric if (Renames.count(&Symbol) && Renames[&Symbol] != Alias) { 1169e8d8bef9SDimitry Andric Asm.getContext().reportError(S.Loc, Twine("multiple versions for ") + 11700b57cec5SDimitry Andric Symbol.getName()); 11710b57cec5SDimitry Andric continue; 11720b57cec5SDimitry Andric } 11730b57cec5SDimitry Andric 11740b57cec5SDimitry Andric Renames.insert(std::make_pair(&Symbol, Alias)); 11750b57cec5SDimitry Andric } 11760b57cec5SDimitry Andric 11770b57cec5SDimitry Andric for (const MCSymbol *&Sym : AddrsigSyms) { 11780b57cec5SDimitry Andric if (const MCSymbol *R = Renames.lookup(cast<MCSymbolELF>(Sym))) 11790b57cec5SDimitry Andric Sym = R; 11805f757f3fSDimitry Andric if (Sym->isInSection() && Sym->getName().starts_with(".L")) 11810b57cec5SDimitry Andric Sym = Sym->getSection().getBeginSymbol(); 11820b57cec5SDimitry Andric Sym->setUsedInReloc(); 11830b57cec5SDimitry Andric } 11840b57cec5SDimitry Andric } 11850b57cec5SDimitry Andric 11860b57cec5SDimitry Andric // It is always valid to create a relocation with a symbol. It is preferable 11870b57cec5SDimitry Andric // to use a relocation with a section if that is possible. Using the section 11880b57cec5SDimitry Andric // allows us to omit some local symbols from the symbol table. 11890b57cec5SDimitry Andric bool ELFObjectWriter::shouldRelocateWithSymbol(const MCAssembler &Asm, 11905f757f3fSDimitry Andric const MCValue &Val, 11910b57cec5SDimitry Andric const MCSymbolELF *Sym, 11920b57cec5SDimitry Andric uint64_t C, 11930b57cec5SDimitry Andric unsigned Type) const { 11945f757f3fSDimitry Andric const MCSymbolRefExpr *RefA = Val.getSymA(); 11950b57cec5SDimitry Andric // A PCRel relocation to an absolute value has no symbol (or section). We 11960b57cec5SDimitry Andric // represent that with a relocation to a null section. 11970b57cec5SDimitry Andric if (!RefA) 11980b57cec5SDimitry Andric return false; 11990b57cec5SDimitry Andric 12000b57cec5SDimitry Andric MCSymbolRefExpr::VariantKind Kind = RefA->getKind(); 12010b57cec5SDimitry Andric switch (Kind) { 12020b57cec5SDimitry Andric default: 12030b57cec5SDimitry Andric break; 12040b57cec5SDimitry Andric // The .odp creation emits a relocation against the symbol ".TOC." which 12050b57cec5SDimitry Andric // create a R_PPC64_TOC relocation. However the relocation symbol name 12060b57cec5SDimitry Andric // in final object creation should be NULL, since the symbol does not 12070b57cec5SDimitry Andric // really exist, it is just the reference to TOC base for the current 12080b57cec5SDimitry Andric // object file. Since the symbol is undefined, returning false results 12090b57cec5SDimitry Andric // in a relocation with a null section which is the desired result. 12100b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_TOCBASE: 12110b57cec5SDimitry Andric return false; 12120b57cec5SDimitry Andric 12130b57cec5SDimitry Andric // These VariantKind cause the relocation to refer to something other than 12140b57cec5SDimitry Andric // the symbol itself, like a linker generated table. Since the address of 12150b57cec5SDimitry Andric // symbol is not relevant, we cannot replace the symbol with the 12160b57cec5SDimitry Andric // section and patch the difference in the addend. 12170b57cec5SDimitry Andric case MCSymbolRefExpr::VK_GOT: 12180b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PLT: 12190b57cec5SDimitry Andric case MCSymbolRefExpr::VK_GOTPCREL: 1220349cc55cSDimitry Andric case MCSymbolRefExpr::VK_GOTPCREL_NORELAX: 12210b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_GOT_LO: 12220b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_GOT_HI: 12230b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_GOT_HA: 12240b57cec5SDimitry Andric return true; 12250b57cec5SDimitry Andric } 12260b57cec5SDimitry Andric 12270b57cec5SDimitry Andric // An undefined symbol is not in any section, so the relocation has to point 12280b57cec5SDimitry Andric // to the symbol itself. 12290b57cec5SDimitry Andric assert(Sym && "Expected a symbol"); 12300b57cec5SDimitry Andric if (Sym->isUndefined()) 12310b57cec5SDimitry Andric return true; 12320b57cec5SDimitry Andric 1233bdd1243dSDimitry Andric // For memory-tagged symbols, ensure that the relocation uses the symbol. For 1234bdd1243dSDimitry Andric // tagged symbols, we emit an empty relocation (R_AARCH64_NONE) in a special 1235bdd1243dSDimitry Andric // section (SHT_AARCH64_MEMTAG_GLOBALS_STATIC) to indicate to the linker that 1236bdd1243dSDimitry Andric // this global needs to be tagged. In addition, the linker needs to know 1237bdd1243dSDimitry Andric // whether to emit a special addend when relocating `end` symbols, and this 1238bdd1243dSDimitry Andric // can only be determined by the attributes of the symbol itself. 1239bdd1243dSDimitry Andric if (Sym->isMemtag()) 1240bdd1243dSDimitry Andric return true; 1241bdd1243dSDimitry Andric 12420b57cec5SDimitry Andric unsigned Binding = Sym->getBinding(); 12430b57cec5SDimitry Andric switch(Binding) { 12440b57cec5SDimitry Andric default: 12450b57cec5SDimitry Andric llvm_unreachable("Invalid Binding"); 12460b57cec5SDimitry Andric case ELF::STB_LOCAL: 12470b57cec5SDimitry Andric break; 12480b57cec5SDimitry Andric case ELF::STB_WEAK: 12490b57cec5SDimitry Andric // If the symbol is weak, it might be overridden by a symbol in another 12500b57cec5SDimitry Andric // file. The relocation has to point to the symbol so that the linker 12510b57cec5SDimitry Andric // can update it. 12520b57cec5SDimitry Andric return true; 12530b57cec5SDimitry Andric case ELF::STB_GLOBAL: 12543a9a9c0cSDimitry Andric case ELF::STB_GNU_UNIQUE: 12550b57cec5SDimitry Andric // Global ELF symbols can be preempted by the dynamic linker. The relocation 12560b57cec5SDimitry Andric // has to point to the symbol for a reason analogous to the STB_WEAK case. 12570b57cec5SDimitry Andric return true; 12580b57cec5SDimitry Andric } 12590b57cec5SDimitry Andric 12600b57cec5SDimitry Andric // Keep symbol type for a local ifunc because it may result in an IRELATIVE 12610b57cec5SDimitry Andric // reloc that the dynamic loader will use to resolve the address at startup 12620b57cec5SDimitry Andric // time. 12630b57cec5SDimitry Andric if (Sym->getType() == ELF::STT_GNU_IFUNC) 12640b57cec5SDimitry Andric return true; 12650b57cec5SDimitry Andric 12660b57cec5SDimitry Andric // If a relocation points to a mergeable section, we have to be careful. 12670b57cec5SDimitry Andric // If the offset is zero, a relocation with the section will encode the 12680b57cec5SDimitry Andric // same information. With a non-zero offset, the situation is different. 12690b57cec5SDimitry Andric // For example, a relocation can point 42 bytes past the end of a string. 12700b57cec5SDimitry Andric // If we change such a relocation to use the section, the linker would think 12710b57cec5SDimitry Andric // that it pointed to another string and subtracting 42 at runtime will 12720b57cec5SDimitry Andric // produce the wrong value. 12730b57cec5SDimitry Andric if (Sym->isInSection()) { 12740b57cec5SDimitry Andric auto &Sec = cast<MCSectionELF>(Sym->getSection()); 12750b57cec5SDimitry Andric unsigned Flags = Sec.getFlags(); 12760b57cec5SDimitry Andric if (Flags & ELF::SHF_MERGE) { 12770b57cec5SDimitry Andric if (C != 0) 12780b57cec5SDimitry Andric return true; 12790b57cec5SDimitry Andric 1280e8d8bef9SDimitry Andric // gold<2.34 incorrectly ignored the addend for R_386_GOTOFF (9) 1281e8d8bef9SDimitry Andric // (http://sourceware.org/PR16794). 1282e8d8bef9SDimitry Andric if (TargetObjectWriter->getEMachine() == ELF::EM_386 && 1283e8d8bef9SDimitry Andric Type == ELF::R_386_GOTOFF) 12840b57cec5SDimitry Andric return true; 1285d409305fSDimitry Andric 1286d409305fSDimitry Andric // ld.lld handles R_MIPS_HI16/R_MIPS_LO16 separately, not as a whole, so 1287d409305fSDimitry Andric // it doesn't know that an R_MIPS_HI16 with implicit addend 1 and an 1288d409305fSDimitry Andric // R_MIPS_LO16 with implicit addend -32768 represents 32768, which is in 1289d409305fSDimitry Andric // range of a MergeInputSection. We could introduce a new RelExpr member 1290d409305fSDimitry Andric // (like R_RISCV_PC_INDIRECT for R_RISCV_PCREL_HI20 / R_RISCV_PCREL_LO12) 1291d409305fSDimitry Andric // but the complexity is unnecessary given that GNU as keeps the original 1292d409305fSDimitry Andric // symbol for this case as well. 1293d409305fSDimitry Andric if (TargetObjectWriter->getEMachine() == ELF::EM_MIPS && 1294d409305fSDimitry Andric !hasRelocationAddend()) 1295d409305fSDimitry Andric return true; 12960b57cec5SDimitry Andric } 12970b57cec5SDimitry Andric 12980b57cec5SDimitry Andric // Most TLS relocations use a got, so they need the symbol. Even those that 12990b57cec5SDimitry Andric // are just an offset (@tpoff), require a symbol in gold versions before 13000b57cec5SDimitry Andric // 5efeedf61e4fe720fd3e9a08e6c91c10abb66d42 (2014-09-26) which fixed 13010b57cec5SDimitry Andric // http://sourceware.org/PR16773. 13020b57cec5SDimitry Andric if (Flags & ELF::SHF_TLS) 13030b57cec5SDimitry Andric return true; 13040b57cec5SDimitry Andric } 13050b57cec5SDimitry Andric 13060b57cec5SDimitry Andric // If the symbol is a thumb function the final relocation must set the lowest 13070b57cec5SDimitry Andric // bit. With a symbol that is done by just having the symbol have that bit 13080b57cec5SDimitry Andric // set, so we would lose the bit if we relocated with the section. 13090b57cec5SDimitry Andric // FIXME: We could use the section but add the bit to the relocation value. 13100b57cec5SDimitry Andric if (Asm.isThumbFunc(Sym)) 13110b57cec5SDimitry Andric return true; 13120b57cec5SDimitry Andric 13135f757f3fSDimitry Andric if (TargetObjectWriter->needsRelocateWithSymbol(Val, *Sym, Type)) 13140b57cec5SDimitry Andric return true; 13150b57cec5SDimitry Andric return false; 13160b57cec5SDimitry Andric } 13170b57cec5SDimitry Andric 1318*0fca6ea1SDimitry Andric bool ELFObjectWriter::checkRelocation(MCContext &Ctx, SMLoc Loc, 1319*0fca6ea1SDimitry Andric const MCSectionELF *From, 1320*0fca6ea1SDimitry Andric const MCSectionELF *To) { 1321*0fca6ea1SDimitry Andric if (DwoOS) { 1322*0fca6ea1SDimitry Andric if (isDwoSection(*From)) { 1323*0fca6ea1SDimitry Andric Ctx.reportError(Loc, "A dwo section may not contain relocations"); 1324*0fca6ea1SDimitry Andric return false; 1325*0fca6ea1SDimitry Andric } 1326*0fca6ea1SDimitry Andric if (To && isDwoSection(*To)) { 1327*0fca6ea1SDimitry Andric Ctx.reportError(Loc, "A relocation may not refer to a dwo section"); 1328*0fca6ea1SDimitry Andric return false; 1329*0fca6ea1SDimitry Andric } 1330*0fca6ea1SDimitry Andric } 1331*0fca6ea1SDimitry Andric return true; 1332*0fca6ea1SDimitry Andric } 1333*0fca6ea1SDimitry Andric 13340b57cec5SDimitry Andric void ELFObjectWriter::recordRelocation(MCAssembler &Asm, 13350b57cec5SDimitry Andric const MCFragment *Fragment, 13360b57cec5SDimitry Andric const MCFixup &Fixup, MCValue Target, 13370b57cec5SDimitry Andric uint64_t &FixedValue) { 13380b57cec5SDimitry Andric MCAsmBackend &Backend = Asm.getBackend(); 13390b57cec5SDimitry Andric bool IsPCRel = Backend.getFixupKindInfo(Fixup.getKind()).Flags & 13400b57cec5SDimitry Andric MCFixupKindInfo::FKF_IsPCRel; 13410b57cec5SDimitry Andric const MCSectionELF &FixupSection = cast<MCSectionELF>(*Fragment->getParent()); 13420b57cec5SDimitry Andric uint64_t C = Target.getConstant(); 1343*0fca6ea1SDimitry Andric uint64_t FixupOffset = Asm.getFragmentOffset(*Fragment) + Fixup.getOffset(); 13440b57cec5SDimitry Andric MCContext &Ctx = Asm.getContext(); 1345*0fca6ea1SDimitry Andric const MCTargetOptions *TO = Ctx.getTargetOptions(); 13460b57cec5SDimitry Andric 13470b57cec5SDimitry Andric if (const MCSymbolRefExpr *RefB = Target.getSymB()) { 13480b57cec5SDimitry Andric const auto &SymB = cast<MCSymbolELF>(RefB->getSymbol()); 13490b57cec5SDimitry Andric if (SymB.isUndefined()) { 13500b57cec5SDimitry Andric Ctx.reportError(Fixup.getLoc(), 13510b57cec5SDimitry Andric Twine("symbol '") + SymB.getName() + 13520b57cec5SDimitry Andric "' can not be undefined in a subtraction expression"); 13530b57cec5SDimitry Andric return; 13540b57cec5SDimitry Andric } 13550b57cec5SDimitry Andric 13560b57cec5SDimitry Andric assert(!SymB.isAbsolute() && "Should have been folded"); 13570b57cec5SDimitry Andric const MCSection &SecB = SymB.getSection(); 13580b57cec5SDimitry Andric if (&SecB != &FixupSection) { 13590b57cec5SDimitry Andric Ctx.reportError(Fixup.getLoc(), 13600b57cec5SDimitry Andric "Cannot represent a difference across sections"); 13610b57cec5SDimitry Andric return; 13620b57cec5SDimitry Andric } 13630b57cec5SDimitry Andric 13648bcb0991SDimitry Andric assert(!IsPCRel && "should have been folded"); 13650b57cec5SDimitry Andric IsPCRel = true; 1366*0fca6ea1SDimitry Andric C += FixupOffset - Asm.getSymbolOffset(SymB); 13670b57cec5SDimitry Andric } 13680b57cec5SDimitry Andric 13690b57cec5SDimitry Andric // We either rejected the fixup or folded B into C at this point. 13700b57cec5SDimitry Andric const MCSymbolRefExpr *RefA = Target.getSymA(); 13710b57cec5SDimitry Andric const auto *SymA = RefA ? cast<MCSymbolELF>(&RefA->getSymbol()) : nullptr; 13720b57cec5SDimitry Andric 13730b57cec5SDimitry Andric bool ViaWeakRef = false; 13740b57cec5SDimitry Andric if (SymA && SymA->isVariable()) { 13750b57cec5SDimitry Andric const MCExpr *Expr = SymA->getVariableValue(); 13760b57cec5SDimitry Andric if (const auto *Inner = dyn_cast<MCSymbolRefExpr>(Expr)) { 13770b57cec5SDimitry Andric if (Inner->getKind() == MCSymbolRefExpr::VK_WEAKREF) { 13780b57cec5SDimitry Andric SymA = cast<MCSymbolELF>(&Inner->getSymbol()); 13790b57cec5SDimitry Andric ViaWeakRef = true; 13800b57cec5SDimitry Andric } 13810b57cec5SDimitry Andric } 13820b57cec5SDimitry Andric } 13830b57cec5SDimitry Andric 13840b57cec5SDimitry Andric const MCSectionELF *SecA = (SymA && SymA->isInSection()) 13850b57cec5SDimitry Andric ? cast<MCSectionELF>(&SymA->getSection()) 13860b57cec5SDimitry Andric : nullptr; 13870b57cec5SDimitry Andric if (!checkRelocation(Ctx, Fixup.getLoc(), &FixupSection, SecA)) 13880b57cec5SDimitry Andric return; 13890b57cec5SDimitry Andric 13908bcb0991SDimitry Andric unsigned Type = TargetObjectWriter->getRelocType(Ctx, Target, Fixup, IsPCRel); 1391fe6060f1SDimitry Andric const auto *Parent = cast<MCSectionELF>(Fragment->getParent()); 1392fe6060f1SDimitry Andric // Emiting relocation with sybmol for CG Profile to help with --cg-profile. 1393fe6060f1SDimitry Andric bool RelocateWithSymbol = 13945f757f3fSDimitry Andric shouldRelocateWithSymbol(Asm, Target, SymA, C, Type) || 1395fe6060f1SDimitry Andric (Parent->getType() == ELF::SHT_LLVM_CALL_GRAPH_PROFILE); 13968bcb0991SDimitry Andric uint64_t Addend = 0; 13978bcb0991SDimitry Andric 13988bcb0991SDimitry Andric FixedValue = !RelocateWithSymbol && SymA && !SymA->isUndefined() 1399*0fca6ea1SDimitry Andric ? C + Asm.getSymbolOffset(*SymA) 14008bcb0991SDimitry Andric : C; 1401*0fca6ea1SDimitry Andric if (usesRela(TO, FixupSection)) { 14028bcb0991SDimitry Andric Addend = FixedValue; 14038bcb0991SDimitry Andric FixedValue = 0; 14048bcb0991SDimitry Andric } 14058bcb0991SDimitry Andric 14060b57cec5SDimitry Andric if (!RelocateWithSymbol) { 14070b57cec5SDimitry Andric const auto *SectionSymbol = 14080b57cec5SDimitry Andric SecA ? cast<MCSymbolELF>(SecA->getBeginSymbol()) : nullptr; 14090b57cec5SDimitry Andric if (SectionSymbol) 14100b57cec5SDimitry Andric SectionSymbol->setUsedInReloc(); 14118bcb0991SDimitry Andric ELFRelocationEntry Rec(FixupOffset, SectionSymbol, Type, Addend, SymA, C); 14120b57cec5SDimitry Andric Relocations[&FixupSection].push_back(Rec); 14130b57cec5SDimitry Andric return; 14140b57cec5SDimitry Andric } 14150b57cec5SDimitry Andric 14168bcb0991SDimitry Andric const MCSymbolELF *RenamedSymA = SymA; 14170b57cec5SDimitry Andric if (SymA) { 14180b57cec5SDimitry Andric if (const MCSymbolELF *R = Renames.lookup(SymA)) 14190b57cec5SDimitry Andric RenamedSymA = R; 14200b57cec5SDimitry Andric 14210b57cec5SDimitry Andric if (ViaWeakRef) 14220b57cec5SDimitry Andric RenamedSymA->setIsWeakrefUsedInReloc(); 14230b57cec5SDimitry Andric else 14240b57cec5SDimitry Andric RenamedSymA->setUsedInReloc(); 14250b57cec5SDimitry Andric } 14268bcb0991SDimitry Andric ELFRelocationEntry Rec(FixupOffset, RenamedSymA, Type, Addend, SymA, C); 14270b57cec5SDimitry Andric Relocations[&FixupSection].push_back(Rec); 14280b57cec5SDimitry Andric } 14290b57cec5SDimitry Andric 1430*0fca6ea1SDimitry Andric bool ELFObjectWriter::usesRela(const MCTargetOptions *TO, 1431*0fca6ea1SDimitry Andric const MCSectionELF &Sec) const { 1432*0fca6ea1SDimitry Andric return (hasRelocationAddend() && 1433*0fca6ea1SDimitry Andric Sec.getType() != ELF::SHT_LLVM_CALL_GRAPH_PROFILE) || 1434*0fca6ea1SDimitry Andric (TO && TO->Crel); 1435*0fca6ea1SDimitry Andric } 1436*0fca6ea1SDimitry Andric 14370b57cec5SDimitry Andric bool ELFObjectWriter::isSymbolRefDifferenceFullyResolvedImpl( 14380b57cec5SDimitry Andric const MCAssembler &Asm, const MCSymbol &SA, const MCFragment &FB, 14390b57cec5SDimitry Andric bool InSet, bool IsPCRel) const { 14400b57cec5SDimitry Andric const auto &SymA = cast<MCSymbolELF>(SA); 14410b57cec5SDimitry Andric if (IsPCRel) { 14420b57cec5SDimitry Andric assert(!InSet); 1443480093f4SDimitry Andric if (SymA.getBinding() != ELF::STB_LOCAL || 1444480093f4SDimitry Andric SymA.getType() == ELF::STT_GNU_IFUNC) 14450b57cec5SDimitry Andric return false; 14460b57cec5SDimitry Andric } 1447*0fca6ea1SDimitry Andric return &SymA.getSection() == FB.getParent(); 14480b57cec5SDimitry Andric } 14490b57cec5SDimitry Andric 1450*0fca6ea1SDimitry Andric uint64_t ELFObjectWriter::writeObject(MCAssembler &Asm) { 1451*0fca6ea1SDimitry Andric uint64_t Size = 1452*0fca6ea1SDimitry Andric ELFWriter(*this, OS, IsLittleEndian, 1453*0fca6ea1SDimitry Andric DwoOS ? ELFWriter::NonDwoOnly : ELFWriter::AllSections) 1454*0fca6ea1SDimitry Andric .writeObject(Asm); 1455*0fca6ea1SDimitry Andric if (DwoOS) 1456*0fca6ea1SDimitry Andric Size += ELFWriter(*this, *DwoOS, IsLittleEndian, ELFWriter::DwoOnly) 1457*0fca6ea1SDimitry Andric .writeObject(Asm); 1458*0fca6ea1SDimitry Andric return Size; 14590b57cec5SDimitry Andric } 1460