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 #include "llvm/Config/config.h" 17 18 #ifdef HAVE_CXXABI_H 19 #include <cxxabi.h> 20 #endif 21 22 using namespace llvm; 23 using namespace llvm::object; 24 using namespace llvm::ELF; 25 26 using namespace lld; 27 using namespace lld::elf2; 28 29 static uint8_t getMinVisibility(uint8_t VA, uint8_t VB) { 30 if (VA == STV_DEFAULT) 31 return VB; 32 if (VB == STV_DEFAULT) 33 return VA; 34 return std::min(VA, VB); 35 } 36 37 // Returns 1, 0 or -1 if this symbol should take precedence 38 // over the Other, tie or lose, respectively. 39 template <class ELFT> int SymbolBody::compare(SymbolBody *Other) { 40 typedef typename ELFFile<ELFT>::uintX_t uintX_t; 41 assert(!isLazy() && !Other->isLazy()); 42 std::tuple<bool, bool, bool> L(isDefined(), !isShared(), !isWeak()); 43 std::tuple<bool, bool, bool> R(Other->isDefined(), !Other->isShared(), 44 !Other->isWeak()); 45 46 // Normalize 47 if (L > R) 48 return -Other->compare<ELFT>(this); 49 50 Visibility = Other->Visibility = 51 getMinVisibility(Visibility, Other->Visibility); 52 53 if (IsUsedInRegularObj || Other->IsUsedInRegularObj) 54 IsUsedInRegularObj = Other->IsUsedInRegularObj = true; 55 56 // We want to export all symbols that exist both in the executable 57 // and in DSOs, so that the symbols in the executable can interrupt 58 // symbols in the DSO at runtime. 59 if (isShared() != Other->isShared()) 60 if (isa<DefinedRegular<ELFT>>(isShared() ? Other : this)) 61 IsUsedInDynamicReloc = Other->IsUsedInDynamicReloc = true; 62 63 if (L != R) 64 return -1; 65 if (!std::get<0>(L) || !std::get<1>(L) || !std::get<2>(L)) 66 return 1; 67 if (isCommon()) { 68 if (!Other->isCommon()) 69 return -1; 70 auto *ThisC = cast<DefinedCommon>(this); 71 auto *OtherC = cast<DefinedCommon>(Other); 72 uintX_t Align = std::max(ThisC->MaxAlignment, OtherC->MaxAlignment); 73 if (ThisC->Size >= OtherC->Size) { 74 ThisC->MaxAlignment = Align; 75 return 1; 76 } 77 OtherC->MaxAlignment = Align; 78 return -1; 79 } 80 if (Other->isCommon()) 81 return 1; 82 return 0; 83 } 84 85 Defined::Defined(Kind K, StringRef Name, bool IsWeak, uint8_t Visibility, 86 bool IsTls) 87 : SymbolBody(K, Name, IsWeak, Visibility, IsTls) {} 88 89 Undefined::Undefined(SymbolBody::Kind K, StringRef N, bool IsWeak, 90 uint8_t Visibility, bool IsTls) 91 : SymbolBody(K, N, IsWeak, Visibility, IsTls), CanKeepUndefined(false) {} 92 93 Undefined::Undefined(StringRef N, bool IsWeak, uint8_t Visibility, 94 bool CanKeepUndefined) 95 : Undefined(SymbolBody::UndefinedKind, N, IsWeak, Visibility, 96 /*IsTls*/ false) { 97 this->CanKeepUndefined = CanKeepUndefined; 98 } 99 100 template <typename ELFT> 101 UndefinedElf<ELFT>::UndefinedElf(StringRef N, const Elf_Sym &Sym) 102 : Undefined(SymbolBody::UndefinedElfKind, N, 103 Sym.getBinding() == llvm::ELF::STB_WEAK, Sym.getVisibility(), 104 Sym.getType() == llvm::ELF::STT_TLS), 105 Sym(Sym) {} 106 107 template <typename ELFT> 108 DefinedSynthetic<ELFT>::DefinedSynthetic(StringRef N, uintX_t Value, 109 OutputSectionBase<ELFT> &Section) 110 : Defined(SymbolBody::DefinedSyntheticKind, N, false, STV_DEFAULT, false), 111 Value(Value), Section(Section) {} 112 113 DefinedCommon::DefinedCommon(StringRef N, uint64_t Size, uint64_t Alignment, 114 bool IsWeak, uint8_t Visibility) 115 : Defined(SymbolBody::DefinedCommonKind, N, IsWeak, Visibility, false) { 116 MaxAlignment = Alignment; 117 this->Size = Size; 118 } 119 120 std::unique_ptr<InputFile> Lazy::getMember() { 121 MemoryBufferRef MBRef = File->getMember(&Sym); 122 123 // getMember returns an empty buffer if the member was already 124 // read from the library. 125 if (MBRef.getBuffer().empty()) 126 return std::unique_ptr<InputFile>(nullptr); 127 return createObjectFile(MBRef); 128 } 129 130 template <class ELFT> static void doInitSymbols() { 131 ElfSym<ELFT>::End.setBinding(STB_GLOBAL); 132 ElfSym<ELFT>::Ignored.setBinding(STB_WEAK); 133 ElfSym<ELFT>::Ignored.setVisibility(STV_HIDDEN); 134 } 135 136 void elf2::initSymbols() { 137 doInitSymbols<ELF32LE>(); 138 doInitSymbols<ELF32BE>(); 139 doInitSymbols<ELF64LE>(); 140 doInitSymbols<ELF64BE>(); 141 } 142 143 // Returns the demangled C++ symbol name for Name. 144 std::string elf2::demangle(StringRef Name) { 145 #if !defined(HAVE_CXXABI_H) 146 return Name; 147 #else 148 if (!Config->Demangle) 149 return Name; 150 151 // __cxa_demangle can be used to demangle strings other than symbol 152 // names which do not necessarily start with "_Z". Name can be 153 // either a C or C++ symbol. Don't call __cxa_demangle if the name 154 // does not look like a C++ symbol name to avoid getting unexpected 155 // result for a C symbol that happens to match a mangled type name. 156 if (!Name.startswith("_Z")) 157 return Name; 158 159 char *Buf = 160 abi::__cxa_demangle(Name.str().c_str(), nullptr, nullptr, nullptr); 161 if (!Buf) 162 return Name; 163 std::string S(Buf); 164 free(Buf); 165 return S; 166 #endif 167 } 168 169 template int SymbolBody::compare<ELF32LE>(SymbolBody *Other); 170 template int SymbolBody::compare<ELF32BE>(SymbolBody *Other); 171 template int SymbolBody::compare<ELF64LE>(SymbolBody *Other); 172 template int SymbolBody::compare<ELF64BE>(SymbolBody *Other); 173 174 template class elf2::UndefinedElf<ELF32LE>; 175 template class elf2::UndefinedElf<ELF32BE>; 176 template class elf2::UndefinedElf<ELF64LE>; 177 template class elf2::UndefinedElf<ELF64BE>; 178 179 template class elf2::DefinedSynthetic<ELF32LE>; 180 template class elf2::DefinedSynthetic<ELF32BE>; 181 template class elf2::DefinedSynthetic<ELF64LE>; 182 template class elf2::DefinedSynthetic<ELF64BE>; 183