authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-06-10 11:25:33-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-06-11 10:31:48-07:00
log264969a8c3f84212a71fc43f9239b0dc7684994c
tree7348dc01f191bae3b331519986ea51f23c197212
parente3a74697f0317e1e6185262b477c0bfcad06d788

better awareness of unwind tables

* stage1 backend allows configuring the uwtables function attr via a flag rather than its own logic. * stage2 defaults to enabling uwtable attr when linking libunwind, or always on windows * stage2 makes link_eh_frame_hdr true automatically if uwtable attr is set to be on for zig functions * CLI: add -funwind-tables and -fno-unwind-tables to allow the user to override the defaults. * hook it up to `zig cc` closes #9046

10 files changed, 82 insertions(+), 22 deletions(-)

src/Compilation.zig+26-12
......@@ -81,6 +81,7 @@ verbose_llvm_cpu_features: bool,
8181disable_c_depfile: bool,
8282time_report: bool,
8383stack_report: bool,
84unwind_tables: bool,
8485
8586c_source_files: []const CSourceFile,
8687clang_argv: []const []const u8,
......@@ -659,6 +660,7 @@ pub const InitOptions = struct {
659660 want_tsan: ?bool = null,
660661 want_compiler_rt: ?bool = null,
661662 want_lto: ?bool = null,
663 want_unwind_tables: ?bool = null,
662664 use_llvm: ?bool = null,
663665 use_lld: ?bool = null,
664666 use_clang: ?bool = null,
......@@ -815,8 +817,20 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {
815817 return error.MachineCodeModelNotSupported;
816818 }
817819
820 const tsan = options.want_tsan orelse false;
821 // TSAN is implemented in C++ so it requires linking libc++.
822 const link_libcpp = options.link_libcpp or tsan;
823 const link_libc = link_libcpp or options.link_libc or
824 target_util.osRequiresLibC(options.target);
825
826 const link_libunwind = options.link_libunwind or
827 (link_libcpp and target_util.libcNeedsLibUnwind(options.target));
828 const unwind_tables = options.want_unwind_tables orelse
829 (link_libunwind or target_util.needUnwindTables(options.target));
830 const link_eh_frame_hdr = options.link_eh_frame_hdr or unwind_tables;
831
818832 // Make a decision on whether to use LLD or our own linker.
819 const use_lld = if (options.use_lld) |explicit| explicit else blk: {
833 const use_lld = options.use_lld orelse blk: {
820834 if (!build_options.have_llvm)
821835 break :blk false;
822836
......@@ -835,7 +849,7 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {
835849 options.frameworks.len != 0 or
836850 options.system_libs.len != 0 or
837851 options.link_libc or options.link_libcpp or
838 options.link_eh_frame_hdr or
852 link_eh_frame_hdr or
839853 options.link_emit_relocs or
840854 options.output_mode == .Lib or
841855 options.lld_argv.len != 0 or
......@@ -894,15 +908,6 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {
894908 }
895909 };
896910
897 const tsan = options.want_tsan orelse false;
898 // TSAN is implemented in C++ so it requires linking libc++.
899 const link_libcpp = options.link_libcpp or tsan;
900 const link_libc = link_libcpp or options.link_libc or
901 target_util.osRequiresLibC(options.target);
902
903 const link_libunwind = options.link_libunwind or
904 (link_libcpp and target_util.libcNeedsLibUnwind(options.target));
905
906911 const must_dynamic_link = dl: {
907912 if (target_util.cannotDynamicLink(options.target))
908913 break :dl false;
......@@ -1072,6 +1077,7 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {
10721077 cache.hash.add(pic);
10731078 cache.hash.add(pie);
10741079 cache.hash.add(lto);
1080 cache.hash.add(unwind_tables);
10751081 cache.hash.add(tsan);
10761082 cache.hash.add(stack_check);
10771083 cache.hash.add(red_zone);
......@@ -1303,7 +1309,7 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {
13031309 .linker_script = options.linker_script,
13041310 .version_script = options.version_script,
13051311 .gc_sections = options.linker_gc_sections,
1306 .eh_frame_hdr = options.link_eh_frame_hdr,
1312 .eh_frame_hdr = link_eh_frame_hdr,
13071313 .emit_relocs = options.link_emit_relocs,
13081314 .rdynamic = options.rdynamic,
13091315 .extra_lld_args = options.lld_argv,
......@@ -1366,6 +1372,7 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {
13661372 .color = options.color,
13671373 .time_report = options.time_report,
13681374 .stack_report = options.stack_report,
1375 .unwind_tables = unwind_tables,
13691376 .test_filter = options.test_filter,
13701377 .test_name_prefix = options.test_name_prefix,
13711378 .test_evented_io = options.test_evented_io,
......@@ -2963,6 +2970,12 @@ pub fn addCCArgs(
29632970 if (target_util.supports_fpic(target) and comp.bin_file.options.pic) {
29642971 try argv.append("-fPIC");
29652972 }
2973
2974 if (comp.unwind_tables) {
2975 try argv.append("-funwind-tables");
2976 } else {
2977 try argv.append("-fno-unwind-tables");
2978 }
29662979 },
29672980 .shared_library, .ll, .bc, .unknown, .static_library, .object, .zig => {},
29682981 .assembly => {
......@@ -3927,6 +3940,7 @@ fn updateStage1Module(comp: *Compilation, main_progress_node: *std.Progress.Node
39273940 .pic = comp.bin_file.options.pic,
39283941 .pie = comp.bin_file.options.pie,
39293942 .lto = comp.bin_file.options.lto,
3943 .unwind_tables = comp.unwind_tables,
39303944 .link_libc = comp.bin_file.options.link_libc,
39313945 .link_libcpp = comp.bin_file.options.link_libcpp,
39323946 .strip = comp.bin_file.options.strip,
src/clang_options_data.zig+16-2
......@@ -3151,7 +3151,14 @@ flagpd1("fno-unsafe-loop-optimizations"),
31513151flagpd1("fno-unsafe-math-optimizations"),
31523152flagpd1("fno-unsigned-char"),
31533153flagpd1("fno-unswitch-loops"),
3154flagpd1("fno-unwind-tables"),
3154.{
3155 .name = "fno-unwind-tables",
3156 .syntax = .flag,
3157 .zig_equivalent = .no_unwind_tables,
3158 .pd1 = true,
3159 .pd2 = false,
3160 .psl = false,
3161},
31553162flagpd1("fno-use-cxa-atexit"),
31563163flagpd1("fno-use-init-array"),
31573164flagpd1("fno-use-line-directives"),
......@@ -3410,7 +3417,14 @@ flagpd1("funsafe-math-optimizations"),
34103417flagpd1("funsigned-bitfields"),
34113418flagpd1("funsigned-char"),
34123419flagpd1("funswitch-loops"),
3413flagpd1("funwind-tables"),
3420.{
3421 .name = "funwind-tables",
3422 .syntax = .flag,
3423 .zig_equivalent = .unwind_tables,
3424 .pd1 = true,
3425 .pd2 = false,
3426 .psl = false,
3427},
34143428flagpd1("fuse-ctor-homing"),
34153429flagpd1("fuse-cxa-atexit"),
34163430flagpd1("fuse-init-array"),
src/main.zig+23-7
......@@ -263,22 +263,26 @@ pub fn mainArgs(gpa: *Allocator, arena: *Allocator, args: []const []const u8) !v
263263}
264264
265265const usage_build_generic =
266 \\Usage: zig build-exe <options> [files]
267 \\ zig build-lib <options> [files]
268 \\ zig build-obj <options> [files]
269 \\ zig test <options> [files]
270 \\ zig run <options> [file] [-- [args]]
266 \\Usage: zig build-exe <options> [files]
267 \\ zig build-lib <options> [files]
268 \\ zig build-obj <options> [files]
269 \\ zig test <options> [files]
270 \\ zig run <options> [file] [-- [args]]
271 \\ zig translate-c <options> [file]
271272 \\
272273 \\Supported file types:
273274 \\ .zig Zig source code
274275 \\ .o ELF object file
275 \\ .o MACH-O (macOS) object file
276 \\ .o Mach-O (macOS) object file
277 \\ .o WebAssembly object file
276278 \\ .obj COFF (Windows) object file
277279 \\ .lib COFF (Windows) static library
278280 \\ .a ELF static library
281 \\ .a Mach-O (macOS) static library
282 \\ .a WebAssembly static library
279283 \\ .so ELF shared object (dynamic link)
280284 \\ .dll Windows Dynamic Link Library
281 \\ .dylib MACH-O (macOS) dynamic library
285 \\ .dylib Mach-O (macOS) dynamic library
282286 \\ .tbd (macOS) text-based dylib definition
283287 \\ .s Target-specific assembly source code
284288 \\ .S Assembly with C preprocessor (requires LLVM extensions)
......@@ -341,6 +345,8 @@ const usage_build_generic =
341345 \\ -fno-sanitize-thread Disable Thread Sanitizer
342346 \\ -fdll-export-fns Mark exported functions as DLL exports (Windows)
343347 \\ -fno-dll-export-fns Force-disable marking exported functions as DLL exports
348 \\ -funwind-tables Always produce unwind table entries for all functions
349 \\ -fno-unwind-tables Never produce unwind table entries
344350 \\ -fLLVM Force using LLVM as the codegen backend
345351 \\ -fno-LLVM Prevent using LLVM as a codegen backend
346352 \\ -fClang Force using Clang as the C/C++ compilation backend
......@@ -568,6 +574,7 @@ fn buildOutputType(
568574 var want_pic: ?bool = null;
569575 var want_pie: ?bool = null;
570576 var want_lto: ?bool = null;
577 var want_unwind_tables: ?bool = null;
571578 var want_sanitize_c: ?bool = null;
572579 var want_stack_check: ?bool = null;
573580 var want_red_zone: ?bool = null;
......@@ -920,6 +927,10 @@ fn buildOutputType(
920927 want_lto = true;
921928 } else if (mem.eql(u8, arg, "-fno-lto")) {
922929 want_lto = false;
930 } else if (mem.eql(u8, arg, "-funwind-tables")) {
931 want_unwind_tables = true;
932 } else if (mem.eql(u8, arg, "-fno-unwind-tables")) {
933 want_unwind_tables = false;
923934 } else if (mem.eql(u8, arg, "-fstack-check")) {
924935 want_stack_check = true;
925936 } else if (mem.eql(u8, arg, "-fno-stack-check")) {
......@@ -1151,6 +1162,8 @@ fn buildOutputType(
11511162 .no_lto => want_lto = false,
11521163 .red_zone => want_red_zone = true,
11531164 .no_red_zone => want_red_zone = false,
1165 .unwind_tables => want_unwind_tables = true,
1166 .no_unwind_tables => want_unwind_tables = false,
11541167 .nostdlib => ensure_libc_on_non_freestanding = false,
11551168 .nostdlib_cpp => ensure_libcpp_on_non_freestanding = false,
11561169 .shared => {
......@@ -1893,6 +1906,7 @@ fn buildOutputType(
18931906 .want_pic = want_pic,
18941907 .want_pie = want_pie,
18951908 .want_lto = want_lto,
1909 .want_unwind_tables = want_unwind_tables,
18961910 .want_sanitize_c = want_sanitize_c,
18971911 .want_stack_check = want_stack_check,
18981912 .want_red_zone = want_red_zone,
......@@ -3294,6 +3308,8 @@ pub const ClangArgIterator = struct {
32943308 no_pie,
32953309 lto,
32963310 no_lto,
3311 unwind_tables,
3312 no_unwind_tables,
32973313 nostdlib,
32983314 nostdlib_cpp,
32993315 shared,
src/stage1.zig+1
......@@ -110,6 +110,7 @@ pub const Module = extern struct {
110110 pic: bool,
111111 pie: bool,
112112 lto: bool,
113 unwind_tables: bool,
113114 link_libc: bool,
114115 link_libcpp: bool,
115116 strip: bool,
src/stage1/all_types.hpp+1
......@@ -2144,6 +2144,7 @@ struct CodeGen {
21442144 bool have_pic;
21452145 bool have_pie;
21462146 bool have_lto;
2147 bool unwind_tables;
21472148 bool link_mode_dynamic;
21482149 bool dll_export_fns;
21492150 bool have_stack_probing;
src/stage1/codegen.cpp+1-1
......@@ -211,7 +211,7 @@ static ZigLLVM_CallingConv get_llvm_cc(CodeGen *g, CallingConvention cc) {
211211}
212212
213213static void add_uwtable_attr(CodeGen *g, LLVMValueRef fn_val) {
214 if (g->zig_target->os == OsWindows) {
214 if (g->unwind_tables) {
215215 addLLVMFnAttr(fn_val, "uwtable");
216216 }
217217}
src/stage1/stage1.cpp+1
......@@ -91,6 +91,7 @@ void zig_stage1_build_object(struct ZigStage1 *stage1) {
9191 g->have_pic = stage1->pic;
9292 g->have_pie = stage1->pie;
9393 g->have_lto = stage1->lto;
94 g->unwind_tables = stage1->unwind_tables;
9495 g->have_stack_probing = stage1->enable_stack_probing;
9596 g->red_zone = stage1->red_zone;
9697 g->is_single_threaded = stage1->is_single_threaded;
src/stage1/stage1.h+1
......@@ -182,6 +182,7 @@ struct ZigStage1 {
182182 bool pic;
183183 bool pie;
184184 bool lto;
185 bool unwind_tables;
185186 bool link_libc;
186187 bool link_libcpp;
187188 bool strip;
src/target.zig+4
......@@ -404,3 +404,7 @@ pub fn clangAssemblerSupportsMcpuArg(target: std.Target) bool {
404404 else => false,
405405 };
406406}
407
408pub fn needUnwindTables(target: std.Target) bool {
409 return target.os.tag == .windows;
410}
tools/update_clang_options.zig+8
......@@ -70,6 +70,14 @@ const known_options = [_]KnownOpt{
7070 .name = "fno-lto",
7171 .ident = "no_lto",
7272 },
73 .{
74 .name = "funwind-tables",
75 .ident = "unwind_tables",
76 },
77 .{
78 .name = "fno-unwind-tables",
79 .ident = "no_unwind_tables",
80 },
7381 .{
7482 .name = "nolibc",
7583 .ident = "nostdlib",