diff --git a/lld/MachO/Driver.cpp b/lld/MachO/Driver.cpp --- a/lld/MachO/Driver.cpp +++ b/lld/MachO/Driver.cpp @@ -1472,8 +1472,15 @@ StringRef symbolName = defined->getName(); if (config->exportedSymbols.match(symbolName)) { if (defined->privateExtern) { - warn("cannot export hidden symbol " + symbolName + - "\n>>> defined in " + toString(defined->getFile())); + // If it's a weak, it's not "hidden". + if (!defined->isWeakDef()) + warn("cannot export hidden symbol " + symbolName + + "\n>>> defined in " + toString(defined->getFile())); + else + // When a weakdef private extern symbol is exported, + // it becomes "non-private". + // This matches LD64's behavior. + defined->privateExtern = false; } } else { defined->privateExtern = true; diff --git a/lld/MachO/MarkLive.cpp b/lld/MachO/MarkLive.cpp --- a/lld/MachO/MarkLive.cpp +++ b/lld/MachO/MarkLive.cpp @@ -67,7 +67,7 @@ // FIXME: Instead of doing this here, maybe the Driver code doing // the matching should add them to explicitUndefineds? Then the // explicitUndefineds code below would handle this automatically. - assert(!defined->privateExtern && + assert((!defined->privateExtern || defined->isWeakDef()) && "should have been rejected by driver"); addSym(defined); continue; diff --git a/lld/test/MachO/exported-symbols.s b/lld/test/MachO/exported-symbols.s new file mode 100644 --- /dev/null +++ b/lld/test/MachO/exported-symbols.s @@ -0,0 +1,27 @@ +# REQUIRES: x86 + +# RUN: rm -rf %t && mkdir -p %t +# RUN: llvm-mc %s -triple=x86_64-apple-macos -filetype=obj -o %t/foo.o +# RUN: llvm-objdump --macho --syms %t/foo.o | FileCheck %s --check-prefix=PRE-CHECK + +# PRE-CHECK: SYMBOL TABLE: +# PRE-CHECK-NEXT w F __TEXT,__text __foo + +# RUN: %lld -exported_symbol "__foo" %t/foo.o -o %t/a.out +## Post link check that __foo was exported. +# RUN: llvm-nm %t/a.out | FileCheck %s --check-prefix=POST-CHECK +# POST-CHECK-DAG: T __foo +# POST-CHECK-DAG: t _main +.section __TEXT,__text,regular,pure_instructions + +.globl __foo, _main +.weak_def_can_be_hidden __foo +__foo: + pushq %rbp + popq %rbp + retq + + +_main: + callq __foo + retq