[ELF] Revert "Also demote lazy symbols."

This reverts commit https://reviews.llvm.org/rL330869
for a regression to link Android dex2oatds.

Differential Revision: https://reviews.llvm.org/D51892

llvm-svn: 342007
This commit is contained in:
Chih-Hung Hsieh
2018-09-11 23:00:36 +00:00
parent f21e8ebb91
commit 73e04847bf
5 changed files with 41 additions and 30 deletions

View File

@@ -1231,33 +1231,19 @@ template <class ELFT> static void handleLibcall(StringRef Name) {
Symtab->fetchLazy<ELFT>(Sym);
}
template <class ELFT> static bool shouldDemote(Symbol &Sym) {
// If all references to a DSO happen to be weak, the DSO is not added to
// DT_NEEDED. If that happens, we need to eliminate shared symbols created
// from the DSO. Otherwise, they become dangling references that point to a
// non-existent DSO.
if (auto *S = dyn_cast<SharedSymbol>(&Sym))
return !S->getFile<ELFT>().IsNeeded;
// We are done processing archives, so lazy symbols that were used but not
// found can be converted to undefined. We could also just delete the other
// lazy symbols, but that seems to be more work than it is worth.
return Sym.isLazy() && Sym.IsUsedInRegularObj;
}
// Some files, such as .so or files between -{start,end}-lib may be removed
// after their symbols are added to the symbol table. If that happens, we
// need to remove symbols that refer files that no longer exist, so that
// they won't appear in the symbol table of the output file.
//
// We remove symbols by demoting them to undefined symbol.
template <class ELFT> static void demoteSymbols() {
// If all references to a DSO happen to be weak, the DSO is not added
// to DT_NEEDED. If that happens, we need to eliminate shared symbols
// created from the DSO. Otherwise, they become dangling references
// that point to a non-existent DSO.
template <class ELFT> static void demoteSharedSymbols() {
for (Symbol *Sym : Symtab->getSymbols()) {
if (shouldDemote<ELFT>(*Sym)) {
bool Used = Sym->Used;
replaceSymbol<Undefined>(Sym, nullptr, Sym->getName(), Sym->Binding,
Sym->StOther, Sym->Type);
Sym->Used = Used;
if (auto *S = dyn_cast<SharedSymbol>(Sym)) {
if (!S->getFile<ELFT>().IsNeeded) {
bool Used = S->Used;
replaceSymbol<Undefined>(S, nullptr, S->getName(), STB_WEAK, S->StOther,
S->Type);
S->Used = Used;
}
}
}
}
@@ -1592,7 +1578,7 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &Args) {
decompressSections();
splitSections<ELFT>();
markLive<ELFT>();
demoteSymbols<ELFT>();
demoteSharedSymbols<ELFT>();
mergeSections();
if (Config->ICF != ICFLevel::None) {
findKeepUniqueSections<ELFT>(Args);

View File

@@ -103,7 +103,8 @@ static uint64_t getSymVA(const Symbol &Sym, int64_t &Addend) {
return 0;
case Symbol::LazyArchiveKind:
case Symbol::LazyObjectKind:
llvm_unreachable("lazy symbol reached writer");
assert(Sym.IsUsedInRegularObj && "lazy symbol reached writer");
return 0;
}
llvm_unreachable("invalid symbol kind");
}

View File

@@ -128,8 +128,12 @@ public:
return SymbolKind == LazyArchiveKind || SymbolKind == LazyObjectKind;
}
// True if this is an undefined weak symbol.
bool isUndefWeak() const { return isWeak() && isUndefined(); }
// True if this is an undefined weak symbol. This only works once
// all input files have been added.
bool isUndefWeak() const {
// See comment on lazy symbols for details.
return isWeak() && (isUndefined() || isLazy());
}
StringRef getName() const {
if (NameSize == (uint32_t)-1)

View File

@@ -0,0 +1,11 @@
.section .gnu.linkonce.t.__i686.get_pc_thunk.bx
.global __i686.get_pc_thunk.bx
__i686.get_pc_thunk.bx:
mov (%esp),%ebx
ret
.section .text
.global _strchr1
_strchr1:
call __i686.get_pc_thunk.bx
ret

View File

@@ -0,0 +1,9 @@
// REQUIRES: x86
// RUN: llvm-mc -filetype=obj -triple=i386-linux-gnu %s -o %t.o
// RUN: llvm-mc -filetype=obj -triple=i386-linux-gnu %p/Inputs/i386-linkonce.s -o %t2.o
// RUN: llvm-ar rcs %t2.a %t2.o
// RUN: ld.lld %t.o %t2.a -o %t
.globl _start
_start:
call _strchr1