brintos

brintos / llvm-project-archived public Read only

0
0
Text · 46.2 KiB · 759d3e0 Raw
1406 lines · cpp
1//===- lib/MC/ELFObjectWriter.cpp - ELF File Writer -----------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// This file implements ELF object file writer information.10//11//===----------------------------------------------------------------------===//12 13#include "llvm/ADT/ArrayRef.h"14#include "llvm/ADT/DenseMap.h"15#include "llvm/ADT/STLExtras.h"16#include "llvm/ADT/SmallVector.h"17#include "llvm/ADT/Statistic.h"18#include "llvm/ADT/StringExtras.h"19#include "llvm/ADT/StringRef.h"20#include "llvm/ADT/Twine.h"21#include "llvm/BinaryFormat/ELF.h"22#include "llvm/MC/MCAsmBackend.h"23#include "llvm/MC/MCAsmInfo.h"24#include "llvm/MC/MCAssembler.h"25#include "llvm/MC/MCContext.h"26#include "llvm/MC/MCELFExtras.h"27#include "llvm/MC/MCELFObjectWriter.h"28#include "llvm/MC/MCExpr.h"29#include "llvm/MC/MCFixup.h"30#include "llvm/MC/MCObjectWriter.h"31#include "llvm/MC/MCSection.h"32#include "llvm/MC/MCSectionELF.h"33#include "llvm/MC/MCSymbol.h"34#include "llvm/MC/MCSymbolELF.h"35#include "llvm/MC/MCTargetOptions.h"36#include "llvm/MC/MCValue.h"37#include "llvm/MC/StringTableBuilder.h"38#include "llvm/Support/Alignment.h"39#include "llvm/Support/Casting.h"40#include "llvm/Support/Compression.h"41#include "llvm/Support/Endian.h"42#include "llvm/Support/EndianStream.h"43#include "llvm/Support/ErrorHandling.h"44#include "llvm/Support/LEB128.h"45#include "llvm/Support/SMLoc.h"46#include "llvm/Support/raw_ostream.h"47#include "llvm/TargetParser/Host.h"48#include <cassert>49#include <cstddef>50#include <cstdint>51#include <memory>52#include <string>53#include <utility>54#include <vector>55 56using namespace llvm;57 58#define DEBUG_TYPE "elf-object-writer"59 60namespace {61namespace stats {62 63STATISTIC(ELFHeaderBytes, "Total size of ELF headers");64STATISTIC(SectionHeaderBytes, "Total size of section headers table");65STATISTIC(AllocTextBytes, "Total size of SHF_ALLOC text sections");66STATISTIC(AllocROBytes, "Total size of SHF_ALLOC readonly sections");67STATISTIC(AllocRWBytes, "Total size of SHF_ALLOC read-write sections");68STATISTIC(StrtabBytes, "Total size of SHT_STRTAB sections");69STATISTIC(SymtabBytes, "Total size of SHT_SYMTAB sections");70STATISTIC(RelocationBytes, "Total size of relocation sections");71STATISTIC(DynsymBytes, "Total size of SHT_DYNSYM sections");72STATISTIC(73    DebugBytes,74    "Total size of debug info sections (not including those written to .dwo)");75STATISTIC(UnwindBytes, "Total size of unwind sections");76STATISTIC(OtherBytes, "Total size of uncategorized sections");77STATISTIC(DwoBytes, "Total size of sections written to .dwo file");78 79} // namespace stats80 81struct ELFWriter;82 83bool isDwoSection(const MCSectionELF &Sec) {84  return Sec.getName().ends_with(".dwo");85}86 87class SymbolTableWriter {88  ELFWriter &EWriter;89  bool Is64Bit;90 91  // indexes we are going to write to .symtab_shndx.92  std::vector<uint32_t> ShndxIndexes;93 94  // The numbel of symbols written so far.95  unsigned NumWritten;96 97  void createSymtabShndx();98 99  template <typename T> void write(T Value);100 101public:102  SymbolTableWriter(ELFWriter &EWriter, bool Is64Bit);103 104  void writeSymbol(uint32_t name, uint8_t info, uint64_t value, uint64_t size,105                   uint8_t other, uint32_t shndx, bool Reserved);106 107  ArrayRef<uint32_t> getShndxIndexes() const { return ShndxIndexes; }108};109 110struct ELFWriter {111  MCAssembler &Asm;112  ELFObjectWriter &OWriter;113  support::endian::Writer W;114 115  enum DwoMode {116    AllSections,117    NonDwoOnly,118    DwoOnly,119  } Mode;120 121  uint64_t symbolValue(const MCSymbol &Sym);122  bool isInSymtab(const MCSymbolELF &Symbol);123 124  /// Helper struct for containing some precomputed information on symbols.125  struct ELFSymbolData {126    const MCSymbolELF *Symbol;127    StringRef Name;128    uint32_t SectionIndex;129    uint32_t Order;130  };131 132  /// @}133  /// @name Symbol Table Data134  /// @{135 136  StringTableBuilder StrTabBuilder{StringTableBuilder::ELF};137 138  /// @}139 140  // This holds the symbol table index of the last local symbol.141  unsigned LastLocalSymbolIndex = ~0u;142  // This holds the .strtab section index.143  unsigned StringTableIndex = ~0u;144  // This holds the .symtab section index.145  unsigned SymbolTableIndex = ~0u;146 147  // Sections in the order they are to be output in the section table.148  std::vector<MCSectionELF *> SectionTable;149  unsigned addToSectionTable(MCSectionELF *Sec);150 151  // TargetObjectWriter wrappers.152  bool is64Bit() const;153 154  uint64_t align(Align Alignment);155 156  bool maybeWriteCompression(uint32_t ChType, uint64_t Size,157                             SmallVectorImpl<uint8_t> &CompressedContents,158                             Align Alignment);159 160public:161  ELFWriter(MCAssembler &Asm, ELFObjectWriter &OWriter, raw_pwrite_stream &OS,162            bool IsLittleEndian, DwoMode Mode)163      : Asm(Asm), OWriter(OWriter),164        W(OS,165          IsLittleEndian ? llvm::endianness::little : llvm::endianness::big),166        Mode(Mode) {}167 168  MCContext &getContext() const { return Asm.getContext(); }169 170  void writeWord(uint64_t Word) {171    if (is64Bit())172      W.write<uint64_t>(Word);173    else174      W.write<uint32_t>(Word);175  }176 177  template <typename T> void write(T Val) {178    W.write(Val);179  }180 181  void writeHeader();182 183  void writeSymbol(SymbolTableWriter &Writer, uint32_t StringIndex,184                   ELFSymbolData &MSD);185 186  // Map from a signature symbol to the group section index187  using RevGroupMapTy = DenseMap<const MCSymbol *, unsigned>;188 189  /// Compute the symbol table data190  ///191  /// \param Asm - The assembler.192  /// \param RevGroupMap - Maps a signature symbol to the group section.193  void computeSymbolTable(const RevGroupMapTy &RevGroupMap);194 195  void writeAddrsigSection();196 197  MCSectionELF *createRelocationSection(MCContext &Ctx,198                                        const MCSectionELF &Sec);199 200  void writeSectionHeaders();201 202  void writeSectionData(MCSection &Sec);203 204  void writeSectionHeaderEntry(uint32_t Name, uint32_t Type, uint64_t Flags,205                               uint64_t Address, uint64_t Offset, uint64_t Size,206                               uint32_t Link, uint32_t Info,207                               MaybeAlign Alignment, uint64_t EntrySize);208 209  void writeRelocations(const MCSectionELF &Sec);210 211  uint64_t writeObject();212  void writeSectionHeader(uint32_t GroupSymbolIndex, uint64_t Offset,213                          uint64_t Size, const MCSectionELF &Section);214};215} // end anonymous namespace216 217uint64_t ELFWriter::align(Align Alignment) {218  uint64_t Offset = W.OS.tell();219  uint64_t NewOffset = alignTo(Offset, Alignment);220  W.OS.write_zeros(NewOffset - Offset);221  return NewOffset;222}223 224unsigned ELFWriter::addToSectionTable(MCSectionELF *Sec) {225  SectionTable.push_back(Sec);226  StrTabBuilder.add(Sec->getName());227  return SectionTable.size();228}229 230void SymbolTableWriter::createSymtabShndx() {231  if (!ShndxIndexes.empty())232    return;233 234  ShndxIndexes.resize(NumWritten);235}236 237template <typename T> void SymbolTableWriter::write(T Value) {238  EWriter.write(Value);239}240 241SymbolTableWriter::SymbolTableWriter(ELFWriter &EWriter, bool Is64Bit)242    : EWriter(EWriter), Is64Bit(Is64Bit), NumWritten(0) {}243 244void SymbolTableWriter::writeSymbol(uint32_t name, uint8_t info, uint64_t value,245                                    uint64_t size, uint8_t other,246                                    uint32_t shndx, bool Reserved) {247  bool LargeIndex = shndx >= ELF::SHN_LORESERVE && !Reserved;248 249  if (LargeIndex)250    createSymtabShndx();251 252  if (!ShndxIndexes.empty()) {253    if (LargeIndex)254      ShndxIndexes.push_back(shndx);255    else256      ShndxIndexes.push_back(0);257  }258 259  uint16_t Index = LargeIndex ? uint16_t(ELF::SHN_XINDEX) : shndx;260 261  if (Is64Bit) {262    write(name);  // st_name263    write(info);  // st_info264    write(other); // st_other265    write(Index); // st_shndx266    write(value); // st_value267    write(size);  // st_size268  } else {269    write(name);            // st_name270    write(uint32_t(value)); // st_value271    write(uint32_t(size));  // st_size272    write(info);            // st_info273    write(other);           // st_other274    write(Index);           // st_shndx275  }276 277  ++NumWritten;278}279 280bool ELFWriter::is64Bit() const {281  return OWriter.TargetObjectWriter->is64Bit();282}283 284// Emit the ELF header.285void ELFWriter::writeHeader() {286  // ELF Header287  // ----------288  //289  // Note290  // ----291  // emitWord method behaves differently for ELF32 and ELF64, writing292  // 4 bytes in the former and 8 in the latter.293 294  W.OS << ELF::ElfMagic; // e_ident[EI_MAG0] to e_ident[EI_MAG3]295 296  W.OS << char(is64Bit() ? ELF::ELFCLASS64 : ELF::ELFCLASS32); // e_ident[EI_CLASS]297 298  // e_ident[EI_DATA]299  W.OS << char(W.Endian == llvm::endianness::little ? ELF::ELFDATA2LSB300                                                    : ELF::ELFDATA2MSB);301 302  W.OS << char(ELF::EV_CURRENT);        // e_ident[EI_VERSION]303  // e_ident[EI_OSABI]304  uint8_t OSABI = OWriter.TargetObjectWriter->getOSABI();305  W.OS << char(OSABI == ELF::ELFOSABI_NONE && OWriter.seenGnuAbi()306                   ? int(ELF::ELFOSABI_GNU)307                   : OSABI);308  // e_ident[EI_ABIVERSION]309  W.OS << char(OWriter.OverrideABIVersion310                   ? *OWriter.OverrideABIVersion311                   : OWriter.TargetObjectWriter->getABIVersion());312 313  W.OS.write_zeros(ELF::EI_NIDENT - ELF::EI_PAD);314 315  W.write<uint16_t>(ELF::ET_REL);             // e_type316 317  W.write<uint16_t>(OWriter.TargetObjectWriter->getEMachine()); // e_machine = target318 319  W.write<uint32_t>(ELF::EV_CURRENT);         // e_version320  writeWord(0); // e_entry, no entry point in .o file321  writeWord(0); // e_phoff, no program header for .o322  writeWord(0); // e_shoff = sec hdr table off in bytes323 324  // e_flags = whatever the target wants325  W.write<uint32_t>(OWriter.getELFHeaderEFlags());326 327  // e_ehsize = ELF header size328  W.write<uint16_t>(is64Bit() ? sizeof(ELF::Elf64_Ehdr)329                              : sizeof(ELF::Elf32_Ehdr));330 331  W.write<uint16_t>(0);                  // e_phentsize = prog header entry size332  W.write<uint16_t>(0);                  // e_phnum = # prog header entries = 0333 334  // e_shentsize = Section header entry size335  W.write<uint16_t>(is64Bit() ? sizeof(ELF::Elf64_Shdr)336                              : sizeof(ELF::Elf32_Shdr));337 338  // e_shnum     = # of section header ents339  W.write<uint16_t>(0);340 341  // e_shstrndx  = Section # of '.strtab'342  assert(StringTableIndex < ELF::SHN_LORESERVE);343  W.write<uint16_t>(StringTableIndex);344}345 346uint64_t ELFWriter::symbolValue(const MCSymbol &Sym) {347  if (Sym.isCommon())348    return Sym.getCommonAlignment()->value();349 350  uint64_t Res;351  if (!Asm.getSymbolOffset(Sym, Res))352    return 0;353 354  if (Asm.isThumbFunc(&Sym))355    Res |= 1;356 357  return Res;358}359 360static uint8_t mergeTypeForSet(uint8_t origType, uint8_t newType) {361  uint8_t Type = newType;362 363  // Propagation rules:364  // IFUNC > FUNC > OBJECT > NOTYPE365  // TLS_OBJECT > OBJECT > NOTYPE366  //367  // dont let the new type degrade the old type368  switch (origType) {369  default:370    break;371  case ELF::STT_GNU_IFUNC:372    if (Type == ELF::STT_FUNC || Type == ELF::STT_OBJECT ||373        Type == ELF::STT_NOTYPE || Type == ELF::STT_TLS)374      Type = ELF::STT_GNU_IFUNC;375    break;376  case ELF::STT_FUNC:377    if (Type == ELF::STT_OBJECT || Type == ELF::STT_NOTYPE ||378        Type == ELF::STT_TLS)379      Type = ELF::STT_FUNC;380    break;381  case ELF::STT_OBJECT:382    if (Type == ELF::STT_NOTYPE)383      Type = ELF::STT_OBJECT;384    break;385  case ELF::STT_TLS:386    if (Type == ELF::STT_OBJECT || Type == ELF::STT_NOTYPE ||387        Type == ELF::STT_GNU_IFUNC || Type == ELF::STT_FUNC)388      Type = ELF::STT_TLS;389    break;390  }391 392  return Type;393}394 395static bool isIFunc(const MCSymbolELF *Symbol) {396  while (Symbol->getType() != ELF::STT_GNU_IFUNC) {397    const MCSymbolRefExpr *Value;398    if (!Symbol->isVariable() ||399        !(Value = dyn_cast<MCSymbolRefExpr>(Symbol->getVariableValue())) ||400        Value->getSpecifier() ||401        mergeTypeForSet(Symbol->getType(), ELF::STT_GNU_IFUNC) !=402            ELF::STT_GNU_IFUNC)403      return false;404    Symbol = &static_cast<const MCSymbolELF &>(Value->getSymbol());405  }406  return true;407}408 409void ELFWriter::writeSymbol(SymbolTableWriter &Writer, uint32_t StringIndex,410                            ELFSymbolData &MSD) {411  auto &Symbol = static_cast<const MCSymbolELF &>(*MSD.Symbol);412  auto *Base = static_cast<const MCSymbolELF *>(Asm.getBaseSymbol(Symbol));413 414  // This has to be in sync with when computeSymbolTable uses SHN_ABS or415  // SHN_COMMON.416  bool IsReserved = !Base || Symbol.isCommon();417 418  // Binding and Type share the same byte as upper and lower nibbles419  uint8_t Binding = Symbol.getBinding();420  uint8_t Type = Symbol.getType();421  if (isIFunc(&Symbol))422    Type = ELF::STT_GNU_IFUNC;423  if (Base) {424    Type = mergeTypeForSet(Type, Base->getType());425  }426  uint8_t Info = (Binding << 4) | Type;427 428  // Other and Visibility share the same byte with Visibility using the lower429  // 2 bits430  uint8_t Visibility = Symbol.getVisibility();431  uint8_t Other = Symbol.getOther() | Visibility;432 433  uint64_t Value = symbolValue(*MSD.Symbol);434  uint64_t Size = 0;435 436  const MCExpr *ESize = MSD.Symbol->getSize();437  if (!ESize && Base) {438    // For expressions like .set y, x+1, if y's size is unset, inherit from x.439    ESize = Base->getSize();440 441    // For `.size x, 2; y = x; .size y, 1; z = y; z1 = z; .symver y, y@v1`, z,442    // z1, and y@v1's st_size equals y's. However, `Base` is `x` which will give443    // us 2. Follow the MCSymbolRefExpr assignment chain, which covers most444    // needs. MCBinaryExpr is not handled.445    const MCSymbolELF *Sym = &Symbol;446    while (Sym->isVariable()) {447      if (auto *Expr = dyn_cast<MCSymbolRefExpr>(Sym->getVariableValue())) {448        Sym = static_cast<const MCSymbolELF *>(&Expr->getSymbol());449        if (!Sym->getSize())450          continue;451        ESize = Sym->getSize();452      }453      break;454    }455  }456 457  if (ESize) {458    int64_t Res;459    if (!ESize->evaluateKnownAbsolute(Res, Asm))460      report_fatal_error("Size expression must be absolute.");461    Size = Res;462  }463 464  // Write out the symbol table entry465  Writer.writeSymbol(StringIndex, Info, Value, Size, Other, MSD.SectionIndex,466                     IsReserved);467}468 469bool ELFWriter::isInSymtab(const MCSymbolELF &Symbol) {470  if (Symbol.isUsedInReloc() || Symbol.isSignature())471    return true;472 473  if (OWriter.Renames.count(&Symbol))474    return false;475 476  if (Symbol.isVariable()) {477    const MCExpr *Expr = Symbol.getVariableValue();478    // Target Expressions that are always inlined do not appear in the symtab479    if (const auto *T = dyn_cast<MCTargetExpr>(Expr))480      if (T->inlineAssignedExpr())481        return false;482    // The .weakref alias does not appear in the symtab.483    if (Symbol.isWeakref())484      return false;485 486    if (Symbol.isUndefined()) {487      // FIXME: this is here just to diagnose the case of a var = commmon_sym.488      Asm.getBaseSymbol(Symbol);489      return false;490    }491  }492 493  if (Symbol.isTemporary())494    return false;495 496  return Symbol.getType() != ELF::STT_SECTION;497}498 499void ELFWriter::computeSymbolTable(const RevGroupMapTy &RevGroupMap) {500  MCContext &Ctx = Asm.getContext();501  SymbolTableWriter Writer(*this, is64Bit());502 503  // Symbol table504  unsigned EntrySize = is64Bit() ? ELF::SYMENTRY_SIZE64 : ELF::SYMENTRY_SIZE32;505  MCSectionELF *SymtabSection =506      Ctx.getELFSection(".symtab", ELF::SHT_SYMTAB, 0, EntrySize);507  SymtabSection->setAlignment(is64Bit() ? Align(8) : Align(4));508  SymbolTableIndex = addToSectionTable(SymtabSection);509 510  uint64_t SecStart = align(SymtabSection->getAlign());511 512  // The first entry is the undefined symbol entry.513  Writer.writeSymbol(0, 0, 0, 0, 0, 0, false);514 515  std::vector<ELFSymbolData> LocalSymbolData;516  std::vector<ELFSymbolData> ExternalSymbolData;517  MutableArrayRef<std::pair<std::string, size_t>> FileNames =518      OWriter.getFileNames();519  for (const std::pair<std::string, size_t> &F : FileNames)520    StrTabBuilder.add(F.first);521 522  // Add the data for the symbols.523  bool HasLargeSectionIndex = false;524  for (auto It : llvm::enumerate(Asm.symbols())) {525    auto &Symbol = static_cast<const MCSymbolELF &>(It.value());526    if (!isInSymtab(Symbol))527      continue;528 529    if (Symbol.isTemporary() && Symbol.isUndefined()) {530      Ctx.reportError(SMLoc(), "Undefined temporary symbol " + Symbol.getName());531      continue;532    }533 534    ELFSymbolData MSD;535    MSD.Symbol = static_cast<const MCSymbolELF *>(&Symbol);536    MSD.Order = It.index();537 538    bool Local = Symbol.getBinding() == ELF::STB_LOCAL;539    assert(Local || !Symbol.isTemporary());540 541    if (Symbol.isAbsolute()) {542      MSD.SectionIndex = ELF::SHN_ABS;543    } else if (Symbol.isCommon()) {544      auto Shndx = Symbol.getIndex();545      if (!Shndx) {546        assert(!Local);547        Shndx = ELF::SHN_COMMON;548      }549      MSD.SectionIndex = Shndx;550    } else if (Symbol.isUndefined()) {551      if (Symbol.isSignature() && !Symbol.isUsedInReloc()) {552        MSD.SectionIndex = RevGroupMap.lookup(&Symbol);553        if (MSD.SectionIndex >= ELF::SHN_LORESERVE)554          HasLargeSectionIndex = true;555      } else {556        MSD.SectionIndex = ELF::SHN_UNDEF;557      }558    } else {559      const MCSectionELF &Section =560          static_cast<const MCSectionELF &>(Symbol.getSection());561      assert(Section.isRegistered());562      if (Mode == NonDwoOnly && isDwoSection(Section))563        continue;564      MSD.SectionIndex = Section.getOrdinal();565      assert(MSD.SectionIndex && "Invalid section index!");566      if (MSD.SectionIndex >= ELF::SHN_LORESERVE)567        HasLargeSectionIndex = true;568    }569 570    // Temporary symbols generated for certain assembler features (.eh_frame,571    // .debug_line) of an empty name may be referenced by relocations due to572    // linker relaxation. Rename them to ".L0 " to match the gas fake label name573    // and allow ld/objcopy --discard-locals to discard such symbols.574    StringRef Name = Symbol.getName();575    if (Name.empty())576      Name = ".L0 ";577 578    // Sections have their own string table579    if (Symbol.getType() != ELF::STT_SECTION) {580      MSD.Name = Name;581      StrTabBuilder.add(Name);582    }583 584    if (Local)585      LocalSymbolData.push_back(MSD);586    else587      ExternalSymbolData.push_back(MSD);588  }589 590  // This holds the .symtab_shndx section index.591  unsigned SymtabShndxSectionIndex = 0;592 593  if (HasLargeSectionIndex) {594    MCSectionELF *SymtabShndxSection =595        Ctx.getELFSection(".symtab_shndx", ELF::SHT_SYMTAB_SHNDX, 0, 4);596    SymtabShndxSectionIndex = addToSectionTable(SymtabShndxSection);597    SymtabShndxSection->setAlignment(Align(4));598  }599 600  StrTabBuilder.finalize();601 602  // Make the first STT_FILE precede previous local symbols.603  unsigned Index = 1;604  auto FileNameIt = FileNames.begin();605  if (!FileNames.empty())606    FileNames[0].second = 0;607 608  for (ELFSymbolData &MSD : LocalSymbolData) {609    // Emit STT_FILE symbols before their associated local symbols.610    for (; FileNameIt != FileNames.end() && FileNameIt->second <= MSD.Order;611         ++FileNameIt) {612      Writer.writeSymbol(StrTabBuilder.getOffset(FileNameIt->first),613                         ELF::STT_FILE | ELF::STB_LOCAL, 0, 0, ELF::STV_DEFAULT,614                         ELF::SHN_ABS, true);615      ++Index;616    }617 618    unsigned StringIndex = MSD.Symbol->getType() == ELF::STT_SECTION619                               ? 0620                               : StrTabBuilder.getOffset(MSD.Name);621    MSD.Symbol->setIndex(Index++);622    writeSymbol(Writer, StringIndex, MSD);623  }624  for (; FileNameIt != FileNames.end(); ++FileNameIt) {625    Writer.writeSymbol(StrTabBuilder.getOffset(FileNameIt->first),626                       ELF::STT_FILE | ELF::STB_LOCAL, 0, 0, ELF::STV_DEFAULT,627                       ELF::SHN_ABS, true);628    ++Index;629  }630 631  // Write the symbol table entries.632  LastLocalSymbolIndex = Index;633 634  for (ELFSymbolData &MSD : ExternalSymbolData) {635    unsigned StringIndex = StrTabBuilder.getOffset(MSD.Name);636    MSD.Symbol->setIndex(Index++);637    writeSymbol(Writer, StringIndex, MSD);638    assert(MSD.Symbol->getBinding() != ELF::STB_LOCAL);639  }640 641  uint64_t SecEnd = W.OS.tell();642  SymtabSection->setOffsets(SecStart, SecEnd);643 644  ArrayRef<uint32_t> ShndxIndexes = Writer.getShndxIndexes();645  if (ShndxIndexes.empty()) {646    assert(SymtabShndxSectionIndex == 0);647    return;648  }649  assert(SymtabShndxSectionIndex != 0);650 651  SecStart = W.OS.tell();652  MCSectionELF *SymtabShndxSection = SectionTable[SymtabShndxSectionIndex - 1];653  for (uint32_t Index : ShndxIndexes)654    write(Index);655  SecEnd = W.OS.tell();656  SymtabShndxSection->setOffsets(SecStart, SecEnd);657}658 659void ELFWriter::writeAddrsigSection() {660  for (const MCSymbol *Sym : OWriter.getAddrsigSyms())661    if (Sym->getIndex() != 0)662      encodeULEB128(Sym->getIndex(), W.OS);663}664 665MCSectionELF *ELFWriter::createRelocationSection(MCContext &Ctx,666                                                 const MCSectionELF &Sec) {667  if (OWriter.Relocations[&Sec].empty())668    return nullptr;669 670  unsigned Flags = ELF::SHF_INFO_LINK;671  if (Sec.getFlags() & ELF::SHF_GROUP)672    Flags = ELF::SHF_GROUP;673 674  const StringRef SectionName = Sec.getName();675  const MCTargetOptions *TO = Ctx.getTargetOptions();676  if (TO && TO->Crel) {677    MCSectionELF *RelaSection =678        Ctx.createELFRelSection(".crel" + SectionName, ELF::SHT_CREL, Flags,679                                /*EntrySize=*/1, Sec.getGroup(), &Sec);680    return RelaSection;681  }682 683  const bool Rela = OWriter.usesRela(TO, Sec);684  unsigned EntrySize;685  if (Rela)686    EntrySize = is64Bit() ? sizeof(ELF::Elf64_Rela) : sizeof(ELF::Elf32_Rela);687  else688    EntrySize = is64Bit() ? sizeof(ELF::Elf64_Rel) : sizeof(ELF::Elf32_Rel);689 690  MCSectionELF *RelaSection =691      Ctx.createELFRelSection(((Rela ? ".rela" : ".rel") + SectionName),692                              Rela ? ELF::SHT_RELA : ELF::SHT_REL, Flags,693                              EntrySize, Sec.getGroup(), &Sec);694  RelaSection->setAlignment(is64Bit() ? Align(8) : Align(4));695  return RelaSection;696}697 698// Include the debug info compression header.699bool ELFWriter::maybeWriteCompression(700    uint32_t ChType, uint64_t Size,701    SmallVectorImpl<uint8_t> &CompressedContents, Align Alignment) {702  uint64_t HdrSize =703      is64Bit() ? sizeof(ELF::Elf64_Chdr) : sizeof(ELF::Elf32_Chdr);704  if (Size <= HdrSize + CompressedContents.size())705    return false;706  // Platform specific header is followed by compressed data.707  if (is64Bit()) {708    // Write Elf64_Chdr header.709    write(static_cast<ELF::Elf64_Word>(ChType));710    write(static_cast<ELF::Elf64_Word>(0)); // ch_reserved field.711    write(static_cast<ELF::Elf64_Xword>(Size));712    write(static_cast<ELF::Elf64_Xword>(Alignment.value()));713  } else {714    // Write Elf32_Chdr header otherwise.715    write(static_cast<ELF::Elf32_Word>(ChType));716    write(static_cast<ELF::Elf32_Word>(Size));717    write(static_cast<ELF::Elf32_Word>(Alignment.value()));718  }719  return true;720}721 722void ELFWriter::writeSectionData(MCSection &Sec) {723  MCSectionELF &Section = static_cast<MCSectionELF &>(Sec);724  StringRef SectionName = Section.getName();725  auto &Ctx = Asm.getContext();726  const DebugCompressionType CompressionType =727      Ctx.getTargetOptions() ? Ctx.getTargetOptions()->CompressDebugSections728                             : DebugCompressionType::None;729  if (CompressionType == DebugCompressionType::None ||730      !SectionName.starts_with(".debug_")) {731    Asm.writeSectionData(W.OS, &Section);732    return;733  }734 735  SmallVector<char, 128> UncompressedData;736  raw_svector_ostream VecOS(UncompressedData);737  Asm.writeSectionData(VecOS, &Section);738  ArrayRef<uint8_t> Uncompressed =739      ArrayRef(reinterpret_cast<uint8_t *>(UncompressedData.data()),740               UncompressedData.size());741 742  SmallVector<uint8_t, 128> Compressed;743  uint32_t ChType;744  switch (CompressionType) {745  case DebugCompressionType::None:746    llvm_unreachable("has been handled");747  case DebugCompressionType::Zlib:748    ChType = ELF::ELFCOMPRESS_ZLIB;749    break;750  case DebugCompressionType::Zstd:751    ChType = ELF::ELFCOMPRESS_ZSTD;752    break;753  }754  compression::compress(compression::Params(CompressionType), Uncompressed,755                        Compressed);756  if (!maybeWriteCompression(ChType, UncompressedData.size(), Compressed,757                             Sec.getAlign())) {758    W.OS << UncompressedData;759    return;760  }761 762  Section.setFlags(Section.getFlags() | ELF::SHF_COMPRESSED);763  // Alignment field should reflect the requirements of764  // the compressed section header.765  Section.setAlignment(is64Bit() ? Align(8) : Align(4));766  W.OS << toStringRef(Compressed);767}768 769void ELFWriter::writeSectionHeaderEntry(uint32_t Name, uint32_t Type,770                                        uint64_t Flags, uint64_t Address,771                                        uint64_t Offset, uint64_t Size,772                                        uint32_t Link, uint32_t Info,773                                        MaybeAlign Alignment,774                                        uint64_t EntrySize) {775  W.write<uint32_t>(Name);        // sh_name: index into string table776  W.write<uint32_t>(Type);        // sh_type777  writeWord(Flags);               // sh_flags778  writeWord(Address);             // sh_addr779  writeWord(Offset);              // sh_offset780  writeWord(Size);                // sh_size781  W.write<uint32_t>(Link);        // sh_link782  W.write<uint32_t>(Info);        // sh_info783  writeWord(Alignment ? Alignment->value() : 0); // sh_addralign784  writeWord(EntrySize);                          // sh_entsize785}786 787template <bool Is64>788static void encodeCrel(ArrayRef<ELFRelocationEntry> Relocs, raw_ostream &OS) {789  using uint = std::conditional_t<Is64, uint64_t, uint32_t>;790  ELF::encodeCrel<Is64>(OS, Relocs, [&](const ELFRelocationEntry &R) {791    uint32_t SymIdx = R.Symbol ? R.Symbol->getIndex() : 0;792    return ELF::Elf_Crel<Is64>{static_cast<uint>(R.Offset), SymIdx, R.Type,793                               std::make_signed_t<uint>(R.Addend)};794  });795}796 797void ELFWriter::writeRelocations(const MCSectionELF &Sec) {798  std::vector<ELFRelocationEntry> &Relocs = OWriter.Relocations[&Sec];799  const MCTargetOptions *TO = getContext().getTargetOptions();800  const bool Rela = OWriter.usesRela(TO, Sec);801 802  // Sort the relocation entries. MIPS needs this.803  OWriter.TargetObjectWriter->sortRelocs(Relocs);804 805  if (OWriter.TargetObjectWriter->getEMachine() == ELF::EM_MIPS) {806    for (const ELFRelocationEntry &Entry : Relocs) {807      uint32_t SymIdx = Entry.Symbol ? Entry.Symbol->getIndex() : 0;808      if (is64Bit()) {809        write(Entry.Offset);810        write(uint32_t(SymIdx));811        write(OWriter.TargetObjectWriter->getRSsym(Entry.Type));812        write(OWriter.TargetObjectWriter->getRType3(Entry.Type));813        write(OWriter.TargetObjectWriter->getRType2(Entry.Type));814        write(OWriter.TargetObjectWriter->getRType(Entry.Type));815        if (Rela)816          write(Entry.Addend);817      } else {818        write(uint32_t(Entry.Offset));819        ELF::Elf32_Rela ERE32;820        ERE32.setSymbolAndType(SymIdx, Entry.Type);821        write(ERE32.r_info);822        if (Rela)823          write(uint32_t(Entry.Addend));824        if (uint32_t RType =825                OWriter.TargetObjectWriter->getRType2(Entry.Type)) {826          write(uint32_t(Entry.Offset));827          ERE32.setSymbolAndType(0, RType);828          write(ERE32.r_info);829          write(uint32_t(0));830        }831        if (uint32_t RType =832                OWriter.TargetObjectWriter->getRType3(Entry.Type)) {833          write(uint32_t(Entry.Offset));834          ERE32.setSymbolAndType(0, RType);835          write(ERE32.r_info);836          write(uint32_t(0));837        }838      }839    }840  } else if (TO && TO->Crel) {841    if (is64Bit())842      encodeCrel<true>(Relocs, W.OS);843    else844      encodeCrel<false>(Relocs, W.OS);845  } else {846    for (const ELFRelocationEntry &Entry : Relocs) {847      uint32_t Symidx = Entry.Symbol ? Entry.Symbol->getIndex() : 0;848      if (is64Bit()) {849        write(Entry.Offset);850        ELF::Elf64_Rela ERE;851        ERE.setSymbolAndType(Symidx, Entry.Type);852        write(ERE.r_info);853        if (Rela)854          write(Entry.Addend);855      } else {856        write(uint32_t(Entry.Offset));857        ELF::Elf32_Rela ERE;858        ERE.setSymbolAndType(Symidx, Entry.Type);859        write(ERE.r_info);860        if (Rela)861          write(uint32_t(Entry.Addend));862      }863    }864  }865}866 867void ELFWriter::writeSectionHeader(uint32_t GroupSymbolIndex, uint64_t Offset,868                                   uint64_t Size, const MCSectionELF &Section) {869  uint64_t sh_link = 0;870  uint64_t sh_info = 0;871 872  switch(Section.getType()) {873  default:874    // Nothing to do.875    break;876 877  case ELF::SHT_DYNAMIC:878    llvm_unreachable("SHT_DYNAMIC in a relocatable object");879 880  case ELF::SHT_REL:881  case ELF::SHT_RELA:882  case ELF::SHT_CREL: {883    sh_link = SymbolTableIndex;884    assert(sh_link && ".symtab not found");885    const MCSection *InfoSection = Section.getLinkedToSection();886    sh_info = InfoSection->getOrdinal();887    break;888  }889 890  case ELF::SHT_SYMTAB:891    sh_link = StringTableIndex;892    sh_info = LastLocalSymbolIndex;893    break;894 895  case ELF::SHT_SYMTAB_SHNDX:896  case ELF::SHT_LLVM_CALL_GRAPH_PROFILE:897  case ELF::SHT_LLVM_ADDRSIG:898    sh_link = SymbolTableIndex;899    break;900 901  case ELF::SHT_GROUP:902    sh_link = SymbolTableIndex;903    sh_info = GroupSymbolIndex;904    break;905  }906 907  if (Section.getFlags() & ELF::SHF_LINK_ORDER) {908    // If the value in the associated metadata is not a definition, Sym will be909    // undefined. Represent this with sh_link=0.910    const MCSymbol *Sym = Section.getLinkedToSymbol();911    if (Sym && Sym->isInSection())912      sh_link = Sym->getSection().getOrdinal();913  }914 915  writeSectionHeaderEntry(StrTabBuilder.getOffset(Section.getName()),916                          Section.getType(), Section.getFlags(), 0, Offset,917                          Size, sh_link, sh_info, Section.getAlign(),918                          Section.getEntrySize());919}920 921void ELFWriter::writeSectionHeaders() {922  uint64_t Start = W.OS.tell();923  const unsigned NumSections = SectionTable.size();924 925  // Null section first.926  uint64_t FirstSectionSize =927      (NumSections + 1) >= ELF::SHN_LORESERVE ? NumSections + 1 : 0;928  writeSectionHeaderEntry(0, 0, 0, 0, 0, FirstSectionSize, 0, 0, std::nullopt,929                          0);930 931  for (const MCSectionELF *Section : SectionTable) {932    uint32_t GroupSymbolIndex;933    unsigned Type = Section->getType();934    if (Type != ELF::SHT_GROUP)935      GroupSymbolIndex = 0;936    else937      GroupSymbolIndex = Section->getGroup()->getIndex();938 939    std::pair<uint64_t, uint64_t> Offsets = Section->getOffsets();940    uint64_t Size;941    if (Type == ELF::SHT_NOBITS)942      Size = Asm.getSectionAddressSize(*Section);943    else944      Size = Offsets.second - Offsets.first;945 946    auto SectionHasFlag = [&](uint64_t Flag) -> bool {947      return Section->getFlags() & Flag;948    };949 950    if (Mode == DwoOnly) {951      stats::DwoBytes += Size;952    } else if (Section->getName().starts_with(".debug")) {953      stats::DebugBytes += Size;954    } else if (Section->getName().starts_with(".eh_frame")) {955      stats::UnwindBytes += Size;956    } else if (SectionHasFlag(ELF::SHF_ALLOC)) {957      if (SectionHasFlag(ELF::SHF_EXECINSTR)) {958        stats::AllocTextBytes += Size;959      } else if (SectionHasFlag(ELF::SHF_WRITE)) {960        stats::AllocRWBytes += Size;961      } else {962        stats::AllocROBytes += Size;963      }964    } else {965      switch (Section->getType()) {966      case ELF::SHT_STRTAB:967        stats::StrtabBytes += Size;968        break;969      case ELF::SHT_SYMTAB:970        stats::SymtabBytes += Size;971        break;972      case ELF::SHT_DYNSYM:973        stats::DynsymBytes += Size;974        break;975      case ELF::SHT_REL:976      case ELF::SHT_RELA:977      case ELF::SHT_CREL:978        stats::RelocationBytes += Size;979        break;980      default:981        stats::OtherBytes += Size;982        break;983      }984    }985 986    writeSectionHeader(GroupSymbolIndex, Offsets.first, Size, *Section);987  }988 989  stats::SectionHeaderBytes += W.OS.tell() - Start;990}991 992uint64_t ELFWriter::writeObject() {993  uint64_t StartOffset = W.OS.tell();994 995  MCContext &Ctx = getContext();996  MCSectionELF *StrtabSection =997      Ctx.getELFSection(".strtab", ELF::SHT_STRTAB, 0);998  StringTableIndex = addToSectionTable(StrtabSection);999 1000  RevGroupMapTy RevGroupMap;1001 1002  // Write out the ELF header ...1003  writeHeader();1004 1005  stats::ELFHeaderBytes += W.OS.tell() - StartOffset;1006 1007  // ... then the sections ...1008  SmallVector<std::pair<MCSectionELF *, SmallVector<unsigned>>, 0> Groups;1009  // Map from group section index to group1010  SmallVector<unsigned, 0> GroupMap;1011  SmallVector<MCSectionELF *> Relocations;1012  for (MCSection &Sec : Asm) {1013    MCSectionELF &Section = static_cast<MCSectionELF &>(Sec);1014    if (Mode == NonDwoOnly && isDwoSection(Section))1015      continue;1016    if (Mode == DwoOnly && !isDwoSection(Section))1017      continue;1018 1019    // Remember the offset into the file for this section.1020    const uint64_t SecStart = align(Section.getAlign());1021 1022    const MCSymbolELF *SignatureSymbol = Section.getGroup();1023    writeSectionData(Section);1024 1025    uint64_t SecEnd = W.OS.tell();1026    Section.setOffsets(SecStart, SecEnd);1027 1028    MCSectionELF *RelSection = createRelocationSection(Ctx, Section);1029 1030    unsigned *GroupIdxEntry = nullptr;1031    if (SignatureSymbol) {1032      GroupIdxEntry = &RevGroupMap[SignatureSymbol];1033      if (!*GroupIdxEntry) {1034        MCSectionELF *Group =1035            Ctx.createELFGroupSection(SignatureSymbol, Section.isComdat());1036        *GroupIdxEntry = addToSectionTable(Group);1037        Group->setAlignment(Align(4));1038 1039        GroupMap.resize(*GroupIdxEntry + 1);1040        GroupMap[*GroupIdxEntry] = Groups.size();1041        Groups.emplace_back(Group, SmallVector<unsigned>{});1042      }1043    }1044 1045    Section.setOrdinal(addToSectionTable(&Section));1046    if (RelSection) {1047      RelSection->setOrdinal(addToSectionTable(RelSection));1048      Relocations.push_back(RelSection);1049    }1050 1051    if (GroupIdxEntry) {1052      auto &Members = Groups[GroupMap[*GroupIdxEntry]];1053      Members.second.push_back(Section.getOrdinal());1054      if (RelSection)1055        Members.second.push_back(RelSection->getOrdinal());1056    }1057  }1058 1059  for (auto &[Group, Members] : Groups) {1060    // Remember the offset into the file for this section.1061    const uint64_t SecStart = align(Group->getAlign());1062 1063    write(uint32_t(Group->isComdat() ? unsigned(ELF::GRP_COMDAT) : 0));1064    W.write<unsigned>(Members);1065 1066    uint64_t SecEnd = W.OS.tell();1067    Group->setOffsets(SecStart, SecEnd);1068  }1069 1070  if (Mode == DwoOnly) {1071    // dwo files don't have symbol tables or relocations, but they do have1072    // string tables.1073    StrTabBuilder.finalize();1074  } else {1075    MCSectionELF *AddrsigSection;1076    if (OWriter.getEmitAddrsigSection()) {1077      AddrsigSection = Ctx.getELFSection(".llvm_addrsig", ELF::SHT_LLVM_ADDRSIG,1078                                         ELF::SHF_EXCLUDE);1079      addToSectionTable(AddrsigSection);1080    }1081 1082    // Compute symbol table information.1083    computeSymbolTable(RevGroupMap);1084 1085    for (MCSectionELF *RelSection : Relocations) {1086      // Remember the offset into the file for this section.1087      const uint64_t SecStart = align(RelSection->getAlign());1088 1089      writeRelocations(1090          static_cast<const MCSectionELF &>(*RelSection->getLinkedToSection()));1091 1092      uint64_t SecEnd = W.OS.tell();1093      RelSection->setOffsets(SecStart, SecEnd);1094    }1095 1096    if (OWriter.getEmitAddrsigSection()) {1097      uint64_t SecStart = W.OS.tell();1098      writeAddrsigSection();1099      uint64_t SecEnd = W.OS.tell();1100      AddrsigSection->setOffsets(SecStart, SecEnd);1101    }1102  }1103 1104  {1105    uint64_t SecStart = W.OS.tell();1106    StrTabBuilder.write(W.OS);1107    StrtabSection->setOffsets(SecStart, W.OS.tell());1108  }1109 1110  const uint64_t SectionHeaderOffset = align(is64Bit() ? Align(8) : Align(4));1111 1112  // ... then the section header table ...1113  writeSectionHeaders();1114 1115  uint16_t NumSections = support::endian::byte_swap<uint16_t>(1116      (SectionTable.size() + 1 >= ELF::SHN_LORESERVE) ? (uint16_t)ELF::SHN_UNDEF1117                                                      : SectionTable.size() + 1,1118      W.Endian);1119  unsigned NumSectionsOffset;1120 1121  auto &Stream = static_cast<raw_pwrite_stream &>(W.OS);1122  if (is64Bit()) {1123    uint64_t Val =1124        support::endian::byte_swap<uint64_t>(SectionHeaderOffset, W.Endian);1125    Stream.pwrite(reinterpret_cast<char *>(&Val), sizeof(Val),1126                  offsetof(ELF::Elf64_Ehdr, e_shoff));1127    NumSectionsOffset = offsetof(ELF::Elf64_Ehdr, e_shnum);1128  } else {1129    uint32_t Val =1130        support::endian::byte_swap<uint32_t>(SectionHeaderOffset, W.Endian);1131    Stream.pwrite(reinterpret_cast<char *>(&Val), sizeof(Val),1132                  offsetof(ELF::Elf32_Ehdr, e_shoff));1133    NumSectionsOffset = offsetof(ELF::Elf32_Ehdr, e_shnum);1134  }1135  Stream.pwrite(reinterpret_cast<char *>(&NumSections), sizeof(NumSections),1136                NumSectionsOffset);1137 1138  return W.OS.tell() - StartOffset;1139}1140 1141ELFObjectWriter::ELFObjectWriter(std::unique_ptr<MCELFObjectTargetWriter> MOTW,1142                                 raw_pwrite_stream &OS, bool IsLittleEndian)1143    : TargetObjectWriter(std::move(MOTW)), OS(OS),1144      IsLittleEndian(IsLittleEndian) {}1145ELFObjectWriter::ELFObjectWriter(std::unique_ptr<MCELFObjectTargetWriter> MOTW,1146                                 raw_pwrite_stream &OS,1147                                 raw_pwrite_stream &DwoOS, bool IsLittleEndian)1148    : TargetObjectWriter(std::move(MOTW)), OS(OS), DwoOS(&DwoOS),1149      IsLittleEndian(IsLittleEndian) {}1150 1151void ELFObjectWriter::reset() {1152  ELFHeaderEFlags = 0;1153  SeenGnuAbi = false;1154  OverrideABIVersion.reset();1155  Relocations.clear();1156  Renames.clear();1157  Weakrefs.clear();1158  Symvers.clear();1159  SeenGnuAbi = false;1160  MCObjectWriter::reset();1161}1162 1163void ELFObjectWriter::setAssembler(MCAssembler *Asm) {1164  MCObjectWriter::setAssembler(Asm);1165  TargetObjectWriter->setAssembler(Asm);1166}1167 1168bool ELFObjectWriter::hasRelocationAddend() const {1169  return TargetObjectWriter->hasRelocationAddend();1170}1171 1172void ELFObjectWriter::executePostLayoutBinding() {1173  // The presence of symbol versions causes undefined symbols and1174  // versions declared with @@@ to be renamed.1175  for (const Symver &S : Symvers) {1176    StringRef AliasName = S.Name;1177    auto &Symbol = static_cast<const MCSymbolELF &>(*S.Sym);1178    size_t Pos = AliasName.find('@');1179    assert(Pos != StringRef::npos);1180 1181    StringRef Prefix = AliasName.substr(0, Pos);1182    StringRef Rest = AliasName.substr(Pos);1183    StringRef Tail = Rest;1184    if (Rest.starts_with("@@@"))1185      Tail = Rest.substr(Symbol.isUndefined() ? 2 : 1);1186 1187    auto *Alias = static_cast<MCSymbolELF *>(1188        Asm->getContext().getOrCreateSymbol(Prefix + Tail));1189    Asm->registerSymbol(*Alias);1190    const MCExpr *Value = MCSymbolRefExpr::create(&Symbol, Asm->getContext());1191    Alias->setVariableValue(Value);1192 1193    // Aliases defined with .symvar copy the binding from the symbol they alias.1194    // This is the first place we are able to copy this information.1195    Alias->setBinding(Symbol.getBinding());1196    Alias->setVisibility(Symbol.getVisibility());1197    Alias->setOther(Symbol.getOther());1198 1199    if (!Symbol.isUndefined() && S.KeepOriginalSym)1200      continue;1201 1202    if (Symbol.isUndefined() && Rest.starts_with("@@") &&1203        !Rest.starts_with("@@@")) {1204      Asm->getContext().reportError(S.Loc, "default version symbol " +1205                                               AliasName + " must be defined");1206      continue;1207    }1208 1209    if (auto It = Renames.find(&Symbol);1210        It != Renames.end() && It->second != Alias) {1211      Asm->getContext().reportError(S.Loc, Twine("multiple versions for ") +1212                                               Symbol.getName());1213      continue;1214    }1215 1216    Renames.insert(std::make_pair(&Symbol, Alias));1217  }1218 1219  for (const MCSymbol *&Sym : AddrsigSyms) {1220    if (const MCSymbol *R =1221            Renames.lookup(static_cast<const MCSymbolELF *>(Sym)))1222      Sym = R;1223    if (Sym->isInSection() && Sym->getName().starts_with(".L"))1224      Sym = Sym->getSection().getBeginSymbol();1225    Sym->setUsedInReloc();1226  }1227 1228  // For each `.weakref alias, target`, if the variable `alias` is registered1229  // (typically through MCObjectStreamer::visitUsedSymbol), register `target`.1230  // If `target` was unregistered before (not directly referenced or defined),1231  // make it weak.1232  for (const MCSymbol *Alias : Weakrefs) {1233    if (!Alias->isRegistered())1234      continue;1235    auto *Expr = Alias->getVariableValue();1236    if (const auto *Inner = dyn_cast<MCSymbolRefExpr>(Expr)) {1237      auto &Sym = static_cast<const MCSymbolELF &>(Inner->getSymbol());1238      if (Asm->registerSymbol(Sym))1239        Sym.setBinding(ELF::STB_WEAK);1240    }1241  }1242}1243 1244// It is always valid to create a relocation with a symbol. It is preferable1245// to use a relocation with a section if that is possible. Using the section1246// allows us to omit some local symbols from the symbol table.1247bool ELFObjectWriter::useSectionSymbol(const MCValue &Val,1248                                       const MCSymbolELF *Sym, uint64_t C,1249                                       unsigned Type) const {1250  // Keep symbol type for a local ifunc because it may result in an IRELATIVE1251  // reloc that the dynamic loader will use to resolve the address at startup1252  // time.1253  if (Sym->getType() == ELF::STT_GNU_IFUNC)1254    return false;1255 1256  // If a relocation points to a mergeable section, we have to be careful.1257  // If the offset is zero, a relocation with the section will encode the1258  // same information. With a non-zero offset, the situation is different.1259  // For example, a relocation can point 42 bytes past the end of a string.1260  // If we change such a relocation to use the section, the linker would think1261  // that it pointed to another string and subtracting 42 at runtime will1262  // produce the wrong value.1263  if (Sym->isInSection()) {1264    auto &Sec = static_cast<const MCSectionELF &>(Sym->getSection());1265    unsigned Flags = Sec.getFlags();1266    if (Flags & ELF::SHF_MERGE) {1267      if (C != 0)1268        return false;1269 1270      // gold<2.34 incorrectly ignored the addend for R_386_GOTOFF (9)1271      // (http://sourceware.org/PR16794).1272      if (TargetObjectWriter->getEMachine() == ELF::EM_386 &&1273          Type == ELF::R_386_GOTOFF)1274        return false;1275 1276      // ld.lld handles R_MIPS_HI16/R_MIPS_LO16 separately, not as a whole, so1277      // it doesn't know that an R_MIPS_HI16 with implicit addend 1 and an1278      // R_MIPS_LO16 with implicit addend -32768 represents 32768, which is in1279      // range of a MergeInputSection. We could introduce a new RelExpr member1280      // (like R_RISCV_PC_INDIRECT for R_RISCV_PCREL_HI20 / R_RISCV_PCREL_LO12)1281      // but the complexity is unnecessary given that GNU as keeps the original1282      // symbol for this case as well.1283      if (TargetObjectWriter->getEMachine() == ELF::EM_MIPS &&1284          !hasRelocationAddend())1285        return false;1286    }1287 1288    // Most TLS relocations use a got, so they need the symbol. Even those that1289    // are just an offset (@tpoff), require a symbol in gold versions before1290    // 5efeedf61e4fe720fd3e9a08e6c91c10abb66d42 (2014-09-26) which fixed1291    // http://sourceware.org/PR16773.1292    if (Flags & ELF::SHF_TLS)1293      return false;1294  }1295 1296  return !TargetObjectWriter->needsRelocateWithSymbol(Val, Type);1297}1298 1299bool ELFObjectWriter::checkRelocation(SMLoc Loc, const MCSectionELF *From,1300                                      const MCSectionELF *To) {1301  if (isDwoSection(*From)) {1302    getContext().reportError(Loc, "A dwo section may not contain relocations");1303    return false;1304  }1305  if (To && isDwoSection(*To)) {1306    getContext().reportError(Loc,1307                             "A relocation may not refer to a dwo section");1308    return false;1309  }1310  return true;1311}1312 1313void ELFObjectWriter::recordRelocation(const MCFragment &F,1314                                       const MCFixup &Fixup, MCValue Target,1315                                       uint64_t &FixedValue) {1316  auto &Section = static_cast<const MCSectionELF &>(*F.getParent());1317  MCContext &Ctx = getContext();1318 1319  auto *SymA = static_cast<const MCSymbolELF *>(Target.getAddSym());1320  const MCSectionELF *SecA =1321      (SymA && SymA->isInSection())1322          ? static_cast<const MCSectionELF *>(&SymA->getSection())1323          : nullptr;1324  if (DwoOS && !checkRelocation(Fixup.getLoc(), &Section, SecA))1325    return;1326 1327  bool IsPCRel = Fixup.isPCRel();1328  uint64_t FixupOffset = Asm->getFragmentOffset(F) + Fixup.getOffset();1329  uint64_t Addend = Target.getConstant();1330  if (auto *RefB = Target.getSubSym()) {1331    auto &SymB = static_cast<const MCSymbolELF &>(*RefB);1332    if (SymB.isUndefined()) {1333      Ctx.reportError(Fixup.getLoc(),1334                      Twine("symbol '") + SymB.getName() +1335                          "' can not be undefined in a subtraction expression");1336      return;1337    }1338 1339    assert(!SymB.isAbsolute() && "Should have been folded");1340    const MCSection &SecB = SymB.getSection();1341    if (&SecB != &Section) {1342      Ctx.reportError(Fixup.getLoc(),1343                      "Cannot represent a difference across sections");1344      return;1345    }1346 1347    assert(!IsPCRel && "should have been folded");1348    IsPCRel = true;1349    Addend += FixupOffset - Asm->getSymbolOffset(SymB);1350  }1351 1352  unsigned Type;1353  if (mc::isRelocRelocation(Fixup.getKind()))1354    Type = Fixup.getKind() - FirstLiteralRelocationKind;1355  else1356    Type = TargetObjectWriter->getRelocType(Fixup, Target, IsPCRel);1357 1358  // Convert SymA to an STT_SECTION symbol if it's defined, local, and meets1359  // specific conditions, unless it's a .reloc directive, which disables1360  // STT_SECTION adjustment.1361  bool UseSectionSym = SymA && SymA->getBinding() == ELF::STB_LOCAL &&1362                       !SymA->isUndefined() &&1363                       !mc::isRelocRelocation(Fixup.getKind());1364  if (UseSectionSym && useSectionSymbol(Target, SymA, Addend, Type)) {1365    Addend += Asm->getSymbolOffset(*SymA);1366    SymA = static_cast<const MCSymbolELF *>(SecA->getBeginSymbol());1367  } else if (const MCSymbolELF *R = Renames.lookup(SymA)) {1368    SymA = R;1369  }1370  if (SymA)1371    SymA->setUsedInReloc();1372 1373  FixedValue = usesRela(Ctx.getTargetOptions(), Section) ? 0 : Addend;1374  Relocations[&Section].emplace_back(FixupOffset, SymA, Type, Addend);1375}1376 1377bool ELFObjectWriter::usesRela(const MCTargetOptions *TO,1378                               const MCSectionELF &Sec) const {1379  return (hasRelocationAddend() &&1380          Sec.getType() != ELF::SHT_LLVM_CALL_GRAPH_PROFILE) ||1381         (TO && TO->Crel);1382}1383 1384bool ELFObjectWriter::isSymbolRefDifferenceFullyResolvedImpl(1385    const MCSymbol &SA, const MCFragment &FB, bool InSet, bool IsPCRel) const {1386  auto &SymA = static_cast<const MCSymbolELF &>(SA);1387  if (IsPCRel) {1388    assert(!InSet);1389    if (SymA.getBinding() != ELF::STB_LOCAL ||1390        SymA.getType() == ELF::STT_GNU_IFUNC)1391      return false;1392  }1393  return &SymA.getSection() == FB.getParent();1394}1395 1396uint64_t ELFObjectWriter::writeObject() {1397  uint64_t Size =1398      ELFWriter(*Asm, *this, OS, IsLittleEndian,1399                DwoOS ? ELFWriter::NonDwoOnly : ELFWriter::AllSections)1400          .writeObject();1401  if (DwoOS)1402    Size += ELFWriter(*Asm, *this, *DwoOS, IsLittleEndian, ELFWriter::DwoOnly)1403                .writeObject();1404  return Size;1405}1406