diff --git a/lld/MachO/Arch/X86_64.cpp b/lld/MachO/Arch/X86_64.cpp --- a/lld/MachO/Arch/X86_64.cpp +++ b/lld/MachO/Arch/X86_64.cpp @@ -221,7 +221,7 @@ const InputSection *isec, const Reloc &r) { switch (r.type) { case X86_64_RELOC_GOT_LOAD: { - if (sym->isWeakDef() || isa(sym)) + if (needsBinding(sym)) in.got->addEntry(sym); if (sym->isTlv()) @@ -275,7 +275,7 @@ // TODO: warn if they refer to a weak global break; case X86_64_RELOC_TLV: { - if (sym->isWeakDef() || isa(sym)) + if (needsBinding(sym)) in.tlvPointers->addEntry(sym); if (!sym->isTlv()) diff --git a/lld/MachO/SyntheticSections.h b/lld/MachO/SyntheticSections.h --- a/lld/MachO/SyntheticSections.h +++ b/lld/MachO/SyntheticSections.h @@ -234,6 +234,9 @@ SmallVector contents; }; +// Whether a given symbol's address can only be resolved at runtime. +bool needsBinding(const Symbol *); + // Add bindings for symbols that need weak or non-lazy bindings. void addNonLazyBindingEntries(const Symbol *, SectionPointerUnion, uint64_t offset, int64_t addend = 0); diff --git a/lld/MachO/SyntheticSections.cpp b/lld/MachO/SyntheticSections.cpp --- a/lld/MachO/SyntheticSections.cpp +++ b/lld/MachO/SyntheticSections.cpp @@ -266,6 +266,16 @@ memcpy(buf, contents.data(), contents.size()); } +bool macho::needsBinding(const Symbol *sym) { + if (isa(sym)) { + return true; + } else if (const auto *defined = dyn_cast(sym)) { + if (defined->isWeakDef() && defined->isExternal()) + return true; + } + return false; +} + void macho::addNonLazyBindingEntries(const Symbol *sym, SectionPointerUnion section, uint64_t offset, int64_t addend) { diff --git a/lld/test/MachO/weak-binding.s b/lld/test/MachO/weak-binding.s --- a/lld/test/MachO/weak-binding.s +++ b/lld/test/MachO/weak-binding.s @@ -21,9 +21,10 @@ # CHECK: <_main>: # CHECK-NEXT: movq [[#]](%rip), %rax # [[#%X,WEAK_DY_GOT_ADDR:]] # CHECK-NEXT: movq [[#]](%rip), %rax # [[#%X,WEAK_EXT_GOT_ADDR:]] +# CHECK-NEXT: leaq [[#]](%rip), %rax # [[#%X,WEAK_INT_GOT_ADDR:]] # CHECK-NEXT: movq [[#]](%rip), %rax # [[#%X,WEAK_TLV_ADDR:]] # CHECK-NEXT: movq [[#]](%rip), %rax # [[#%X,WEAK_DY_TLV_ADDR:]] -# CHECK-NEXT: movq [[#]](%rip), %rax # [[#%X,WEAK_INT_TLV_ADDR:]] +# CHECK-NEXT: leaq [[#]](%rip), %rax # [[#%X,WEAK_INT_TLV_ADDR:]] # CHECK-NEXT: callq 0x{{[0-9a-f]*}} # CHECK-NEXT: callq 0x{{[0-9a-f]*}} # CHECK-NEXT: callq 0x{{[0-9a-f]*}} @@ -86,11 +87,12 @@ #--- test.s .globl _main, _weak_external, _weak_external_for_gotpcrel, _weak_external_fn -.weak_definition _weak_external, _weak_external_for_gotpcrel, _weak_external_fn, _weak_internal, _weak_internal_fn +.weak_definition _weak_external, _weak_external_for_gotpcrel, _weak_external_fn, _weak_internal, _weak_internal_for_gotpcrel, _weak_internal_fn _main: mov _weak_dysym_for_gotpcrel@GOTPCREL(%rip), %rax mov _weak_external_for_gotpcrel@GOTPCREL(%rip), %rax + mov _weak_internal_for_gotpcrel@GOTPCREL(%rip), %rax mov _weak_tlv@TLVP(%rip), %rax mov _weak_dysym_tlv@TLVP(%rip), %rax mov _weak_internal_tlv@TLVP(%rip), %rax @@ -112,6 +114,9 @@ _weak_internal: .quad 0x1234 +_weak_internal_for_gotpcrel: + .quad 0x1234 + _weak_internal_fn: ret