From b4ead2c37bcbb1f81919c68e2a2a227aac90f07c Mon Sep 17 00:00:00 2001 From: Nico Weber Date: Mon, 17 May 2021 13:49:17 -0400 Subject: [PATCH] [lld/mac] Correctly set nextdefsym In LC_DYSYMTAB, private externs were still emitted as exported symbols instead of as locals. Fixes PR50373. See bug for details. Differential Revision: https://reviews.llvm.org/D102662 --- lld/MachO/SyntheticSections.cpp | 5 +- lld/test/MachO/symtab.s | 82 +++++++++++++++++++++++++-------- 2 files changed, 67 insertions(+), 20 deletions(-) diff --git a/lld/MachO/SyntheticSections.cpp b/lld/MachO/SyntheticSections.cpp index 38c93e1f8f96..f0070fe48e69 100644 --- a/lld/MachO/SyntheticSections.cpp +++ b/lld/MachO/SyntheticSections.cpp @@ -753,7 +753,10 @@ void SymtabSection::finalizeContents() { if (!defined->includeInSymtab) continue; assert(defined->isExternal()); - addSymbol(externalSymbols, defined); + if (defined->privateExtern) + addSymbol(localSymbols, defined); + else + addSymbol(externalSymbols, defined); } else if (auto *dysym = dyn_cast(sym)) { if (dysym->isReferenced()) addSymbol(undefinedSymbols, sym); diff --git a/lld/test/MachO/symtab.s b/lld/test/MachO/symtab.s index 2a23b3fb77f2..a2232c93f9ff 100644 --- a/lld/test/MachO/symtab.s +++ b/lld/test/MachO/symtab.s @@ -1,9 +1,10 @@ # REQUIRES: x86 # RUN: rm -rf %t && split-file %s %t # RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin %t/test.s -o %t/test.o +# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin %t/test2.s -o %t/test2.o # RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin %t/libfoo.s -o %t/libfoo.o # RUN: %lld -dylib %t/libfoo.o -o %t/libfoo.dylib -# RUN: %lld -lSystem %t/test.o %t/libfoo.dylib -o %t/test +# RUN: %lld -lSystem %t/test.o %t/test2.o %t/libfoo.dylib -o %t/test # RUN: llvm-readobj --syms --macho-dysymtab %t/test | FileCheck %s # CHECK: Symbols [ @@ -26,6 +27,26 @@ # CHECK-NEXT: Value: 0x1{{[0-9a-f]*}} # CHECK-NEXT: } # CHECK-NEXT: Symbol { +# CHECK-NEXT: Name: _private_external +# CHECK-NEXT: PrivateExtern +# CHECK-NEXT: Type: Section (0xE) +# CHECK-NEXT: Section: __text (0x1) +# CHECK-NEXT: RefType: UndefinedNonLazy (0x0) +# CHECK-NEXT: Flags [ (0x0) +# CHECK-NEXT: ] +# CHECK-NEXT: Value: 0x1{{[0-9a-f]*}} +# CHECK-NEXT: } +# CHECK-NEXT: Symbol { +# CHECK-NEXT: Name: _private_external_weak +# CHECK-NEXT: PrivateExtern +# CHECK-NEXT: Type: Section (0xE) +# CHECK-NEXT: Section: __text (0x1) +# CHECK-NEXT: RefType: UndefinedNonLazy (0x0) +# CHECK-NEXT: Flags [ (0x0) +# CHECK-NEXT: ] +# CHECK-NEXT: Value: 0x1{{[0-9a-f]*}} +# CHECK-NEXT: } +# CHECK-NEXT: Symbol { # CHECK-NEXT: Name: _main # CHECK-NEXT: Extern # CHECK-NEXT: Type: Section (0xE) @@ -56,17 +77,17 @@ # CHECK-NEXT: ] # CHECK-NEXT: Value: 0x1{{[0-9a-f]*}} # CHECK-NEXT: } -# CHECK-NEXT: Symbol { -# CHECK-NEXT: Name: __mh_execute_header (81) -# CHECK-NEXT: Extern -# CHECK-NEXT: Type: Section (0xE) -# CHECK-NEXT: Section: __text (0x1) -# CHECK-NEXT: RefType: UndefinedNonLazy (0x0) -# CHECK-NEXT: Flags [ (0x10) -# CHECK-NEXT: ReferencedDynamically (0x10) -# CHECK-NEXT: ] -# CHECK-NEXT: Value: 0x100000000 -# CHECK-NEXT: } +# CHECK-NEXT: Symbol { +# CHECK-NEXT: Name: __mh_execute_header +# CHECK-NEXT: Extern +# CHECK-NEXT: Type: Section (0xE) +# CHECK-NEXT: Section: __text (0x1) +# CHECK-NEXT: RefType: UndefinedNonLazy (0x0) +# CHECK-NEXT: Flags [ (0x10) +# CHECK-NEXT: ReferencedDynamically (0x10) +# CHECK-NEXT: ] +# CHECK-NEXT: Value: 0x100000000 +# CHECK-NEXT: } # CHECK-NEXT: Symbol { # CHECK-NEXT: Name: dyld_stub_binder # CHECK-NEXT: Extern @@ -92,10 +113,10 @@ # CHECK-NEXT: ] # CHECK-NEXT: Dysymtab { # CHECK-NEXT: ilocalsym: 0 -# CHECK-NEXT: nlocalsym: 2 -# CHECK-NEXT: iextdefsym: 2 +# CHECK-NEXT: nlocalsym: 4 +# CHECK-NEXT: iextdefsym: 4 # CHECK-NEXT: nextdefsym: 4 -# CHECK-NEXT: iundefsym: 6 +# CHECK-NEXT: iundefsym: 8 # CHECK-NEXT: nundefsym: 2 ## Verify that the first entry in the StringTable is a space, and that @@ -110,20 +131,43 @@ _dynamic: #--- test.s -.globl _main, _external, _external_weak, _unreferenced +.globl _main, _external, _private_external, _external_weak, _private_external_weak, _unreferenced .data _external: - .space 0 + .space 1 _local: - .space 0 + .space 1 .text .weak_definition _external_weak _external_weak: - .space 0 + .space 1 + +.private_extern _private_external +_private_external: + .space 1 + +.weak_definition _private_external_weak +.private_extern _private_external_weak +_private_external_weak: + .space 1 _main: + callq _private_external callq _dynamic mov $0, %rax ret + +#--- test2.s +## These are both already in test.s and should make it into the symbol table +## just once. +.globl _external_weak, _private_external_weak +.text +.weak_definition _external_weak +_external_weak: + .space 1 +.weak_definition _private_external_weak +.private_extern _private_external_weak +_private_external_weak: + .space 1