From 5d3feefa0df9c054f6d683ca13316a822b596f87 Mon Sep 17 00:00:00 2001 From: Jez Ng Date: Wed, 29 Apr 2020 05:30:47 -0700 Subject: [PATCH] [lld-macho] Dylib symbols should always replace undefined symbols Summary: Otherwise we get undefined symbol errors depending on the order of arguments on the command line. Depends on D78270. Reviewers: ruiu, pcc, MaskRay, smeenai, alexshap, gkm, Ktwu, christylee Subscribers: llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D79114 --- lld/MachO/SymbolTable.cpp | 2 +- lld/test/MachO/resolution.s | 44 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+), 1 deletion(-) create mode 100644 lld/test/MachO/resolution.s diff --git a/lld/MachO/SymbolTable.cpp b/lld/MachO/SymbolTable.cpp index 41446d6..6e1d977 100644 --- a/lld/MachO/SymbolTable.cpp +++ b/lld/MachO/SymbolTable.cpp @@ -64,7 +64,7 @@ Symbol *SymbolTable::addDylib(StringRef name, DylibFile *file) { bool wasInserted; std::tie(s, wasInserted) = insert(name); - if (wasInserted) + if (wasInserted || isa(s)) replaceSymbol(s, file, name); return s; } diff --git a/lld/test/MachO/resolution.s b/lld/test/MachO/resolution.s new file mode 100644 index 0000000..a13bb52 --- /dev/null +++ b/lld/test/MachO/resolution.s @@ -0,0 +1,44 @@ +# REQUIRES: x86 +# RUN: mkdir -p %t +# RUN: echo '.globl _foo, _bar, _baz; _foo: _bar: _baz:' | \ +# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin -o %t/libresolution.o +# RUN: lld -flavor darwinnew -dylib -install_name \ +# RUN: @executable_path/libresolution.dylib %t/libresolution.o -o %t/libresolution.dylib +# RUN: lld -flavor darwinnew -dylib -install_name \ +# RUN: @executable_path/libresolution2.dylib %t/libresolution.o -o %t/libresolution2.dylib +# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin %s -o %t/resolution.o + +## Check that we select the symbol defined in the first dylib passed on the +## command line. +# RUN: lld -flavor darwinnew -o %t/dylib-first -Z -L%t -lresolution -lresolution2 %t/resolution.o +# RUN: llvm-objdump --macho --bind %t/dylib-first | FileCheck %s --check-prefix=DYLIB-FIRST +# DYLIB-FIRST: libresolution _foo + +# RUN: lld -flavor darwinnew -o %t/dylib2-first -Z -L%t -lresolution2 -lresolution %t/resolution.o +# RUN: llvm-objdump --macho --bind %t/dylib2-first | FileCheck %s --check-prefix=DYLIB2-FIRST +# DYLIB2-FIRST: libresolution2 _foo + +## Also check that defined symbols take precedence over dylib symbols. +# DYLIB-FIRST-NOT: libresolution _bar +# DYLIB-FIRST-NOT: libresolution _baz + +## Check that we pick the dylib symbol over the undefined symbol in the object +## file, even if the object file appears first on the command line. +# RUN: lld -flavor darwinnew -o %t/obj-first -Z -L%t %t/resolution.o -lresolution +# RUN: llvm-objdump --macho --bind %t/obj-first | FileCheck %s --check-prefix=OBJ-FIRST +# OBJ-FIRST: libresolution _foo +## But defined symbols should still take precedence. +# OBJ-FIRST-NOT: libresolution _bar +# OBJ-FIRST-NOT: libresolution _baz + +.globl _main, _bar +# Global defined symbol +_bar: +# Local defined symbol +_baz: + +_main: + movq _foo@GOTPCREL(%rip), %rsi + movq _bar@GOTPCREL(%rip), %rsi + movq _baz@GOTPCREL(%rip), %rsi + ret -- 2.7.4