diff --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp index 83a3788e0dc6..8487210eb6e1 100644 --- a/lld/ELF/InputFiles.cpp +++ b/lld/ELF/InputFiles.cpp @@ -1262,7 +1262,7 @@ void ArchiveFile::fetch(const Archive::Symbol &sym) { // // 2) Consider the tentative definition as still undefined (ie the promotion to // a real definition happens only after all symbol resolution is done). -// The linker searches archive members for global or weak definitions to +// The linker searches archive members for STB_GLOBAL definitions to // replace the tentative definition with. This is the behavior used by // GNU ld. // @@ -1278,7 +1278,7 @@ static bool isBitcodeNonCommonDef(MemoryBufferRef mb, StringRef symName, for (const irsymtab::Reader::SymbolRef &sym : symtabFile.TheReader.symbols()) { if (sym.isGlobal() && sym.getName() == symName) - return !sym.isUndefined() && !sym.isCommon(); + return !sym.isUndefined() && !sym.isWeak() && !sym.isCommon(); } return false; } @@ -1292,7 +1292,8 @@ static bool isNonCommonDef(MemoryBufferRef mb, StringRef symName, for (auto sym : obj->template getGlobalELFSyms()) { Expected name = sym.getName(stringtable); if (name && name.get() == symName) - return sym.isDefined() && !sym.isCommon(); + return sym.isDefined() && sym.getBinding() == STB_GLOBAL && + !sym.isCommon(); } return false; } diff --git a/lld/test/ELF/common-archive-lookup.s b/lld/test/ELF/common-archive-lookup.s index efaad669b724..bbfadb448f2d 100644 --- a/lld/test/ELF/common-archive-lookup.s +++ b/lld/test/ELF/common-archive-lookup.s @@ -20,6 +20,7 @@ ## Bitcode files. # RUN: llvm-as -o 1.bc commonblock.ll # RUN: llvm-as -o 2.bc blockdata.ll +# RUN: llvm-as -o 3.bc weak.ll ## Bitcode archive. # RUN: llvm-ar crs 4.a 1.bc 2.bc @@ -31,10 +32,10 @@ # RUN: llvm-objdump -D -j .data 2 | FileCheck --check-prefix=TEST1 %s # RUN: ld.lld -o 3 main.o 2.a -# RUN: llvm-objdump -D -j .data 3 | FileCheck --check-prefix=TEST1 %s +# RUN: llvm-objdump -t 3 | FileCheck --check-prefix=BSS %s # RUN: ld.lld -o 4 main.o --start-lib 1.o weak_data_only.o --end-lib -# RUN: llvm-objdump -D -j .data 4 | FileCheck --check-prefix=TEST1 %s +# RUN: llvm-objdump -t 4 | FileCheck --check-prefix=BSS %s # RUN: ld.lld -o 5 main.o 3.a --print-map | FileCheck --check-prefix=MAP %s @@ -63,6 +64,9 @@ # RUN: ld.lld -o - main.o --start-lib 1.bc 2.bc --end-lib --lto-emit-asm | \ # RUN: FileCheck --check-prefix=ASM %s +## COMMON overrides weak. Don't extract 3.bc which provides a weak definition. +# RUN: ld.lld -o /dev/null main.o --start-lib 1.bc 3.bc --end-lib -y block | FileCheck --check-prefix=LTO_WEAK %s + ## Old FORTRAN that mixes use of COMMON blocks and BLOCK DATA requires that we ## search through archives for non-tentative definitions (from the BLOCK DATA) ## to replace the tentative definitions (from the COMMON block(s)). @@ -75,6 +79,7 @@ # TEST1-NEXT: fb 21 09 40 # TEST1-NEXT: ... +# BSS: [[#%x,]] g O .bss 0000000000000028 block # NFC: Name: block # NFC-NEXT: Value: @@ -100,6 +105,10 @@ # ASM-NEXT: .long 5 # ASM: .size block, 20 +# LTO_WEAK: 1.bc: common definition of block +# LTO_WEAK: : reference to block +# LTO_WEAK-NOT: {{.}} + #--- ref.s .text .abiversion 2 @@ -167,6 +176,12 @@ target triple = "powerpc64le-unknown-linux-gnu" @block = dso_local local_unnamed_addr global [5 x i32] [i32 5, i32 0, i32 0, i32 0, i32 0], align 4 +#--- weak.ll +target datalayout = "e-m:e-i64:64-n32:64-S128-v256:256:256-v512:512:512" +target triple = "powerpc64le-unknown-linux-gnu" + +@block = weak dso_local global [5 x i32] [i32 5, i32 0, i32 0, i32 0, i32 0], align 4 + #--- commonblock.ll target datalayout = "e-m:e-i64:64-n32:64-S128-v256:256:256-v512:512:512" target triple = "powerpc64le-unknown-linux-gnu"