[ELF] Set `referenced` bit of Undefined created by BitcodeFile

D64136 and D65584, while fixing STB_WEAK issues and improving our
compatibility with ld.bfd, can cause another STB_WEAK problem related to
LTO:

If %tundef.o has an undefined reference on f,
and %tweakundef.o has a weak undefined reference on f,
%tdef.o has a definition of f

```
ld.lld %tundef.o %tweakundef.o --start-lib %tdef.o --end-lib
```

1) `%tundef.o` doesn't set the `referenced` bit.
2) `%weakundef.o` changes the binding from STB_GLOBAL to STB_WEAK
3) `%tdef.o` is not fetched because the binding is weak.

Step (1) is incorrect. This patch sets the `referenced` bit of Undefined
created by bitcode files.

Reviewed By: ruiu

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

llvm-svn: 370437
This commit is contained in:
Fangrui Song 2019-08-30 07:10:30 +00:00
parent 3d3a9b3b41
commit 688183ec54
3 changed files with 30 additions and 1 deletions

View File

@ -1478,7 +1478,9 @@ static Symbol *createBitcodeSymbol(const std::vector<bool> &keptComdats,
Undefined newSym(&f, name, binding, visibility, type);
if (canOmitFromDynSym)
newSym.exportDynamic = false;
return symtab->addSymbol(newSym);
Symbol *ret = symtab->addSymbol(newSym);
ret->referenced = true;
return ret;
}
if (objSym.isCommon())

View File

@ -0,0 +1,4 @@
target triple = "x86_64-unknown-linux-gnu"
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
declare void @foo()

View File

@ -0,0 +1,23 @@
; REQUIRES: x86
; RUN: llvm-as %S/Inputs/undef.ll -o %tundef.o
; RUN: llvm-as %s -o %tweakundef.o
; RUN: llvm-as %S/Inputs/archive-3.ll -o %tdef.o
;; Test that the lazy bitcode %tdef.o is fetched.
; RUN: ld.lld %tundef.o --start-lib %tdef.o --end-lib -shared -o %t.so
; RUN: llvm-nm %t.so | FileCheck %s
;; Test %tweakundef.o does not change STB_GLOBAL to STB_WEAK.
; RUN: ld.lld %tundef.o %tweakundef.o --start-lib %tdef.o --end-lib -shared -o %t.so
; RUN: llvm-nm %t.so | FileCheck %s
;; %tweakundef.o does not fetch %tdef.o but %tundef.o does.
; RUN: ld.lld --start-lib %tdef.o --end-lib %tweakundef.o %tundef.o -shared -o %t.so
; RUN: llvm-nm %t.so | FileCheck %s
; CHECK: T foo
target triple = "x86_64-unknown-linux-gnu"
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
declare extern_weak void @foo()