1 //===- SymbolTable.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 "SymbolTable.h" 11 #include "Config.h" 12 #include "Driver.h" 13 #include "Error.h" 14 #include "LTO.h" 15 #include "Memory.h" 16 #include "Symbols.h" 17 #include "llvm/IR/LLVMContext.h" 18 #include "llvm/Support/Debug.h" 19 #include "llvm/Support/raw_ostream.h" 20 #include <utility> 21 22 using namespace llvm; 23 24 namespace lld { 25 namespace coff { 26 27 enum SymbolPreference { 28 SP_EXISTING = -1, 29 SP_CONFLICT = 0, 30 SP_NEW = 1, 31 }; 32 33 /// Checks if an existing symbol S should be kept or replaced by a new symbol. 34 /// Returns SP_EXISTING when S should be kept, SP_NEW when the new symbol 35 /// should be kept, and SP_CONFLICT if no valid resolution exists. 36 static SymbolPreference compareDefined(Symbol *S, bool WasInserted, 37 bool NewIsCOMDAT) { 38 // If the symbol wasn't previously known, the new symbol wins by default. 39 if (WasInserted || !isa<Defined>(S->body())) 40 return SP_NEW; 41 42 // If the existing symbol is a DefinedRegular, both it and the new symbol 43 // must be comdats. In that case, we have no reason to prefer one symbol 44 // over the other, and we keep the existing one. If one of the symbols 45 // is not a comdat, we report a conflict. 46 if (auto *R = dyn_cast<DefinedRegular>(S->body())) { 47 if (NewIsCOMDAT && R->isCOMDAT()) 48 return SP_EXISTING; 49 else 50 return SP_CONFLICT; 51 } 52 53 // Existing symbol is not a DefinedRegular; new symbol wins. 54 return SP_NEW; 55 } 56 57 SymbolTable *Symtab; 58 59 void SymbolTable::addFile(InputFile *File) { 60 log("Reading " + toString(File)); 61 File->parse(); 62 63 MachineTypes MT = File->getMachineType(); 64 if (Config->Machine == IMAGE_FILE_MACHINE_UNKNOWN) { 65 Config->Machine = MT; 66 } else if (MT != IMAGE_FILE_MACHINE_UNKNOWN && Config->Machine != MT) { 67 fatal(toString(File) + ": machine type " + machineToStr(MT) + 68 " conflicts with " + machineToStr(Config->Machine)); 69 } 70 71 if (auto *F = dyn_cast<ObjectFile>(File)) { 72 ObjectFiles.push_back(F); 73 } else if (auto *F = dyn_cast<BitcodeFile>(File)) { 74 BitcodeFiles.push_back(F); 75 } else if (auto *F = dyn_cast<ImportFile>(File)) { 76 ImportFiles.push_back(F); 77 } 78 79 StringRef S = File->getDirectives(); 80 if (S.empty()) 81 return; 82 83 log("Directives: " + toString(File) + ": " + S); 84 Driver->parseDirectives(S); 85 } 86 87 void SymbolTable::reportRemainingUndefines() { 88 SmallPtrSet<SymbolBody *, 8> Undefs; 89 for (auto &I : Symtab) { 90 Symbol *Sym = I.second; 91 auto *Undef = dyn_cast<Undefined>(Sym->body()); 92 if (!Undef) 93 continue; 94 if (!Sym->IsUsedInRegularObj) 95 continue; 96 StringRef Name = Undef->getName(); 97 // A weak alias may have been resolved, so check for that. 98 if (Defined *D = Undef->getWeakAlias()) { 99 // We resolve weak aliases by replacing the alias's SymbolBody with the 100 // target's SymbolBody. This causes all SymbolBody pointers referring to 101 // the old symbol to instead refer to the new symbol. However, we can't 102 // just blindly copy sizeof(Symbol::Body) bytes from D to Sym->Body 103 // because D may be an internal symbol, and internal symbols are stored as 104 // "unparented" SymbolBodies. For that reason we need to check which type 105 // of symbol we are dealing with and copy the correct number of bytes. 106 if (isa<DefinedRegular>(D)) 107 memcpy(Sym->Body.buffer, D, sizeof(DefinedRegular)); 108 else if (isa<DefinedAbsolute>(D)) 109 memcpy(Sym->Body.buffer, D, sizeof(DefinedAbsolute)); 110 else 111 // No other internal symbols are possible. 112 Sym->Body = D->symbol()->Body; 113 continue; 114 } 115 // If we can resolve a symbol by removing __imp_ prefix, do that. 116 // This odd rule is for compatibility with MSVC linker. 117 if (Name.startswith("__imp_")) { 118 Symbol *Imp = find(Name.substr(strlen("__imp_"))); 119 if (Imp && isa<Defined>(Imp->body())) { 120 auto *D = cast<Defined>(Imp->body()); 121 replaceBody<DefinedLocalImport>(Sym, Name, D); 122 LocalImportChunks.push_back( 123 cast<DefinedLocalImport>(Sym->body())->getChunk()); 124 continue; 125 } 126 } 127 // Remaining undefined symbols are not fatal if /force is specified. 128 // They are replaced with dummy defined symbols. 129 if (Config->Force) 130 replaceBody<DefinedAbsolute>(Sym, Name, 0); 131 Undefs.insert(Sym->body()); 132 } 133 if (Undefs.empty()) 134 return; 135 for (SymbolBody *B : Config->GCRoot) 136 if (Undefs.count(B)) 137 warn("<root>: undefined symbol: " + B->getName()); 138 for (ObjectFile *File : ObjectFiles) 139 for (SymbolBody *Sym : File->getSymbols()) 140 if (Undefs.count(Sym)) 141 warn(toString(File) + ": undefined symbol: " + Sym->getName()); 142 if (!Config->Force) 143 fatal("link failed"); 144 } 145 146 std::pair<Symbol *, bool> SymbolTable::insert(StringRef Name) { 147 Symbol *&Sym = Symtab[CachedHashStringRef(Name)]; 148 if (Sym) 149 return {Sym, false}; 150 Sym = make<Symbol>(); 151 Sym->IsUsedInRegularObj = false; 152 Sym->PendingArchiveLoad = false; 153 return {Sym, true}; 154 } 155 156 Symbol *SymbolTable::addUndefined(StringRef Name, InputFile *F, 157 bool IsWeakAlias) { 158 Symbol *S; 159 bool WasInserted; 160 std::tie(S, WasInserted) = insert(Name); 161 if (!F || !isa<BitcodeFile>(F)) 162 S->IsUsedInRegularObj = true; 163 if (WasInserted || (isa<Lazy>(S->body()) && IsWeakAlias)) { 164 replaceBody<Undefined>(S, Name); 165 return S; 166 } 167 if (auto *L = dyn_cast<Lazy>(S->body())) { 168 if (!S->PendingArchiveLoad) { 169 S->PendingArchiveLoad = true; 170 L->File->addMember(&L->Sym); 171 } 172 } 173 return S; 174 } 175 176 void SymbolTable::addLazy(ArchiveFile *F, const Archive::Symbol Sym) { 177 StringRef Name = Sym.getName(); 178 Symbol *S; 179 bool WasInserted; 180 std::tie(S, WasInserted) = insert(Name); 181 if (WasInserted) { 182 replaceBody<Lazy>(S, F, Sym); 183 return; 184 } 185 auto *U = dyn_cast<Undefined>(S->body()); 186 if (!U || U->WeakAlias || S->PendingArchiveLoad) 187 return; 188 S->PendingArchiveLoad = true; 189 F->addMember(&Sym); 190 } 191 192 void SymbolTable::reportDuplicate(Symbol *Existing, InputFile *NewFile) { 193 fatal("duplicate symbol: " + toString(*Existing->body()) + " in " + 194 toString(Existing->body()->getFile()) + " and in " + 195 (NewFile ? toString(NewFile) : "(internal)")); 196 } 197 198 Symbol *SymbolTable::addAbsolute(StringRef N, COFFSymbolRef Sym) { 199 Symbol *S; 200 bool WasInserted; 201 std::tie(S, WasInserted) = insert(N); 202 S->IsUsedInRegularObj = true; 203 if (WasInserted || isa<Undefined>(S->body()) || isa<Lazy>(S->body())) 204 replaceBody<DefinedAbsolute>(S, N, Sym); 205 else if (!isa<DefinedCOFF>(S->body())) 206 reportDuplicate(S, nullptr); 207 return S; 208 } 209 210 Symbol *SymbolTable::addAbsolute(StringRef N, uint64_t VA) { 211 Symbol *S; 212 bool WasInserted; 213 std::tie(S, WasInserted) = insert(N); 214 S->IsUsedInRegularObj = true; 215 if (WasInserted || isa<Undefined>(S->body()) || isa<Lazy>(S->body())) 216 replaceBody<DefinedAbsolute>(S, N, VA); 217 else if (!isa<DefinedCOFF>(S->body())) 218 reportDuplicate(S, nullptr); 219 return S; 220 } 221 222 Symbol *SymbolTable::addRelative(StringRef N, uint64_t VA) { 223 Symbol *S; 224 bool WasInserted; 225 std::tie(S, WasInserted) = insert(N); 226 S->IsUsedInRegularObj = true; 227 if (WasInserted || isa<Undefined>(S->body()) || isa<Lazy>(S->body())) 228 replaceBody<DefinedRelative>(S, N, VA); 229 else if (!isa<DefinedCOFF>(S->body())) 230 reportDuplicate(S, nullptr); 231 return S; 232 } 233 234 Symbol *SymbolTable::addRegular(InputFile *F, StringRef N, bool IsCOMDAT, 235 const coff_symbol_generic *Sym, 236 SectionChunk *C) { 237 Symbol *S; 238 bool WasInserted; 239 std::tie(S, WasInserted) = insert(N); 240 if (!isa<BitcodeFile>(F)) 241 S->IsUsedInRegularObj = true; 242 SymbolPreference SP = compareDefined(S, WasInserted, IsCOMDAT); 243 if (SP == SP_CONFLICT) { 244 reportDuplicate(S, F); 245 } else if (SP == SP_NEW) { 246 replaceBody<DefinedRegular>(S, F, N, IsCOMDAT, /*IsExternal*/ true, Sym, C); 247 } 248 return S; 249 } 250 251 Symbol *SymbolTable::addCommon(InputFile *F, StringRef N, uint64_t Size, 252 const coff_symbol_generic *Sym, CommonChunk *C) { 253 Symbol *S; 254 bool WasInserted; 255 std::tie(S, WasInserted) = insert(N); 256 if (!isa<BitcodeFile>(F)) 257 S->IsUsedInRegularObj = true; 258 if (WasInserted || !isa<DefinedCOFF>(S->body())) 259 replaceBody<DefinedCommon>(S, F, N, Size, Sym, C); 260 else if (auto *DC = dyn_cast<DefinedCommon>(S->body())) 261 if (Size > DC->getSize()) 262 replaceBody<DefinedCommon>(S, F, N, Size, Sym, C); 263 return S; 264 } 265 266 Symbol *SymbolTable::addImportData(StringRef N, ImportFile *F) { 267 Symbol *S; 268 bool WasInserted; 269 std::tie(S, WasInserted) = insert(N); 270 S->IsUsedInRegularObj = true; 271 if (WasInserted || isa<Undefined>(S->body()) || isa<Lazy>(S->body())) 272 replaceBody<DefinedImportData>(S, N, F); 273 else if (!isa<DefinedCOFF>(S->body())) 274 reportDuplicate(S, nullptr); 275 return S; 276 } 277 278 Symbol *SymbolTable::addImportThunk(StringRef Name, DefinedImportData *ID, 279 uint16_t Machine) { 280 Symbol *S; 281 bool WasInserted; 282 std::tie(S, WasInserted) = insert(Name); 283 S->IsUsedInRegularObj = true; 284 if (WasInserted || isa<Undefined>(S->body()) || isa<Lazy>(S->body())) 285 replaceBody<DefinedImportThunk>(S, Name, ID, Machine); 286 else if (!isa<DefinedCOFF>(S->body())) 287 reportDuplicate(S, nullptr); 288 return S; 289 } 290 291 std::vector<Chunk *> SymbolTable::getChunks() { 292 std::vector<Chunk *> Res; 293 for (ObjectFile *File : ObjectFiles) { 294 std::vector<Chunk *> &V = File->getChunks(); 295 Res.insert(Res.end(), V.begin(), V.end()); 296 } 297 return Res; 298 } 299 300 Symbol *SymbolTable::find(StringRef Name) { 301 auto It = Symtab.find(CachedHashStringRef(Name)); 302 if (It == Symtab.end()) 303 return nullptr; 304 return It->second; 305 } 306 307 Symbol *SymbolTable::findUnderscore(StringRef Name) { 308 if (Config->Machine == I386) 309 return find(("_" + Name).str()); 310 return find(Name); 311 } 312 313 StringRef SymbolTable::findByPrefix(StringRef Prefix) { 314 for (auto Pair : Symtab) { 315 StringRef Name = Pair.first.val(); 316 if (Name.startswith(Prefix)) 317 return Name; 318 } 319 return ""; 320 } 321 322 StringRef SymbolTable::findMangle(StringRef Name) { 323 if (Symbol *Sym = find(Name)) 324 if (!isa<Undefined>(Sym->body())) 325 return Name; 326 if (Config->Machine != I386) 327 return findByPrefix(("?" + Name + "@@Y").str()); 328 if (!Name.startswith("_")) 329 return ""; 330 // Search for x86 C function. 331 StringRef S = findByPrefix((Name + "@").str()); 332 if (!S.empty()) 333 return S; 334 // Search for x86 C++ non-member function. 335 return findByPrefix(("?" + Name.substr(1) + "@@Y").str()); 336 } 337 338 void SymbolTable::mangleMaybe(SymbolBody *B) { 339 auto *U = dyn_cast<Undefined>(B); 340 if (!U || U->WeakAlias) 341 return; 342 StringRef Alias = findMangle(U->getName()); 343 if (!Alias.empty()) 344 U->WeakAlias = addUndefined(Alias); 345 } 346 347 SymbolBody *SymbolTable::addUndefined(StringRef Name) { 348 return addUndefined(Name, nullptr, false)->body(); 349 } 350 351 std::vector<StringRef> SymbolTable::compileBitcodeFiles() { 352 LTO.reset(new BitcodeCompiler); 353 for (BitcodeFile *F : BitcodeFiles) 354 LTO->add(*F); 355 return LTO->compile(); 356 } 357 358 void SymbolTable::addCombinedLTOObjects() { 359 if (BitcodeFiles.empty()) 360 return; 361 for (StringRef Object : compileBitcodeFiles()) { 362 auto *Obj = make<ObjectFile>(MemoryBufferRef(Object, "lto.tmp")); 363 Obj->parse(); 364 ObjectFiles.push_back(Obj); 365 } 366 } 367 368 } // namespace coff 369 } // namespace lld 370