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 "InputSection.h" 12 #include "Error.h" 13 #include "InputFiles.h" 14 15 #include "llvm/ADT/STLExtras.h" 16 17 using namespace llvm; 18 using namespace llvm::object; 19 using namespace llvm::ELF; 20 21 using namespace lld; 22 using namespace lld::elf2; 23 24 static uint8_t getMinVisibility(uint8_t VA, uint8_t VB) { 25 if (VA == STV_DEFAULT) 26 return VB; 27 if (VB == STV_DEFAULT) 28 return VA; 29 return std::min(VA, VB); 30 } 31 32 // Returns 1, 0 or -1 if this symbol should take precedence 33 // over the Other, tie or lose, respectively. 34 template <class ELFT> int SymbolBody::compare(SymbolBody *Other) { 35 typedef typename ELFFile<ELFT>::uintX_t uintX_t; 36 assert(!isLazy() && !Other->isLazy()); 37 std::pair<bool, bool> L(isDefined(), !isWeak()); 38 std::pair<bool, bool> R(Other->isDefined(), !Other->isWeak()); 39 40 // Normalize 41 if (L > R) 42 return -Other->compare<ELFT>(this); 43 44 Visibility = Other->Visibility = 45 getMinVisibility(Visibility, Other->Visibility); 46 47 if (IsUsedInRegularObj || Other->IsUsedInRegularObj) 48 IsUsedInRegularObj = Other->IsUsedInRegularObj = true; 49 50 if (L != R) 51 return -1; 52 if (!L.first || !L.second) 53 return 1; 54 if (isShared()) 55 return -1; 56 if (Other->isShared()) 57 return 1; 58 if (isCommon()) { 59 if (!Other->isCommon()) 60 return -1; 61 auto *ThisC = cast<DefinedCommon>(this); 62 auto *OtherC = cast<DefinedCommon>(Other); 63 uintX_t Align = std::max(ThisC->MaxAlignment, OtherC->MaxAlignment); 64 if (ThisC->Size >= OtherC->Size) { 65 ThisC->MaxAlignment = Align; 66 return 1; 67 } 68 OtherC->MaxAlignment = Align; 69 return -1; 70 } 71 if (Other->isCommon()) 72 return 1; 73 return 0; 74 } 75 76 Defined::Defined(Kind K, StringRef Name, bool IsWeak, uint8_t Visibility, 77 bool IsTls) 78 : SymbolBody(K, Name, IsWeak, Visibility, IsTls) {} 79 80 Undefined::Undefined(SymbolBody::Kind K, StringRef N, bool IsWeak, 81 uint8_t Visibility, bool IsTls) 82 : SymbolBody(K, N, IsWeak, Visibility, IsTls), CanKeepUndefined(false) {} 83 84 Undefined::Undefined(StringRef N, bool IsWeak, uint8_t Visibility, 85 bool CanKeepUndefined) 86 : Undefined(SymbolBody::UndefinedKind, N, IsWeak, Visibility, 87 /*IsTls*/ false) { 88 this->CanKeepUndefined = CanKeepUndefined; 89 } 90 91 template <typename ELFT> 92 UndefinedElf<ELFT>::UndefinedElf(StringRef N, const Elf_Sym &Sym) 93 : Undefined(SymbolBody::UndefinedElfKind, N, 94 Sym.getBinding() == llvm::ELF::STB_WEAK, Sym.getVisibility(), 95 Sym.getType() == llvm::ELF::STT_TLS), 96 Sym(Sym) {} 97 98 template <typename ELFT> 99 DefinedSynthetic<ELFT>::DefinedSynthetic(StringRef N, uintX_t Value, 100 OutputSectionBase<ELFT> &Section) 101 : Defined(SymbolBody::DefinedSyntheticKind, N, false, STV_DEFAULT, false), 102 Value(Value), Section(Section) {} 103 104 DefinedCommon::DefinedCommon(StringRef N, uint64_t Size, uint64_t Alignment, 105 bool IsWeak, uint8_t Visibility) 106 : Defined(SymbolBody::DefinedCommonKind, N, IsWeak, Visibility, false) { 107 MaxAlignment = Alignment; 108 this->Size = Size; 109 } 110 111 std::unique_ptr<InputFile> Lazy::getMember() { 112 MemoryBufferRef MBRef = File->getMember(&Sym); 113 114 // getMember returns an empty buffer if the member was already 115 // read from the library. 116 if (MBRef.getBuffer().empty()) 117 return std::unique_ptr<InputFile>(nullptr); 118 return createObjectFile(MBRef); 119 } 120 121 template <class ELFT> static void doInitSymbols() { 122 ElfSym<ELFT>::End.setBinding(STB_GLOBAL); 123 ElfSym<ELFT>::IgnoredWeak.setBinding(STB_WEAK); 124 ElfSym<ELFT>::IgnoredWeak.setVisibility(STV_HIDDEN); 125 ElfSym<ELFT>::Ignored.setBinding(STB_GLOBAL); 126 ElfSym<ELFT>::Ignored.setVisibility(STV_HIDDEN); 127 } 128 129 void elf2::initSymbols() { 130 doInitSymbols<ELF32LE>(); 131 doInitSymbols<ELF32BE>(); 132 doInitSymbols<ELF64LE>(); 133 doInitSymbols<ELF64BE>(); 134 } 135 136 template int SymbolBody::compare<ELF32LE>(SymbolBody *Other); 137 template int SymbolBody::compare<ELF32BE>(SymbolBody *Other); 138 template int SymbolBody::compare<ELF64LE>(SymbolBody *Other); 139 template int SymbolBody::compare<ELF64BE>(SymbolBody *Other); 140 141 template class elf2::UndefinedElf<ELF32LE>; 142 template class elf2::UndefinedElf<ELF32BE>; 143 template class elf2::UndefinedElf<ELF64LE>; 144 template class elf2::UndefinedElf<ELF64BE>; 145 146 template class elf2::DefinedSynthetic<ELF32LE>; 147 template class elf2::DefinedSynthetic<ELF32BE>; 148 template class elf2::DefinedSynthetic<ELF64LE>; 149 template class elf2::DefinedSynthetic<ELF64BE>; 150