diff --git a/lib/std/build.zig b/lib/std/build.zig index 1565980279..ad4be9e4ca 100644 --- a/lib/std/build.zig +++ b/lib/std/build.zig @@ -1175,6 +1175,8 @@ pub const LibExeObjStep = struct { valgrind_support: ?bool = null, + link_eh_frame_hdr: bool = false, + /// Uses system Wine installation to run cross compiled Windows build artifacts. enable_wine: bool = false, @@ -1910,7 +1912,10 @@ pub const LibExeObjStep = struct { if (builder.verbose_cc or self.verbose_cc) zig_args.append("--verbose-cc") catch unreachable; if (self.strip) { - zig_args.append("--strip") catch unreachable; + try zig_args.append("--strip"); + } + if (self.link_eh_frame_hdr) { + try zig_args.append("--eh-frame-hdr"); } if (self.single_threaded) { diff --git a/src-self-hosted/compilation.zig b/src-self-hosted/compilation.zig index a7ba07342e..0f455fadcd 100644 --- a/src-self-hosted/compilation.zig +++ b/src-self-hosted/compilation.zig @@ -170,6 +170,8 @@ pub const Compilation = struct { verbose_llvm_ir: bool = false, verbose_link: bool = false, + link_eh_frame_hdr: bool = false, + darwin_version_min: DarwinVersionMin = .None, test_filters: []const []const u8 = &[_][]const u8{}, diff --git a/src-self-hosted/link.zig b/src-self-hosted/link.zig index afe4d10c65..efb83710d9 100644 --- a/src-self-hosted/link.zig +++ b/src-self-hosted/link.zig @@ -144,6 +144,9 @@ fn constructLinkerArgsElf(ctx: *Context) !void { // lj->args.append(g->linker_script); //} try ctx.args.append("--gc-sections"); + if (ctx.comp.link_eh_frame_hdr) { + try ctx.args.append("--eh-frame-hdr"); + } //lj->args.append("-m"); //lj->args.append(getLDMOption(&g->zig_target)); diff --git a/src-self-hosted/main.zig b/src-self-hosted/main.zig index 5224375e46..a19743bd71 100644 --- a/src-self-hosted/main.zig +++ b/src-self-hosted/main.zig @@ -154,6 +154,7 @@ const usage_build_generic = \\ --static Output will be statically linked \\ --strip Exclude debug symbols \\ -target [name] -- see the targets command + \\ --eh-frame-hdr enable C++ exception handling by passing --eh-frame-hdr to linker \\ --verbose-tokenize Turn on compiler debug output for tokenization \\ --verbose-ast-tree Turn on compiler debug output for parsing into an AST (tree view) \\ --verbose-ast-fmt Turn on compiler debug output for parsing into an AST (render source) @@ -207,6 +208,7 @@ fn buildOutputType(allocator: *Allocator, args: []const []const u8, out_type: Co var verbose_llvm_ir = false; var verbose_cimport = false; var linker_rdynamic = false; + var link_eh_frame_hdr = false; var macosx_version_min: ?[]const u8 = null; var ios_version_min: ?[]const u8 = null; @@ -369,6 +371,8 @@ fn buildOutputType(allocator: *Allocator, args: []const []const u8, out_type: Co verbose_ir = true; } else if (mem.eql(u8, arg, "--verbose-llvm-ir")) { verbose_llvm_ir = true; + } else if (mem.eql(u8, arg, "--eh-frame-hdr")) { + link_eh_frame_hdr = true; } else if (mem.eql(u8, arg, "--verbose-cimport")) { verbose_cimport = true; } else if (mem.eql(u8, arg, "-rdynamic")) { @@ -498,6 +502,8 @@ fn buildOutputType(allocator: *Allocator, args: []const []const u8, out_type: Co comp.verbose_llvm_ir = verbose_llvm_ir; comp.verbose_cimport = verbose_cimport; + comp.link_eh_frame_hdr = link_eh_frame_hdr; + comp.err_color = color; comp.linker_rdynamic = linker_rdynamic; diff --git a/src/all_types.hpp b/src/all_types.hpp index fe77d3db3b..4b957b18a3 100644 --- a/src/all_types.hpp +++ b/src/all_types.hpp @@ -2131,6 +2131,7 @@ struct CodeGen { bool have_winmain_crt_startup; bool have_dllmain_crt_startup; bool have_err_ret_tracing; + bool link_eh_frame_hdr; bool c_want_stdint; bool c_want_stdbool; bool verbose_tokenize; diff --git a/src/codegen.cpp b/src/codegen.cpp index 59f69539bc..937ccf1a34 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -8629,6 +8629,7 @@ static Error define_builtin_compile_vars(CodeGen *g) { cache_bool(&cache_hash, g->have_err_ret_tracing); cache_bool(&cache_hash, g->libc_link_lib != nullptr); cache_bool(&cache_hash, g->valgrind_support); + cache_bool(&cache_hash, g->link_eh_frame_hdr); cache_int(&cache_hash, detect_subsystem(g)); Buf digest = BUF_INIT; @@ -10279,6 +10280,7 @@ static Error check_cache(CodeGen *g, Buf *manifest_dir, Buf *digest) { cache_buf_opt(ch, g->test_filter); cache_buf_opt(ch, g->test_name_prefix); } + cache_bool(ch, g->link_eh_frame_hdr); cache_bool(ch, g->is_single_threaded); cache_bool(ch, g->linker_rdynamic); cache_bool(ch, g->each_lib_rpath); diff --git a/src/link.cpp b/src/link.cpp index 530a0c27c4..e0deb0d413 100644 --- a/src/link.cpp +++ b/src/link.cpp @@ -1647,6 +1647,10 @@ static void construct_linker_job_elf(LinkJob *lj) { lj->args.append("--gc-sections"); } + if (g->link_eh_frame_hdr) { + lj->args.append("--eh-frame-hdr"); + } + lj->args.append("-m"); lj->args.append(getLDMOption(g->zig_target)); diff --git a/src/main.cpp b/src/main.cpp index 8a661bfa05..0b12218d62 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -55,6 +55,7 @@ static int print_full_usage(const char *arg0, FILE *file, int return_code) { " --color [auto|off|on] enable or disable colored error messages\n" " --disable-gen-h do not generate a C header file (.h)\n" " --disable-valgrind omit valgrind client requests in debug builds\n" + " --eh-frame-hdr enable C++ exception handling by passing --eh-frame-hdr to linker\n" " --enable-valgrind include valgrind client requests release builds\n" " -fstack-check enable stack probing in unsafe builds\n" " -fno-stack-check disable stack probing in safe builds\n" @@ -477,6 +478,7 @@ int main(int argc, char **argv) { bool verbose_llvm_ir = false; bool verbose_cimport = false; bool verbose_cc = false; + bool link_eh_frame_hdr = false; ErrColor color = ErrColorAuto; CacheOpt enable_cache = CacheOptAuto; Buf *dynamic_linker = nullptr; @@ -715,6 +717,8 @@ int main(int argc, char **argv) { valgrind_support = ValgrindSupportEnabled; } else if (strcmp(arg, "--disable-valgrind") == 0) { valgrind_support = ValgrindSupportDisabled; + } else if (strcmp(arg, "--eh-frame-hdr") == 0) { + link_eh_frame_hdr = true; } else if (strcmp(arg, "-fPIC") == 0) { want_pic = WantPICEnabled; } else if (strcmp(arg, "-fno-PIC") == 0) { @@ -1191,6 +1195,7 @@ int main(int argc, char **argv) { override_lib_dir, libc, cache_dir_buf, cmd == CmdTest, root_progress_node); if (llvm_argv.length >= 2) codegen_set_llvm_argv(g, llvm_argv.items + 1, llvm_argv.length - 2); g->valgrind_support = valgrind_support; + g->link_eh_frame_hdr = link_eh_frame_hdr; g->want_pic = want_pic; g->want_stack_check = want_stack_check; g->want_sanitize_c = want_sanitize_c;