Symbols.cpp revision 293258
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 17using namespace llvm; 18using namespace llvm::object; 19using namespace llvm::ELF; 20 21using namespace lld; 22using namespace lld::elf2; 23 24static 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. 34template <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 76Defined::Defined(Kind K, StringRef Name, bool IsWeak, uint8_t Visibility, 77 bool IsTls) 78 : SymbolBody(K, Name, IsWeak, Visibility, IsTls) {} 79 80Undefined::Undefined(SymbolBody::Kind K, StringRef N, bool IsWeak, 81 uint8_t Visibility, bool IsTls) 82 : SymbolBody(K, N, IsWeak, Visibility, IsTls), CanKeepUndefined(false) {} 83 84Undefined::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 91template <typename ELFT> 92UndefinedElf<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 98template <typename ELFT> 99DefinedSynthetic<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 104DefinedCommon::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 111std::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 121template <class ELFT> static void doInitSymbols() { 122 ElfSym<ELFT>::End.setBinding(STB_GLOBAL); 123 ElfSym<ELFT>::IgnoreUndef.setBinding(STB_WEAK); 124 ElfSym<ELFT>::IgnoreUndef.setVisibility(STV_HIDDEN); 125} 126 127void lld::elf2::initSymbols() { 128 doInitSymbols<ELF32LE>(); 129 doInitSymbols<ELF32BE>(); 130 doInitSymbols<ELF64LE>(); 131 doInitSymbols<ELF64BE>(); 132} 133 134template int SymbolBody::compare<ELF32LE>(SymbolBody *Other); 135template int SymbolBody::compare<ELF32BE>(SymbolBody *Other); 136template int SymbolBody::compare<ELF64LE>(SymbolBody *Other); 137template int SymbolBody::compare<ELF64BE>(SymbolBody *Other); 138 139template class lld::elf2::UndefinedElf<ELF32LE>; 140template class lld::elf2::UndefinedElf<ELF32BE>; 141template class lld::elf2::UndefinedElf<ELF64LE>; 142template class lld::elf2::UndefinedElf<ELF64BE>; 143 144template class lld::elf2::DefinedSynthetic<ELF32LE>; 145template class lld::elf2::DefinedSynthetic<ELF32BE>; 146template class lld::elf2::DefinedSynthetic<ELF64LE>; 147template class lld::elf2::DefinedSynthetic<ELF64BE>; 148