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 13:23:00-04:00
logb6277a4b1c2be27701d594bc1465ac72fc226260
tree6a422059457c92c6baeaba53e6e95a2195cc0d43
parent6cc88458029759bbedcb4d949deb887d464cdd60

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,
......@@ -665,6 +666,7 @@ pub const InitOptions = struct {
665666 want_tsan: ?bool = null,
666667 want_compiler_rt: ?bool = null,
667668 want_lto: ?bool = null,
669 want_unwind_tables: ?bool = null,
668670 use_llvm: ?bool = null,
669671 use_lld: ?bool = null,
670672 use_clang: ?bool = null,
......@@ -823,8 +825,20 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {
823825 return error.MachineCodeModelNotSupported;
824826 }
825827
828 const tsan = options.want_tsan orelse false;
829 // TSAN is implemented in C++ so it requires linking libc++.
830 const link_libcpp = options.link_libcpp or tsan;
831 const link_libc = link_libcpp or options.link_libc or
832 target_util.osRequiresLibC(options.target);
833
834 const link_libunwind = options.link_libunwind or
835 (link_libcpp and target_util.libcNeedsLibUnwind(options.target));
836 const unwind_tables = options.want_unwind_tables orelse
837 (link_libunwind or target_util.needUnwindTables(options.target));
838 const link_eh_frame_hdr = options.link_eh_frame_hdr or unwind_tables;
839
826840 // Make a decision on whether to use LLD or our own linker.
827 const use_lld = if (options.use_lld) |explicit| explicit else blk: {
841 const use_lld = options.use_lld orelse blk: {
828842 if (!build_options.have_llvm)
829843 break :blk false;
830844
......@@ -843,7 +857,7 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {
843857 options.frameworks.len != 0 or
844858 options.system_libs.len != 0 or
845859 options.link_libc or options.link_libcpp or
846 options.link_eh_frame_hdr or
860 link_eh_frame_hdr or
847861 options.link_emit_relocs or
848862 options.output_mode == .Lib or
849863 options.lld_argv.len != 0 or
......@@ -902,15 +916,6 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {
902916 }
903917 };
904918
905 const tsan = options.want_tsan orelse false;
906 // TSAN is implemented in C++ so it requires linking libc++.
907 const link_libcpp = options.link_libcpp or tsan;
908 const link_libc = link_libcpp or options.link_libc or
909 target_util.osRequiresLibC(options.target);
910
911 const link_libunwind = options.link_libunwind or
912 (link_libcpp and target_util.libcNeedsLibUnwind(options.target));
913
914919 const must_dynamic_link = dl: {
915920 if (target_util.cannotDynamicLink(options.target))
916921 break :dl false;
......@@ -1080,6 +1085,7 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {
10801085 cache.hash.add(pic);
10811086 cache.hash.add(pie);
10821087 cache.hash.add(lto);
1088 cache.hash.add(unwind_tables);
10831089 cache.hash.add(tsan);
10841090 cache.hash.add(stack_check);
10851091 cache.hash.add(red_zone);
......@@ -1312,7 +1318,7 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {
13121318 .linker_script = options.linker_script,
13131319 .version_script = options.version_script,
13141320 .gc_sections = options.linker_gc_sections,
1315 .eh_frame_hdr = options.link_eh_frame_hdr,
1321 .eh_frame_hdr = link_eh_frame_hdr,
13161322 .emit_relocs = options.link_emit_relocs,
13171323 .rdynamic = options.rdynamic,
13181324 .extra_lld_args = options.lld_argv,
......@@ -1376,6 +1382,7 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {
13761382 .color = options.color,
13771383 .time_report = options.time_report,
13781384 .stack_report = options.stack_report,
1385 .unwind_tables = unwind_tables,
13791386 .test_filter = options.test_filter,
13801387 .test_name_prefix = options.test_name_prefix,
13811388 .test_evented_io = options.test_evented_io,
......@@ -2983,6 +2990,12 @@ pub fn addCCArgs(
29832990 if (target_util.supports_fpic(target) and comp.bin_file.options.pic) {
29842991 try argv.append("-fPIC");
29852992 }
2993
2994 if (comp.unwind_tables) {
2995 try argv.append("-funwind-tables");
2996 } else {
2997 try argv.append("-fno-unwind-tables");
2998 }
29862999 },
29873000 .shared_library, .ll, .bc, .unknown, .static_library, .object, .zig => {},
29883001 .assembly => {
......@@ -3948,6 +3961,7 @@ fn updateStage1Module(comp: *Compilation, main_progress_node: *std.Progress.Node
39483961 .pic = comp.bin_file.options.pic,
39493962 .pie = comp.bin_file.options.pie,
39503963 .lto = comp.bin_file.options.lto,
3964 .unwind_tables = comp.unwind_tables,
39513965 .link_libc = comp.bin_file.options.link_libc,
39523966 .link_libcpp = comp.bin_file.options.link_libcpp,
39533967 .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
......@@ -264,22 +264,26 @@ pub fn mainArgs(gpa: *Allocator, arena: *Allocator, args: []const []const u8) !v
264264}
265265
266266const usage_build_generic =
267 \\Usage: zig build-exe <options> [files]
268 \\ zig build-lib <options> [files]
269 \\ zig build-obj <options> [files]
270 \\ zig test <options> [files]
271 \\ zig run <options> [file] [-- [args]]
267 \\Usage: zig build-exe <options> [files]
268 \\ zig build-lib <options> [files]
269 \\ zig build-obj <options> [files]
270 \\ zig test <options> [files]
271 \\ zig run <options> [file] [-- [args]]
272 \\ zig translate-c <options> [file]
272273 \\
273274 \\Supported file types:
274275 \\ .zig Zig source code
275276 \\ .o ELF object file
276 \\ .o MACH-O (macOS) object file
277 \\ .o Mach-O (macOS) object file
278 \\ .o WebAssembly object file
277279 \\ .obj COFF (Windows) object file
278280 \\ .lib COFF (Windows) static library
279281 \\ .a ELF static library
282 \\ .a Mach-O (macOS) static library
283 \\ .a WebAssembly static library
280284 \\ .so ELF shared object (dynamic link)
281285 \\ .dll Windows Dynamic Link Library
282 \\ .dylib MACH-O (macOS) dynamic library
286 \\ .dylib Mach-O (macOS) dynamic library
283287 \\ .tbd (macOS) text-based dylib definition
284288 \\ .s Target-specific assembly source code
285289 \\ .S Assembly with C preprocessor (requires LLVM extensions)
......@@ -342,6 +346,8 @@ const usage_build_generic =
342346 \\ -fno-sanitize-thread Disable Thread Sanitizer
343347 \\ -fdll-export-fns Mark exported functions as DLL exports (Windows)
344348 \\ -fno-dll-export-fns Force-disable marking exported functions as DLL exports
349 \\ -funwind-tables Always produce unwind table entries for all functions
350 \\ -fno-unwind-tables Never produce unwind table entries
345351 \\ -fLLVM Force using LLVM as the codegen backend
346352 \\ -fno-LLVM Prevent using LLVM as a codegen backend
347353 \\ -fClang Force using Clang as the C/C++ compilation backend
......@@ -569,6 +575,7 @@ fn buildOutputType(
569575 var want_pic: ?bool = null;
570576 var want_pie: ?bool = null;
571577 var want_lto: ?bool = null;
578 var want_unwind_tables: ?bool = null;
572579 var want_sanitize_c: ?bool = null;
573580 var want_stack_check: ?bool = null;
574581 var want_red_zone: ?bool = null;
......@@ -925,6 +932,10 @@ fn buildOutputType(
925932 want_lto = true;
926933 } else if (mem.eql(u8, arg, "-fno-lto")) {
927934 want_lto = false;
935 } else if (mem.eql(u8, arg, "-funwind-tables")) {
936 want_unwind_tables = true;
937 } else if (mem.eql(u8, arg, "-fno-unwind-tables")) {
938 want_unwind_tables = false;
928939 } else if (mem.eql(u8, arg, "-fstack-check")) {
929940 want_stack_check = true;
930941 } else if (mem.eql(u8, arg, "-fno-stack-check")) {
......@@ -1156,6 +1167,8 @@ fn buildOutputType(
11561167 .no_lto => want_lto = false,
11571168 .red_zone => want_red_zone = true,
11581169 .no_red_zone => want_red_zone = false,
1170 .unwind_tables => want_unwind_tables = true,
1171 .no_unwind_tables => want_unwind_tables = false,
11591172 .nostdlib => ensure_libc_on_non_freestanding = false,
11601173 .nostdlib_cpp => ensure_libcpp_on_non_freestanding = false,
11611174 .shared => {
......@@ -1913,6 +1926,7 @@ fn buildOutputType(
19131926 .want_pic = want_pic,
19141927 .want_pie = want_pie,
19151928 .want_lto = want_lto,
1929 .want_unwind_tables = want_unwind_tables,
19161930 .want_sanitize_c = want_sanitize_c,
19171931 .want_stack_check = want_stack_check,
19181932 .want_red_zone = want_red_zone,
......@@ -3315,6 +3329,8 @@ pub const ClangArgIterator = struct {
33153329 no_pie,
33163330 lto,
33173331 no_lto,
3332 unwind_tables,
3333 no_unwind_tables,
33183334 nostdlib,
33193335 nostdlib_cpp,
33203336 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",