brintos

brintos / llvm-project-archived public Read only

0
0
Text · 58.2 KiB · c08099b Raw
1585 lines · cpp
1//===- InputFiles.cpp -----------------------------------------------------===//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#include "InputFiles.h"10#include "COFFLinkerContext.h"11#include "Chunks.h"12#include "Config.h"13#include "DebugTypes.h"14#include "Driver.h"15#include "SymbolTable.h"16#include "Symbols.h"17#include "lld/Common/DWARF.h"18#include "llvm/ADT/SmallVector.h"19#include "llvm/ADT/Twine.h"20#include "llvm/BinaryFormat/COFF.h"21#include "llvm/DebugInfo/CodeView/DebugSubsectionRecord.h"22#include "llvm/DebugInfo/CodeView/SymbolDeserializer.h"23#include "llvm/DebugInfo/CodeView/SymbolRecord.h"24#include "llvm/DebugInfo/CodeView/TypeDeserializer.h"25#include "llvm/DebugInfo/PDB/Native/NativeSession.h"26#include "llvm/DebugInfo/PDB/Native/PDBFile.h"27#include "llvm/IR/Mangler.h"28#include "llvm/LTO/LTO.h"29#include "llvm/Object/Binary.h"30#include "llvm/Object/COFF.h"31#include "llvm/Object/COFFImportFile.h"32#include "llvm/Support/Casting.h"33#include "llvm/Support/Endian.h"34#include "llvm/Support/Error.h"35#include "llvm/Support/FileSystem.h"36#include "llvm/Support/Path.h"37#include "llvm/TargetParser/Triple.h"38#include <cstring>39#include <optional>40#include <utility>41 42using namespace llvm;43using namespace llvm::COFF;44using namespace llvm::codeview;45using namespace llvm::object;46using namespace llvm::support::endian;47using namespace lld;48using namespace lld::coff;49 50using llvm::Triple;51using llvm::support::ulittle32_t;52 53// Returns the last element of a path, which is supposed to be a filename.54static StringRef getBasename(StringRef path) {55  return sys::path::filename(path, sys::path::Style::windows);56}57 58// Returns a string in the format of "foo.obj" or "foo.obj(bar.lib)".59std::string lld::toString(const coff::InputFile *file) {60  if (!file)61    return "<internal>";62  if (file->parentName.empty())63    return std::string(file->getName());64 65  return (getBasename(file->parentName) + "(" + getBasename(file->getName()) +66          ")")67      .str();68}69 70const COFFSyncStream &coff::operator<<(const COFFSyncStream &s,71                                       const InputFile *f) {72  return s << toString(f);73}74 75/// Checks that Source is compatible with being a weak alias to Target.76/// If Source is Undefined and has no weak alias set, makes it a weak77/// alias to Target.78static void checkAndSetWeakAlias(SymbolTable &symtab, InputFile *f,79                                 Symbol *source, Symbol *target,80                                 bool isAntiDep) {81  if (auto *u = dyn_cast<Undefined>(source)) {82    if (u->weakAlias && u->weakAlias != target) {83      // Ignore duplicated anti-dependency symbols.84      if (isAntiDep)85        return;86      if (!u->isAntiDep) {87        // Weak aliases as produced by GCC are named in the form88        // .weak.<weaksymbol>.<othersymbol>, where <othersymbol> is the name89        // of another symbol emitted near the weak symbol.90        // Just use the definition from the first object file that defined91        // this weak symbol.92        if (symtab.ctx.config.allowDuplicateWeak)93          return;94        symtab.reportDuplicate(source, f);95      }96    }97    u->setWeakAlias(target, isAntiDep);98  }99}100 101static bool ignoredSymbolName(StringRef name) {102  return name == "@feat.00" || name == "@comp.id";103}104 105static coff_symbol_generic *cloneSymbol(COFFSymbolRef sym) {106  if (sym.isBigObj()) {107    auto *copy = make<coff_symbol32>(108        *reinterpret_cast<const coff_symbol32 *>(sym.getRawPtr()));109    return reinterpret_cast<coff_symbol_generic *>(copy);110  } else {111    auto *copy = make<coff_symbol16>(112        *reinterpret_cast<const coff_symbol16 *>(sym.getRawPtr()));113    return reinterpret_cast<coff_symbol_generic *>(copy);114  }115}116 117// Skip importing DllMain thunks from import libraries.118static bool fixupDllMain(COFFLinkerContext &ctx, llvm::object::Archive *file,119                         const Archive::Symbol &sym, bool &skipDllMain) {120  const Archive::Child &c =121      CHECK(sym.getMember(), file->getFileName() +122                                 ": could not get the member for symbol " +123                                 toCOFFString(ctx, sym));124  MemoryBufferRef mb =125      CHECK(c.getMemoryBufferRef(),126            file->getFileName() +127                ": could not get the buffer for a child buffer of the archive");128  if (identify_magic(mb.getBuffer()) == file_magic::coff_import_library) {129    if (ctx.config.warnImportedDllMain) {130      // We won't place DllMain symbols in the symbol table if they are131      // coming from a import library. This message can be ignored with the flag132      // '/ignore:importeddllmain'133      Warn(ctx)134          << file->getFileName()135          << ": skipping imported DllMain symbol [importeddllmain]\nNOTE: this "136             "might be a mistake when the DLL/library was produced.";137    }138    skipDllMain = true;139    return true;140  }141  return false;142}143 144ArchiveFile::ArchiveFile(COFFLinkerContext &ctx, MemoryBufferRef m)145    : InputFile(ctx.symtab, ArchiveKind, m) {}146 147void ArchiveFile::parse() {148  COFFLinkerContext &ctx = symtab.ctx;149  SymbolTable *archiveSymtab = &symtab;150 151  // Parse a MemoryBufferRef as an archive file.152  file = CHECK(Archive::create(mb), this);153 154  // Try to read symbols from ECSYMBOLS section on ARM64EC.155  if (ctx.symtab.isEC()) {156    iterator_range<Archive::symbol_iterator> symbols =157        CHECK(file->ec_symbols(), this);158    if (!symbols.empty()) {159      for (const Archive::Symbol &sym : symbols)160        ctx.symtab.addLazyArchive(this, sym);161 162      // Read both EC and native symbols on ARM64X.163      archiveSymtab = &*ctx.hybridSymtab;164    } else {165      // If the ECSYMBOLS section is missing in the archive, the archive could166      // be either a native-only ARM64 or x86_64 archive. Check the machine type167      // of the object containing a symbol to determine which symbol table to168      // use.169      Archive::symbol_iterator sym = file->symbol_begin();170      if (sym != file->symbol_end()) {171        MachineTypes machine = IMAGE_FILE_MACHINE_UNKNOWN;172        Archive::Child child =173            CHECK(sym->getMember(),174                  file->getFileName() +175                      ": could not get the buffer for a child of the archive");176        MemoryBufferRef mb = CHECK(177            child.getMemoryBufferRef(),178            file->getFileName() +179                ": could not get the buffer for a child buffer of the archive");180        switch (identify_magic(mb.getBuffer())) {181        case file_magic::coff_object: {182          std::unique_ptr<COFFObjectFile> obj =183              CHECK(COFFObjectFile::create(mb),184                    check(child.getName()) + ":" + ": not a valid COFF file");185          machine = MachineTypes(obj->getMachine());186          break;187        }188        case file_magic::coff_import_library:189          machine = MachineTypes(COFFImportFile(mb).getMachine());190          break;191        case file_magic::bitcode: {192          std::unique_ptr<lto::InputFile> obj =193              check(lto::InputFile::create(mb));194          machine = BitcodeFile::getMachineType(obj.get());195          break;196        }197        default:198          break;199        }200        archiveSymtab = &ctx.getSymtab(machine);201      }202    }203  }204 205  bool skipDllMain = false;206  StringRef mangledDllMain, impMangledDllMain;207 208  // The calls below will fail if we haven't set the machine type yet. Instead209  // of failing, it is preferable to skip this "imported DllMain" check if we210  // don't know the machine type at this point.211  if (!file->isEmpty() && ctx.config.machine != IMAGE_FILE_MACHINE_UNKNOWN) {212    mangledDllMain = archiveSymtab->mangle("DllMain");213    impMangledDllMain = uniqueSaver().save("__imp_" + mangledDllMain);214  }215 216  // Read the symbol table to construct Lazy objects.217  for (const Archive::Symbol &sym : file->symbols()) {218    // If an import library provides the DllMain symbol, skip importing it, as219    // we should be using our own DllMain, not another DLL's DllMain.220    if (!mangledDllMain.empty() && (sym.getName() == mangledDllMain ||221                                    sym.getName() == impMangledDllMain)) {222      if (skipDllMain || fixupDllMain(ctx, file.get(), sym, skipDllMain))223        continue;224    }225    archiveSymtab->addLazyArchive(this, sym);226  }227}228 229// Returns a buffer pointing to a member file containing a given symbol.230void ArchiveFile::addMember(const Archive::Symbol &sym) {231  const Archive::Child &c =232      CHECK(sym.getMember(), "could not get the member for symbol " +233                                 toCOFFString(symtab.ctx, sym));234 235  // Return an empty buffer if we have already returned the same buffer.236  // FIXME: Remove this once we resolve all defineds before all undefineds in237  //        ObjFile::initializeSymbols().238  if (!seen.insert(c.getChildOffset()).second)239    return;240 241  symtab.ctx.driver.enqueueArchiveMember(c, sym, getName());242}243 244std::vector<MemoryBufferRef>245lld::coff::getArchiveMembers(COFFLinkerContext &ctx, Archive *file) {246  std::vector<MemoryBufferRef> v;247  Error err = Error::success();248 249  // Thin archives refer to .o files, so --reproduces needs the .o files too.250  bool addToTar = file->isThin() && ctx.driver.tar;251 252  for (const Archive::Child &c : file->children(err)) {253    MemoryBufferRef mbref =254        CHECK(c.getMemoryBufferRef(),255              file->getFileName() +256                  ": could not get the buffer for a child of the archive");257    if (addToTar) {258      ctx.driver.tar->append(relativeToRoot(check(c.getFullName())),259                             mbref.getBuffer());260    }261    v.push_back(mbref);262  }263  if (err)264    Fatal(ctx) << file->getFileName()265               << ": Archive::children failed: " << toString(std::move(err));266  return v;267}268 269ObjFile::ObjFile(SymbolTable &symtab, COFFObjectFile *coffObj, bool lazy)270    : InputFile(symtab, ObjectKind, coffObj->getMemoryBufferRef(), lazy),271      coffObj(coffObj) {}272 273ObjFile *ObjFile::create(COFFLinkerContext &ctx, MemoryBufferRef m, bool lazy) {274  // Parse a memory buffer as a COFF file.275  Expected<std::unique_ptr<Binary>> bin = createBinary(m);276  if (!bin)277    Fatal(ctx) << "Could not parse " << m.getBufferIdentifier();278 279  auto *obj = dyn_cast<COFFObjectFile>(bin->get());280  if (!obj)281    Fatal(ctx) << m.getBufferIdentifier() << " is not a COFF file";282 283  bin->release();284  return make<ObjFile>(ctx.getSymtab(MachineTypes(obj->getMachine())), obj,285                       lazy);286}287 288void ObjFile::parseLazy() {289  // Native object file.290  uint32_t numSymbols = coffObj->getNumberOfSymbols();291  for (uint32_t i = 0; i < numSymbols; ++i) {292    COFFSymbolRef coffSym = check(coffObj->getSymbol(i));293    if (coffSym.isUndefined() || !coffSym.isExternal() ||294        coffSym.isWeakExternal())295      continue;296    StringRef name = check(coffObj->getSymbolName(coffSym));297    if (coffSym.isAbsolute() && ignoredSymbolName(name))298      continue;299    symtab.addLazyObject(this, name);300    if (!lazy)301      return;302    i += coffSym.getNumberOfAuxSymbols();303  }304}305 306struct ECMapEntry {307  ulittle32_t src;308  ulittle32_t dst;309  ulittle32_t type;310};311 312void ObjFile::initializeECThunks() {313  for (SectionChunk *chunk : hybmpChunks) {314    if (chunk->getContents().size() % sizeof(ECMapEntry)) {315      Err(symtab.ctx) << "Invalid .hybmp chunk size "316                      << chunk->getContents().size();317      continue;318    }319 320    const uint8_t *end =321        chunk->getContents().data() + chunk->getContents().size();322    for (const uint8_t *iter = chunk->getContents().data(); iter != end;323         iter += sizeof(ECMapEntry)) {324      auto entry = reinterpret_cast<const ECMapEntry *>(iter);325      switch (entry->type) {326      case Arm64ECThunkType::Entry:327        symtab.addEntryThunk(getSymbol(entry->src), getSymbol(entry->dst));328        break;329      case Arm64ECThunkType::Exit:330        symtab.addExitThunk(getSymbol(entry->src), getSymbol(entry->dst));331        break;332      case Arm64ECThunkType::GuestExit:333        break;334      default:335        Warn(symtab.ctx) << "Ignoring unknown EC thunk type " << entry->type;336      }337    }338  }339}340 341void ObjFile::parse() {342  // Read section and symbol tables.343  initializeChunks();344  initializeSymbols();345  initializeFlags();346  initializeDependencies();347  initializeECThunks();348}349 350const coff_section *ObjFile::getSection(uint32_t i) {351  auto sec = coffObj->getSection(i);352  if (!sec)353    Fatal(symtab.ctx) << "getSection failed: #" << i << ": " << sec.takeError();354  return *sec;355}356 357// We set SectionChunk pointers in the SparseChunks vector to this value358// temporarily to mark comdat sections as having an unknown resolution. As we359// walk the object file's symbol table, once we visit either a leader symbol or360// an associative section definition together with the parent comdat's leader,361// we set the pointer to either nullptr (to mark the section as discarded) or a362// valid SectionChunk for that section.363static SectionChunk *const pendingComdat = reinterpret_cast<SectionChunk *>(1);364 365void ObjFile::initializeChunks() {366  uint32_t numSections = coffObj->getNumberOfSections();367  sparseChunks.resize(numSections + 1);368  for (uint32_t i = 1; i < numSections + 1; ++i) {369    const coff_section *sec = getSection(i);370    if (sec->Characteristics & IMAGE_SCN_LNK_COMDAT)371      sparseChunks[i] = pendingComdat;372    else373      sparseChunks[i] = readSection(i, nullptr, "");374  }375}376 377SectionChunk *ObjFile::readSection(uint32_t sectionNumber,378                                   const coff_aux_section_definition *def,379                                   StringRef leaderName) {380  const coff_section *sec = getSection(sectionNumber);381 382  StringRef name;383  if (Expected<StringRef> e = coffObj->getSectionName(sec))384    name = *e;385  else386    Fatal(symtab.ctx) << "getSectionName failed: #" << sectionNumber << ": "387                      << e.takeError();388 389  if (name == ".drectve") {390    ArrayRef<uint8_t> data;391    cantFail(coffObj->getSectionContents(sec, data));392    directives = StringRef((const char *)data.data(), data.size());393    return nullptr;394  }395 396  if (name == ".llvm_addrsig") {397    addrsigSec = sec;398    return nullptr;399  }400 401  if (name == ".llvm.call-graph-profile") {402    callgraphSec = sec;403    return nullptr;404  }405 406  // Those sections are generated by -fembed-bitcode and do not need to be kept407  // in executable files.408  if (name == ".llvmbc" || name == ".llvmcmd")409    return nullptr;410 411  // Object files may have DWARF debug info or MS CodeView debug info412  // (or both).413  //414  // DWARF sections don't need any special handling from the perspective415  // of the linker; they are just a data section containing relocations.416  // We can just link them to complete debug info.417  //418  // CodeView needs linker support. We need to interpret debug info,419  // and then write it to a separate .pdb file.420 421  // Ignore DWARF debug info unless requested to be included.422  if (!symtab.ctx.config.includeDwarfChunks && name.starts_with(".debug_"))423    return nullptr;424 425  if (sec->Characteristics & llvm::COFF::IMAGE_SCN_LNK_REMOVE)426    return nullptr;427  SectionChunk *c;428  if (isArm64EC(getMachineType()))429    c = make<SectionChunkEC>(this, sec);430  else431    c = make<SectionChunk>(this, sec);432  if (def)433    c->checksum = def->CheckSum;434 435  // CodeView sections are stored to a different vector because they are not436  // linked in the regular manner.437  if (c->isCodeView())438    debugChunks.push_back(c);439  else if (name == ".gfids$y")440    guardFidChunks.push_back(c);441  else if (name == ".giats$y")442    guardIATChunks.push_back(c);443  else if (name == ".gljmp$y")444    guardLJmpChunks.push_back(c);445  else if (name == ".gehcont$y")446    guardEHContChunks.push_back(c);447  else if (name == ".sxdata")448    sxDataChunks.push_back(c);449  else if (isArm64EC(getMachineType()) && name == ".hybmp$x")450    hybmpChunks.push_back(c);451  else if (symtab.ctx.config.tailMerge && sec->NumberOfRelocations == 0 &&452           name == ".rdata" && leaderName.starts_with("??_C@"))453    // COFF sections that look like string literal sections (i.e. no454    // relocations, in .rdata, leader symbol name matches the MSVC name mangling455    // for string literals) are subject to string tail merging.456    MergeChunk::addSection(symtab.ctx, c);457  else if (name == ".rsrc" || name.starts_with(".rsrc$"))458    resourceChunks.push_back(c);459  else if (!(sec->Characteristics & llvm::COFF::IMAGE_SCN_LNK_INFO))460    chunks.push_back(c);461 462  return c;463}464 465void ObjFile::includeResourceChunks() {466  chunks.insert(chunks.end(), resourceChunks.begin(), resourceChunks.end());467}468 469void ObjFile::readAssociativeDefinition(470    COFFSymbolRef sym, const coff_aux_section_definition *def) {471  readAssociativeDefinition(sym, def, def->getNumber(sym.isBigObj()));472}473 474void ObjFile::readAssociativeDefinition(COFFSymbolRef sym,475                                        const coff_aux_section_definition *def,476                                        uint32_t parentIndex) {477  SectionChunk *parent = sparseChunks[parentIndex];478  int32_t sectionNumber = sym.getSectionNumber();479 480  auto diag = [&]() {481    StringRef name = check(coffObj->getSymbolName(sym));482 483    StringRef parentName;484    const coff_section *parentSec = getSection(parentIndex);485    if (Expected<StringRef> e = coffObj->getSectionName(parentSec))486      parentName = *e;487    Err(symtab.ctx) << toString(this) << ": associative comdat " << name488                    << " (sec " << sectionNumber489                    << ") has invalid reference to section " << parentName490                    << " (sec " << parentIndex << ")";491  };492 493  if (parent == pendingComdat) {494    // This can happen if an associative comdat refers to another associative495    // comdat that appears after it (invalid per COFF spec) or to a section496    // without any symbols.497    diag();498    return;499  }500 501  // Check whether the parent is prevailing. If it is, so are we, and we read502  // the section; otherwise mark it as discarded.503  if (parent) {504    SectionChunk *c = readSection(sectionNumber, def, "");505    sparseChunks[sectionNumber] = c;506    if (c) {507      c->selection = IMAGE_COMDAT_SELECT_ASSOCIATIVE;508      parent->addAssociative(c);509    }510  } else {511    sparseChunks[sectionNumber] = nullptr;512  }513}514 515void ObjFile::recordPrevailingSymbolForMingw(516    COFFSymbolRef sym, DenseMap<StringRef, uint32_t> &prevailingSectionMap) {517  // For comdat symbols in executable sections, where this is the copy518  // of the section chunk we actually include instead of discarding it,519  // add the symbol to a map to allow using it for implicitly520  // associating .[px]data$<func> sections to it.521  // Use the suffix from the .text$<func> instead of the leader symbol522  // name, for cases where the names differ (i386 mangling/decorations,523  // cases where the leader is a weak symbol named .weak.func.default*).524  int32_t sectionNumber = sym.getSectionNumber();525  SectionChunk *sc = sparseChunks[sectionNumber];526  if (sc && sc->getOutputCharacteristics() & IMAGE_SCN_MEM_EXECUTE) {527    StringRef name = sc->getSectionName().split('$').second;528    prevailingSectionMap[name] = sectionNumber;529  }530}531 532void ObjFile::maybeAssociateSEHForMingw(533    COFFSymbolRef sym, const coff_aux_section_definition *def,534    const DenseMap<StringRef, uint32_t> &prevailingSectionMap) {535  StringRef name = check(coffObj->getSymbolName(sym));536  if (name.consume_front(".pdata$") || name.consume_front(".xdata$") ||537      name.consume_front(".eh_frame$")) {538    // For MinGW, treat .[px]data$<func> and .eh_frame$<func> as implicitly539    // associative to the symbol <func>.540    auto parentSym = prevailingSectionMap.find(name);541    if (parentSym != prevailingSectionMap.end())542      readAssociativeDefinition(sym, def, parentSym->second);543  }544}545 546Symbol *ObjFile::createRegular(COFFSymbolRef sym) {547  SectionChunk *sc = sparseChunks[sym.getSectionNumber()];548  if (sym.isExternal()) {549    StringRef name = check(coffObj->getSymbolName(sym));550    if (sc)551      return symtab.addRegular(this, name, sym.getGeneric(), sc,552                               sym.getValue());553    // For MinGW symbols named .weak.* that point to a discarded section,554    // don't create an Undefined symbol. If nothing ever refers to the symbol,555    // everything should be fine. If something actually refers to the symbol556    // (e.g. the undefined weak alias), linking will fail due to undefined557    // references at the end.558    if (symtab.ctx.config.mingw && name.starts_with(".weak."))559      return nullptr;560    return symtab.addUndefined(name, this, false);561  }562  if (sc) {563    const coff_symbol_generic *symGen = sym.getGeneric();564    if (sym.isSection()) {565      auto *customSymGen = cloneSymbol(sym);566      customSymGen->Value = 0;567      symGen = customSymGen;568    }569    return make<DefinedRegular>(this, /*Name*/ "", /*IsCOMDAT*/ false,570                                /*IsExternal*/ false, symGen, sc);571  }572  return nullptr;573}574 575void ObjFile::initializeSymbols() {576  uint32_t numSymbols = coffObj->getNumberOfSymbols();577  symbols.resize(numSymbols);578 579  SmallVector<std::pair<Symbol *, const coff_aux_weak_external *>, 8>580      weakAliases;581  std::vector<uint32_t> pendingIndexes;582  pendingIndexes.reserve(numSymbols);583 584  DenseMap<StringRef, uint32_t> prevailingSectionMap;585  std::vector<const coff_aux_section_definition *> comdatDefs(586      coffObj->getNumberOfSections() + 1);587  COFFLinkerContext &ctx = symtab.ctx;588 589  for (uint32_t i = 0; i < numSymbols; ++i) {590    COFFSymbolRef coffSym = check(coffObj->getSymbol(i));591    bool prevailingComdat;592    if (coffSym.isUndefined()) {593      symbols[i] = createUndefined(coffSym, false);594    } else if (coffSym.isWeakExternal()) {595      auto aux = coffSym.getAux<coff_aux_weak_external>();596      bool overrideLazy = true;597 598      // On ARM64EC, external function calls emit a pair of weak-dependency599      // aliases: func to #func and #func to the func guess exit thunk600      // (instead of a single undefined func symbol, which would be emitted on601      // other targets). Allow such aliases to be overridden by lazy archive602      // symbols, just as we would for undefined symbols.603      if (isArm64EC(getMachineType()) &&604          aux->Characteristics == IMAGE_WEAK_EXTERN_ANTI_DEPENDENCY) {605        COFFSymbolRef targetSym = check(coffObj->getSymbol(aux->TagIndex));606        if (!targetSym.isAnyUndefined()) {607          // If the target is defined, it may be either a guess exit thunk or608          // the actual implementation. If it's the latter, consider the alias609          // to be part of the implementation and override potential lazy610          // archive symbols.611          StringRef targetName = check(coffObj->getSymbolName(targetSym));612          StringRef name = check(coffObj->getSymbolName(coffSym));613          std::optional<std::string> mangledName =614              getArm64ECMangledFunctionName(name);615          overrideLazy = mangledName == targetName;616        } else {617          overrideLazy = false;618        }619      }620      symbols[i] = createUndefined(coffSym, overrideLazy);621      weakAliases.emplace_back(symbols[i], aux);622    } else if (std::optional<Symbol *> optSym =623                   createDefined(coffSym, comdatDefs, prevailingComdat)) {624      symbols[i] = *optSym;625      if (ctx.config.mingw && prevailingComdat)626        recordPrevailingSymbolForMingw(coffSym, prevailingSectionMap);627    } else {628      // createDefined() returns std::nullopt if a symbol belongs to a section629      // that was pending at the point when the symbol was read. This can happen630      // in two cases:631      // 1) section definition symbol for a comdat leader;632      // 2) symbol belongs to a comdat section associated with another section.633      // In both of these cases, we can expect the section to be resolved by634      // the time we finish visiting the remaining symbols in the symbol635      // table. So we postpone the handling of this symbol until that time.636      pendingIndexes.push_back(i);637    }638    i += coffSym.getNumberOfAuxSymbols();639  }640 641  for (uint32_t i : pendingIndexes) {642    COFFSymbolRef sym = check(coffObj->getSymbol(i));643    if (const coff_aux_section_definition *def = sym.getSectionDefinition()) {644      if (def->Selection == IMAGE_COMDAT_SELECT_ASSOCIATIVE)645        readAssociativeDefinition(sym, def);646      else if (ctx.config.mingw)647        maybeAssociateSEHForMingw(sym, def, prevailingSectionMap);648    }649    if (sparseChunks[sym.getSectionNumber()] == pendingComdat) {650      StringRef name = check(coffObj->getSymbolName(sym));651      Log(ctx) << "comdat section " << name652               << " without leader and unassociated, discarding";653      continue;654    }655    symbols[i] = createRegular(sym);656  }657 658  for (auto &kv : weakAliases) {659    Symbol *sym = kv.first;660    const coff_aux_weak_external *aux = kv.second;661    checkAndSetWeakAlias(symtab, this, sym, symbols[aux->TagIndex],662                         aux->Characteristics ==663                             IMAGE_WEAK_EXTERN_ANTI_DEPENDENCY);664  }665 666  // Free the memory used by sparseChunks now that symbol loading is finished.667  decltype(sparseChunks)().swap(sparseChunks);668}669 670Symbol *ObjFile::createUndefined(COFFSymbolRef sym, bool overrideLazy) {671  StringRef name = check(coffObj->getSymbolName(sym));672  Symbol *s = symtab.addUndefined(name, this, overrideLazy);673 674  // Add an anti-dependency alias for undefined AMD64 symbols on the ARM64EC675  // target.676  if (symtab.isEC() && getMachineType() == AMD64) {677    auto u = dyn_cast<Undefined>(s);678    if (u && !u->weakAlias) {679      if (std::optional<std::string> mangledName =680              getArm64ECMangledFunctionName(name)) {681        Symbol *m = symtab.addUndefined(saver().save(*mangledName), this,682                                        /*overrideLazy=*/false);683        u->setWeakAlias(m, /*antiDep=*/true);684      }685    }686  }687  return s;688}689 690static const coff_aux_section_definition *findSectionDef(COFFObjectFile *obj,691                                                         int32_t section) {692  uint32_t numSymbols = obj->getNumberOfSymbols();693  for (uint32_t i = 0; i < numSymbols; ++i) {694    COFFSymbolRef sym = check(obj->getSymbol(i));695    if (sym.getSectionNumber() != section)696      continue;697    if (const coff_aux_section_definition *def = sym.getSectionDefinition())698      return def;699  }700  return nullptr;701}702 703void ObjFile::handleComdatSelection(704    COFFSymbolRef sym, COMDATType &selection, bool &prevailing,705    DefinedRegular *leader,706    const llvm::object::coff_aux_section_definition *def) {707  if (prevailing)708    return;709  // There's already an existing comdat for this symbol: `Leader`.710  // Use the comdats's selection field to determine if the new711  // symbol in `Sym` should be discarded, produce a duplicate symbol712  // error, etc.713 714  SectionChunk *leaderChunk = leader->getChunk();715  COMDATType leaderSelection = leaderChunk->selection;716  COFFLinkerContext &ctx = symtab.ctx;717 718  assert(leader->data && "Comdat leader without SectionChunk?");719  if (isa<BitcodeFile>(leader->file)) {720    // If the leader is only a LTO symbol, we don't know e.g. its final size721    // yet, so we can't do the full strict comdat selection checking yet.722    selection = leaderSelection = IMAGE_COMDAT_SELECT_ANY;723  }724 725  if ((selection == IMAGE_COMDAT_SELECT_ANY &&726       leaderSelection == IMAGE_COMDAT_SELECT_LARGEST) ||727      (selection == IMAGE_COMDAT_SELECT_LARGEST &&728       leaderSelection == IMAGE_COMDAT_SELECT_ANY)) {729    // cl.exe picks "any" for vftables when building with /GR- and730    // "largest" when building with /GR. To be able to link object files731    // compiled with each flag, "any" and "largest" are merged as "largest".732    leaderSelection = selection = IMAGE_COMDAT_SELECT_LARGEST;733  }734 735  // GCCs __declspec(selectany) doesn't actually pick "any" but "same size as".736  // Clang on the other hand picks "any". To be able to link two object files737  // with a __declspec(selectany) declaration, one compiled with gcc and the738  // other with clang, we merge them as proper "same size as"739  if (ctx.config.mingw && ((selection == IMAGE_COMDAT_SELECT_ANY &&740                            leaderSelection == IMAGE_COMDAT_SELECT_SAME_SIZE) ||741                           (selection == IMAGE_COMDAT_SELECT_SAME_SIZE &&742                            leaderSelection == IMAGE_COMDAT_SELECT_ANY))) {743    leaderSelection = selection = IMAGE_COMDAT_SELECT_SAME_SIZE;744  }745 746  // Other than that, comdat selections must match.  This is a bit more747  // strict than link.exe which allows merging "any" and "largest" if "any"748  // is the first symbol the linker sees, and it allows merging "largest"749  // with everything (!) if "largest" is the first symbol the linker sees.750  // Making this symmetric independent of which selection is seen first751  // seems better though.752  // (This behavior matches ModuleLinker::getComdatResult().)753  if (selection != leaderSelection) {754    Log(ctx) << "conflicting comdat type for " << symtab.printSymbol(leader)755             << ": " << (int)leaderSelection << " in " << leader->getFile()756             << " and " << (int)selection << " in " << this;757    symtab.reportDuplicate(leader, this);758    return;759  }760 761  switch (selection) {762  case IMAGE_COMDAT_SELECT_NODUPLICATES:763    symtab.reportDuplicate(leader, this);764    break;765 766  case IMAGE_COMDAT_SELECT_ANY:767    // Nothing to do.768    break;769 770  case IMAGE_COMDAT_SELECT_SAME_SIZE:771    if (leaderChunk->getSize() != getSection(sym)->SizeOfRawData) {772      if (!ctx.config.mingw) {773        symtab.reportDuplicate(leader, this);774      } else {775        const coff_aux_section_definition *leaderDef = nullptr;776        if (leaderChunk->file)777          leaderDef = findSectionDef(leaderChunk->file->getCOFFObj(),778                                     leaderChunk->getSectionNumber());779        if (!leaderDef || leaderDef->Length != def->Length)780          symtab.reportDuplicate(leader, this);781      }782    }783    break;784 785  case IMAGE_COMDAT_SELECT_EXACT_MATCH: {786    SectionChunk newChunk(this, getSection(sym));787    // link.exe only compares section contents here and doesn't complain788    // if the two comdat sections have e.g. different alignment.789    // Match that.790    if (leaderChunk->getContents() != newChunk.getContents())791      symtab.reportDuplicate(leader, this, &newChunk, sym.getValue());792    break;793  }794 795  case IMAGE_COMDAT_SELECT_ASSOCIATIVE:796    // createDefined() is never called for IMAGE_COMDAT_SELECT_ASSOCIATIVE.797    // (This means lld-link doesn't produce duplicate symbol errors for798    // associative comdats while link.exe does, but associate comdats799    // are never extern in practice.)800    llvm_unreachable("createDefined not called for associative comdats");801 802  case IMAGE_COMDAT_SELECT_LARGEST:803    if (leaderChunk->getSize() < getSection(sym)->SizeOfRawData) {804      // Replace the existing comdat symbol with the new one.805      StringRef name = check(coffObj->getSymbolName(sym));806      // FIXME: This is incorrect: With /opt:noref, the previous sections807      // make it into the final executable as well. Correct handling would808      // be to undo reading of the whole old section that's being replaced,809      // or doing one pass that determines what the final largest comdat810      // is for all IMAGE_COMDAT_SELECT_LARGEST comdats and then reading811      // only the largest one.812      replaceSymbol<DefinedRegular>(leader, this, name, /*IsCOMDAT*/ true,813                                    /*IsExternal*/ true, sym.getGeneric(),814                                    nullptr);815      prevailing = true;816    }817    break;818 819  case IMAGE_COMDAT_SELECT_NEWEST:820    llvm_unreachable("should have been rejected earlier");821  }822}823 824std::optional<Symbol *> ObjFile::createDefined(825    COFFSymbolRef sym,826    std::vector<const coff_aux_section_definition *> &comdatDefs,827    bool &prevailing) {828  prevailing = false;829  auto getName = [&]() { return check(coffObj->getSymbolName(sym)); };830 831  if (sym.isCommon()) {832    auto *c = make<CommonChunk>(sym);833    chunks.push_back(c);834    return symtab.addCommon(this, getName(), sym.getValue(), sym.getGeneric(),835                            c);836  }837 838  COFFLinkerContext &ctx = symtab.ctx;839  if (sym.isAbsolute()) {840    StringRef name = getName();841 842    if (name == "@feat.00")843      feat00Flags = sym.getValue();844    // Skip special symbols.845    if (ignoredSymbolName(name))846      return nullptr;847 848    if (sym.isExternal())849      return symtab.addAbsolute(name, sym);850    return make<DefinedAbsolute>(ctx, name, sym);851  }852 853  int32_t sectionNumber = sym.getSectionNumber();854  if (sectionNumber == llvm::COFF::IMAGE_SYM_DEBUG)855    return nullptr;856 857  if (sym.isEmptySectionDeclaration()) {858    // As there is no coff_section in the object file for these, make a859    // new virtual one, with everything zeroed out (i.e. an empty section),860    // with only the name and characteristics set.861    StringRef name = getName();862    auto *hdr = make<coff_section>();863    memset(hdr, 0, sizeof(*hdr));864    strncpy(hdr->Name, name.data(),865            std::min(name.size(), (size_t)COFF::NameSize));866    // The Value field in a section symbol may contain the characteristics,867    // or it may be zero, where we make something up (that matches what is868    // used in .idata sections in the regular object files in import libraries).869    if (sym.getValue())870      hdr->Characteristics = sym.getValue() | IMAGE_SCN_ALIGN_4BYTES;871    else872      hdr->Characteristics = IMAGE_SCN_CNT_INITIALIZED_DATA |873                             IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE |874                             IMAGE_SCN_ALIGN_4BYTES;875    auto *sc = make<SectionChunk>(this, hdr);876    chunks.push_back(sc);877 878    auto *symGen = cloneSymbol(sym);879    // Ignore the Value offset of these symbols, as it may be a bitmask.880    symGen->Value = 0;881    return make<DefinedRegular>(this, /*name=*/"", /*isCOMDAT=*/false,882                                /*isExternal=*/false, symGen, sc);883  }884 885  if (llvm::COFF::isReservedSectionNumber(sectionNumber))886    Fatal(ctx) << toString(this) << ": " << getName()887               << " should not refer to special section "888               << Twine(sectionNumber);889 890  if ((uint32_t)sectionNumber >= sparseChunks.size())891    Fatal(ctx) << toString(this) << ": " << getName()892               << " should not refer to non-existent section "893               << Twine(sectionNumber);894 895  // Comdat handling.896  // A comdat symbol consists of two symbol table entries.897  // The first symbol entry has the name of the section (e.g. .text), fixed898  // values for the other fields, and one auxiliary record.899  // The second symbol entry has the name of the comdat symbol, called the900  // "comdat leader".901  // When this function is called for the first symbol entry of a comdat,902  // it sets comdatDefs and returns std::nullopt, and when it's called for the903  // second symbol entry it reads comdatDefs and then sets it back to nullptr.904 905  // Handle comdat leader.906  if (const coff_aux_section_definition *def = comdatDefs[sectionNumber]) {907    comdatDefs[sectionNumber] = nullptr;908    DefinedRegular *leader;909 910    if (sym.isExternal()) {911      std::tie(leader, prevailing) =912          symtab.addComdat(this, getName(), sym.getGeneric());913    } else {914      leader = make<DefinedRegular>(this, /*Name*/ "", /*IsCOMDAT*/ false,915                                    /*IsExternal*/ false, sym.getGeneric());916      prevailing = true;917    }918 919    if (def->Selection < (int)IMAGE_COMDAT_SELECT_NODUPLICATES ||920        // Intentionally ends at IMAGE_COMDAT_SELECT_LARGEST: link.exe921        // doesn't understand IMAGE_COMDAT_SELECT_NEWEST either.922        def->Selection > (int)IMAGE_COMDAT_SELECT_LARGEST) {923      Fatal(ctx) << "unknown comdat type "924                 << std::to_string((int)def->Selection) << " for " << getName()925                 << " in " << toString(this);926    }927    COMDATType selection = (COMDATType)def->Selection;928 929    if (leader->isCOMDAT)930      handleComdatSelection(sym, selection, prevailing, leader, def);931 932    if (prevailing) {933      SectionChunk *c = readSection(sectionNumber, def, getName());934      sparseChunks[sectionNumber] = c;935      if (!c)936        return nullptr;937      c->sym = cast<DefinedRegular>(leader);938      c->selection = selection;939      cast<DefinedRegular>(leader)->data = &c->repl;940    } else {941      sparseChunks[sectionNumber] = nullptr;942    }943    return leader;944  }945 946  // Prepare to handle the comdat leader symbol by setting the section's947  // ComdatDefs pointer if we encounter a non-associative comdat.948  if (sparseChunks[sectionNumber] == pendingComdat) {949    if (const coff_aux_section_definition *def = sym.getSectionDefinition()) {950      if (def->Selection != IMAGE_COMDAT_SELECT_ASSOCIATIVE)951        comdatDefs[sectionNumber] = def;952    }953    return std::nullopt;954  }955 956  return createRegular(sym);957}958 959MachineTypes ObjFile::getMachineType() const {960  return static_cast<MachineTypes>(coffObj->getMachine());961}962 963ArrayRef<uint8_t> ObjFile::getDebugSection(StringRef secName) {964  if (SectionChunk *sec = SectionChunk::findByName(debugChunks, secName))965    return sec->consumeDebugMagic();966  return {};967}968 969// OBJ files systematically store critical information in a .debug$S stream,970// even if the TU was compiled with no debug info. At least two records are971// always there. S_OBJNAME stores a 32-bit signature, which is loaded into the972// PCHSignature member. S_COMPILE3 stores compile-time cmd-line flags. This is973// currently used to initialize the hotPatchable member.974void ObjFile::initializeFlags() {975  ArrayRef<uint8_t> data = getDebugSection(".debug$S");976  if (data.empty())977    return;978 979  DebugSubsectionArray subsections;980 981  BinaryStreamReader reader(data, llvm::endianness::little);982  ExitOnError exitOnErr;983  exitOnErr(reader.readArray(subsections, data.size()));984 985  for (const DebugSubsectionRecord &ss : subsections) {986    if (ss.kind() != DebugSubsectionKind::Symbols)987      continue;988 989    unsigned offset = 0;990 991    // Only parse the first two records. We are only looking for S_OBJNAME992    // and S_COMPILE3, and they usually appear at the beginning of the993    // stream.994    for (unsigned i = 0; i < 2; ++i) {995      Expected<CVSymbol> sym = readSymbolFromStream(ss.getRecordData(), offset);996      if (!sym) {997        consumeError(sym.takeError());998        return;999      }1000      if (sym->kind() == SymbolKind::S_COMPILE3) {1001        auto cs =1002            cantFail(SymbolDeserializer::deserializeAs<Compile3Sym>(sym.get()));1003        hotPatchable =1004            (cs.Flags & CompileSym3Flags::HotPatch) != CompileSym3Flags::None;1005      }1006      if (sym->kind() == SymbolKind::S_OBJNAME) {1007        auto objName = cantFail(SymbolDeserializer::deserializeAs<ObjNameSym>(1008            sym.get()));1009        if (objName.Signature)1010          pchSignature = objName.Signature;1011      }1012      offset += sym->length();1013    }1014  }1015}1016 1017// Depending on the compilation flags, OBJs can refer to external files,1018// necessary to merge this OBJ into the final PDB. We currently support two1019// types of external files: Precomp/PCH OBJs, when compiling with /Yc and /Yu.1020// And PDB type servers, when compiling with /Zi. This function extracts these1021// dependencies and makes them available as a TpiSource interface (see1022// DebugTypes.h). Both cases only happen with cl.exe: clang-cl produces regular1023// output even with /Yc and /Yu and with /Zi.1024void ObjFile::initializeDependencies() {1025  COFFLinkerContext &ctx = symtab.ctx;1026  if (!ctx.config.debug)1027    return;1028 1029  bool isPCH = false;1030 1031  ArrayRef<uint8_t> data = getDebugSection(".debug$P");1032  if (!data.empty())1033    isPCH = true;1034  else1035    data = getDebugSection(".debug$T");1036 1037  // symbols but no types, make a plain, empty TpiSource anyway, because it1038  // simplifies adding the symbols later.1039  if (data.empty()) {1040    if (!debugChunks.empty())1041      debugTypesObj = makeTpiSource(ctx, this);1042    return;1043  }1044 1045  // Get the first type record. It will indicate if this object uses a type1046  // server (/Zi) or a PCH file (/Yu).1047  CVTypeArray types;1048  BinaryStreamReader reader(data, llvm::endianness::little);1049  cantFail(reader.readArray(types, reader.getLength()));1050  CVTypeArray::Iterator firstType = types.begin();1051  if (firstType == types.end())1052    return;1053 1054  // Remember the .debug$T or .debug$P section.1055  debugTypes = data;1056 1057  // This object file is a PCH file that others will depend on.1058  if (isPCH) {1059    debugTypesObj = makePrecompSource(ctx, this);1060    return;1061  }1062 1063  // This object file was compiled with /Zi. Enqueue the PDB dependency.1064  if (firstType->kind() == LF_TYPESERVER2) {1065    TypeServer2Record ts = cantFail(1066        TypeDeserializer::deserializeAs<TypeServer2Record>(firstType->data()));1067    debugTypesObj = makeUseTypeServerSource(ctx, this, ts);1068    enqueuePdbFile(ts.getName(), this);1069    return;1070  }1071 1072  // This object was compiled with /Yu. It uses types from another object file1073  // with a matching signature.1074  if (firstType->kind() == LF_PRECOMP) {1075    PrecompRecord precomp = cantFail(1076        TypeDeserializer::deserializeAs<PrecompRecord>(firstType->data()));1077    // We're better off trusting the LF_PRECOMP signature. In some cases the1078    // S_OBJNAME record doesn't contain a valid PCH signature.1079    if (precomp.Signature)1080      pchSignature = precomp.Signature;1081    debugTypesObj = makeUsePrecompSource(ctx, this, precomp);1082    // Drop the LF_PRECOMP record from the input stream.1083    debugTypes = debugTypes.drop_front(firstType->RecordData.size());1084    return;1085  }1086 1087  // This is a plain old object file.1088  debugTypesObj = makeTpiSource(ctx, this);1089}1090 1091// The casing of the PDB path stamped in the OBJ can differ from the actual path1092// on disk. With this, we ensure to always use lowercase as a key for the1093// pdbInputFileInstances map, at least on Windows.1094static std::string normalizePdbPath(StringRef path) {1095#if defined(_WIN32)1096  return path.lower();1097#else // LINUX1098  return std::string(path);1099#endif1100}1101 1102// If existing, return the actual PDB path on disk.1103static std::optional<std::string>1104findPdbPath(StringRef pdbPath, ObjFile *dependentFile, StringRef outputPath) {1105  // Ensure the file exists before anything else. In some cases, if the path1106  // points to a removable device, Driver::enqueuePath() would fail with an1107  // error (EAGAIN, "resource unavailable try again") which we want to skip1108  // silently.1109  if (llvm::sys::fs::exists(pdbPath))1110    return normalizePdbPath(pdbPath);1111 1112  StringRef objPath = !dependentFile->parentName.empty()1113                          ? dependentFile->parentName1114                          : dependentFile->getName();1115 1116  // Currently, type server PDBs are only created by MSVC cl, which only runs1117  // on Windows, so we can assume type server paths are Windows style.1118  StringRef pdbName = sys::path::filename(pdbPath, sys::path::Style::windows);1119 1120  // Check if the PDB is in the same folder as the OBJ.1121  SmallString<128> path;1122  sys::path::append(path, sys::path::parent_path(objPath), pdbName);1123  if (llvm::sys::fs::exists(path))1124    return normalizePdbPath(path);1125 1126  // Check if the PDB is in the output folder.1127  path.clear();1128  sys::path::append(path, sys::path::parent_path(outputPath), pdbName);1129  if (llvm::sys::fs::exists(path))1130    return normalizePdbPath(path);1131 1132  return std::nullopt;1133}1134 1135PDBInputFile::PDBInputFile(COFFLinkerContext &ctx, MemoryBufferRef m)1136    : InputFile(ctx.symtab, PDBKind, m) {}1137 1138PDBInputFile::~PDBInputFile() = default;1139 1140PDBInputFile *PDBInputFile::findFromRecordPath(const COFFLinkerContext &ctx,1141                                               StringRef path,1142                                               ObjFile *fromFile) {1143  auto p = findPdbPath(path.str(), fromFile, ctx.config.outputFile);1144  if (!p)1145    return nullptr;1146  auto it = ctx.pdbInputFileInstances.find(*p);1147  if (it != ctx.pdbInputFileInstances.end())1148    return it->second;1149  return nullptr;1150}1151 1152void PDBInputFile::parse() {1153  symtab.ctx.pdbInputFileInstances[mb.getBufferIdentifier().str()] = this;1154 1155  std::unique_ptr<pdb::IPDBSession> thisSession;1156  Error E = pdb::NativeSession::createFromPdb(1157      MemoryBuffer::getMemBuffer(mb, false), thisSession);1158  if (E) {1159    loadErrorStr.emplace(toString(std::move(E)));1160    return; // fail silently at this point - the error will be handled later,1161            // when merging the debug type stream1162  }1163 1164  session.reset(static_cast<pdb::NativeSession *>(thisSession.release()));1165 1166  pdb::PDBFile &pdbFile = session->getPDBFile();1167  auto expectedInfo = pdbFile.getPDBInfoStream();1168  // All PDB Files should have an Info stream.1169  if (!expectedInfo) {1170    loadErrorStr.emplace(toString(expectedInfo.takeError()));1171    return;1172  }1173  debugTypesObj = makeTypeServerSource(symtab.ctx, this);1174}1175 1176// Used only for DWARF debug info, which is not common (except in MinGW1177// environments). This returns an optional pair of file name and line1178// number for where the variable was defined.1179std::optional<std::pair<StringRef, uint32_t>>1180ObjFile::getVariableLocation(StringRef var) {1181  if (!dwarf) {1182    dwarf = make<DWARFCache>(DWARFContext::create(*getCOFFObj()));1183    if (!dwarf)1184      return std::nullopt;1185  }1186  if (symtab.machine == I386)1187    var.consume_front("_");1188  std::optional<std::pair<std::string, unsigned>> ret =1189      dwarf->getVariableLoc(var);1190  if (!ret)1191    return std::nullopt;1192  return std::make_pair(saver().save(ret->first), ret->second);1193}1194 1195// Used only for DWARF debug info, which is not common (except in MinGW1196// environments).1197std::optional<DILineInfo> ObjFile::getDILineInfo(uint32_t offset,1198                                                 uint32_t sectionIndex) {1199  if (!dwarf) {1200    dwarf = make<DWARFCache>(DWARFContext::create(*getCOFFObj()));1201    if (!dwarf)1202      return std::nullopt;1203  }1204 1205  return dwarf->getDILineInfo(offset, sectionIndex);1206}1207 1208void ObjFile::enqueuePdbFile(StringRef path, ObjFile *fromFile) {1209  auto p = findPdbPath(path.str(), fromFile, symtab.ctx.config.outputFile);1210  if (!p)1211    return;1212  auto it = symtab.ctx.pdbInputFileInstances.emplace(*p, nullptr);1213  if (!it.second)1214    return; // already scheduled for load1215  symtab.ctx.driver.enqueuePDB(*p);1216}1217 1218ImportFile::ImportFile(COFFLinkerContext &ctx, MemoryBufferRef m)1219    : InputFile(ctx.getSymtab(getMachineType(m)), ImportKind, m),1220      live(!ctx.config.doGC) {}1221 1222MachineTypes ImportFile::getMachineType(MemoryBufferRef m) {1223  uint16_t machine =1224      reinterpret_cast<const coff_import_header *>(m.getBufferStart())->Machine;1225  return MachineTypes(machine);1226}1227 1228bool ImportFile::isSameImport(const ImportFile *other) const {1229  if (!externalName.empty())1230    return other->externalName == externalName;1231  return hdr->OrdinalHint == other->hdr->OrdinalHint;1232}1233 1234ImportThunkChunk *ImportFile::makeImportThunk() {1235  switch (hdr->Machine) {1236  case AMD64:1237    return make<ImportThunkChunkX64>(symtab.ctx, impSym);1238  case I386:1239    return make<ImportThunkChunkX86>(symtab.ctx, impSym);1240  case ARM64:1241    return make<ImportThunkChunkARM64>(symtab.ctx, impSym, ARM64);1242  case ARMNT:1243    return make<ImportThunkChunkARM>(symtab.ctx, impSym);1244  }1245  llvm_unreachable("unknown machine type");1246}1247 1248void ImportFile::parse() {1249  const auto *hdr =1250      reinterpret_cast<const coff_import_header *>(mb.getBufferStart());1251 1252  // Check if the total size is valid.1253  if (mb.getBufferSize() < sizeof(*hdr) ||1254      mb.getBufferSize() != sizeof(*hdr) + hdr->SizeOfData)1255    Fatal(symtab.ctx) << "broken import library";1256 1257  // Read names and create an __imp_ symbol.1258  StringRef buf = mb.getBuffer().substr(sizeof(*hdr));1259  auto split = buf.split('\0');1260  buf = split.second;1261  StringRef name;1262  if (isArm64EC(hdr->Machine)) {1263    if (std::optional<std::string> demangledName =1264            getArm64ECDemangledFunctionName(split.first))1265      name = saver().save(*demangledName);1266  }1267  if (name.empty())1268    name = saver().save(split.first);1269  StringRef impName = saver().save("__imp_" + name);1270  dllName = buf.split('\0').first;1271  StringRef extName;1272  switch (hdr->getNameType()) {1273  case IMPORT_ORDINAL:1274    extName = "";1275    break;1276  case IMPORT_NAME:1277    extName = name;1278    break;1279  case IMPORT_NAME_NOPREFIX:1280    extName = ltrim1(name, "?@_");1281    break;1282  case IMPORT_NAME_UNDECORATE:1283    extName = ltrim1(name, "?@_");1284    extName = extName.substr(0, extName.find('@'));1285    break;1286  case IMPORT_NAME_EXPORTAS:1287    extName = buf.substr(dllName.size() + 1).split('\0').first;1288    break;1289  }1290 1291  this->hdr = hdr;1292  externalName = extName;1293 1294  bool isCode = hdr->getType() == llvm::COFF::IMPORT_CODE;1295 1296  if (!symtab.isEC()) {1297    impSym = symtab.addImportData(impName, this, location);1298  } else {1299    // In addition to the regular IAT, ARM64EC also contains an auxiliary IAT,1300    // which holds addresses that are guaranteed to be callable directly from1301    // ARM64 code. Function symbol naming is swapped: __imp_ symbols refer to1302    // the auxiliary IAT, while __imp_aux_ symbols refer to the regular IAT. For1303    // data imports, the naming is reversed.1304    StringRef auxImpName = saver().save("__imp_aux_" + name);1305    if (isCode) {1306      impSym = symtab.addImportData(auxImpName, this, location);1307      impECSym = symtab.addImportData(impName, this, auxLocation);1308    } else {1309      impSym = symtab.addImportData(impName, this, location);1310      impECSym = symtab.addImportData(auxImpName, this, auxLocation);1311    }1312    if (!impECSym)1313      return;1314 1315    StringRef auxImpCopyName = saver().save("__auximpcopy_" + name);1316    auxImpCopySym = symtab.addImportData(auxImpCopyName, this, auxCopyLocation);1317    if (!auxImpCopySym)1318      return;1319  }1320  // If this was a duplicate, we logged an error but may continue;1321  // in this case, impSym is nullptr.1322  if (!impSym)1323    return;1324 1325  if (hdr->getType() == llvm::COFF::IMPORT_CONST)1326    static_cast<void>(symtab.addImportData(name, this, location));1327 1328  // If type is function, we need to create a thunk which jump to an1329  // address pointed by the __imp_ symbol. (This allows you to call1330  // DLL functions just like regular non-DLL functions.)1331  if (isCode) {1332    if (!symtab.isEC()) {1333      thunkSym = symtab.addImportThunk(name, impSym, makeImportThunk());1334    } else {1335      thunkSym = symtab.addImportThunk(1336          name, impSym, make<ImportThunkChunkX64>(symtab.ctx, impSym));1337 1338      if (std::optional<std::string> mangledName =1339              getArm64ECMangledFunctionName(name)) {1340        StringRef auxThunkName = saver().save(*mangledName);1341        auxThunkSym = symtab.addImportThunk(1342            auxThunkName, impECSym,1343            make<ImportThunkChunkARM64>(symtab.ctx, impECSym, ARM64EC));1344      }1345 1346      StringRef impChkName = saver().save("__impchk_" + name);1347      impchkThunk = make<ImportThunkChunkARM64EC>(this);1348      impchkThunk->sym = symtab.addImportThunk(impChkName, impSym, impchkThunk);1349      symtab.ctx.driver.pullArm64ECIcallHelper();1350    }1351  }1352}1353 1354BitcodeFile::BitcodeFile(SymbolTable &symtab, MemoryBufferRef mb,1355                         std::unique_ptr<lto::InputFile> &o, bool lazy)1356    : InputFile(symtab, BitcodeKind, mb, lazy) {1357  obj.swap(o);1358}1359 1360BitcodeFile *BitcodeFile::create(COFFLinkerContext &ctx, MemoryBufferRef mb,1361                                 StringRef archiveName,1362                                 uint64_t offsetInArchive, bool lazy) {1363  std::string path = mb.getBufferIdentifier().str();1364  if (ctx.config.thinLTOIndexOnly)1365    path = replaceThinLTOSuffix(mb.getBufferIdentifier(),1366                                ctx.config.thinLTOObjectSuffixReplace.first,1367                                ctx.config.thinLTOObjectSuffixReplace.second);1368 1369  // ThinLTO assumes that all MemoryBufferRefs given to it have a unique1370  // name. If two archives define two members with the same name, this1371  // causes a collision which result in only one of the objects being taken1372  // into consideration at LTO time (which very likely causes undefined1373  // symbols later in the link stage). So we append file offset to make1374  // filename unique.1375  MemoryBufferRef mbref(mb.getBuffer(),1376                        saver().save(archiveName.empty()1377                                         ? path1378                                         : archiveName +1379                                               sys::path::filename(path) +1380                                               utostr(offsetInArchive)));1381 1382  std::unique_ptr<lto::InputFile> obj = check(lto::InputFile::create(mbref));1383  return make<BitcodeFile>(ctx.getSymtab(getMachineType(obj.get())), mb, obj,1384                           lazy);1385}1386 1387BitcodeFile::~BitcodeFile() = default;1388 1389void BitcodeFile::parse() {1390  llvm::StringSaver &saver = lld::saver();1391 1392  std::vector<std::pair<Symbol *, bool>> comdat(obj->getComdatTable().size());1393  for (size_t i = 0; i != obj->getComdatTable().size(); ++i)1394    // FIXME: Check nodeduplicate1395    comdat[i] =1396        symtab.addComdat(this, saver.save(obj->getComdatTable()[i].first));1397  for (const lto::InputFile::Symbol &objSym : obj->symbols()) {1398    StringRef symName = saver.save(objSym.getName());1399    int comdatIndex = objSym.getComdatIndex();1400    Symbol *sym;1401    SectionChunk *fakeSC = nullptr;1402    if (objSym.isExecutable())1403      fakeSC = &symtab.ctx.ltoTextSectionChunk.chunk;1404    else1405      fakeSC = &symtab.ctx.ltoDataSectionChunk.chunk;1406    if (objSym.isUndefined()) {1407      sym = symtab.addUndefined(symName, this, false);1408      if (objSym.isWeak())1409        sym->deferUndefined = true;1410      // If one LTO object file references (i.e. has an undefined reference to)1411      // a symbol with an __imp_ prefix, the LTO compilation itself sees it1412      // as unprefixed but with a dllimport attribute instead, and doesn't1413      // understand the relation to a concrete IR symbol with the __imp_ prefix.1414      //1415      // For such cases, mark the symbol as used in a regular object (i.e. the1416      // symbol must be retained) so that the linker can associate the1417      // references in the end. If the symbol is defined in an import library1418      // or in a regular object file, this has no effect, but if it is defined1419      // in another LTO object file, this makes sure it is kept, to fulfill1420      // the reference when linking the output of the LTO compilation.1421      if (symName.starts_with("__imp_"))1422        sym->isUsedInRegularObj = true;1423    } else if (objSym.isCommon()) {1424      sym = symtab.addCommon(this, symName, objSym.getCommonSize());1425    } else if (objSym.isWeak() && objSym.isIndirect()) {1426      // Weak external.1427      sym = symtab.addUndefined(symName, this, true);1428      std::string fallback = std::string(objSym.getCOFFWeakExternalFallback());1429      Symbol *alias = symtab.addUndefined(saver.save(fallback));1430      checkAndSetWeakAlias(symtab, this, sym, alias, false);1431    } else if (comdatIndex != -1) {1432      if (symName == obj->getComdatTable()[comdatIndex].first) {1433        sym = comdat[comdatIndex].first;1434        if (cast<DefinedRegular>(sym)->data == nullptr)1435          cast<DefinedRegular>(sym)->data = &fakeSC->repl;1436      } else if (comdat[comdatIndex].second) {1437        sym = symtab.addRegular(this, symName, nullptr, fakeSC);1438      } else {1439        sym = symtab.addUndefined(symName, this, false);1440      }1441    } else {1442      sym =1443          symtab.addRegular(this, symName, nullptr, fakeSC, 0, objSym.isWeak());1444    }1445    symbols.push_back(sym);1446    if (objSym.isUsed())1447      symtab.ctx.config.gcroot.push_back(sym);1448  }1449  directives = saver.save(obj->getCOFFLinkerOpts());1450}1451 1452void BitcodeFile::parseLazy() {1453  for (const lto::InputFile::Symbol &sym : obj->symbols())1454    if (!sym.isUndefined()) {1455      symtab.addLazyObject(this, sym.getName());1456      if (!lazy)1457        return;1458    }1459}1460 1461MachineTypes BitcodeFile::getMachineType(const llvm::lto::InputFile *obj) {1462  Triple t(obj->getTargetTriple());1463  switch (t.getArch()) {1464  case Triple::x86_64:1465    return AMD64;1466  case Triple::x86:1467    return I386;1468  case Triple::arm:1469  case Triple::thumb:1470    return ARMNT;1471  case Triple::aarch64:1472    return t.isWindowsArm64EC() ? ARM64EC : ARM64;1473  default:1474    return IMAGE_FILE_MACHINE_UNKNOWN;1475  }1476}1477 1478std::string lld::coff::replaceThinLTOSuffix(StringRef path, StringRef suffix,1479                                            StringRef repl) {1480  if (path.consume_back(suffix))1481    return (path + repl).str();1482  return std::string(path);1483}1484 1485static bool isRVACode(COFFObjectFile *coffObj, uint64_t rva, InputFile *file) {1486  for (size_t i = 1, e = coffObj->getNumberOfSections(); i <= e; i++) {1487    const coff_section *sec = CHECK(coffObj->getSection(i), file);1488    if (rva >= sec->VirtualAddress &&1489        rva <= sec->VirtualAddress + sec->VirtualSize) {1490      return (sec->Characteristics & COFF::IMAGE_SCN_CNT_CODE) != 0;1491    }1492  }1493  return false;1494}1495 1496void DLLFile::parse() {1497  // Parse a memory buffer as a PE-COFF executable.1498  std::unique_ptr<Binary> bin = CHECK(createBinary(mb), this);1499 1500  if (auto *obj = dyn_cast<COFFObjectFile>(bin.get())) {1501    bin.release();1502    coffObj.reset(obj);1503  } else {1504    Err(symtab.ctx) << toString(this) << " is not a COFF file";1505    return;1506  }1507 1508  if (!coffObj->getPE32Header() && !coffObj->getPE32PlusHeader()) {1509    Err(symtab.ctx) << toString(this) << " is not a PE-COFF executable";1510    return;1511  }1512 1513  for (const auto &exp : coffObj->export_directories()) {1514    StringRef dllName, symbolName;1515    uint32_t exportRVA;1516    checkError(exp.getDllName(dllName));1517    checkError(exp.getSymbolName(symbolName));1518    checkError(exp.getExportRVA(exportRVA));1519 1520    if (symbolName.empty())1521      continue;1522 1523    bool code = isRVACode(coffObj.get(), exportRVA, this);1524 1525    Symbol *s = make<Symbol>();1526    s->dllName = dllName;1527    s->symbolName = symbolName;1528    s->importType = code ? ImportType::IMPORT_CODE : ImportType::IMPORT_DATA;1529    s->nameType = ImportNameType::IMPORT_NAME;1530 1531    if (coffObj->getMachine() == I386) {1532      s->symbolName = symbolName = saver().save("_" + symbolName);1533      s->nameType = ImportNameType::IMPORT_NAME_NOPREFIX;1534    }1535 1536    StringRef impName = saver().save("__imp_" + symbolName);1537    symtab.addLazyDLLSymbol(this, s, impName);1538    if (code)1539      symtab.addLazyDLLSymbol(this, s, symbolName);1540    if (symtab.isEC()) {1541      StringRef impAuxName = saver().save("__imp_aux_" + symbolName);1542      symtab.addLazyDLLSymbol(this, s, impAuxName);1543 1544      if (code) {1545        std::optional<std::string> mangledName =1546            getArm64ECMangledFunctionName(symbolName);1547        if (mangledName)1548          symtab.addLazyDLLSymbol(this, s, *mangledName);1549      }1550    }1551  }1552}1553 1554MachineTypes DLLFile::getMachineType() const {1555  if (coffObj)1556    return static_cast<MachineTypes>(coffObj->getMachine());1557  return IMAGE_FILE_MACHINE_UNKNOWN;1558}1559 1560void DLLFile::makeImport(DLLFile::Symbol *s) {1561  if (!seen.insert(s->symbolName).second)1562    return;1563 1564  size_t impSize = s->dllName.size() + s->symbolName.size() + 2; // +2 for NULs1565  size_t size = sizeof(coff_import_header) + impSize;1566  char *buf = bAlloc().Allocate<char>(size);1567  memset(buf, 0, size);1568  char *p = buf;1569  auto *imp = reinterpret_cast<coff_import_header *>(p);1570  p += sizeof(*imp);1571  imp->Sig2 = 0xFFFF;1572  imp->Machine = coffObj->getMachine();1573  imp->SizeOfData = impSize;1574  imp->OrdinalHint = 0; // Only linking by name1575  imp->TypeInfo = (s->nameType << 2) | s->importType;1576 1577  // Write symbol name and DLL name.1578  memcpy(p, s->symbolName.data(), s->symbolName.size());1579  p += s->symbolName.size() + 1;1580  memcpy(p, s->dllName.data(), s->dllName.size());1581  MemoryBufferRef mbref = MemoryBufferRef(StringRef(buf, size), s->dllName);1582  ImportFile *impFile = make<ImportFile>(symtab.ctx, mbref);1583  symtab.ctx.driver.addFile(impFile);1584}1585