zig

fork of https://codeberg.org/ziglang/zig
Log | Files | Refs | README | LICENSE

blob 9b590790 (3020B) - Raw


      1 //===- Symbols.cpp --------------------------------------------------------===//
      2 //
      3 //                             The LLVM Linker
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 
     10 #include "Symbols.h"
     11 #include "Error.h"
     12 #include "InputFiles.h"
     13 #include "Memory.h"
     14 #include "Strings.h"
     15 #include "llvm/ADT/STLExtras.h"
     16 #include "llvm/Support/Debug.h"
     17 #include "llvm/Support/raw_ostream.h"
     18 
     19 using namespace llvm;
     20 using namespace llvm::object;
     21 
     22 // Returns a symbol name for an error message.
     23 std::string lld::toString(coff::SymbolBody &B) {
     24   if (Optional<std::string> S = coff::demangle(B.getName()))
     25     return ("\"" + *S + "\" (" + B.getName() + ")").str();
     26   return B.getName();
     27 }
     28 
     29 namespace lld {
     30 namespace coff {
     31 
     32 StringRef SymbolBody::getName() {
     33   // COFF symbol names are read lazily for a performance reason.
     34   // Non-external symbol names are never used by the linker except for logging
     35   // or debugging. Their internal references are resolved not by name but by
     36   // symbol index. And because they are not external, no one can refer them by
     37   // name. Object files contain lots of non-external symbols, and creating
     38   // StringRefs for them (which involves lots of strlen() on the string table)
     39   // is a waste of time.
     40   if (Name.empty()) {
     41     auto *D = cast<DefinedCOFF>(this);
     42     cast<ObjectFile>(D->File)->getCOFFObj()->getSymbolName(D->Sym, Name);
     43   }
     44   return Name;
     45 }
     46 
     47 InputFile *SymbolBody::getFile() {
     48   if (auto *Sym = dyn_cast<DefinedCOFF>(this))
     49     return Sym->File;
     50   if (auto *Sym = dyn_cast<Lazy>(this))
     51     return Sym->File;
     52   return nullptr;
     53 }
     54 
     55 COFFSymbolRef DefinedCOFF::getCOFFSymbol() {
     56   size_t SymSize =
     57       cast<ObjectFile>(File)->getCOFFObj()->getSymbolTableEntrySize();
     58   if (SymSize == sizeof(coff_symbol16))
     59     return COFFSymbolRef(reinterpret_cast<const coff_symbol16 *>(Sym));
     60   assert(SymSize == sizeof(coff_symbol32));
     61   return COFFSymbolRef(reinterpret_cast<const coff_symbol32 *>(Sym));
     62 }
     63 
     64 uint16_t DefinedAbsolute::OutputSectionIndex = 0;
     65 
     66 static Chunk *makeImportThunk(DefinedImportData *S, uint16_t Machine) {
     67   if (Machine == AMD64)
     68     return make<ImportThunkChunkX64>(S);
     69   if (Machine == I386)
     70     return make<ImportThunkChunkX86>(S);
     71   if (Machine == ARM64)
     72     return make<ImportThunkChunkARM64>(S);
     73   assert(Machine == ARMNT);
     74   return make<ImportThunkChunkARM>(S);
     75 }
     76 
     77 DefinedImportThunk::DefinedImportThunk(StringRef Name, DefinedImportData *S,
     78                                        uint16_t Machine)
     79     : Defined(DefinedImportThunkKind, Name), WrappedSym(S),
     80       Data(makeImportThunk(S, Machine)) {}
     81 
     82 Defined *Undefined::getWeakAlias() {
     83   // A weak alias may be a weak alias to another symbol, so check recursively.
     84   for (SymbolBody *A = WeakAlias; A; A = cast<Undefined>(A)->WeakAlias)
     85     if (auto *D = dyn_cast<Defined>(A))
     86       return D;
     87   return nullptr;
     88 }
     89 } // namespace coff
     90 } // namespace lld