mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-18 07:16:40 +00:00
[lld-macho] Ignore duplicate -rpath
entries (#99289)
Starting with Xcode 16 (dyld-1122), Apple's binary utilities, e.g. `dyld_info` (but not dyld itself), will refuse to load binaries built against the macOS 15 SDK or newer that contain the same `LC_RPATH` entry multiple times: https://github.com/apple-oss-distributions/dyld/blob/rel/dyld-1122/mach_o/Policy.cpp#L246-L249 `ld-prime` deduplicates entries (regardless of the deployment target), we now do the same. We also match `ld-prime`'s and `ld64`'s behavior by warning on duplicate `-rpath` arguments. This can be disabled by the LLD-specific `--no-warn-duplicate-rpath` flag.
This commit is contained in:
parent
474d35f238
commit
b1864a8d6a
@ -199,6 +199,7 @@ struct Configuration {
|
||||
std::vector<llvm::StringRef> systemLibraryRoots;
|
||||
std::vector<llvm::StringRef> librarySearchPaths;
|
||||
std::vector<llvm::StringRef> frameworkSearchPaths;
|
||||
bool warnDuplicateRpath = true;
|
||||
llvm::SmallVector<llvm::StringRef, 0> runtimePaths;
|
||||
std::vector<std::string> astPaths;
|
||||
std::vector<Symbol *> explicitUndefineds;
|
||||
|
@ -1402,6 +1402,19 @@ static void eraseInitializerSymbols() {
|
||||
sym->used = false;
|
||||
}
|
||||
|
||||
static SmallVector<StringRef, 0> getRuntimePaths(opt::InputArgList &args) {
|
||||
SmallVector<StringRef, 0> vals;
|
||||
DenseSet<StringRef> seen;
|
||||
for (const Arg *arg : args.filtered(OPT_rpath)) {
|
||||
StringRef val = arg->getValue();
|
||||
if (seen.insert(val).second)
|
||||
vals.push_back(val);
|
||||
else if (config->warnDuplicateRpath)
|
||||
warn("duplicate -rpath '" + val + "' ignored [--warn-duplicate-rpath]");
|
||||
}
|
||||
return vals;
|
||||
}
|
||||
|
||||
namespace lld {
|
||||
namespace macho {
|
||||
bool link(ArrayRef<const char *> argsArr, llvm::raw_ostream &stdoutOS,
|
||||
@ -1642,7 +1655,9 @@ bool link(ArrayRef<const char *> argsArr, llvm::raw_ostream &stdoutOS,
|
||||
error("--thinlto-prefix-replace=old_dir;new_dir;obj_dir must be used with "
|
||||
"--thinlto-index-only=");
|
||||
}
|
||||
config->runtimePaths = args::getStrings(args, OPT_rpath);
|
||||
config->warnDuplicateRpath =
|
||||
args.hasFlag(OPT_warn_duplicate_rpath, OPT_no_warn_duplicate_rpath, true);
|
||||
config->runtimePaths = getRuntimePaths(args);
|
||||
config->allLoad = args.hasFlag(OPT_all_load, OPT_noall_load, false);
|
||||
config->archMultiple = args.hasArg(OPT_arch_multiple);
|
||||
config->applicationExtension = args.hasFlag(
|
||||
|
@ -111,6 +111,12 @@ def no_warn_dylib_install_name: Flag<["--"], "no-warn-dylib-install-name">,
|
||||
def warn_dylib_install_name: Flag<["--"], "warn-dylib-install-name">,
|
||||
HelpText<"Warn on -install_name if -dylib is not passed">,
|
||||
Group<grp_lld>;
|
||||
def warn_duplicate_rpath: Flag<["--"], "warn-duplicate-rpath">,
|
||||
HelpText<"Warn if the same -rpath is specified multiple times (default)">,
|
||||
Group<grp_lld>;
|
||||
def no_warn_duplicate_rpath: Flag<["--"], "no-warn-duplicate-rpath">,
|
||||
HelpText<"Do not warn if the same -rpath is specified multiple times">,
|
||||
Group<grp_lld>;
|
||||
def call_graph_profile_sort: Flag<["--"], "call-graph-profile-sort">,
|
||||
HelpText<"Reorder sections with call graph profile (default)">,
|
||||
Group<grp_lld>;
|
||||
|
@ -14,6 +14,7 @@
|
||||
# RUN: -rpath @loader_path/../foo \
|
||||
# RUN: -rpath @loader_path/../subdir \
|
||||
# RUN: -rpath @loader_path/../foo \
|
||||
# RUN: --no-warn-duplicate-rpath \
|
||||
# RUN: %t/bar.o -o %t/subdir2/libbar.dylib
|
||||
|
||||
# RUN: %lld -lSystem %t/main.o %t/subdir2/libbar.dylib -o %t/test
|
||||
|
@ -12,6 +12,21 @@
|
||||
# CHECK-NEXT: cmdsize 32
|
||||
# CHECK-NEXT: path /another/rpath
|
||||
|
||||
## Check that -rpath entries are deduplicated.
|
||||
# RUN: not %lld %t.o -o /dev/null -rpath /some/rpath -rpath /other/rpath -rpath /some/rpath 2>&1 | \
|
||||
# RUN: FileCheck --check-prefix=FATAL %s
|
||||
# FATAL: error: duplicate -rpath '/some/rpath' ignored [--warn-duplicate-rpath]
|
||||
|
||||
# RUN: %lld -o %t-dup %t.o -rpath /some/rpath -rpath /other/rpath -rpath /some/rpath --no-warn-duplicate-rpath
|
||||
# RUN: llvm-objdump --macho --all-headers %t-dup | FileCheck %s --check-prefix=DEDUP
|
||||
# DEDUP: LC_RPATH
|
||||
# DEDUP-NEXT: cmdsize 24
|
||||
# DEDUP-NEXT: path /some/rpath
|
||||
# DEDUP: LC_RPATH
|
||||
# DEDUP-NEXT: cmdsize 32
|
||||
# DEDUP-NEXT: path /other/rpath
|
||||
# DEDUP-NOT: LC_RPATH
|
||||
|
||||
.text
|
||||
.global _main
|
||||
_main:
|
||||
|
Loading…
x
Reference in New Issue
Block a user