Index: lld/trunk/ELF/InputFiles.cpp =================================================================== --- lld/trunk/ELF/InputFiles.cpp +++ lld/trunk/ELF/InputFiles.cpp @@ -316,7 +316,8 @@ InputSectionBase *Sec = getSection(*Sym); if (Binding == STB_LOCAL) { if (Sym->st_shndx == SHN_UNDEF) - return new (Alloc) UndefinedElf(*Sym); + return new (Alloc) + Undefined(Sym->st_name, Sym->st_other, Sym->getType(), Sym->st_size); return new (Alloc) DefinedRegular(*Sym, Sec); } @@ -324,7 +325,9 @@ switch (Sym->st_shndx) { case SHN_UNDEF: - return new (Alloc) UndefinedElf(Name, *Sym); + return new (Alloc) + Undefined(Name, Binding, Sym->st_other, Sym->getType(), Sym->st_size, + /*IsBitcode*/ false); case SHN_COMMON: return new (Alloc) DefinedCommon(Name, Sym->st_size, Sym->st_value, Binding, Sym->st_other, Sym->getType()); @@ -337,7 +340,9 @@ case STB_WEAK: case STB_GNU_UNIQUE: if (Sec == &InputSection::Discarded) - return new (Alloc) UndefinedElf(Name, *Sym); + return new (Alloc) + Undefined(Name, Binding, Sym->st_other, Sym->getType(), Sym->st_size, + /*IsBitcode*/ false); return new (Alloc) DefinedRegular(Name, *Sym, Sec); } } @@ -470,6 +475,7 @@ uint32_t Flags = Sym.getFlags(); bool IsWeak = Flags & BasicSymbolRef::SF_Weak; + uint32_t Binding = IsWeak ? STB_WEAK : STB_GLOBAL; uint8_t Visibility; if (GV) @@ -482,23 +488,23 @@ if (GV) if (const Comdat *C = GV->getComdat()) if (!KeptComdats.count(C)) { - Body = new (Alloc) - UndefinedBitcode(NameRef, IsWeak, Visibility); + Body = new (Alloc) Undefined(NameRef, Binding, Visibility, /*Type*/ 0, + /*Size*/ 0, /*IsBitcode*/ true); return Body; } const Module &M = Obj.getModule(); if (Flags & BasicSymbolRef::SF_Undefined) - return new (Alloc) UndefinedBitcode(NameRef, IsWeak, Visibility); + return new (Alloc) Undefined(NameRef, Binding, Visibility, /*Type*/ 0, + /*Size*/ 0, /*IsBitcode*/ true); if (Flags & BasicSymbolRef::SF_Common) { // FIXME: Set SF_Common flag correctly for module asm symbols, and expose // size and alignment. assert(GV); const DataLayout &DL = M.getDataLayout(); uint64_t Size = DL.getTypeAllocSize(GV->getValueType()); - return new (Alloc) - DefinedCommon(NameRef, Size, GV->getAlignment(), - IsWeak ? STB_WEAK : STB_GLOBAL, Visibility, /*Type*/ 0); + return new (Alloc) DefinedCommon(NameRef, Size, GV->getAlignment(), Binding, + Visibility, /*Type*/ 0); } return new (Alloc) DefinedBitcode(NameRef, IsWeak, Visibility); } Index: lld/trunk/ELF/OutputSections.cpp =================================================================== --- lld/trunk/ELF/OutputSections.cpp +++ lld/trunk/ELF/OutputSections.cpp @@ -1503,8 +1503,7 @@ if (cast>(Sym)->needsCopy()) return Out::Bss; break; - case SymbolBody::UndefinedElfKind: - case SymbolBody::UndefinedBitcodeKind: + case SymbolBody::UndefinedKind: case SymbolBody::LazyArchiveKind: case SymbolBody::LazyObjectKind: break; Index: lld/trunk/ELF/SymbolTable.cpp =================================================================== --- lld/trunk/ELF/SymbolTable.cpp +++ lld/trunk/ELF/SymbolTable.cpp @@ -151,7 +151,8 @@ template SymbolBody *SymbolTable::addUndefined(StringRef Name) { auto *Sym = new (Alloc) - UndefinedElf(Name, STB_GLOBAL, STV_DEFAULT, /*Type*/ 0); + Undefined(Name, STB_GLOBAL, STV_DEFAULT, /*Type*/ 0, /*Size*/ 0, + /*IsBitcode*/ false); resolve(Sym); return Sym; } @@ -314,7 +315,7 @@ if (K == SymbolBody::DefinedRegularKind || K == SymbolBody::DefinedCommonKind || K == SymbolBody::DefinedSyntheticKind || - K == SymbolBody::UndefinedElfKind) + (K == SymbolBody::UndefinedKind && !New->IsUndefinedBitcode)) Sym->IsUsedInRegularObj = true; return Sym; } Index: lld/trunk/ELF/Symbols.h =================================================================== --- lld/trunk/ELF/Symbols.h +++ lld/trunk/ELF/Symbols.h @@ -90,8 +90,7 @@ DefinedBitcodeKind, DefinedSyntheticKind, DefinedLast = DefinedSyntheticKind, - UndefinedElfKind, - UndefinedBitcodeKind, + UndefinedKind, LazyArchiveKind, LazyObjectKind, }; @@ -99,9 +98,7 @@ Kind kind() const { return static_cast(SymbolKind); } bool isWeak() const { return Binding == llvm::ELF::STB_WEAK; } - bool isUndefined() const { - return SymbolKind == UndefinedBitcodeKind || SymbolKind == UndefinedElfKind; - } + bool isUndefined() const { return SymbolKind == UndefinedKind; } bool isDefined() const { return SymbolKind <= DefinedLast; } bool isCommon() const { return SymbolKind == DefinedCommonKind; } bool isLazy() const { @@ -177,6 +174,11 @@ // symbol or if the symbol should point to its plt entry. unsigned NeedsCopyOrPltAddr : 1; + // True if the symbol is undefined and comes from a bitcode file. We need to + // keep track of this because undefined symbols only prevent internalization + // of bitcode symbols if they did not come from a bitcode file. + unsigned IsUndefinedBitcode : 1; + // The following fields have the same meaning as the ELF symbol attributes. uint8_t Type; // symbol type uint8_t Binding; // symbol binding @@ -307,28 +309,16 @@ const OutputSectionBase &Section; }; -class UndefinedBitcode : public SymbolBody { +class Undefined : public SymbolBody { public: - UndefinedBitcode(StringRef N, bool IsWeak, uint8_t StOther); + Undefined(StringRef Name, uint8_t Binding, uint8_t StOther, uint8_t Type, + uint64_t Size, bool IsBitcode); + Undefined(uint32_t NameOffset, uint8_t StOther, uint8_t Type, uint64_t Size); - static bool classof(const SymbolBody *S) { - return S->kind() == UndefinedBitcodeKind; - } -}; - -template class UndefinedElf : public SymbolBody { - typedef typename ELFT::uint uintX_t; - typedef typename ELFT::Sym Elf_Sym; - -public: - UndefinedElf(StringRef N, const Elf_Sym &Sym); - UndefinedElf(const Elf_Sym &Sym); - UndefinedElf(StringRef Name, uint8_t Binding, uint8_t StOther, uint8_t Type); - - uintX_t Size; + uint64_t Size; static bool classof(const SymbolBody *S) { - return S->kind() == SymbolBody::UndefinedElfKind; + return S->kind() == UndefinedKind; } }; Index: lld/trunk/ELF/Symbols.cpp =================================================================== --- lld/trunk/ELF/Symbols.cpp +++ lld/trunk/ELF/Symbols.cpp @@ -75,8 +75,7 @@ return Body.getPltVA(); return Out::Bss->getVA() + SS.OffsetInBss; } - case SymbolBody::UndefinedElfKind: - case SymbolBody::UndefinedBitcodeKind: + case SymbolBody::UndefinedKind: return 0; case SymbolBody::LazyArchiveKind: case SymbolBody::LazyObjectKind: @@ -175,7 +174,7 @@ return DR->Size; if (const auto *S = dyn_cast>(this)) return S->Sym.st_size; - if (const auto *U = dyn_cast>(this)) + if (const auto *U = dyn_cast(this)) return U->Size; return 0; } @@ -232,27 +231,18 @@ return S->kind() == DefinedBitcodeKind; } -UndefinedBitcode::UndefinedBitcode(StringRef N, bool IsWeak, uint8_t StOther) - : SymbolBody(SymbolBody::UndefinedBitcodeKind, N, - IsWeak ? STB_WEAK : STB_GLOBAL, StOther, 0 /* Type */) {} - -template -UndefinedElf::UndefinedElf(StringRef N, const Elf_Sym &Sym) - : SymbolBody(SymbolBody::UndefinedElfKind, N, Sym.getBinding(), - Sym.st_other, Sym.getType()), - Size(Sym.st_size) {} - -template -UndefinedElf::UndefinedElf(StringRef Name, uint8_t Binding, - uint8_t StOther, uint8_t Type) - : SymbolBody(SymbolBody::UndefinedElfKind, Name, Binding, StOther, Type) {} +Undefined::Undefined(StringRef Name, uint8_t Binding, uint8_t StOther, + uint8_t Type, uint64_t Size, bool IsBitcode) + : SymbolBody(SymbolBody::UndefinedKind, Name, Binding, StOther, Type), + Size(Size) { + this->IsUndefinedBitcode = IsBitcode; +} -template -UndefinedElf::UndefinedElf(const Elf_Sym &Sym) - : SymbolBody(SymbolBody::UndefinedElfKind, Sym.st_name, Sym.st_other, - Sym.getType()), - Size(Sym.st_size) { - assert(Sym.getBinding() == STB_LOCAL); +Undefined::Undefined(uint32_t NameOffset, uint8_t StOther, uint8_t Type, + uint64_t Size) + : SymbolBody(SymbolBody::UndefinedKind, NameOffset, StOther, Type), + Size(Size) { + this->IsUndefinedBitcode = false; } template @@ -360,11 +350,6 @@ template uint64_t SymbolBody::template getThunkVA() const; template uint64_t SymbolBody::template getThunkVA() const; -template class elf::UndefinedElf; -template class elf::UndefinedElf; -template class elf::UndefinedElf; -template class elf::UndefinedElf; - template class elf::DefinedSynthetic; template class elf::DefinedSynthetic; template class elf::DefinedSynthetic;