diff --git a/src/all_types.hpp b/src/all_types.hpp index 8db9440580..9304a215dc 100644 --- a/src/all_types.hpp +++ b/src/all_types.hpp @@ -2270,6 +2270,7 @@ struct CodeGen { CodeModel code_model; OptionalBool linker_gc_sections; OptionalBool linker_allow_shlib_undefined; + OptionalBool linker_bind_global_refs_locally; bool strip_debug_symbols; bool is_test_build; bool is_single_threaded; diff --git a/src/codegen.cpp b/src/codegen.cpp index 1b7d8e7013..bb189075be 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -10685,6 +10685,7 @@ static Error check_cache(CodeGen *g, Buf *manifest_dir, Buf *digest) { cache_buf_opt(ch, g->linker_optimization); cache_int(ch, g->linker_gc_sections); cache_int(ch, g->linker_allow_shlib_undefined); + cache_int(ch, g->linker_bind_global_refs_locally); cache_bool(ch, g->linker_z_nodelete); cache_bool(ch, g->linker_z_defs); cache_usize(ch, g->stack_size_override); diff --git a/src/link.cpp b/src/link.cpp index d4fc7ae228..546c5cabc1 100644 --- a/src/link.cpp +++ b/src/link.cpp @@ -2086,6 +2086,14 @@ static void construct_linker_job_elf(LinkJob *lj) { lj->args.append("--allow-shlib-undefined"); break; } + switch (g->linker_bind_global_refs_locally) { + case OptionalBoolNull: + case OptionalBoolFalse: + break; + case OptionalBoolTrue: + lj->args.append("-Bsymbolic"); + break; + } } static void construct_linker_job_wasm(LinkJob *lj) { @@ -2810,6 +2818,14 @@ static void construct_linker_job_macho(LinkJob *lj) { lj->args.append("dynamic_lookup"); break; } + switch (g->linker_bind_global_refs_locally) { + case OptionalBoolNull: + case OptionalBoolFalse: + break; + case OptionalBoolTrue: + lj->args.append("-Bsymbolic"); + break; + } for (size_t i = 0; i < g->framework_dirs.length; i += 1) { const char *framework_dir = g->framework_dirs.at(i); diff --git a/src/main.cpp b/src/main.cpp index f67fec795f..41aade9431 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -132,6 +132,7 @@ static int print_full_usage(const char *arg0, FILE *file, int return_code) { " --ver-major [ver] dynamic library semver major version\n" " --ver-minor [ver] dynamic library semver minor version\n" " --ver-patch [ver] dynamic library semver patch version\n" + " -Bsymbolic bind global references locally\n" "\n" "Test Options:\n" " --test-filter [text] skip tests that do not match filter\n" @@ -452,6 +453,7 @@ static int main0(int argc, char **argv) { Buf *linker_optimization = nullptr; OptionalBool linker_gc_sections = OptionalBoolNull; OptionalBool linker_allow_shlib_undefined = OptionalBoolNull; + OptionalBool linker_bind_global_refs_locally = OptionalBoolNull; bool linker_z_nodelete = false; bool linker_z_defs = false; size_t stack_size_override = 0; @@ -842,6 +844,8 @@ static int main0(int argc, char **argv) { buf_eql_str(arg, "-no-allow-shlib-undefined")) { linker_allow_shlib_undefined = OptionalBoolFalse; + } else if (buf_eql_str(arg, "-Bsymbolic")) { + linker_bind_global_refs_locally = OptionalBoolTrue; } else if (buf_eql_str(arg, "-z")) { i += 1; if (i >= linker_args.length) { @@ -1013,6 +1017,8 @@ static int main0(int argc, char **argv) { want_single_threaded = true;; } else if (strcmp(arg, "--bundle-compiler-rt") == 0) { bundle_compiler_rt = true; + } else if (strcmp(arg, "-Bsymbolic") == 0) { + linker_bind_global_refs_locally = OptionalBoolTrue; } else if (strcmp(arg, "--test-cmd-bin") == 0) { test_exec_args.append(nullptr); } else if (arg[1] == 'D' && arg[2] != 0) { @@ -1609,6 +1615,7 @@ static int main0(int argc, char **argv) { g->linker_optimization = linker_optimization; g->linker_gc_sections = linker_gc_sections; g->linker_allow_shlib_undefined = linker_allow_shlib_undefined; + g->linker_bind_global_refs_locally = linker_bind_global_refs_locally; g->linker_z_nodelete = linker_z_nodelete; g->linker_z_defs = linker_z_defs; g->stack_size_override = stack_size_override;