diff --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp index 95d55f70cce6..e0ed1623a11a 100644 --- a/lld/ELF/SyntheticSections.cpp +++ b/lld/ELF/SyntheticSections.cpp @@ -1608,7 +1608,7 @@ void GnuHashTableSection::addSymbols(std::vector &V) { // its type correctly. std::vector::iterator Mid = std::stable_partition(V.begin(), V.end(), [](const SymbolTableEntry &S) { - return S.Symbol->isUndefined(); + return S.Symbol->isUndefined() || S.Symbol->isLazy(); }); if (Mid == V.end()) return; diff --git a/lld/test/ELF/gnu-hash-table.s b/lld/test/ELF/gnu-hash-table.s index 759ee0a53a3e..6e322a4a6cc6 100644 --- a/lld/test/ELF/gnu-hash-table.s +++ b/lld/test/ELF/gnu-hash-table.s @@ -6,10 +6,29 @@ # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t-x86_64.o # RUN: llvm-mc -filetype=obj -triple=powerpc64-pc-linux %s -o %t-ppc64.o +# RUN: echo ".global zed; zed:" > %t2.s +# RUN: llvm-mc -filetype=obj -triple=i386-pc-linux %t2.s -o %t2-i386.o +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %t2.s -o %t2-x86_64.o +# RUN: llvm-mc -filetype=obj -triple=powerpc64-pc-linux %t2.s -o %t2-ppc64.o + +# RUN: rm -f %t2-i386.a %t2-x86_64.a %t2-ppc64.a +# RUN: llvm-ar rc %t2-i386.a %t2-i386.o +# RUN: llvm-ar rc %t2-x86_64.a %t2-x86_64.o +# RUN: llvm-ar rc %t2-ppc64.a %t2-ppc64.o + +# RUN: echo ".global xyz; xyz:" > %t3.s +# RUN: llvm-mc -filetype=obj -triple=i386-pc-linux %t3.s -o %t3-i386.o +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %t3.s -o %t3-x86_64.o +# RUN: llvm-mc -filetype=obj -triple=powerpc64-pc-linux %t3.s -o %t3-ppc64.o + +# RUN: ld.lld -shared %t3-i386.o -o %t3-i386.so +# RUN: ld.lld -shared %t3-x86_64.o -o %t3-x86_64.so +# RUN: ld.lld -shared %t3-ppc64.o -o %t3-ppc64.so + # RUN: ld.lld -shared --hash-style=gnu -o %te-i386.so %te-i386.o -# RUN: ld.lld -shared -hash-style=gnu -o %t-i386.so %t-i386.o -# RUN: ld.lld -shared -hash-style=gnu -o %t-x86_64.so %t-x86_64.o -# RUN: ld.lld -shared --hash-style both -o %t-ppc64.so %t-ppc64.o +# RUN: ld.lld -shared -hash-style=gnu -o %t-i386.so %t-i386.o %t2-i386.a %t3-i386.so +# RUN: ld.lld -shared -hash-style=gnu -o %t-x86_64.so %t-x86_64.o %t2-x86_64.a %t3-x86_64.so +# RUN: ld.lld -shared --hash-style both -o %t-ppc64.so %t-ppc64.o %t2-ppc64.a %t3-ppc64.so # RUN: llvm-readobj -dyn-symbols -gnu-hash-table %te-i386.so \ # RUN: | FileCheck %s -check-prefix=EMPTY @@ -52,7 +71,7 @@ # I386-NEXT: ] # I386-NEXT: Address: # I386-NEXT: Offset: -# I386-NEXT: Size: 32 +# I386-NEXT: Size: 44 # I386-NEXT: Link: # I386-NEXT: Info: 0 # I386-NEXT: AddressAlignment: 4 @@ -70,6 +89,11 @@ # I386: Section: Undefined # I386: } # I386: Symbol { +# I386: Name: zed@ +# I386: Binding: Weak +# I386: Section: Undefined +# I386: } +# I386: Symbol { # I386: Name: bar@ # I386: Binding: Global # I386: Section: .text @@ -79,15 +103,20 @@ # I386: Binding: Global # I386: Section: .text # I386: } +# I386: Symbol { +# I386: Name: xyz@ +# I386: Binding: Global +# I386: Section: Undefined +# I386: } # I386: ] # I386: GnuHashTable { -# I386-NEXT: Num Buckets: 1 -# I386-NEXT: First Hashed Symbol Index: 2 +# I386-NEXT: Num Buckets: 3 +# I386-NEXT: First Hashed Symbol Index: 3 # I386-NEXT: Num Mask Words: 1 # I386-NEXT: Shift Count: 5 -# I386-NEXT: Bloom Filter: [0x14000220] -# I386-NEXT: Buckets: [2] -# I386-NEXT: Values: [0xB8860BA, 0xB887389] +# I386-NEXT: Bloom Filter: [0x14010A20] +# I386-NEXT: Buckets: [3, 0, 5] +# I386-NEXT: Values: [0xB8860BA, 0xB887389, 0xB88C171] # I386-NEXT: } # X86_64: Format: ELF64-x86-64 @@ -101,7 +130,7 @@ # X86_64-NEXT: ] # X86_64-NEXT: Address: # X86_64-NEXT: Offset: -# X86_64-NEXT: Size: 36 +# X86_64-NEXT: Size: 48 # X86_64-NEXT: Link: # X86_64-NEXT: Info: 0 # X86_64-NEXT: AddressAlignment: 8 @@ -120,6 +149,11 @@ # X86_64: Section: Undefined # X86_64: } # X86_64: Symbol { +# X86_64: Name: zed@ +# X86_64: Binding: Weak +# X86_64: Section: Undefined +# X86_64: } +# X86_64: Symbol { # X86_64: Name: bar@ # X86_64: Binding: Global # X86_64: Section: .text @@ -129,15 +163,20 @@ # X86_64: Binding: Global # X86_64: Section: .text # X86_64: } +# X86_64: Symbol { +# X86_64: Name: xyz@ +# X86_64: Binding: Global +# X86_64: Section: Undefined +# X86_64: } # X86_64: ] # X86_64: GnuHashTable { -# X86_64-NEXT: Num Buckets: 1 -# X86_64-NEXT: First Hashed Symbol Index: 2 +# X86_64-NEXT: Num Buckets: 3 +# X86_64-NEXT: First Hashed Symbol Index: 3 # X86_64-NEXT: Num Mask Words: 1 # X86_64-NEXT: Shift Count: 6 -# X86_64-NEXT: Bloom Filter: [0x400000000004204] -# X86_64-NEXT: Buckets: [2] -# X86_64-NEXT: Values: [0xB8860BA, 0xB887389] +# X86_64-NEXT: Bloom Filter: [0x401000000004224] +# X86_64-NEXT: Buckets: [3, 0, 5] +# X86_64-NEXT: Values: [0xB8860BA, 0xB887389, 0xB88C171] # X86_64-NEXT: } # PPC64: Format: ELF64-ppc64 @@ -151,7 +190,7 @@ # PPC64-NEXT: ] # PPC64-NEXT: Address: # PPC64-NEXT: Offset: -# PPC64-NEXT: Size: 36 +# PPC64-NEXT: Size: 48 # PPC64-NEXT: Link: # PPC64-NEXT: Info: 0 # PPC64-NEXT: AddressAlignment: 8 @@ -170,6 +209,11 @@ # PPC64: Section: Undefined # PPC64: } # PPC64: Symbol { +# PPC64: Name: zed@ +# PPC64: Binding: Weak +# PPC64: Section: Undefined +# PPC64: } +# PPC64: Symbol { # PPC64: Name: bar@ # PPC64: Binding: Global # PPC64: Section: .text @@ -179,17 +223,24 @@ # PPC64: Binding: Global # PPC64: Section: .text # PPC64: } +# PPC64: Symbol { +# PPC64: Name: xyz@ +# PPC64: Binding: Global +# PPC64: Section: Undefined +# PPC64: } # PPC64: ] # PPC64: GnuHashTable { -# PPC64-NEXT: Num Buckets: 1 -# PPC64-NEXT: First Hashed Symbol Index: 2 +# PPC64-NEXT: Num Buckets: 3 +# PPC64-NEXT: First Hashed Symbol Index: 3 # PPC64-NEXT: Num Mask Words: 1 # PPC64-NEXT: Shift Count: 6 -# PPC64-NEXT: Bloom Filter: [0x400000000004204] -# PPC64-NEXT: Buckets: [2] -# PPC64-NEXT: Values: [0xB8860BA, 0xB887389] +# PPC64-NEXT: Bloom Filter: [0x401000000004224] +# PPC64-NEXT: Buckets: [3, 0, 5] +# PPC64-NEXT: Values: [0xB8860BA, 0xB887389, 0xB88C171] # PPC64-NEXT: } .globl foo,bar,baz foo: bar: +.weak zed +.global xyz