Symbols.cpp revision 292934
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 "Error.h" 11#include "InputFiles.h" 12#include "Symbols.h" 13#include "llvm/ADT/STLExtras.h" 14#include "llvm/Support/Debug.h" 15#include "llvm/Support/raw_ostream.h" 16 17using namespace llvm::object; 18using llvm::sys::fs::identify_magic; 19using llvm::sys::fs::file_magic; 20 21namespace lld { 22namespace coff { 23 24StringRef SymbolBody::getName() { 25 // DefinedCOFF names are read lazily for a performance reason. 26 // Non-external symbol names are never used by the linker except for logging 27 // or debugging. Their internal references are resolved not by name but by 28 // symbol index. And because they are not external, no one can refer them by 29 // name. Object files contain lots of non-external symbols, and creating 30 // StringRefs for them (which involves lots of strlen() on the string table) 31 // is a waste of time. 32 if (Name.empty()) { 33 auto *D = cast<DefinedCOFF>(this); 34 D->File->getCOFFObj()->getSymbolName(D->Sym, Name); 35 } 36 return Name; 37} 38 39// Returns 1, 0 or -1 if this symbol should take precedence 40// over the Other, tie or lose, respectively. 41int SymbolBody::compare(SymbolBody *Other) { 42 Kind LK = kind(), RK = Other->kind(); 43 44 // Normalize so that the smaller kind is on the left. 45 if (LK > RK) 46 return -Other->compare(this); 47 48 // First handle comparisons between two different kinds. 49 if (LK != RK) { 50 if (RK > LastDefinedKind) { 51 if (LK == LazyKind && cast<Undefined>(Other)->WeakAlias) 52 return -1; 53 54 // The LHS is either defined or lazy and so it wins. 55 assert((LK <= LastDefinedKind || LK == LazyKind) && "Bad kind!"); 56 return 1; 57 } 58 59 // Bitcode has special complexities. 60 if (RK == DefinedBitcodeKind) { 61 auto *RHS = cast<DefinedBitcode>(Other); 62 63 switch (LK) { 64 case DefinedCommonKind: 65 return 1; 66 67 case DefinedRegularKind: 68 // As an approximation, regular symbols win over bitcode symbols, 69 // but we definitely have a conflict if the regular symbol is not 70 // replaceable and neither is the bitcode symbol. We do not 71 // replicate the rest of the symbol resolution logic here; symbol 72 // resolution will be done accurately after lowering bitcode symbols 73 // to regular symbols in addCombinedLTOObject(). 74 if (cast<DefinedRegular>(this)->isCOMDAT() || RHS->IsReplaceable) 75 return 1; 76 77 // Fallthrough to the default of a tie otherwise. 78 default: 79 return 0; 80 } 81 } 82 83 // Either of the object file kind will trump a higher kind. 84 if (LK <= LastDefinedCOFFKind) 85 return 1; 86 87 // The remaining kind pairs are ties amongst defined symbols. 88 return 0; 89 } 90 91 // Now handle the case where the kinds are the same. 92 switch (LK) { 93 case DefinedRegularKind: { 94 auto *LHS = cast<DefinedRegular>(this); 95 auto *RHS = cast<DefinedRegular>(Other); 96 if (LHS->isCOMDAT() && RHS->isCOMDAT()) 97 return LHS->getFileIndex() < RHS->getFileIndex() ? 1 : -1; 98 return 0; 99 } 100 101 case DefinedCommonKind: { 102 auto *LHS = cast<DefinedCommon>(this); 103 auto *RHS = cast<DefinedCommon>(Other); 104 if (LHS->getSize() == RHS->getSize()) 105 return LHS->getFileIndex() < RHS->getFileIndex() ? 1 : -1; 106 return LHS->getSize() > RHS->getSize() ? 1 : -1; 107 } 108 109 case DefinedBitcodeKind: { 110 auto *LHS = cast<DefinedBitcode>(this); 111 auto *RHS = cast<DefinedBitcode>(Other); 112 // If both are non-replaceable, we have a tie. 113 if (!LHS->IsReplaceable && !RHS->IsReplaceable) 114 return 0; 115 116 // Non-replaceable symbols win, but even two replaceable symboles don't 117 // tie. If both symbols are replaceable, choice is arbitrary. 118 if (RHS->IsReplaceable && LHS->IsReplaceable) 119 return uintptr_t(LHS) < uintptr_t(RHS) ? 1 : -1; 120 return LHS->IsReplaceable ? -1 : 1; 121 } 122 123 case LazyKind: { 124 // Don't tie, pick the earliest. 125 auto *LHS = cast<Lazy>(this); 126 auto *RHS = cast<Lazy>(Other); 127 return LHS->getFileIndex() < RHS->getFileIndex() ? 1 : -1; 128 } 129 130 case UndefinedKind: { 131 auto *LHS = cast<Undefined>(this); 132 auto *RHS = cast<Undefined>(Other); 133 // Tie if both undefined symbols have different weak aliases. 134 if (LHS->WeakAlias && RHS->WeakAlias) { 135 if (LHS->WeakAlias->getName() != RHS->WeakAlias->getName()) 136 return 0; 137 return uintptr_t(LHS) < uintptr_t(RHS) ? 1 : -1; 138 } 139 return LHS->WeakAlias ? 1 : -1; 140 } 141 142 case DefinedLocalImportKind: 143 case DefinedImportThunkKind: 144 case DefinedImportDataKind: 145 case DefinedAbsoluteKind: 146 case DefinedRelativeKind: 147 // These all simply tie. 148 return 0; 149 } 150 llvm_unreachable("unknown symbol kind"); 151} 152 153std::string SymbolBody::getDebugName() { 154 std::string N = getName().str(); 155 if (auto *D = dyn_cast<DefinedCOFF>(this)) { 156 N += " "; 157 N += D->File->getShortName(); 158 } else if (auto *D = dyn_cast<DefinedBitcode>(this)) { 159 N += " "; 160 N += D->File->getShortName(); 161 } 162 return N; 163} 164 165uint64_t Defined::getFileOff() { 166 switch (kind()) { 167 case DefinedImportDataKind: 168 return cast<DefinedImportData>(this)->getFileOff(); 169 case DefinedImportThunkKind: 170 return cast<DefinedImportThunk>(this)->getFileOff(); 171 case DefinedLocalImportKind: 172 return cast<DefinedLocalImport>(this)->getFileOff(); 173 case DefinedCommonKind: 174 return cast<DefinedCommon>(this)->getFileOff(); 175 case DefinedRegularKind: 176 return cast<DefinedRegular>(this)->getFileOff(); 177 178 case DefinedBitcodeKind: 179 llvm_unreachable("There is no file offset for a bitcode symbol."); 180 case DefinedAbsoluteKind: 181 llvm_unreachable("Cannot get a file offset for an absolute symbol."); 182 case DefinedRelativeKind: 183 llvm_unreachable("Cannot get a file offset for a relative symbol."); 184 case LazyKind: 185 case UndefinedKind: 186 llvm_unreachable("Cannot get a file offset for an undefined symbol."); 187 } 188 llvm_unreachable("unknown symbol kind"); 189} 190 191COFFSymbolRef DefinedCOFF::getCOFFSymbol() { 192 size_t SymSize = File->getCOFFObj()->getSymbolTableEntrySize(); 193 if (SymSize == sizeof(coff_symbol16)) 194 return COFFSymbolRef(reinterpret_cast<const coff_symbol16 *>(Sym)); 195 assert(SymSize == sizeof(coff_symbol32)); 196 return COFFSymbolRef(reinterpret_cast<const coff_symbol32 *>(Sym)); 197} 198 199DefinedImportThunk::DefinedImportThunk(StringRef Name, DefinedImportData *S, 200 uint16_t Machine) 201 : Defined(DefinedImportThunkKind, Name) { 202 switch (Machine) { 203 case AMD64: Data.reset(new ImportThunkChunkX64(S)); return; 204 case I386: Data.reset(new ImportThunkChunkX86(S)); return; 205 case ARMNT: Data.reset(new ImportThunkChunkARM(S)); return; 206 default: llvm_unreachable("unknown machine type"); 207 } 208} 209 210std::unique_ptr<InputFile> Lazy::getMember() { 211 MemoryBufferRef MBRef = File->getMember(&Sym); 212 213 // getMember returns an empty buffer if the member was already 214 // read from the library. 215 if (MBRef.getBuffer().empty()) 216 return std::unique_ptr<InputFile>(nullptr); 217 218 file_magic Magic = identify_magic(MBRef.getBuffer()); 219 if (Magic == file_magic::coff_import_library) 220 return std::unique_ptr<InputFile>(new ImportFile(MBRef)); 221 222 std::unique_ptr<InputFile> Obj; 223 if (Magic == file_magic::coff_object) 224 Obj.reset(new ObjectFile(MBRef)); 225 else if (Magic == file_magic::bitcode) 226 Obj.reset(new BitcodeFile(MBRef)); 227 else 228 error(Twine(File->getName()) + ": unknown file type"); 229 230 Obj->setParentName(File->getName()); 231 return Obj; 232} 233 234Defined *Undefined::getWeakAlias() { 235 // A weak alias may be a weak alias to another symbol, so check recursively. 236 for (SymbolBody *A = WeakAlias; A; A = cast<Undefined>(A)->WeakAlias) 237 if (auto *D = dyn_cast<Defined>(A->repl())) 238 return D; 239 return nullptr; 240} 241 242} // namespace coff 243} // namespace lld 244