diff --git a/lld/MachO/SymbolTable.cpp b/lld/MachO/SymbolTable.cpp --- a/lld/MachO/SymbolTable.cpp +++ b/lld/MachO/SymbolTable.cpp @@ -62,28 +62,32 @@ if (!wasInserted) { if (auto *defined = dyn_cast(s)) { if (isWeakDef) { + + // See further comment in createDefined() in InputFiles.cpp if (defined->isWeakDef()) { - // Both old and new symbol weak (e.g. inline function in two TUs): - // If one of them isn't private extern, the merged symbol isn't. defined->privateExtern &= isPrivateExtern; defined->referencedDynamically |= isReferencedDynamically; defined->noDeadStrip |= noDeadStrip; - - // FIXME: Handle this for bitcode files. - // FIXME: We currently only do this if both symbols are weak. - // We could do this if either is weak (but getting the - // case where !isWeakDef && defined->isWeakDef() right - // requires some care and testing). - if (auto concatIsec = dyn_cast_or_null(isec)) - concatIsec->wasCoalesced = true; } - + // FIXME: Handle this for bitcode files. + if (auto concatIsec = dyn_cast_or_null(isec)) + concatIsec->wasCoalesced = true; return defined; } - if (!defined->isWeakDef()) + + if (defined->isWeakDef()) { + // FIXME: Handle this for bitcode files. + if (auto concatIsec = + dyn_cast_or_null(defined->isec)) { + concatIsec->wasCoalesced = true; + concatIsec->symbols.erase(llvm::find(concatIsec->symbols, defined)); + } + } else { error("duplicate symbol: " + name + "\n>>> defined in " + toString(defined->getFile()) + "\n>>> defined in " + toString(file)); + } + } else if (auto *dysym = dyn_cast(s)) { overridesWeakDef = !isWeakDef && dysym->isWeakDef(); dysym->unreference(); diff --git a/lld/test/MachO/dup-symbols-weak-def.s b/lld/test/MachO/dup-symbols-weak-def.s new file mode 100644 --- /dev/null +++ b/lld/test/MachO/dup-symbols-weak-def.s @@ -0,0 +1,47 @@ +# REQUIRES: x86 +# RUN: rm -rf %t; split-file %s %t + +# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-macos %t/lib_def.s -o %t/lib_def.o +# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-macos %t/lib_weak.s -o %t/lib_weak.o +# RUN: %lld -dylib -lSystem -dynamic %t/lib_def.o %t/lib_weak.o -o %t/out.dylib +# RUN: llvm-objdump --macho --syms %t/out.dylib | FileCheck %s + +# CHECK: SYMBOL TABLE: +# CHECK-NEXT: 0{{.*}} g F __TEXT,__text _foo + +#--- lib_def.s +.section __TEXT,__text,regular,pure_instructions + +.globl _foo + +_foo: + .cfi_startproc + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset %rbp, -16 + movq %rsp, %rbp + .cfi_def_cfa_register %rbp + popq %rbp + retq + .cfi_endproc + +.subsections_via_symbols + +#--- lib_weak.s +.section __TEXT,__text,regular,pure_instructions + +.globl _foo +.weak_definition _foo + +_foo: + .cfi_startproc + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset %rbp, -16 + movq %rsp, %rbp + .cfi_def_cfa_register %rbp + popq %rbp + retq + .cfi_endproc + +.subsections_via_symbols diff --git a/lld/test/MachO/weak-definition-gc.s b/lld/test/MachO/weak-definition-gc.s --- a/lld/test/MachO/weak-definition-gc.s +++ b/lld/test/MachO/weak-definition-gc.s @@ -66,6 +66,25 @@ # ALIGN-NEXT: {{0*}}[[#ADDR]] 11111111 33333333 22222222 00000000 # ALIGN-NEXT: {{0*}}[[#ADDR+0x10]] 81818181 81818181 82828282 82828282 +# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin19.0.0 %t/weak-def.s -o %t/weak-def.o +# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin19.0.0 %t/strong-def.s -o %t/strong-def.o +# RUN: %lld -dylib -lc++ -o %t/weak-strong-mixed.dylib %t/weak-def.o %t/strong-def.o +# RUN: %lld -dylib -lc++ -o %t/strong-weak-mixed.dylib %t/strong-def.o %t/weak-def.o +## Check that omitted weak symbols are not adding their section and unwind stuff. + +# RUN: otool -jtV %t/weak-strong-mixed.dylib | FileCheck --check-prefix=MIXED %s +# RUN: otool -jtV %t/strong-weak-mixed.dylib | FileCheck --check-prefix=MIXED %s +# MIXED: (__TEXT,__text) section +# MIXED-NEXT: _foo: +# MIXED-NEXT: {{.+}} 3333 xorl (%rbx), %esi +# MIXED-NEXT: {{.+}} 3333 xorl (%rbx), %esi +# MIXED-NEXT: {{.+}} c3 retq + +# RUN: llvm-objdump --macho --syms --unwind-info %t/weak-strong-mixed.dylib | FileCheck --check-prefix=MIXED-UNWIND %s +# RUN: llvm-objdump --macho --syms --unwind-info %t/strong-weak-mixed.dylib | FileCheck --check-prefix=MIXED-UNWIND %s +# MIXED-UNWIND: g F __TEXT,__text _foo +# MIXED-UNWIND-NOT: Contents of __unwind_info section: + #--- weak-sub.s .globl _foo, _bar .weak_definition _foo, _bar @@ -195,3 +214,35 @@ retq .subsections_via_symbols + +#--- weak-def.s +.section __TEXT,__text,regular,pure_instructions + +.globl _foo +.weak_definition _foo +_foo: + .cfi_startproc + .cfi_personality 155, ___gxx_personality_v0 + .cfi_lsda 16, Lexception + pushq %rbp + .cfi_def_cfa_offset 128 + .cfi_offset %rbp, 48 + movq %rsp, %rbp + .cfi_def_cfa_register %rbp + popq %rbp + retq + .cfi_endproc + +.section __TEXT,__gcc_except_tab +Lexception: + .space 0x10 + +.subsections_via_symbols +#--- strong-def.s +.globl _foo, _bar + +_foo: + .4byte 0x33333333 + retq + +.subsections_via_symbols