From e78431354bcb6bec5be9adf4ea37d860445f8c16 Mon Sep 17 00:00:00 2001 From: Saleem Abdulrasool Date: Thu, 4 Jun 2020 17:40:41 -0700 Subject: [PATCH] lld: use modern library search ordering This merges the static and shared library and behaves as if `-search_paths_first` was specified which is also the default behaviour on ld64 (and now lld). Unify the paths, and use `llvm::sys::path` to deal with the path to be truly agnostic to the host. --- lld/MachO/Driver.cpp | 32 ++++++++++------------ lld/test/MachO/link-search-order.s | 43 ++++++++++++++++++++++++++++++ 2 files changed, 57 insertions(+), 18 deletions(-) create mode 100644 lld/test/MachO/link-search-order.s diff --git a/lld/MachO/Driver.cpp b/lld/MachO/Driver.cpp index 723c62c39185..e0ebf8e5710f 100644 --- a/lld/MachO/Driver.cpp +++ b/lld/MachO/Driver.cpp @@ -73,21 +73,18 @@ opt::InputArgList MachOOptTable::parse(ArrayRef argv) { return args; } -// This is for -lfoo. We'll look for libfoo.dylib from search paths. -static Optional findDylib(StringRef name) { - for (StringRef dir : config->searchPaths) { - std::string path = (dir + "/lib" + name + ".dylib").str(); - if (fs::exists(path)) - return path; - } - return None; -} +static Optional findLibrary(StringRef name) { + std::string shared = (llvm::Twine("lib") + name + ".dylib").str(); + std::string archive = (llvm::Twine("lib") + name + ".a").str(); + llvm::SmallString<260> location; -static Optional findArchive(StringRef name) { for (StringRef dir : config->searchPaths) { - std::string path = (dir + "/lib" + name + ".a").str(); - if (fs::exists(path)) - return path; + for (StringRef library : {shared, archive}) { + location = dir; + llvm::sys::path::append(location, library); + if (fs::exists(location)) + return location.str().str(); + } } return None; } @@ -296,12 +293,11 @@ bool macho::link(llvm::ArrayRef argsArr, bool canExitEarly, break; case OPT_l: { StringRef name = arg->getValue(); - if (Optional path = findDylib(name)) + if (Optional path = findLibrary(name)) { addFile(*path); - else if (Optional path = findArchive(name)) - addFile(*path); - else - error("library not found for -l" + name); + break; + } + error("library not found for -l" + name); break; } case OPT_platform_version: { diff --git a/lld/test/MachO/link-search-order.s b/lld/test/MachO/link-search-order.s new file mode 100644 index 000000000000..289293a8cb47 --- /dev/null +++ b/lld/test/MachO/link-search-order.s @@ -0,0 +1,43 @@ +# REQUIRES: x86 + +# RUN: mkdir -p %t +# +# RUN: llvm-mc -filetype obj -triple x86_64-apple-darwin %p/Inputs/libhello.s -o %t/hello.o +# RUN: lld -flavor darwinnew -dylib -install_name @executable_path/libhello.dylib %t/hello.o -o %t/libhello.dylib +# +# RUN: llvm-mc -filetype obj -triple x86_64-apple-darwin %p/Inputs/libgoodbye.s -o %t/goodbye.o +# RUN: lld -flavor darwinnew -dylib -install_name @executable_path/libgoodbye.dylib %t/goodbye.o -o %t/libgoodbye.dylib +# RUN: llvm-ar --format=darwin crs %t/libgoodbye.a %t/goodbye.o +# +# RUN: llvm-mc -filetype obj -triple x86_64-apple-darwin %s -o %t/test.o +# RUN: lld -flavor darwinnew -o %t/test -Z -L%t -lhello -lgoodbye %t/test.o +# +# RUN: llvm-objdump --macho --dylibs-used %t/test | FileCheck %s + +# CHECK: @executable_path/libhello.dylib +# CHECK: @executable_path/libgoodbye.dylib +# CHECK: /usr/lib/libSystem.B.dylib + +.section __TEXT,__text +.global _main + +_main: + movl $0x2000004, %eax # write() + mov $1, %rdi # stdout + movq _hello_world@GOTPCREL(%rip), %rsi + mov $13, %rdx # length + syscall + + movl $0x2000004, %eax # write() + mov $1, %rdi # stdout + movq _hello_its_me@GOTPCREL(%rip), %rsi + mov $15, %rdx # length + syscall + + movl $0x2000004, %eax # write() + mov $1, %rdi # stdout + movq _goodbye_world@GOTPCREL(%rip), %rsi + mov $15, %rdx # length + syscall + mov $0, %rax + ret