Skip to content

Commit 7de2173

Browse files
committed
[ELF] --fortran-common: prefer STB_WEAK to COMMON
The ELF specification says "The link editor honors the common definition and ignores the weak ones." GNU ld and our Symbol::compare follow this, but the --fortran-common code (D86142) made a mistake on the precedence. Fixes https://bugs.llvm.org/show_bug.cgi?id=51082 Reviewed By: peter.smith, sfertile Differential Revision: https://reviews.llvm.org/D105945
1 parent 338314f commit 7de2173

File tree

2 files changed

+21
-5
lines changed

2 files changed

+21
-5
lines changed

lld/ELF/InputFiles.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1262,7 +1262,7 @@ void ArchiveFile::fetch(const Archive::Symbol &sym) {
12621262
//
12631263
// 2) Consider the tentative definition as still undefined (ie the promotion to
12641264
// a real definition happens only after all symbol resolution is done).
1265-
// The linker searches archive members for global or weak definitions to
1265+
// The linker searches archive members for STB_GLOBAL definitions to
12661266
// replace the tentative definition with. This is the behavior used by
12671267
// GNU ld.
12681268
//
@@ -1278,7 +1278,7 @@ static bool isBitcodeNonCommonDef(MemoryBufferRef mb, StringRef symName,
12781278
for (const irsymtab::Reader::SymbolRef &sym :
12791279
symtabFile.TheReader.symbols()) {
12801280
if (sym.isGlobal() && sym.getName() == symName)
1281-
return !sym.isUndefined() && !sym.isCommon();
1281+
return !sym.isUndefined() && !sym.isWeak() && !sym.isCommon();
12821282
}
12831283
return false;
12841284
}
@@ -1292,7 +1292,8 @@ static bool isNonCommonDef(MemoryBufferRef mb, StringRef symName,
12921292
for (auto sym : obj->template getGlobalELFSyms<ELFT>()) {
12931293
Expected<StringRef> name = sym.getName(stringtable);
12941294
if (name && name.get() == symName)
1295-
return sym.isDefined() && !sym.isCommon();
1295+
return sym.isDefined() && sym.getBinding() == STB_GLOBAL &&
1296+
!sym.isCommon();
12961297
}
12971298
return false;
12981299
}

lld/test/ELF/common-archive-lookup.s

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
## Bitcode files.
2121
# RUN: llvm-as -o 1.bc commonblock.ll
2222
# RUN: llvm-as -o 2.bc blockdata.ll
23+
# RUN: llvm-as -o 3.bc weak.ll
2324

2425
## Bitcode archive.
2526
# RUN: llvm-ar crs 4.a 1.bc 2.bc
@@ -31,10 +32,10 @@
3132
# RUN: llvm-objdump -D -j .data 2 | FileCheck --check-prefix=TEST1 %s
3233

3334
# RUN: ld.lld -o 3 main.o 2.a
34-
# RUN: llvm-objdump -D -j .data 3 | FileCheck --check-prefix=TEST1 %s
35+
# RUN: llvm-objdump -t 3 | FileCheck --check-prefix=BSS %s
3536

3637
# RUN: ld.lld -o 4 main.o --start-lib 1.o weak_data_only.o --end-lib
37-
# RUN: llvm-objdump -D -j .data 4 | FileCheck --check-prefix=TEST1 %s
38+
# RUN: llvm-objdump -t 4 | FileCheck --check-prefix=BSS %s
3839

3940
# RUN: ld.lld -o 5 main.o 3.a --print-map | FileCheck --check-prefix=MAP %s
4041

@@ -63,6 +64,9 @@
6364
# RUN: ld.lld -o - main.o --start-lib 1.bc 2.bc --end-lib --lto-emit-asm | \
6465
# RUN: FileCheck --check-prefix=ASM %s
6566

67+
## COMMON overrides weak. Don't extract 3.bc which provides a weak definition.
68+
# RUN: ld.lld -o /dev/null main.o --start-lib 1.bc 3.bc --end-lib -y block | FileCheck --check-prefix=LTO_WEAK %s
69+
6670
## Old FORTRAN that mixes use of COMMON blocks and BLOCK DATA requires that we
6771
## search through archives for non-tentative definitions (from the BLOCK DATA)
6872
## to replace the tentative definitions (from the COMMON block(s)).
@@ -75,6 +79,7 @@
7579
# TEST1-NEXT: fb 21 09 40
7680
# TEST1-NEXT: ...
7781

82+
# BSS: [[#%x,]] g O .bss 0000000000000028 block
7883

7984
# NFC: Name: block
8085
# NFC-NEXT: Value:
@@ -100,6 +105,10 @@
100105
# ASM-NEXT: .long 5
101106
# ASM: .size block, 20
102107

108+
# LTO_WEAK: 1.bc: common definition of block
109+
# LTO_WEAK: <internal>: reference to block
110+
# LTO_WEAK-NOT: {{.}}
111+
103112
#--- ref.s
104113
.text
105114
.abiversion 2
@@ -167,6 +176,12 @@ target triple = "powerpc64le-unknown-linux-gnu"
167176

168177
@block = dso_local local_unnamed_addr global [5 x i32] [i32 5, i32 0, i32 0, i32 0, i32 0], align 4
169178

179+
#--- weak.ll
180+
target datalayout = "e-m:e-i64:64-n32:64-S128-v256:256:256-v512:512:512"
181+
target triple = "powerpc64le-unknown-linux-gnu"
182+
183+
@block = weak dso_local global [5 x i32] [i32 5, i32 0, i32 0, i32 0, i32 0], align 4
184+
170185
#--- commonblock.ll
171186
target datalayout = "e-m:e-i64:64-n32:64-S128-v256:256:256-v512:512:512"
172187
target triple = "powerpc64le-unknown-linux-gnu"

0 commit comments

Comments
 (0)