Path: blob/main/contrib/llvm-project/lld/COFF/Symbols.cpp
34870 views
//===- Symbols.cpp --------------------------------------------------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//78#include "Symbols.h"9#include "COFFLinkerContext.h"10#include "InputFiles.h"11#include "lld/Common/ErrorHandler.h"12#include "lld/Common/Memory.h"13#include "lld/Common/Strings.h"14#include "llvm/ADT/STLExtras.h"15#include "llvm/Demangle/Demangle.h"16#include "llvm/Support/Debug.h"17#include "llvm/Support/raw_ostream.h"1819using namespace llvm;20using namespace llvm::object;2122using namespace lld::coff;2324namespace lld {2526static_assert(sizeof(SymbolUnion) <= 48,27"symbols should be optimized for memory usage");2829// Returns a symbol name for an error message.30static std::string maybeDemangleSymbol(const COFFLinkerContext &ctx,31StringRef symName) {32if (ctx.config.demangle) {33std::string prefix;34StringRef prefixless = symName;35if (prefixless.consume_front("__imp_"))36prefix = "__declspec(dllimport) ";37StringRef demangleInput = prefixless;38if (ctx.config.machine == I386)39demangleInput.consume_front("_");40std::string demangled = demangle(demangleInput);41if (demangled != demangleInput)42return prefix + demangled;43return (prefix + prefixless).str();44}45return std::string(symName);46}47std::string toString(const COFFLinkerContext &ctx, coff::Symbol &b) {48return maybeDemangleSymbol(ctx, b.getName());49}50std::string toCOFFString(const COFFLinkerContext &ctx,51const Archive::Symbol &b) {52return maybeDemangleSymbol(ctx, b.getName());53}5455namespace coff {5657void Symbol::computeName() {58assert(nameData == nullptr &&59"should only compute the name once for DefinedCOFF symbols");60auto *d = cast<DefinedCOFF>(this);61StringRef nameStr =62check(cast<ObjFile>(d->file)->getCOFFObj()->getSymbolName(d->sym));63nameData = nameStr.data();64nameSize = nameStr.size();65assert(nameSize == nameStr.size() && "name length truncated");66}6768InputFile *Symbol::getFile() {69if (auto *sym = dyn_cast<DefinedCOFF>(this))70return sym->file;71if (auto *sym = dyn_cast<LazyArchive>(this))72return sym->file;73if (auto *sym = dyn_cast<LazyObject>(this))74return sym->file;75if (auto *sym = dyn_cast<LazyDLLSymbol>(this))76return sym->file;77return nullptr;78}7980bool Symbol::isLive() const {81if (auto *r = dyn_cast<DefinedRegular>(this))82return r->getChunk()->live;83if (auto *imp = dyn_cast<DefinedImportData>(this))84return imp->file->live;85if (auto *imp = dyn_cast<DefinedImportThunk>(this))86return imp->wrappedSym->file->thunkLive;87// Assume any other kind of symbol is live.88return true;89}9091// MinGW specific.92void Symbol::replaceKeepingName(Symbol *other, size_t size) {93StringRef origName = getName();94memcpy(this, other, size);95nameData = origName.data();96nameSize = origName.size();97}9899COFFSymbolRef DefinedCOFF::getCOFFSymbol() {100size_t symSize = cast<ObjFile>(file)->getCOFFObj()->getSymbolTableEntrySize();101if (symSize == sizeof(coff_symbol16))102return COFFSymbolRef(reinterpret_cast<const coff_symbol16 *>(sym));103assert(symSize == sizeof(coff_symbol32));104return COFFSymbolRef(reinterpret_cast<const coff_symbol32 *>(sym));105}106107uint64_t DefinedAbsolute::getRVA() { return va - ctx.config.imageBase; }108109static Chunk *makeImportThunk(COFFLinkerContext &ctx, DefinedImportData *s,110uint16_t machine) {111if (machine == AMD64)112return make<ImportThunkChunkX64>(ctx, s);113if (machine == I386)114return make<ImportThunkChunkX86>(ctx, s);115if (machine == ARM64)116return make<ImportThunkChunkARM64>(ctx, s);117assert(machine == ARMNT);118return make<ImportThunkChunkARM>(ctx, s);119}120121DefinedImportThunk::DefinedImportThunk(COFFLinkerContext &ctx, StringRef name,122DefinedImportData *s, uint16_t machine)123: Defined(DefinedImportThunkKind, name), wrappedSym(s),124data(makeImportThunk(ctx, s, machine)) {}125126Defined *Undefined::getWeakAlias() {127// A weak alias may be a weak alias to another symbol, so check recursively.128for (Symbol *a = weakAlias; a; a = cast<Undefined>(a)->weakAlias)129if (auto *d = dyn_cast<Defined>(a))130return d;131return nullptr;132}133134MemoryBufferRef LazyArchive::getMemberBuffer() {135Archive::Child c =136CHECK(sym.getMember(), "could not get the member for symbol " +137toCOFFString(file->ctx, sym));138return CHECK(c.getMemoryBufferRef(),139"could not get the buffer for the member defining symbol " +140toCOFFString(file->ctx, sym));141}142} // namespace coff143} // namespace lld144145146