Vendor import of lld release_40 branch r292732:
https://llvm.org/svn/llvm-project/lld/branches/release_40@292732
This commit is contained in:
parent
1eafc0458f
commit
abe21bdf8e
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/vendor/lld/dist/; revision=312632 svn path=/vendor/lld/lld-release_40-r292951/; revision=312711; tag=vendor/lld/lld-release_40-r292951
@ -140,7 +140,7 @@ template <class ELFT>
|
||||
DefinedRegular<ELFT> *SymbolTable<ELFT>::addIgnored(StringRef Name,
|
||||
uint8_t Visibility) {
|
||||
SymbolBody *S = find(Name);
|
||||
if (!S || !S->isUndefined())
|
||||
if (!S || S->isInCurrentDSO())
|
||||
return nullptr;
|
||||
return addAbsolute(Name, Visibility);
|
||||
}
|
||||
@ -283,7 +283,7 @@ static int compareDefined(Symbol *S, bool WasInserted, uint8_t Binding) {
|
||||
if (WasInserted)
|
||||
return 1;
|
||||
SymbolBody *Body = S->body();
|
||||
if (Body->isLazy() || Body->isUndefined() || Body->isShared())
|
||||
if (Body->isLazy() || !Body->isInCurrentDSO())
|
||||
return 1;
|
||||
if (Binding == STB_WEAK)
|
||||
return -1;
|
||||
@ -426,12 +426,8 @@ void SymbolTable<ELFT>::addShared(SharedFile<ELFT> *F, StringRef Name,
|
||||
std::tie(S, WasInserted) =
|
||||
insert(Name, Sym.getType(), STV_DEFAULT, /*CanOmitFromDynSym*/ true, F);
|
||||
// Make sure we preempt DSO symbols with default visibility.
|
||||
if (Sym.getVisibility() == STV_DEFAULT) {
|
||||
if (Sym.getVisibility() == STV_DEFAULT)
|
||||
S->ExportDynamic = true;
|
||||
// Exporting preempting symbols takes precedence over linker scripts.
|
||||
if (S->VersionId == VER_NDX_LOCAL)
|
||||
S->VersionId = VER_NDX_GLOBAL;
|
||||
}
|
||||
if (WasInserted || isa<Undefined<ELFT>>(S->body())) {
|
||||
replaceBody<SharedSymbol<ELFT>>(S, F, Name, Sym, Verdef);
|
||||
if (!S->isWeak())
|
||||
@ -467,6 +463,14 @@ template <class ELFT> SymbolBody *SymbolTable<ELFT>::find(StringRef Name) {
|
||||
return SymVector[V.Idx]->body();
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
SymbolBody *SymbolTable<ELFT>::findInCurrentDSO(StringRef Name) {
|
||||
if (SymbolBody *S = find(Name))
|
||||
if (S->isInCurrentDSO())
|
||||
return S;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
void SymbolTable<ELFT>::addLazyArchive(ArchiveFile *F,
|
||||
const object::Archive::Symbol Sym) {
|
||||
|
@ -82,6 +82,7 @@ template <class ELFT> class SymbolTable {
|
||||
void scanVersionScript();
|
||||
|
||||
SymbolBody *find(StringRef Name);
|
||||
SymbolBody *findInCurrentDSO(StringRef Name);
|
||||
|
||||
void trace(StringRef Name);
|
||||
void wrap(StringRef Name);
|
||||
|
@ -203,8 +203,8 @@ void SymbolBody::parseSymbolVersion() {
|
||||
// Truncate the symbol name so that it doesn't include the version string.
|
||||
Name = {S.data(), Pos};
|
||||
|
||||
// If this is an undefined or shared symbol it is not a definition.
|
||||
if (isUndefined() || isShared())
|
||||
// If this is not in this DSO, it is not a definition.
|
||||
if (!isInCurrentDSO())
|
||||
return;
|
||||
|
||||
// '@@' in a symbol name means the default version.
|
||||
@ -299,7 +299,8 @@ uint8_t Symbol::computeBinding() const {
|
||||
return Binding;
|
||||
if (Visibility != STV_DEFAULT && Visibility != STV_PROTECTED)
|
||||
return STB_LOCAL;
|
||||
if (VersionId == VER_NDX_LOCAL && !body()->isUndefined())
|
||||
const SymbolBody *Body = body();
|
||||
if (VersionId == VER_NDX_LOCAL && Body->isInCurrentDSO())
|
||||
return STB_LOCAL;
|
||||
if (Config->NoGnuUnique && Binding == STB_GNU_UNIQUE)
|
||||
return STB_GLOBAL;
|
||||
|
@ -67,6 +67,7 @@ class SymbolBody {
|
||||
return SymbolKind == LazyArchiveKind || SymbolKind == LazyObjectKind;
|
||||
}
|
||||
bool isShared() const { return SymbolKind == SharedKind; }
|
||||
bool isInCurrentDSO() const { return !isUndefined() && !isShared(); }
|
||||
bool isLocal() const { return IsLocal; }
|
||||
bool isPreemptible() const;
|
||||
StringRef getName() const { return Name; }
|
||||
|
@ -883,9 +883,9 @@ template <class ELFT> void DynamicSection<ELFT>::finalize() {
|
||||
add({DT_FINI_ARRAYSZ, Out<ELFT>::FiniArray, Entry::SecSize});
|
||||
}
|
||||
|
||||
if (SymbolBody *B = Symtab<ELFT>::X->find(Config->Init))
|
||||
if (SymbolBody *B = Symtab<ELFT>::X->findInCurrentDSO(Config->Init))
|
||||
add({DT_INIT, B});
|
||||
if (SymbolBody *B = Symtab<ELFT>::X->find(Config->Fini))
|
||||
if (SymbolBody *B = Symtab<ELFT>::X->findInCurrentDSO(Config->Fini))
|
||||
add({DT_FINI, B});
|
||||
|
||||
bool HasVerNeed = In<ELFT>::VerNeed->getNeedNum() != 0;
|
||||
|
@ -641,7 +641,7 @@ static void addOptionalSynthetic(StringRef Name, OutputSectionBase *Sec,
|
||||
typename ELFT::uint Val,
|
||||
uint8_t StOther = STV_HIDDEN) {
|
||||
if (SymbolBody *S = Symtab<ELFT>::X->find(Name))
|
||||
if (S->isUndefined() || S->isShared())
|
||||
if (!S->isInCurrentDSO())
|
||||
Symtab<ELFT>::X->addSynthetic(Name, Sec, Val, StOther);
|
||||
}
|
||||
|
||||
@ -661,7 +661,7 @@ static Symbol *addOptionalRegular(StringRef Name, InputSectionBase<ELFT> *IS,
|
||||
SymbolBody *S = Symtab<ELFT>::X->find(Name);
|
||||
if (!S)
|
||||
return nullptr;
|
||||
if (!S->isUndefined() && !S->isShared())
|
||||
if (S->isInCurrentDSO())
|
||||
return S->symbol();
|
||||
return addRegular(Name, IS, Value);
|
||||
}
|
||||
|
2
test/ELF/Inputs/resolution-end.s
Normal file
2
test/ELF/Inputs/resolution-end.s
Normal file
@ -0,0 +1,2 @@
|
||||
.data
|
||||
.quad _end
|
@ -19,15 +19,6 @@
|
||||
# CHECK-NEXT: Section: Undefined (0x0)
|
||||
# CHECK-NEXT: }
|
||||
# CHECK-NEXT: Symbol {
|
||||
# CHECK-NEXT: Name: bar
|
||||
# CHECK-NEXT: Value:
|
||||
# CHECK-NEXT: Size:
|
||||
# CHECK-NEXT: Binding: Global
|
||||
# CHECK-NEXT: Type:
|
||||
# CHECK-NEXT: Other:
|
||||
# CHECK-NEXT: Section: .text
|
||||
# CHECK-NEXT: }
|
||||
# CHECK-NEXT: Symbol {
|
||||
# CHECK-NEXT: Name: bar2
|
||||
# CHECK-NEXT: Value:
|
||||
# CHECK-NEXT: Size:
|
||||
|
@ -17,11 +17,22 @@
|
||||
// RUN: ld.lld -shared %t -o %t2 -init=_foo -fini=_bar
|
||||
// RUN: llvm-readobj -dynamic-table %t2 | FileCheck --check-prefix=OVR %s
|
||||
|
||||
// Should add a dynamic table entry even if a given symbol stay undefined
|
||||
// Don't add an entry for undef. The freebsd dynamic linker doesn't
|
||||
// check if the value is null. If it is, it will just call the
|
||||
// load address.
|
||||
// RUN: ld.lld -shared %t -o %t2 -init=_undef -fini=_undef
|
||||
// RUN: llvm-readobj -dynamic-table %t2 | FileCheck --check-prefix=UNDEF %s
|
||||
// UNDEF: INIT 0x0
|
||||
// UNDEF: FINI 0x0
|
||||
// UNDEF-NOT: INIT
|
||||
// UNDEF-NOT: FINI
|
||||
|
||||
// Don't add an entry for shared. For the same reason as undef.
|
||||
// RUN: ld.lld -shared %t -o %t.so
|
||||
// RUN: echo > %t.s
|
||||
// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %t.s -o %t2.o
|
||||
// RUN: ld.lld -shared %t2.o %t.so -o %t2
|
||||
// RUN: llvm-readobj -dynamic-table %t2 | FileCheck --check-prefix=SHARED %s
|
||||
// SHARED-NOT: INIT
|
||||
// SHARED-NOT: FINI
|
||||
|
||||
// Should not add new entries to the symbol table
|
||||
// and should not require given symbols to be resolved
|
||||
|
39
test/ELF/resolution-end.s
Normal file
39
test/ELF/resolution-end.s
Normal file
@ -0,0 +1,39 @@
|
||||
# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t1.o
|
||||
# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/resolution-end.s -o %t2.o
|
||||
# RUN: ld.lld -shared -o %t2.so %t2.o
|
||||
# RUN: ld.lld %t1.o %t2.so -o %t
|
||||
# RUN: llvm-readobj -t -s -section-data %t | FileCheck %s
|
||||
# REQUIRES: x86
|
||||
|
||||
# Test that we resolve _end to the this executable.
|
||||
|
||||
# CHECK: Name: .text
|
||||
# CHECK-NEXT: Type: SHT_PROGBITS
|
||||
# CHECK-NEXT: Flags [
|
||||
# CHECK-NEXT: SHF_ALLOC
|
||||
# CHECK-NEXT: SHF_EXECINSTR
|
||||
# CHECK-NEXT: ]
|
||||
# CHECK-NEXT: Address:
|
||||
# CHECK-NEXT: Offset:
|
||||
# CHECK-NEXT: Size:
|
||||
# CHECK-NEXT: Link:
|
||||
# CHECK-NEXT: Info:
|
||||
# CHECK-NEXT: AddressAlignment:
|
||||
# CHECK-NEXT: EntrySize:
|
||||
# CHECK-NEXT: SectionData (
|
||||
# CHECK-NEXT: 0000: 80202000 00000000
|
||||
# CHECK-NEXT: )
|
||||
|
||||
# CHECK: Symbol {
|
||||
# CHECK: Name: _end
|
||||
# CHECK-NEXT: Value: 0x202080
|
||||
# CHECK-NEXT: Size:
|
||||
# CHECK-NEXT: Binding: Global
|
||||
# CHECK-NEXT: Type:
|
||||
# CHECK-NEXT: Other:
|
||||
# CHECK-NEXT: Section:
|
||||
# CHECK-NEXT: }
|
||||
|
||||
.global _start
|
||||
_start:
|
||||
.quad _end
|
28
test/ELF/version-script-hide-so-symbol.s
Normal file
28
test/ELF/version-script-hide-so-symbol.s
Normal file
@ -0,0 +1,28 @@
|
||||
# REQUIRES: x86
|
||||
|
||||
# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
|
||||
# RUN: ld.lld -shared %t.o -o %t2.so
|
||||
# RUN: echo "{ local: *; };" > %t.script
|
||||
# RUN: ld.lld --version-script %t.script -shared %t.o %t2.so -o %t.so
|
||||
# RUN: llvm-readobj -dyn-symbols %t.so | FileCheck %s
|
||||
|
||||
# The symbol foo must be hidden. This matches bfd and gold and is
|
||||
# required to make it possible for a c++ library to hide its own
|
||||
# operator delete.
|
||||
|
||||
# CHECK: DynamicSymbols [
|
||||
# CHECK-NEXT: Symbol {
|
||||
# CHECK-NEXT: Name: @ (0)
|
||||
# CHECK-NEXT: Value: 0x0
|
||||
# CHECK-NEXT: Size: 0
|
||||
# CHECK-NEXT: Binding: Local
|
||||
# CHECK-NEXT: Type: None
|
||||
# CHECK-NEXT: Other: 0
|
||||
# CHECK-NEXT: Section: Undefined
|
||||
# CHECK-NEXT: }
|
||||
# CHECK-NEXT: ]
|
||||
|
||||
.global foo
|
||||
foo:
|
||||
nop
|
||||
|
Loading…
Reference in New Issue
Block a user