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 assert(!isLazy() && !Other->isLazy()); 36 std::pair<bool, bool> L(isDefined(), !isWeak()); 37 std::pair<bool, bool> R(Other->isDefined(), !Other->isWeak()); 38 39 // Normalize 40 if (L > R) 41 return -Other->compare<ELFT>(this); 42 43 Visibility = Other->Visibility = 44 getMinVisibility(Visibility, Other->Visibility); 45 46 if (IsUsedInRegularObj || Other->IsUsedInRegularObj) 47 IsUsedInRegularObj = Other->IsUsedInRegularObj = true; 48 49 if (L != R) 50 return -1; 51 if (!L.first || !L.second) 52 return 1; 53 if (isShared()) 54 return -1; 55 if (Other->isShared()) 56 return 1; 57 if (isCommon()) { 58 if (!Other->isCommon()) 59 return -1; 60 auto *ThisC = cast<DefinedCommon<ELFT>>(this); 61 auto *OtherC = cast<DefinedCommon<ELFT>>(Other); 62 typename DefinedCommon<ELFT>::uintX_t MaxAlign = 63 std::max(ThisC->MaxAlignment, OtherC->MaxAlignment); 64 if (ThisC->Sym.st_size >= OtherC->Sym.st_size) { 65 ThisC->MaxAlignment = MaxAlign; 66 return 1; 67 } 68 OtherC->MaxAlignment = MaxAlign; 69 return -1; 70 } 71 if (Other->isCommon()) 72 return 1; 73 return 0; 74 } 75 76 std::unique_ptr<InputFile> Lazy::getMember() { 77 MemoryBufferRef MBRef = File->getMember(&Sym); 78 79 // getMember returns an empty buffer if the member was already 80 // read from the library. 81 if (MBRef.getBuffer().empty()) 82 return std::unique_ptr<InputFile>(nullptr); 83 84 return createELFFile<ObjectFile>(MBRef); 85 } 86 87 template <class ELFT> static void doInitSymbols() { 88 DefinedAbsolute<ELFT>::IgnoreUndef.setBinding(STB_WEAK); 89 DefinedAbsolute<ELFT>::IgnoreUndef.setVisibility(STV_HIDDEN); 90 Undefined<ELFT>::Optional.setVisibility(STV_HIDDEN); 91 } 92 93 void lld::elf2::initSymbols() { 94 doInitSymbols<ELF32LE>(); 95 doInitSymbols<ELF32BE>(); 96 doInitSymbols<ELF64LE>(); 97 doInitSymbols<ELF64BE>(); 98 } 99 100 template int SymbolBody::compare<ELF32LE>(SymbolBody *Other); 101 template int SymbolBody::compare<ELF32BE>(SymbolBody *Other); 102 template int SymbolBody::compare<ELF64LE>(SymbolBody *Other); 103 template int SymbolBody::compare<ELF64BE>(SymbolBody *Other); 104