Path: blob/main/contrib/llvm-project/llvm/lib/MC/ELFObjectWriter.cpp
35232 views
//===- lib/MC/ELFObjectWriter.cpp - ELF File Writer -----------------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// This file implements ELF object file writer information.9//10//===----------------------------------------------------------------------===//1112#include "llvm/ADT/ArrayRef.h"13#include "llvm/ADT/DenseMap.h"14#include "llvm/ADT/STLExtras.h"15#include "llvm/ADT/SmallVector.h"16#include "llvm/ADT/StringExtras.h"17#include "llvm/ADT/StringRef.h"18#include "llvm/ADT/Twine.h"19#include "llvm/ADT/iterator.h"20#include "llvm/BinaryFormat/ELF.h"21#include "llvm/MC/MCAsmBackend.h"22#include "llvm/MC/MCAsmInfo.h"23#include "llvm/MC/MCAssembler.h"24#include "llvm/MC/MCContext.h"25#include "llvm/MC/MCELFExtras.h"26#include "llvm/MC/MCELFObjectWriter.h"27#include "llvm/MC/MCExpr.h"28#include "llvm/MC/MCFixup.h"29#include "llvm/MC/MCFixupKindInfo.h"30#include "llvm/MC/MCFragment.h"31#include "llvm/MC/MCObjectWriter.h"32#include "llvm/MC/MCSection.h"33#include "llvm/MC/MCSectionELF.h"34#include "llvm/MC/MCSymbol.h"35#include "llvm/MC/MCSymbolELF.h"36#include "llvm/MC/MCTargetOptions.h"37#include "llvm/MC/MCValue.h"38#include "llvm/MC/StringTableBuilder.h"39#include "llvm/Support/Alignment.h"40#include "llvm/Support/Casting.h"41#include "llvm/Support/CommandLine.h"42#include "llvm/Support/Compression.h"43#include "llvm/Support/Endian.h"44#include "llvm/Support/EndianStream.h"45#include "llvm/Support/Error.h"46#include "llvm/Support/ErrorHandling.h"47#include "llvm/Support/LEB128.h"48#include "llvm/Support/MathExtras.h"49#include "llvm/Support/SMLoc.h"50#include "llvm/Support/raw_ostream.h"51#include "llvm/TargetParser/Host.h"52#include <algorithm>53#include <cassert>54#include <cstddef>55#include <cstdint>56#include <map>57#include <memory>58#include <string>59#include <utility>60#include <vector>6162using namespace llvm;6364#undef DEBUG_TYPE65#define DEBUG_TYPE "reloc-info"6667namespace {6869struct ELFWriter;7071bool isDwoSection(const MCSectionELF &Sec) {72return Sec.getName().ends_with(".dwo");73}7475class SymbolTableWriter {76ELFWriter &EWriter;77bool Is64Bit;7879// indexes we are going to write to .symtab_shndx.80std::vector<uint32_t> ShndxIndexes;8182// The numbel of symbols written so far.83unsigned NumWritten;8485void createSymtabShndx();8687template <typename T> void write(T Value);8889public:90SymbolTableWriter(ELFWriter &EWriter, bool Is64Bit);9192void writeSymbol(uint32_t name, uint8_t info, uint64_t value, uint64_t size,93uint8_t other, uint32_t shndx, bool Reserved);9495ArrayRef<uint32_t> getShndxIndexes() const { return ShndxIndexes; }96};9798struct ELFWriter {99ELFObjectWriter &OWriter;100support::endian::Writer W;101102enum DwoMode {103AllSections,104NonDwoOnly,105DwoOnly,106} Mode;107108static uint64_t symbolValue(const MCAssembler &Asm, const MCSymbol &Sym);109static bool isInSymtab(const MCAssembler &Asm, const MCSymbolELF &Symbol,110bool Used, bool Renamed);111112/// Helper struct for containing some precomputed information on symbols.113struct ELFSymbolData {114const MCSymbolELF *Symbol;115StringRef Name;116uint32_t SectionIndex;117uint32_t Order;118};119120/// @}121/// @name Symbol Table Data122/// @{123124StringTableBuilder StrTabBuilder{StringTableBuilder::ELF};125126/// @}127128// This holds the symbol table index of the last local symbol.129unsigned LastLocalSymbolIndex = ~0u;130// This holds the .strtab section index.131unsigned StringTableIndex = ~0u;132// This holds the .symtab section index.133unsigned SymbolTableIndex = ~0u;134135// Sections in the order they are to be output in the section table.136std::vector<MCSectionELF *> SectionTable;137unsigned addToSectionTable(MCSectionELF *Sec);138139// TargetObjectWriter wrappers.140bool is64Bit() const;141142uint64_t align(Align Alignment);143144bool maybeWriteCompression(uint32_t ChType, uint64_t Size,145SmallVectorImpl<uint8_t> &CompressedContents,146Align Alignment);147148public:149ELFWriter(ELFObjectWriter &OWriter, raw_pwrite_stream &OS,150bool IsLittleEndian, DwoMode Mode)151: OWriter(OWriter), W(OS, IsLittleEndian ? llvm::endianness::little152: llvm::endianness::big),153Mode(Mode) {}154155void WriteWord(uint64_t Word) {156if (is64Bit())157W.write<uint64_t>(Word);158else159W.write<uint32_t>(Word);160}161162template <typename T> void write(T Val) {163W.write(Val);164}165166void writeHeader(const MCAssembler &Asm);167168void writeSymbol(const MCAssembler &Asm, SymbolTableWriter &Writer,169uint32_t StringIndex, ELFSymbolData &MSD);170171// Map from a signature symbol to the group section index172using RevGroupMapTy = DenseMap<const MCSymbol *, unsigned>;173174/// Compute the symbol table data175///176/// \param Asm - The assembler.177/// \param RevGroupMap - Maps a signature symbol to the group section.178void computeSymbolTable(MCAssembler &Asm, const RevGroupMapTy &RevGroupMap);179180void writeAddrsigSection();181182MCSectionELF *createRelocationSection(MCContext &Ctx,183const MCSectionELF &Sec);184185void writeSectionHeader(const MCAssembler &Asm);186187void writeSectionData(const MCAssembler &Asm, MCSection &Sec);188189void WriteSecHdrEntry(uint32_t Name, uint32_t Type, uint64_t Flags,190uint64_t Address, uint64_t Offset, uint64_t Size,191uint32_t Link, uint32_t Info, MaybeAlign Alignment,192uint64_t EntrySize);193194void writeRelocations(const MCAssembler &Asm, const MCSectionELF &Sec);195196uint64_t writeObject(MCAssembler &Asm);197void writeSection(uint32_t GroupSymbolIndex, uint64_t Offset, uint64_t Size,198const MCSectionELF &Section);199};200} // end anonymous namespace201202uint64_t ELFWriter::align(Align Alignment) {203uint64_t Offset = W.OS.tell();204uint64_t NewOffset = alignTo(Offset, Alignment);205W.OS.write_zeros(NewOffset - Offset);206return NewOffset;207}208209unsigned ELFWriter::addToSectionTable(MCSectionELF *Sec) {210SectionTable.push_back(Sec);211StrTabBuilder.add(Sec->getName());212return SectionTable.size();213}214215void SymbolTableWriter::createSymtabShndx() {216if (!ShndxIndexes.empty())217return;218219ShndxIndexes.resize(NumWritten);220}221222template <typename T> void SymbolTableWriter::write(T Value) {223EWriter.write(Value);224}225226SymbolTableWriter::SymbolTableWriter(ELFWriter &EWriter, bool Is64Bit)227: EWriter(EWriter), Is64Bit(Is64Bit), NumWritten(0) {}228229void SymbolTableWriter::writeSymbol(uint32_t name, uint8_t info, uint64_t value,230uint64_t size, uint8_t other,231uint32_t shndx, bool Reserved) {232bool LargeIndex = shndx >= ELF::SHN_LORESERVE && !Reserved;233234if (LargeIndex)235createSymtabShndx();236237if (!ShndxIndexes.empty()) {238if (LargeIndex)239ShndxIndexes.push_back(shndx);240else241ShndxIndexes.push_back(0);242}243244uint16_t Index = LargeIndex ? uint16_t(ELF::SHN_XINDEX) : shndx;245246if (Is64Bit) {247write(name); // st_name248write(info); // st_info249write(other); // st_other250write(Index); // st_shndx251write(value); // st_value252write(size); // st_size253} else {254write(name); // st_name255write(uint32_t(value)); // st_value256write(uint32_t(size)); // st_size257write(info); // st_info258write(other); // st_other259write(Index); // st_shndx260}261262++NumWritten;263}264265bool ELFWriter::is64Bit() const {266return OWriter.TargetObjectWriter->is64Bit();267}268269// Emit the ELF header.270void ELFWriter::writeHeader(const MCAssembler &Asm) {271// ELF Header272// ----------273//274// Note275// ----276// emitWord method behaves differently for ELF32 and ELF64, writing277// 4 bytes in the former and 8 in the latter.278279W.OS << ELF::ElfMagic; // e_ident[EI_MAG0] to e_ident[EI_MAG3]280281W.OS << char(is64Bit() ? ELF::ELFCLASS64 : ELF::ELFCLASS32); // e_ident[EI_CLASS]282283// e_ident[EI_DATA]284W.OS << char(W.Endian == llvm::endianness::little ? ELF::ELFDATA2LSB285: ELF::ELFDATA2MSB);286287W.OS << char(ELF::EV_CURRENT); // e_ident[EI_VERSION]288// e_ident[EI_OSABI]289uint8_t OSABI = OWriter.TargetObjectWriter->getOSABI();290W.OS << char(OSABI == ELF::ELFOSABI_NONE && OWriter.seenGnuAbi()291? int(ELF::ELFOSABI_GNU)292: OSABI);293// e_ident[EI_ABIVERSION]294W.OS << char(OWriter.OverrideABIVersion295? *OWriter.OverrideABIVersion296: OWriter.TargetObjectWriter->getABIVersion());297298W.OS.write_zeros(ELF::EI_NIDENT - ELF::EI_PAD);299300W.write<uint16_t>(ELF::ET_REL); // e_type301302W.write<uint16_t>(OWriter.TargetObjectWriter->getEMachine()); // e_machine = target303304W.write<uint32_t>(ELF::EV_CURRENT); // e_version305WriteWord(0); // e_entry, no entry point in .o file306WriteWord(0); // e_phoff, no program header for .o307WriteWord(0); // e_shoff = sec hdr table off in bytes308309// e_flags = whatever the target wants310W.write<uint32_t>(OWriter.getELFHeaderEFlags());311312// e_ehsize = ELF header size313W.write<uint16_t>(is64Bit() ? sizeof(ELF::Elf64_Ehdr)314: sizeof(ELF::Elf32_Ehdr));315316W.write<uint16_t>(0); // e_phentsize = prog header entry size317W.write<uint16_t>(0); // e_phnum = # prog header entries = 0318319// e_shentsize = Section header entry size320W.write<uint16_t>(is64Bit() ? sizeof(ELF::Elf64_Shdr)321: sizeof(ELF::Elf32_Shdr));322323// e_shnum = # of section header ents324W.write<uint16_t>(0);325326// e_shstrndx = Section # of '.strtab'327assert(StringTableIndex < ELF::SHN_LORESERVE);328W.write<uint16_t>(StringTableIndex);329}330331uint64_t ELFWriter::symbolValue(const MCAssembler &Asm, const MCSymbol &Sym) {332if (Sym.isCommon())333return Sym.getCommonAlignment()->value();334335uint64_t Res;336if (!Asm.getSymbolOffset(Sym, Res))337return 0;338339if (Asm.isThumbFunc(&Sym))340Res |= 1;341342return Res;343}344345static uint8_t mergeTypeForSet(uint8_t origType, uint8_t newType) {346uint8_t Type = newType;347348// Propagation rules:349// IFUNC > FUNC > OBJECT > NOTYPE350// TLS_OBJECT > OBJECT > NOTYPE351//352// dont let the new type degrade the old type353switch (origType) {354default:355break;356case ELF::STT_GNU_IFUNC:357if (Type == ELF::STT_FUNC || Type == ELF::STT_OBJECT ||358Type == ELF::STT_NOTYPE || Type == ELF::STT_TLS)359Type = ELF::STT_GNU_IFUNC;360break;361case ELF::STT_FUNC:362if (Type == ELF::STT_OBJECT || Type == ELF::STT_NOTYPE ||363Type == ELF::STT_TLS)364Type = ELF::STT_FUNC;365break;366case ELF::STT_OBJECT:367if (Type == ELF::STT_NOTYPE)368Type = ELF::STT_OBJECT;369break;370case ELF::STT_TLS:371if (Type == ELF::STT_OBJECT || Type == ELF::STT_NOTYPE ||372Type == ELF::STT_GNU_IFUNC || Type == ELF::STT_FUNC)373Type = ELF::STT_TLS;374break;375}376377return Type;378}379380static bool isIFunc(const MCSymbolELF *Symbol) {381while (Symbol->getType() != ELF::STT_GNU_IFUNC) {382const MCSymbolRefExpr *Value;383if (!Symbol->isVariable() ||384!(Value = dyn_cast<MCSymbolRefExpr>(Symbol->getVariableValue())) ||385Value->getKind() != MCSymbolRefExpr::VK_None ||386mergeTypeForSet(Symbol->getType(), ELF::STT_GNU_IFUNC) != ELF::STT_GNU_IFUNC)387return false;388Symbol = &cast<MCSymbolELF>(Value->getSymbol());389}390return true;391}392393void ELFWriter::writeSymbol(const MCAssembler &Asm, SymbolTableWriter &Writer,394uint32_t StringIndex, ELFSymbolData &MSD) {395const auto &Symbol = cast<MCSymbolELF>(*MSD.Symbol);396const MCSymbolELF *Base =397cast_or_null<MCSymbolELF>(Asm.getBaseSymbol(Symbol));398399// This has to be in sync with when computeSymbolTable uses SHN_ABS or400// SHN_COMMON.401bool IsReserved = !Base || Symbol.isCommon();402403// Binding and Type share the same byte as upper and lower nibbles404uint8_t Binding = Symbol.getBinding();405uint8_t Type = Symbol.getType();406if (isIFunc(&Symbol))407Type = ELF::STT_GNU_IFUNC;408if (Base) {409Type = mergeTypeForSet(Type, Base->getType());410}411uint8_t Info = (Binding << 4) | Type;412413// Other and Visibility share the same byte with Visibility using the lower414// 2 bits415uint8_t Visibility = Symbol.getVisibility();416uint8_t Other = Symbol.getOther() | Visibility;417418uint64_t Value = symbolValue(Asm, *MSD.Symbol);419uint64_t Size = 0;420421const MCExpr *ESize = MSD.Symbol->getSize();422if (!ESize && Base) {423// For expressions like .set y, x+1, if y's size is unset, inherit from x.424ESize = Base->getSize();425426// For `.size x, 2; y = x; .size y, 1; z = y; z1 = z; .symver y, y@v1`, z,427// z1, and y@v1's st_size equals y's. However, `Base` is `x` which will give428// us 2. Follow the MCSymbolRefExpr assignment chain, which covers most429// needs. MCBinaryExpr is not handled.430const MCSymbolELF *Sym = &Symbol;431while (Sym->isVariable()) {432if (auto *Expr =433dyn_cast<MCSymbolRefExpr>(Sym->getVariableValue(false))) {434Sym = cast<MCSymbolELF>(&Expr->getSymbol());435if (!Sym->getSize())436continue;437ESize = Sym->getSize();438}439break;440}441}442443if (ESize) {444int64_t Res;445if (!ESize->evaluateKnownAbsolute(Res, Asm))446report_fatal_error("Size expression must be absolute.");447Size = Res;448}449450// Write out the symbol table entry451Writer.writeSymbol(StringIndex, Info, Value, Size, Other, MSD.SectionIndex,452IsReserved);453}454455bool ELFWriter::isInSymtab(const MCAssembler &Asm, const MCSymbolELF &Symbol,456bool Used, bool Renamed) {457if (Symbol.isVariable()) {458const MCExpr *Expr = Symbol.getVariableValue();459// Target Expressions that are always inlined do not appear in the symtab460if (const auto *T = dyn_cast<MCTargetExpr>(Expr))461if (T->inlineAssignedExpr())462return false;463if (const MCSymbolRefExpr *Ref = dyn_cast<MCSymbolRefExpr>(Expr)) {464if (Ref->getKind() == MCSymbolRefExpr::VK_WEAKREF)465return false;466}467}468469if (Used)470return true;471472if (Renamed)473return false;474475if (Symbol.isVariable() && Symbol.isUndefined()) {476// FIXME: this is here just to diagnose the case of a var = commmon_sym.477Asm.getBaseSymbol(Symbol);478return false;479}480481if (Symbol.isTemporary())482return false;483484if (Symbol.getType() == ELF::STT_SECTION)485return false;486487return true;488}489490void ELFWriter::computeSymbolTable(MCAssembler &Asm,491const RevGroupMapTy &RevGroupMap) {492MCContext &Ctx = Asm.getContext();493SymbolTableWriter Writer(*this, is64Bit());494495// Symbol table496unsigned EntrySize = is64Bit() ? ELF::SYMENTRY_SIZE64 : ELF::SYMENTRY_SIZE32;497MCSectionELF *SymtabSection =498Ctx.getELFSection(".symtab", ELF::SHT_SYMTAB, 0, EntrySize);499SymtabSection->setAlignment(is64Bit() ? Align(8) : Align(4));500SymbolTableIndex = addToSectionTable(SymtabSection);501502uint64_t SecStart = align(SymtabSection->getAlign());503504// The first entry is the undefined symbol entry.505Writer.writeSymbol(0, 0, 0, 0, 0, 0, false);506507std::vector<ELFSymbolData> LocalSymbolData;508std::vector<ELFSymbolData> ExternalSymbolData;509MutableArrayRef<std::pair<std::string, size_t>> FileNames =510OWriter.getFileNames();511for (const std::pair<std::string, size_t> &F : FileNames)512StrTabBuilder.add(F.first);513514// Add the data for the symbols.515bool HasLargeSectionIndex = false;516for (auto It : llvm::enumerate(Asm.symbols())) {517const auto &Symbol = cast<MCSymbolELF>(It.value());518bool Used = Symbol.isUsedInReloc();519bool WeakrefUsed = Symbol.isWeakrefUsedInReloc();520bool isSignature = Symbol.isSignature();521522if (!isInSymtab(Asm, Symbol, Used || WeakrefUsed || isSignature,523OWriter.Renames.count(&Symbol)))524continue;525526if (Symbol.isTemporary() && Symbol.isUndefined()) {527Ctx.reportError(SMLoc(), "Undefined temporary symbol " + Symbol.getName());528continue;529}530531ELFSymbolData MSD;532MSD.Symbol = cast<MCSymbolELF>(&Symbol);533MSD.Order = It.index();534535bool Local = Symbol.getBinding() == ELF::STB_LOCAL;536assert(Local || !Symbol.isTemporary());537538if (Symbol.isAbsolute()) {539MSD.SectionIndex = ELF::SHN_ABS;540} else if (Symbol.isCommon()) {541if (Symbol.isTargetCommon()) {542MSD.SectionIndex = Symbol.getIndex();543} else {544assert(!Local);545MSD.SectionIndex = ELF::SHN_COMMON;546}547} else if (Symbol.isUndefined()) {548if (isSignature && !Used) {549MSD.SectionIndex = RevGroupMap.lookup(&Symbol);550if (MSD.SectionIndex >= ELF::SHN_LORESERVE)551HasLargeSectionIndex = true;552} else {553MSD.SectionIndex = ELF::SHN_UNDEF;554}555} else {556const MCSectionELF &Section =557static_cast<const MCSectionELF &>(Symbol.getSection());558559// We may end up with a situation when section symbol is technically560// defined, but should not be. That happens because we explicitly561// pre-create few .debug_* sections to have accessors.562// And if these sections were not really defined in the code, but were563// referenced, we simply error out.564if (!Section.isRegistered()) {565assert(static_cast<const MCSymbolELF &>(Symbol).getType() ==566ELF::STT_SECTION);567Ctx.reportError(SMLoc(),568"Undefined section reference: " + Symbol.getName());569continue;570}571572if (Mode == NonDwoOnly && isDwoSection(Section))573continue;574MSD.SectionIndex = Section.getOrdinal();575assert(MSD.SectionIndex && "Invalid section index!");576if (MSD.SectionIndex >= ELF::SHN_LORESERVE)577HasLargeSectionIndex = true;578}579580// Temporary symbols generated for certain assembler features (.eh_frame,581// .debug_line) of an empty name may be referenced by relocations due to582// linker relaxation. Rename them to ".L0 " to match the gas fake label name583// and allow ld/objcopy --discard-locals to discard such symbols.584StringRef Name = Symbol.getName();585if (Name.empty())586Name = ".L0 ";587588// Sections have their own string table589if (Symbol.getType() != ELF::STT_SECTION) {590MSD.Name = Name;591StrTabBuilder.add(Name);592}593594if (Local)595LocalSymbolData.push_back(MSD);596else597ExternalSymbolData.push_back(MSD);598}599600// This holds the .symtab_shndx section index.601unsigned SymtabShndxSectionIndex = 0;602603if (HasLargeSectionIndex) {604MCSectionELF *SymtabShndxSection =605Ctx.getELFSection(".symtab_shndx", ELF::SHT_SYMTAB_SHNDX, 0, 4);606SymtabShndxSectionIndex = addToSectionTable(SymtabShndxSection);607SymtabShndxSection->setAlignment(Align(4));608}609610StrTabBuilder.finalize();611612// Make the first STT_FILE precede previous local symbols.613unsigned Index = 1;614auto FileNameIt = FileNames.begin();615if (!FileNames.empty())616FileNames[0].second = 0;617618for (ELFSymbolData &MSD : LocalSymbolData) {619// Emit STT_FILE symbols before their associated local symbols.620for (; FileNameIt != FileNames.end() && FileNameIt->second <= MSD.Order;621++FileNameIt) {622Writer.writeSymbol(StrTabBuilder.getOffset(FileNameIt->first),623ELF::STT_FILE | ELF::STB_LOCAL, 0, 0, ELF::STV_DEFAULT,624ELF::SHN_ABS, true);625++Index;626}627628unsigned StringIndex = MSD.Symbol->getType() == ELF::STT_SECTION629? 0630: StrTabBuilder.getOffset(MSD.Name);631MSD.Symbol->setIndex(Index++);632writeSymbol(Asm, Writer, StringIndex, MSD);633}634for (; FileNameIt != FileNames.end(); ++FileNameIt) {635Writer.writeSymbol(StrTabBuilder.getOffset(FileNameIt->first),636ELF::STT_FILE | ELF::STB_LOCAL, 0, 0, ELF::STV_DEFAULT,637ELF::SHN_ABS, true);638++Index;639}640641// Write the symbol table entries.642LastLocalSymbolIndex = Index;643644for (ELFSymbolData &MSD : ExternalSymbolData) {645unsigned StringIndex = StrTabBuilder.getOffset(MSD.Name);646MSD.Symbol->setIndex(Index++);647writeSymbol(Asm, Writer, StringIndex, MSD);648assert(MSD.Symbol->getBinding() != ELF::STB_LOCAL);649}650651uint64_t SecEnd = W.OS.tell();652SymtabSection->setOffsets(SecStart, SecEnd);653654ArrayRef<uint32_t> ShndxIndexes = Writer.getShndxIndexes();655if (ShndxIndexes.empty()) {656assert(SymtabShndxSectionIndex == 0);657return;658}659assert(SymtabShndxSectionIndex != 0);660661SecStart = W.OS.tell();662MCSectionELF *SymtabShndxSection = SectionTable[SymtabShndxSectionIndex - 1];663for (uint32_t Index : ShndxIndexes)664write(Index);665SecEnd = W.OS.tell();666SymtabShndxSection->setOffsets(SecStart, SecEnd);667}668669void ELFWriter::writeAddrsigSection() {670for (const MCSymbol *Sym : OWriter.getAddrsigSyms())671if (Sym->getIndex() != 0)672encodeULEB128(Sym->getIndex(), W.OS);673}674675MCSectionELF *ELFWriter::createRelocationSection(MCContext &Ctx,676const MCSectionELF &Sec) {677if (OWriter.Relocations[&Sec].empty())678return nullptr;679680unsigned Flags = ELF::SHF_INFO_LINK;681if (Sec.getFlags() & ELF::SHF_GROUP)682Flags = ELF::SHF_GROUP;683684const StringRef SectionName = Sec.getName();685const MCTargetOptions *TO = Ctx.getTargetOptions();686if (TO && TO->Crel) {687MCSectionELF *RelaSection =688Ctx.createELFRelSection(".crel" + SectionName, ELF::SHT_CREL, Flags,689/*EntrySize=*/1, Sec.getGroup(), &Sec);690return RelaSection;691}692693const bool Rela = OWriter.usesRela(TO, Sec);694unsigned EntrySize;695if (Rela)696EntrySize = is64Bit() ? sizeof(ELF::Elf64_Rela) : sizeof(ELF::Elf32_Rela);697else698EntrySize = is64Bit() ? sizeof(ELF::Elf64_Rel) : sizeof(ELF::Elf32_Rel);699700MCSectionELF *RelaSection =701Ctx.createELFRelSection(((Rela ? ".rela" : ".rel") + SectionName),702Rela ? ELF::SHT_RELA : ELF::SHT_REL, Flags,703EntrySize, Sec.getGroup(), &Sec);704RelaSection->setAlignment(is64Bit() ? Align(8) : Align(4));705return RelaSection;706}707708// Include the debug info compression header.709bool ELFWriter::maybeWriteCompression(710uint32_t ChType, uint64_t Size,711SmallVectorImpl<uint8_t> &CompressedContents, Align Alignment) {712uint64_t HdrSize =713is64Bit() ? sizeof(ELF::Elf64_Chdr) : sizeof(ELF::Elf32_Chdr);714if (Size <= HdrSize + CompressedContents.size())715return false;716// Platform specific header is followed by compressed data.717if (is64Bit()) {718// Write Elf64_Chdr header.719write(static_cast<ELF::Elf64_Word>(ChType));720write(static_cast<ELF::Elf64_Word>(0)); // ch_reserved field.721write(static_cast<ELF::Elf64_Xword>(Size));722write(static_cast<ELF::Elf64_Xword>(Alignment.value()));723} else {724// Write Elf32_Chdr header otherwise.725write(static_cast<ELF::Elf32_Word>(ChType));726write(static_cast<ELF::Elf32_Word>(Size));727write(static_cast<ELF::Elf32_Word>(Alignment.value()));728}729return true;730}731732void ELFWriter::writeSectionData(const MCAssembler &Asm, MCSection &Sec) {733MCSectionELF &Section = static_cast<MCSectionELF &>(Sec);734StringRef SectionName = Section.getName();735auto &Ctx = Asm.getContext();736const DebugCompressionType CompressionType =737Ctx.getTargetOptions() ? Ctx.getTargetOptions()->CompressDebugSections738: DebugCompressionType::None;739if (CompressionType == DebugCompressionType::None ||740!SectionName.starts_with(".debug_")) {741Asm.writeSectionData(W.OS, &Section);742return;743}744745SmallVector<char, 128> UncompressedData;746raw_svector_ostream VecOS(UncompressedData);747Asm.writeSectionData(VecOS, &Section);748ArrayRef<uint8_t> Uncompressed =749ArrayRef(reinterpret_cast<uint8_t *>(UncompressedData.data()),750UncompressedData.size());751752SmallVector<uint8_t, 128> Compressed;753uint32_t ChType;754switch (CompressionType) {755case DebugCompressionType::None:756llvm_unreachable("has been handled");757case DebugCompressionType::Zlib:758ChType = ELF::ELFCOMPRESS_ZLIB;759break;760case DebugCompressionType::Zstd:761ChType = ELF::ELFCOMPRESS_ZSTD;762break;763}764compression::compress(compression::Params(CompressionType), Uncompressed,765Compressed);766if (!maybeWriteCompression(ChType, UncompressedData.size(), Compressed,767Sec.getAlign())) {768W.OS << UncompressedData;769return;770}771772Section.setFlags(Section.getFlags() | ELF::SHF_COMPRESSED);773// Alignment field should reflect the requirements of774// the compressed section header.775Section.setAlignment(is64Bit() ? Align(8) : Align(4));776W.OS << toStringRef(Compressed);777}778779void ELFWriter::WriteSecHdrEntry(uint32_t Name, uint32_t Type, uint64_t Flags,780uint64_t Address, uint64_t Offset,781uint64_t Size, uint32_t Link, uint32_t Info,782MaybeAlign Alignment, uint64_t EntrySize) {783W.write<uint32_t>(Name); // sh_name: index into string table784W.write<uint32_t>(Type); // sh_type785WriteWord(Flags); // sh_flags786WriteWord(Address); // sh_addr787WriteWord(Offset); // sh_offset788WriteWord(Size); // sh_size789W.write<uint32_t>(Link); // sh_link790W.write<uint32_t>(Info); // sh_info791WriteWord(Alignment ? Alignment->value() : 0); // sh_addralign792WriteWord(EntrySize); // sh_entsize793}794795template <bool Is64>796static void encodeCrel(ArrayRef<ELFRelocationEntry> Relocs, raw_ostream &OS) {797using uint = std::conditional_t<Is64, uint64_t, uint32_t>;798ELF::encodeCrel<Is64>(OS, Relocs, [&](const ELFRelocationEntry &R) {799uint32_t SymIdx = R.Symbol ? R.Symbol->getIndex() : 0;800return ELF::Elf_Crel<Is64>{static_cast<uint>(R.Offset), SymIdx, R.Type,801std::make_signed_t<uint>(R.Addend)};802});803}804805void ELFWriter::writeRelocations(const MCAssembler &Asm,806const MCSectionELF &Sec) {807std::vector<ELFRelocationEntry> &Relocs = OWriter.Relocations[&Sec];808const MCTargetOptions *TO = Asm.getContext().getTargetOptions();809const bool Rela = OWriter.usesRela(TO, Sec);810811// Sort the relocation entries. MIPS needs this.812OWriter.TargetObjectWriter->sortRelocs(Asm, Relocs);813814if (OWriter.TargetObjectWriter->getEMachine() == ELF::EM_MIPS) {815for (const ELFRelocationEntry &Entry : Relocs) {816uint32_t SymIdx = Entry.Symbol ? Entry.Symbol->getIndex() : 0;817if (is64Bit()) {818write(Entry.Offset);819write(uint32_t(SymIdx));820write(OWriter.TargetObjectWriter->getRSsym(Entry.Type));821write(OWriter.TargetObjectWriter->getRType3(Entry.Type));822write(OWriter.TargetObjectWriter->getRType2(Entry.Type));823write(OWriter.TargetObjectWriter->getRType(Entry.Type));824if (Rela)825write(Entry.Addend);826} else {827write(uint32_t(Entry.Offset));828ELF::Elf32_Rela ERE32;829ERE32.setSymbolAndType(SymIdx, Entry.Type);830write(ERE32.r_info);831if (Rela)832write(uint32_t(Entry.Addend));833if (uint32_t RType =834OWriter.TargetObjectWriter->getRType2(Entry.Type)) {835write(uint32_t(Entry.Offset));836ERE32.setSymbolAndType(0, RType);837write(ERE32.r_info);838write(uint32_t(0));839}840if (uint32_t RType =841OWriter.TargetObjectWriter->getRType3(Entry.Type)) {842write(uint32_t(Entry.Offset));843ERE32.setSymbolAndType(0, RType);844write(ERE32.r_info);845write(uint32_t(0));846}847}848}849} else if (TO && TO->Crel) {850if (is64Bit())851encodeCrel<true>(Relocs, W.OS);852else853encodeCrel<false>(Relocs, W.OS);854} else {855for (const ELFRelocationEntry &Entry : Relocs) {856uint32_t Symidx = Entry.Symbol ? Entry.Symbol->getIndex() : 0;857if (is64Bit()) {858write(Entry.Offset);859ELF::Elf64_Rela ERE;860ERE.setSymbolAndType(Symidx, Entry.Type);861write(ERE.r_info);862if (Rela)863write(Entry.Addend);864} else {865write(uint32_t(Entry.Offset));866ELF::Elf32_Rela ERE;867ERE.setSymbolAndType(Symidx, Entry.Type);868write(ERE.r_info);869if (Rela)870write(uint32_t(Entry.Addend));871}872}873}874}875876void ELFWriter::writeSection(uint32_t GroupSymbolIndex, uint64_t Offset,877uint64_t Size, const MCSectionELF &Section) {878uint64_t sh_link = 0;879uint64_t sh_info = 0;880881switch(Section.getType()) {882default:883// Nothing to do.884break;885886case ELF::SHT_DYNAMIC:887llvm_unreachable("SHT_DYNAMIC in a relocatable object");888889case ELF::SHT_REL:890case ELF::SHT_RELA:891case ELF::SHT_CREL: {892sh_link = SymbolTableIndex;893assert(sh_link && ".symtab not found");894const MCSection *InfoSection = Section.getLinkedToSection();895sh_info = InfoSection->getOrdinal();896break;897}898899case ELF::SHT_SYMTAB:900sh_link = StringTableIndex;901sh_info = LastLocalSymbolIndex;902break;903904case ELF::SHT_SYMTAB_SHNDX:905case ELF::SHT_LLVM_CALL_GRAPH_PROFILE:906case ELF::SHT_LLVM_ADDRSIG:907sh_link = SymbolTableIndex;908break;909910case ELF::SHT_GROUP:911sh_link = SymbolTableIndex;912sh_info = GroupSymbolIndex;913break;914}915916if (Section.getFlags() & ELF::SHF_LINK_ORDER) {917// If the value in the associated metadata is not a definition, Sym will be918// undefined. Represent this with sh_link=0.919const MCSymbol *Sym = Section.getLinkedToSymbol();920if (Sym && Sym->isInSection())921sh_link = Sym->getSection().getOrdinal();922}923924WriteSecHdrEntry(StrTabBuilder.getOffset(Section.getName()),925Section.getType(), Section.getFlags(), 0, Offset, Size,926sh_link, sh_info, Section.getAlign(),927Section.getEntrySize());928}929930void ELFWriter::writeSectionHeader(const MCAssembler &Asm) {931const unsigned NumSections = SectionTable.size();932933// Null section first.934uint64_t FirstSectionSize =935(NumSections + 1) >= ELF::SHN_LORESERVE ? NumSections + 1 : 0;936WriteSecHdrEntry(0, 0, 0, 0, 0, FirstSectionSize, 0, 0, std::nullopt, 0);937938for (const MCSectionELF *Section : SectionTable) {939uint32_t GroupSymbolIndex;940unsigned Type = Section->getType();941if (Type != ELF::SHT_GROUP)942GroupSymbolIndex = 0;943else944GroupSymbolIndex = Section->getGroup()->getIndex();945946std::pair<uint64_t, uint64_t> Offsets = Section->getOffsets();947uint64_t Size;948if (Type == ELF::SHT_NOBITS)949Size = Asm.getSectionAddressSize(*Section);950else951Size = Offsets.second - Offsets.first;952953writeSection(GroupSymbolIndex, Offsets.first, Size, *Section);954}955}956957uint64_t ELFWriter::writeObject(MCAssembler &Asm) {958uint64_t StartOffset = W.OS.tell();959960MCContext &Ctx = Asm.getContext();961MCSectionELF *StrtabSection =962Ctx.getELFSection(".strtab", ELF::SHT_STRTAB, 0);963StringTableIndex = addToSectionTable(StrtabSection);964965RevGroupMapTy RevGroupMap;966967// Write out the ELF header ...968writeHeader(Asm);969970// ... then the sections ...971SmallVector<std::pair<MCSectionELF *, SmallVector<unsigned>>, 0> Groups;972// Map from group section index to group973SmallVector<unsigned, 0> GroupMap;974SmallVector<MCSectionELF *> Relocations;975for (MCSection &Sec : Asm) {976MCSectionELF &Section = static_cast<MCSectionELF &>(Sec);977if (Mode == NonDwoOnly && isDwoSection(Section))978continue;979if (Mode == DwoOnly && !isDwoSection(Section))980continue;981982// Remember the offset into the file for this section.983const uint64_t SecStart = align(Section.getAlign());984985const MCSymbolELF *SignatureSymbol = Section.getGroup();986writeSectionData(Asm, Section);987988uint64_t SecEnd = W.OS.tell();989Section.setOffsets(SecStart, SecEnd);990991MCSectionELF *RelSection = createRelocationSection(Ctx, Section);992993unsigned *GroupIdxEntry = nullptr;994if (SignatureSymbol) {995GroupIdxEntry = &RevGroupMap[SignatureSymbol];996if (!*GroupIdxEntry) {997MCSectionELF *Group =998Ctx.createELFGroupSection(SignatureSymbol, Section.isComdat());999*GroupIdxEntry = addToSectionTable(Group);1000Group->setAlignment(Align(4));10011002GroupMap.resize(*GroupIdxEntry + 1);1003GroupMap[*GroupIdxEntry] = Groups.size();1004Groups.emplace_back(Group, SmallVector<unsigned>{});1005}1006}10071008Section.setOrdinal(addToSectionTable(&Section));1009if (RelSection) {1010RelSection->setOrdinal(addToSectionTable(RelSection));1011Relocations.push_back(RelSection);1012}10131014if (GroupIdxEntry) {1015auto &Members = Groups[GroupMap[*GroupIdxEntry]];1016Members.second.push_back(Section.getOrdinal());1017if (RelSection)1018Members.second.push_back(RelSection->getOrdinal());1019}10201021OWriter.TargetObjectWriter->addTargetSectionFlags(Ctx, Section);1022}10231024for (auto &[Group, Members] : Groups) {1025// Remember the offset into the file for this section.1026const uint64_t SecStart = align(Group->getAlign());10271028write(uint32_t(Group->isComdat() ? unsigned(ELF::GRP_COMDAT) : 0));1029W.write<unsigned>(Members);10301031uint64_t SecEnd = W.OS.tell();1032Group->setOffsets(SecStart, SecEnd);1033}10341035if (Mode == DwoOnly) {1036// dwo files don't have symbol tables or relocations, but they do have1037// string tables.1038StrTabBuilder.finalize();1039} else {1040MCSectionELF *AddrsigSection;1041if (OWriter.getEmitAddrsigSection()) {1042AddrsigSection = Ctx.getELFSection(".llvm_addrsig", ELF::SHT_LLVM_ADDRSIG,1043ELF::SHF_EXCLUDE);1044addToSectionTable(AddrsigSection);1045}10461047// Compute symbol table information.1048computeSymbolTable(Asm, RevGroupMap);10491050for (MCSectionELF *RelSection : Relocations) {1051// Remember the offset into the file for this section.1052const uint64_t SecStart = align(RelSection->getAlign());10531054writeRelocations(Asm,1055cast<MCSectionELF>(*RelSection->getLinkedToSection()));10561057uint64_t SecEnd = W.OS.tell();1058RelSection->setOffsets(SecStart, SecEnd);1059}10601061if (OWriter.getEmitAddrsigSection()) {1062uint64_t SecStart = W.OS.tell();1063writeAddrsigSection();1064uint64_t SecEnd = W.OS.tell();1065AddrsigSection->setOffsets(SecStart, SecEnd);1066}1067}10681069{1070uint64_t SecStart = W.OS.tell();1071StrTabBuilder.write(W.OS);1072StrtabSection->setOffsets(SecStart, W.OS.tell());1073}10741075const uint64_t SectionHeaderOffset = align(is64Bit() ? Align(8) : Align(4));10761077// ... then the section header table ...1078writeSectionHeader(Asm);10791080uint16_t NumSections = support::endian::byte_swap<uint16_t>(1081(SectionTable.size() + 1 >= ELF::SHN_LORESERVE) ? (uint16_t)ELF::SHN_UNDEF1082: SectionTable.size() + 1,1083W.Endian);1084unsigned NumSectionsOffset;10851086auto &Stream = static_cast<raw_pwrite_stream &>(W.OS);1087if (is64Bit()) {1088uint64_t Val =1089support::endian::byte_swap<uint64_t>(SectionHeaderOffset, W.Endian);1090Stream.pwrite(reinterpret_cast<char *>(&Val), sizeof(Val),1091offsetof(ELF::Elf64_Ehdr, e_shoff));1092NumSectionsOffset = offsetof(ELF::Elf64_Ehdr, e_shnum);1093} else {1094uint32_t Val =1095support::endian::byte_swap<uint32_t>(SectionHeaderOffset, W.Endian);1096Stream.pwrite(reinterpret_cast<char *>(&Val), sizeof(Val),1097offsetof(ELF::Elf32_Ehdr, e_shoff));1098NumSectionsOffset = offsetof(ELF::Elf32_Ehdr, e_shnum);1099}1100Stream.pwrite(reinterpret_cast<char *>(&NumSections), sizeof(NumSections),1101NumSectionsOffset);11021103return W.OS.tell() - StartOffset;1104}11051106ELFObjectWriter::ELFObjectWriter(std::unique_ptr<MCELFObjectTargetWriter> MOTW,1107raw_pwrite_stream &OS, bool IsLittleEndian)1108: TargetObjectWriter(std::move(MOTW)), OS(OS),1109IsLittleEndian(IsLittleEndian) {}1110ELFObjectWriter::ELFObjectWriter(std::unique_ptr<MCELFObjectTargetWriter> MOTW,1111raw_pwrite_stream &OS,1112raw_pwrite_stream &DwoOS, bool IsLittleEndian)1113: TargetObjectWriter(std::move(MOTW)), OS(OS), DwoOS(&DwoOS),1114IsLittleEndian(IsLittleEndian) {}11151116void ELFObjectWriter::reset() {1117ELFHeaderEFlags = 0;1118SeenGnuAbi = false;1119OverrideABIVersion.reset();1120Relocations.clear();1121Renames.clear();1122Symvers.clear();1123MCObjectWriter::reset();1124}11251126bool ELFObjectWriter::hasRelocationAddend() const {1127return TargetObjectWriter->hasRelocationAddend();1128}11291130void ELFObjectWriter::executePostLayoutBinding(MCAssembler &Asm) {1131// The presence of symbol versions causes undefined symbols and1132// versions declared with @@@ to be renamed.1133for (const Symver &S : Symvers) {1134StringRef AliasName = S.Name;1135const auto &Symbol = cast<MCSymbolELF>(*S.Sym);1136size_t Pos = AliasName.find('@');1137assert(Pos != StringRef::npos);11381139StringRef Prefix = AliasName.substr(0, Pos);1140StringRef Rest = AliasName.substr(Pos);1141StringRef Tail = Rest;1142if (Rest.starts_with("@@@"))1143Tail = Rest.substr(Symbol.isUndefined() ? 2 : 1);11441145auto *Alias =1146cast<MCSymbolELF>(Asm.getContext().getOrCreateSymbol(Prefix + Tail));1147Asm.registerSymbol(*Alias);1148const MCExpr *Value = MCSymbolRefExpr::create(&Symbol, Asm.getContext());1149Alias->setVariableValue(Value);11501151// Aliases defined with .symvar copy the binding from the symbol they alias.1152// This is the first place we are able to copy this information.1153Alias->setBinding(Symbol.getBinding());1154Alias->setVisibility(Symbol.getVisibility());1155Alias->setOther(Symbol.getOther());11561157if (!Symbol.isUndefined() && S.KeepOriginalSym)1158continue;11591160if (Symbol.isUndefined() && Rest.starts_with("@@") &&1161!Rest.starts_with("@@@")) {1162Asm.getContext().reportError(S.Loc, "default version symbol " +1163AliasName + " must be defined");1164continue;1165}11661167if (Renames.count(&Symbol) && Renames[&Symbol] != Alias) {1168Asm.getContext().reportError(S.Loc, Twine("multiple versions for ") +1169Symbol.getName());1170continue;1171}11721173Renames.insert(std::make_pair(&Symbol, Alias));1174}11751176for (const MCSymbol *&Sym : AddrsigSyms) {1177if (const MCSymbol *R = Renames.lookup(cast<MCSymbolELF>(Sym)))1178Sym = R;1179if (Sym->isInSection() && Sym->getName().starts_with(".L"))1180Sym = Sym->getSection().getBeginSymbol();1181Sym->setUsedInReloc();1182}1183}11841185// It is always valid to create a relocation with a symbol. It is preferable1186// to use a relocation with a section if that is possible. Using the section1187// allows us to omit some local symbols from the symbol table.1188bool ELFObjectWriter::shouldRelocateWithSymbol(const MCAssembler &Asm,1189const MCValue &Val,1190const MCSymbolELF *Sym,1191uint64_t C,1192unsigned Type) const {1193const MCSymbolRefExpr *RefA = Val.getSymA();1194// A PCRel relocation to an absolute value has no symbol (or section). We1195// represent that with a relocation to a null section.1196if (!RefA)1197return false;11981199MCSymbolRefExpr::VariantKind Kind = RefA->getKind();1200switch (Kind) {1201default:1202break;1203// The .odp creation emits a relocation against the symbol ".TOC." which1204// create a R_PPC64_TOC relocation. However the relocation symbol name1205// in final object creation should be NULL, since the symbol does not1206// really exist, it is just the reference to TOC base for the current1207// object file. Since the symbol is undefined, returning false results1208// in a relocation with a null section which is the desired result.1209case MCSymbolRefExpr::VK_PPC_TOCBASE:1210return false;12111212// These VariantKind cause the relocation to refer to something other than1213// the symbol itself, like a linker generated table. Since the address of1214// symbol is not relevant, we cannot replace the symbol with the1215// section and patch the difference in the addend.1216case MCSymbolRefExpr::VK_GOT:1217case MCSymbolRefExpr::VK_PLT:1218case MCSymbolRefExpr::VK_GOTPCREL:1219case MCSymbolRefExpr::VK_GOTPCREL_NORELAX:1220case MCSymbolRefExpr::VK_PPC_GOT_LO:1221case MCSymbolRefExpr::VK_PPC_GOT_HI:1222case MCSymbolRefExpr::VK_PPC_GOT_HA:1223return true;1224}12251226// An undefined symbol is not in any section, so the relocation has to point1227// to the symbol itself.1228assert(Sym && "Expected a symbol");1229if (Sym->isUndefined())1230return true;12311232// For memory-tagged symbols, ensure that the relocation uses the symbol. For1233// tagged symbols, we emit an empty relocation (R_AARCH64_NONE) in a special1234// section (SHT_AARCH64_MEMTAG_GLOBALS_STATIC) to indicate to the linker that1235// this global needs to be tagged. In addition, the linker needs to know1236// whether to emit a special addend when relocating `end` symbols, and this1237// can only be determined by the attributes of the symbol itself.1238if (Sym->isMemtag())1239return true;12401241unsigned Binding = Sym->getBinding();1242switch(Binding) {1243default:1244llvm_unreachable("Invalid Binding");1245case ELF::STB_LOCAL:1246break;1247case ELF::STB_WEAK:1248// If the symbol is weak, it might be overridden by a symbol in another1249// file. The relocation has to point to the symbol so that the linker1250// can update it.1251return true;1252case ELF::STB_GLOBAL:1253case ELF::STB_GNU_UNIQUE:1254// Global ELF symbols can be preempted by the dynamic linker. The relocation1255// has to point to the symbol for a reason analogous to the STB_WEAK case.1256return true;1257}12581259// Keep symbol type for a local ifunc because it may result in an IRELATIVE1260// reloc that the dynamic loader will use to resolve the address at startup1261// time.1262if (Sym->getType() == ELF::STT_GNU_IFUNC)1263return true;12641265// If a relocation points to a mergeable section, we have to be careful.1266// If the offset is zero, a relocation with the section will encode the1267// same information. With a non-zero offset, the situation is different.1268// For example, a relocation can point 42 bytes past the end of a string.1269// If we change such a relocation to use the section, the linker would think1270// that it pointed to another string and subtracting 42 at runtime will1271// produce the wrong value.1272if (Sym->isInSection()) {1273auto &Sec = cast<MCSectionELF>(Sym->getSection());1274unsigned Flags = Sec.getFlags();1275if (Flags & ELF::SHF_MERGE) {1276if (C != 0)1277return true;12781279// gold<2.34 incorrectly ignored the addend for R_386_GOTOFF (9)1280// (http://sourceware.org/PR16794).1281if (TargetObjectWriter->getEMachine() == ELF::EM_386 &&1282Type == ELF::R_386_GOTOFF)1283return true;12841285// ld.lld handles R_MIPS_HI16/R_MIPS_LO16 separately, not as a whole, so1286// it doesn't know that an R_MIPS_HI16 with implicit addend 1 and an1287// R_MIPS_LO16 with implicit addend -32768 represents 32768, which is in1288// range of a MergeInputSection. We could introduce a new RelExpr member1289// (like R_RISCV_PC_INDIRECT for R_RISCV_PCREL_HI20 / R_RISCV_PCREL_LO12)1290// but the complexity is unnecessary given that GNU as keeps the original1291// symbol for this case as well.1292if (TargetObjectWriter->getEMachine() == ELF::EM_MIPS &&1293!hasRelocationAddend())1294return true;1295}12961297// Most TLS relocations use a got, so they need the symbol. Even those that1298// are just an offset (@tpoff), require a symbol in gold versions before1299// 5efeedf61e4fe720fd3e9a08e6c91c10abb66d42 (2014-09-26) which fixed1300// http://sourceware.org/PR16773.1301if (Flags & ELF::SHF_TLS)1302return true;1303}13041305// If the symbol is a thumb function the final relocation must set the lowest1306// bit. With a symbol that is done by just having the symbol have that bit1307// set, so we would lose the bit if we relocated with the section.1308// FIXME: We could use the section but add the bit to the relocation value.1309if (Asm.isThumbFunc(Sym))1310return true;13111312if (TargetObjectWriter->needsRelocateWithSymbol(Val, *Sym, Type))1313return true;1314return false;1315}13161317bool ELFObjectWriter::checkRelocation(MCContext &Ctx, SMLoc Loc,1318const MCSectionELF *From,1319const MCSectionELF *To) {1320if (DwoOS) {1321if (isDwoSection(*From)) {1322Ctx.reportError(Loc, "A dwo section may not contain relocations");1323return false;1324}1325if (To && isDwoSection(*To)) {1326Ctx.reportError(Loc, "A relocation may not refer to a dwo section");1327return false;1328}1329}1330return true;1331}13321333void ELFObjectWriter::recordRelocation(MCAssembler &Asm,1334const MCFragment *Fragment,1335const MCFixup &Fixup, MCValue Target,1336uint64_t &FixedValue) {1337MCAsmBackend &Backend = Asm.getBackend();1338bool IsPCRel = Backend.getFixupKindInfo(Fixup.getKind()).Flags &1339MCFixupKindInfo::FKF_IsPCRel;1340const MCSectionELF &FixupSection = cast<MCSectionELF>(*Fragment->getParent());1341uint64_t C = Target.getConstant();1342uint64_t FixupOffset = Asm.getFragmentOffset(*Fragment) + Fixup.getOffset();1343MCContext &Ctx = Asm.getContext();1344const MCTargetOptions *TO = Ctx.getTargetOptions();13451346if (const MCSymbolRefExpr *RefB = Target.getSymB()) {1347const auto &SymB = cast<MCSymbolELF>(RefB->getSymbol());1348if (SymB.isUndefined()) {1349Ctx.reportError(Fixup.getLoc(),1350Twine("symbol '") + SymB.getName() +1351"' can not be undefined in a subtraction expression");1352return;1353}13541355assert(!SymB.isAbsolute() && "Should have been folded");1356const MCSection &SecB = SymB.getSection();1357if (&SecB != &FixupSection) {1358Ctx.reportError(Fixup.getLoc(),1359"Cannot represent a difference across sections");1360return;1361}13621363assert(!IsPCRel && "should have been folded");1364IsPCRel = true;1365C += FixupOffset - Asm.getSymbolOffset(SymB);1366}13671368// We either rejected the fixup or folded B into C at this point.1369const MCSymbolRefExpr *RefA = Target.getSymA();1370const auto *SymA = RefA ? cast<MCSymbolELF>(&RefA->getSymbol()) : nullptr;13711372bool ViaWeakRef = false;1373if (SymA && SymA->isVariable()) {1374const MCExpr *Expr = SymA->getVariableValue();1375if (const auto *Inner = dyn_cast<MCSymbolRefExpr>(Expr)) {1376if (Inner->getKind() == MCSymbolRefExpr::VK_WEAKREF) {1377SymA = cast<MCSymbolELF>(&Inner->getSymbol());1378ViaWeakRef = true;1379}1380}1381}13821383const MCSectionELF *SecA = (SymA && SymA->isInSection())1384? cast<MCSectionELF>(&SymA->getSection())1385: nullptr;1386if (!checkRelocation(Ctx, Fixup.getLoc(), &FixupSection, SecA))1387return;13881389unsigned Type = TargetObjectWriter->getRelocType(Ctx, Target, Fixup, IsPCRel);1390const auto *Parent = cast<MCSectionELF>(Fragment->getParent());1391// Emiting relocation with sybmol for CG Profile to help with --cg-profile.1392bool RelocateWithSymbol =1393shouldRelocateWithSymbol(Asm, Target, SymA, C, Type) ||1394(Parent->getType() == ELF::SHT_LLVM_CALL_GRAPH_PROFILE);1395uint64_t Addend = 0;13961397FixedValue = !RelocateWithSymbol && SymA && !SymA->isUndefined()1398? C + Asm.getSymbolOffset(*SymA)1399: C;1400if (usesRela(TO, FixupSection)) {1401Addend = FixedValue;1402FixedValue = 0;1403}14041405if (!RelocateWithSymbol) {1406const auto *SectionSymbol =1407SecA ? cast<MCSymbolELF>(SecA->getBeginSymbol()) : nullptr;1408if (SectionSymbol)1409SectionSymbol->setUsedInReloc();1410ELFRelocationEntry Rec(FixupOffset, SectionSymbol, Type, Addend, SymA, C);1411Relocations[&FixupSection].push_back(Rec);1412return;1413}14141415const MCSymbolELF *RenamedSymA = SymA;1416if (SymA) {1417if (const MCSymbolELF *R = Renames.lookup(SymA))1418RenamedSymA = R;14191420if (ViaWeakRef)1421RenamedSymA->setIsWeakrefUsedInReloc();1422else1423RenamedSymA->setUsedInReloc();1424}1425ELFRelocationEntry Rec(FixupOffset, RenamedSymA, Type, Addend, SymA, C);1426Relocations[&FixupSection].push_back(Rec);1427}14281429bool ELFObjectWriter::usesRela(const MCTargetOptions *TO,1430const MCSectionELF &Sec) const {1431return (hasRelocationAddend() &&1432Sec.getType() != ELF::SHT_LLVM_CALL_GRAPH_PROFILE) ||1433(TO && TO->Crel);1434}14351436bool ELFObjectWriter::isSymbolRefDifferenceFullyResolvedImpl(1437const MCAssembler &Asm, const MCSymbol &SA, const MCFragment &FB,1438bool InSet, bool IsPCRel) const {1439const auto &SymA = cast<MCSymbolELF>(SA);1440if (IsPCRel) {1441assert(!InSet);1442if (SymA.getBinding() != ELF::STB_LOCAL ||1443SymA.getType() == ELF::STT_GNU_IFUNC)1444return false;1445}1446return &SymA.getSection() == FB.getParent();1447}14481449uint64_t ELFObjectWriter::writeObject(MCAssembler &Asm) {1450uint64_t Size =1451ELFWriter(*this, OS, IsLittleEndian,1452DwoOS ? ELFWriter::NonDwoOnly : ELFWriter::AllSections)1453.writeObject(Asm);1454if (DwoOS)1455Size += ELFWriter(*this, *DwoOS, IsLittleEndian, ELFWriter::DwoOnly)1456.writeObject(Asm);1457return Size;1458}145914601461