Commit 8af82621d7
Changed files (16)
lib
std
src
test
standalone
stack_iterator
lib/std/Build/Module.zig
@@ -22,7 +22,7 @@ frameworks: std.StringArrayHashMapUnmanaged(LinkFrameworkOptions),
link_objects: std.ArrayListUnmanaged(LinkObject),
strip: ?bool,
-unwind_tables: ?bool,
+unwind_tables: ?std.builtin.UnwindTables,
single_threaded: ?bool,
stack_protector: ?bool,
stack_check: ?bool,
@@ -218,7 +218,7 @@ pub const CreateOptions = struct {
link_libcpp: ?bool = null,
single_threaded: ?bool = null,
strip: ?bool = null,
- unwind_tables: ?bool = null,
+ unwind_tables: ?std.builtin.UnwindTables = null,
dwarf_format: ?std.dwarf.Format = null,
code_model: std.builtin.CodeModel = .default,
stack_protector: ?bool = null,
@@ -675,7 +675,6 @@ pub fn appendZigProcessFlags(
const b = m.owner;
try addFlag(zig_args, m.strip, "-fstrip", "-fno-strip");
- try addFlag(zig_args, m.unwind_tables, "-funwind-tables", "-fno-unwind-tables");
try addFlag(zig_args, m.single_threaded, "-fsingle-threaded", "-fno-single-threaded");
try addFlag(zig_args, m.stack_check, "-fstack-check", "-fno-stack-check");
try addFlag(zig_args, m.stack_protector, "-fstack-protector", "-fno-stack-protector");
@@ -695,6 +694,14 @@ pub fn appendZigProcessFlags(
});
}
+ if (m.unwind_tables) |unwind_tables| {
+ try zig_args.append(switch (unwind_tables) {
+ .none => "-fno-unwind-tables",
+ .sync => "-funwind-tables",
+ .@"async" => "-fasync-unwind-tables",
+ });
+ }
+
try zig_args.ensureUnusedCapacity(1);
if (m.optimize) |optimize| switch (optimize) {
.Debug => zig_args.appendAssumeCapacity("-ODebug"),
lib/std/Build.zig
@@ -706,7 +706,7 @@ pub const ExecutableOptions = struct {
single_threaded: ?bool = null,
pic: ?bool = null,
strip: ?bool = null,
- unwind_tables: ?bool = null,
+ unwind_tables: ?std.builtin.UnwindTables = null,
omit_frame_pointer: ?bool = null,
sanitize_thread: ?bool = null,
error_tracing: ?bool = null,
@@ -762,7 +762,7 @@ pub const ObjectOptions = struct {
single_threaded: ?bool = null,
pic: ?bool = null,
strip: ?bool = null,
- unwind_tables: ?bool = null,
+ unwind_tables: ?std.builtin.UnwindTables = null,
omit_frame_pointer: ?bool = null,
sanitize_thread: ?bool = null,
error_tracing: ?bool = null,
@@ -810,7 +810,7 @@ pub const SharedLibraryOptions = struct {
single_threaded: ?bool = null,
pic: ?bool = null,
strip: ?bool = null,
- unwind_tables: ?bool = null,
+ unwind_tables: ?std.builtin.UnwindTables = null,
omit_frame_pointer: ?bool = null,
sanitize_thread: ?bool = null,
error_tracing: ?bool = null,
@@ -867,7 +867,7 @@ pub const StaticLibraryOptions = struct {
single_threaded: ?bool = null,
pic: ?bool = null,
strip: ?bool = null,
- unwind_tables: ?bool = null,
+ unwind_tables: ?std.builtin.UnwindTables = null,
omit_frame_pointer: ?bool = null,
sanitize_thread: ?bool = null,
error_tracing: ?bool = null,
@@ -919,7 +919,7 @@ pub const TestOptions = struct {
single_threaded: ?bool = null,
pic: ?bool = null,
strip: ?bool = null,
- unwind_tables: ?bool = null,
+ unwind_tables: ?std.builtin.UnwindTables = null,
omit_frame_pointer: ?bool = null,
sanitize_thread: ?bool = null,
error_tracing: ?bool = null,
lib/std/builtin.zig
@@ -804,6 +804,14 @@ pub const LinkMode = enum {
dynamic,
};
+/// This data structure is used by the Zig language code generation and
+/// therefore must be kept in sync with the compiler implementation.
+pub const UnwindTables = enum {
+ none,
+ sync,
+ @"async",
+};
+
/// This data structure is used by the Zig language code generation and
/// therefore must be kept in sync with the compiler implementation.
pub const WasiExecModel = enum {
src/codegen/llvm.zig
@@ -3141,8 +3141,11 @@ pub const Object = struct {
} }, &o.builder);
}
try attributes.addFnAttr(.nounwind, &o.builder);
- if (owner_mod.unwind_tables) {
- try attributes.addFnAttr(.{ .uwtable = Builder.Attribute.UwTable.default }, &o.builder);
+ if (owner_mod.unwind_tables != .none) {
+ try attributes.addFnAttr(
+ .{ .uwtable = if (owner_mod.unwind_tables == .@"async") .@"async" else .sync },
+ &o.builder,
+ );
}
if (owner_mod.no_builtin) {
// The intent here is for compiler-rt and libc functions to not generate
src/Compilation/Config.zig
@@ -12,13 +12,14 @@ link_libunwind: bool,
/// True if and only if the c_source_files field will have nonzero length when
/// calling Compilation.create.
any_c_source_files: bool,
-/// This is true if any Module has unwind_tables set explicitly to true. Until
-/// Compilation.create is called, it is possible for this to be false while in
-/// fact all Module instances have unwind_tables=true due to the default
-/// being unwind_tables=true. After Compilation.create is called this will
-/// also take into account the default setting, making this value true if and
-/// only if any Module has unwind_tables set to true.
-any_unwind_tables: bool,
+/// This is not `.none` if any `Module` has `unwind_tables` set explicitly to a
+/// value other than `.none`. Until `Compilation.create()` is called, it is
+/// possible for this to be `.none` while in fact all `Module` instances have
+/// `unwind_tables != .none` due to the default. After `Compilation.create()` is
+/// called, this will also take into account the default setting, making this
+/// value `.sync` or `.@"async"` if and only if any `Module` has
+/// `unwind_tables != .none`.
+any_unwind_tables: std.builtin.UnwindTables,
/// This is true if any Module has single_threaded set explicitly to false. Until
/// Compilation.create is called, it is possible for this to be false while in
/// fact all Module instances have single_threaded=false due to the default
@@ -85,7 +86,7 @@ pub const Options = struct {
any_non_single_threaded: bool = false,
any_sanitize_thread: bool = false,
any_fuzz: bool = false,
- any_unwind_tables: bool = false,
+ any_unwind_tables: std.builtin.UnwindTables = .none,
any_dyn_libs: bool = false,
any_c_source_files: bool = false,
any_non_stripped: bool = false,
@@ -356,8 +357,11 @@ pub fn resolve(options: Options) ResolveError!Config {
break :b false;
};
- const any_unwind_tables = options.any_unwind_tables or
- link_libunwind or target_util.needUnwindTables(target);
+ const any_unwind_tables = b: {
+ if (options.any_unwind_tables != .none) break :b options.any_unwind_tables;
+
+ break :b target_util.needUnwindTables(target, link_libunwind, options.any_sanitize_thread);
+ };
const link_mode = b: {
const explicitly_exe_or_dyn_lib = switch (options.output_mode) {
src/Package/Module.zig
@@ -27,7 +27,7 @@ red_zone: bool,
sanitize_c: bool,
sanitize_thread: bool,
fuzz: bool,
-unwind_tables: bool,
+unwind_tables: std.builtin.UnwindTables,
cc_argv: []const []const u8,
/// (SPIR-V) whether to generate a structured control flow graph or not
structured_cfg: bool,
@@ -91,7 +91,7 @@ pub const CreateOptions = struct {
/// other number means stack protection with that buffer size.
stack_protector: ?u32 = null,
red_zone: ?bool = null,
- unwind_tables: ?bool = null,
+ unwind_tables: ?std.builtin.UnwindTables = null,
sanitize_c: ?bool = null,
sanitize_thread: ?bool = null,
fuzz: ?bool = null,
@@ -112,7 +112,7 @@ pub fn create(arena: Allocator, options: CreateOptions) !*Package.Module {
if (options.inherited.sanitize_thread == true) assert(options.global.any_sanitize_thread);
if (options.inherited.fuzz == true) assert(options.global.any_fuzz);
if (options.inherited.single_threaded == false) assert(options.global.any_non_single_threaded);
- if (options.inherited.unwind_tables == true) assert(options.global.any_unwind_tables);
+ if (options.inherited.unwind_tables) |uwt| if (uwt != .none) assert(options.global.any_unwind_tables != .none);
if (options.inherited.error_tracing == true) assert(options.global.any_error_tracing);
const resolved_target = options.inherited.resolved_target orelse options.parent.?.resolved_target;
@@ -382,6 +382,7 @@ pub fn create(arena: Allocator, options: CreateOptions) !*Package.Module {
.zig_backend = zig_backend,
.output_mode = options.global.output_mode,
.link_mode = options.global.link_mode,
+ .unwind_tables = options.global.any_unwind_tables,
.is_test = options.global.is_test,
.single_threaded = single_threaded,
.link_libc = options.global.link_libc,
src/Builtin.zig
@@ -2,6 +2,7 @@ target: std.Target,
zig_backend: std.builtin.CompilerBackend,
output_mode: std.builtin.OutputMode,
link_mode: std.builtin.LinkMode,
+unwind_tables: std.builtin.UnwindTables,
is_test: bool,
single_threaded: bool,
link_libc: bool,
@@ -40,6 +41,7 @@ pub fn append(opts: @This(), buffer: *std.ArrayList(u8)) Allocator.Error!void {
\\
\\pub const output_mode: std.builtin.OutputMode = .{p_};
\\pub const link_mode: std.builtin.LinkMode = .{p_};
+ \\pub const unwind_tables: std.builtin.UnwindTables = .{p_};
\\pub const is_test = {};
\\pub const single_threaded = {};
\\pub const abi: std.Target.Abi = .{p_};
@@ -53,6 +55,7 @@ pub fn append(opts: @This(), buffer: *std.ArrayList(u8)) Allocator.Error!void {
std.zig.fmtId(@tagName(zig_backend)),
std.zig.fmtId(@tagName(opts.output_mode)),
std.zig.fmtId(@tagName(opts.link_mode)),
+ std.zig.fmtId(@tagName(opts.unwind_tables)),
opts.is_test,
opts.single_threaded,
std.zig.fmtId(@tagName(target.abi)),
src/clang_options_data.zig
@@ -2757,7 +2757,14 @@ flagpd1("fast"),
flagpd1("fastcp"),
flagpd1("fastf"),
flagpd1("fasync-exceptions"),
-flagpd1("fasynchronous-unwind-tables"),
+.{
+ .name = "fasynchronous-unwind-tables",
+ .syntax = .flag,
+ .zig_equivalent = .asynchronous_unwind_tables,
+ .pd1 = true,
+ .pd2 = false,
+ .psl = false,
+},
flagpd1("fauto-import"),
flagpd1("fauto-profile"),
flagpd1("fauto-profile-accurate"),
@@ -3247,7 +3254,14 @@ flagpd1("fno-assume-sane-operator-new"),
flagpd1("fno-assume-unique-vtables"),
flagpd1("fno-assumptions"),
flagpd1("fno-async-exceptions"),
-flagpd1("fno-asynchronous-unwind-tables"),
+.{
+ .name = "fno-asynchronous-unwind-tables",
+ .syntax = .flag,
+ .zig_equivalent = .no_asynchronous_unwind_tables,
+ .pd1 = true,
+ .pd2 = false,
+ .psl = false,
+},
flagpd1("fno-auto-import"),
flagpd1("fno-auto-profile"),
flagpd1("fno-auto-profile-accurate"),
src/Compilation.zig
@@ -1261,12 +1261,15 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil
// The "any" values provided by resolved config only account for
// explicitly-provided settings. We now make them additionally account
// for default setting resolution.
- const any_unwind_tables = options.config.any_unwind_tables or options.root_mod.unwind_tables;
+ const any_unwind_tables = switch (options.config.any_unwind_tables) {
+ .none => options.root_mod.unwind_tables,
+ .sync, .@"async" => |uwt| uwt,
+ };
const any_non_single_threaded = options.config.any_non_single_threaded or !options.root_mod.single_threaded;
const any_sanitize_thread = options.config.any_sanitize_thread or options.root_mod.sanitize_thread;
const any_fuzz = options.config.any_fuzz or options.root_mod.fuzz;
- const link_eh_frame_hdr = options.link_eh_frame_hdr or any_unwind_tables;
+ const link_eh_frame_hdr = options.link_eh_frame_hdr or any_unwind_tables != .none;
const build_id = options.build_id orelse .none;
const link_libc = options.config.link_libc;
@@ -1354,6 +1357,7 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil
cache.hash.add(options.config.pie);
cache.hash.add(options.config.lto);
cache.hash.add(options.config.link_mode);
+ cache.hash.add(options.config.any_unwind_tables);
cache.hash.add(options.function_sections);
cache.hash.add(options.data_sections);
cache.hash.add(link_libc);
@@ -5538,10 +5542,17 @@ pub fn addCCArgs(
try argv.append("-Werror=date-time");
}
- if (mod.unwind_tables) {
- try argv.append("-funwind-tables");
- } else {
- try argv.append("-fno-unwind-tables");
+ switch (mod.unwind_tables) {
+ .none => {
+ try argv.append("-fno-unwind-tables");
+ try argv.append("-fno-asynchronous-unwind-tables");
+ },
+ .sync => {
+ // Need to override Clang's convoluted default logic.
+ try argv.append("-fno-asynchronous-unwind-tables");
+ try argv.append("-funwind-tables");
+ },
+ .@"async" => try argv.append("-fasynchronous-unwind-tables"),
}
},
.shared_library, .ll, .bc, .unknown, .static_library, .object, .def, .zig, .res, .manifest => {},
@@ -6273,6 +6284,7 @@ pub const CrtFileOptions = struct {
function_sections: ?bool = null,
data_sections: ?bool = null,
omit_frame_pointer: ?bool = null,
+ unwind_tables: ?std.builtin.UnwindTables = null,
pic: ?bool = null,
no_builtin: ?bool = null,
};
@@ -6334,7 +6346,8 @@ pub fn build_crt_file(
// Some libcs (e.g. musl) are opinionated about -fomit-frame-pointer.
.omit_frame_pointer = options.omit_frame_pointer orelse comp.root_mod.omit_frame_pointer,
.valgrind = false,
- .unwind_tables = false,
+ // Some libcs (e.g. MinGW) are opinionated about -funwind-tables.
+ .unwind_tables = options.unwind_tables orelse .none,
// Some CRT objects (e.g. musl's rcrt1.o and Scrt1.o) are opinionated about PIC.
.pic = options.pic orelse comp.root_mod.pic,
.optimize_mode = comp.compilerRtOptMode(),
src/libcxx.zig
@@ -397,7 +397,6 @@ pub fn buildLibCXXABI(comp: *Compilation, prog_node: std.Progress.Node) BuildErr
const optimize_mode = comp.compilerRtOptMode();
const strip = comp.compilerRtStrip();
- const unwind_tables = true;
const config = Compilation.Config.resolve(.{
.output_mode = output_mode,
@@ -409,7 +408,6 @@ pub fn buildLibCXXABI(comp: *Compilation, prog_node: std.Progress.Node) BuildErr
.root_optimize_mode = optimize_mode,
.root_strip = strip,
.link_libc = true,
- .any_unwind_tables = unwind_tables,
.lto = comp.config.lto,
.any_sanitize_thread = comp.config.any_sanitize_thread,
}) catch |err| {
@@ -440,7 +438,12 @@ pub fn buildLibCXXABI(comp: *Compilation, prog_node: std.Progress.Node) BuildErr
.valgrind = false,
.optimize_mode = optimize_mode,
.structured_cfg = comp.root_mod.structured_cfg,
- .unwind_tables = unwind_tables,
+ // See the `-fno-exceptions` logic for WASI.
+ // The old 32-bit x86 variant of SEH doesn't use tables.
+ .unwind_tables = if (target.os.tag == .wasi or (target.cpu.arch == .x86 and target.os.tag == .windows))
+ .none
+ else
+ .@"async",
.pic = comp.root_mod.pic,
},
.global = config,
src/libunwind.zig
@@ -65,7 +65,8 @@ pub fn buildStaticLib(comp: *Compilation, prog_node: std.Progress.Node) BuildErr
.sanitize_c = false,
.sanitize_thread = false,
// necessary so that libunwind can unwind through its own stack frames
- .unwind_tables = true,
+ // The old 32-bit x86 variant of SEH doesn't use tables.
+ .unwind_tables = if (target.cpu.arch == .x86 and target.os.tag == .windows) .none else .@"async",
.pic = if (target_util.supports_fpic(target)) true else null,
.optimize_mode = comp.compilerRtOptMode(),
},
src/main.zig
@@ -510,6 +510,7 @@ const usage_build_generic =
\\ -ffuzz Enable fuzz testing instrumentation
\\ -fno-fuzz Disable fuzz testing instrumentation
\\ -funwind-tables Always produce unwind table entries for all functions
+ \\ -fasync-unwind-tables Always produce asynchronous unwind table entries for all functions
\\ -fno-unwind-tables Never produce unwind table entries
\\ -ferror-tracing Enable error tracing in ReleaseFast mode
\\ -fno-error-tracing Disable error tracing in Debug and ReleaseSafe mode
@@ -1385,9 +1386,11 @@ fn buildOutputType(
} else if (mem.eql(u8, arg, "-fno-lto")) {
create_module.opts.lto = false;
} else if (mem.eql(u8, arg, "-funwind-tables")) {
- mod_opts.unwind_tables = true;
+ mod_opts.unwind_tables = .sync;
+ } else if (mem.eql(u8, arg, "-fasync-unwind-tables")) {
+ mod_opts.unwind_tables = .@"async";
} else if (mem.eql(u8, arg, "-fno-unwind-tables")) {
- mod_opts.unwind_tables = false;
+ mod_opts.unwind_tables = .none;
} else if (mem.eql(u8, arg, "-fstack-check")) {
mod_opts.stack_check = true;
} else if (mem.eql(u8, arg, "-fno-stack-check")) {
@@ -1973,8 +1976,27 @@ fn buildOutputType(
}
},
.no_stack_protector => mod_opts.stack_protector = 0,
- .unwind_tables => mod_opts.unwind_tables = true,
- .no_unwind_tables => mod_opts.unwind_tables = false,
+ // The way these unwind table options are processed in GCC and Clang is crazy
+ // convoluted, and we also don't know the target triple here, so this is all
+ // best-effort.
+ .unwind_tables => if (mod_opts.unwind_tables) |uwt| switch (uwt) {
+ .none => {
+ mod_opts.unwind_tables = .sync;
+ },
+ .sync, .@"async" => {},
+ } else {
+ mod_opts.unwind_tables = .sync;
+ },
+ .no_unwind_tables => mod_opts.unwind_tables = .none,
+ .asynchronous_unwind_tables => mod_opts.unwind_tables = .@"async",
+ .no_asynchronous_unwind_tables => if (mod_opts.unwind_tables) |uwt| switch (uwt) {
+ .none, .sync => {},
+ .@"async" => {
+ mod_opts.unwind_tables = .sync;
+ },
+ } else {
+ mod_opts.unwind_tables = .sync;
+ },
.nostdlib => {
create_module.opts.ensure_libc_on_non_freestanding = false;
create_module.opts.ensure_libcpp_on_non_freestanding = false;
@@ -2788,8 +2810,15 @@ fn buildOutputType(
create_module.opts.any_sanitize_thread = true;
if (mod_opts.fuzz == true)
create_module.opts.any_fuzz = true;
- if (mod_opts.unwind_tables == true)
- create_module.opts.any_unwind_tables = true;
+ if (mod_opts.unwind_tables) |uwt| switch (uwt) {
+ .none => {},
+ .sync => if (create_module.opts.any_unwind_tables == .none) {
+ create_module.opts.any_unwind_tables = .sync;
+ },
+ .@"async" => {
+ create_module.opts.any_unwind_tables = .@"async";
+ },
+ };
if (mod_opts.strip == false)
create_module.opts.any_non_stripped = true;
if (mod_opts.error_tracing == true)
@@ -5713,6 +5742,8 @@ pub const ClangArgIterator = struct {
no_lto,
unwind_tables,
no_unwind_tables,
+ asynchronous_unwind_tables,
+ no_asynchronous_unwind_tables,
nostdlib,
nostdlib_cpp,
shared,
@@ -7435,8 +7466,15 @@ fn handleModArg(
create_module.opts.any_sanitize_thread = true;
if (mod_opts.fuzz == true)
create_module.opts.any_fuzz = true;
- if (mod_opts.unwind_tables == true)
- create_module.opts.any_unwind_tables = true;
+ if (mod_opts.unwind_tables) |uwt| switch (uwt) {
+ .none => {},
+ .sync => if (create_module.opts.any_unwind_tables == .none) {
+ create_module.opts.any_unwind_tables = .sync;
+ },
+ .@"async" => {
+ create_module.opts.any_unwind_tables = .@"async";
+ },
+ };
if (mod_opts.strip == false)
create_module.opts.any_non_stripped = true;
if (mod_opts.error_tracing == true)
src/mingw.zig
@@ -24,6 +24,10 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre
var arena_allocator = std.heap.ArenaAllocator.init(comp.gpa);
defer arena_allocator.deinit();
const arena = arena_allocator.allocator();
+ const target = comp.getTarget();
+
+ // The old 32-bit x86 variant of SEH doesn't use tables.
+ const unwind_tables: std.builtin.UnwindTables = if (target.cpu.arch != .x86) .@"async" else .none;
switch (crt_file) {
.crt2_o => {
@@ -41,7 +45,9 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre
.owner = undefined,
},
};
- return comp.build_crt_file("crt2", .Obj, .@"mingw-w64 crt2.o", prog_node, &files, .{});
+ return comp.build_crt_file("crt2", .Obj, .@"mingw-w64 crt2.o", prog_node, &files, .{
+ .unwind_tables = unwind_tables,
+ });
},
.dllcrt2_o => {
@@ -56,7 +62,9 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre
.owner = undefined,
},
};
- return comp.build_crt_file("dllcrt2", .Obj, .@"mingw-w64 dllcrt2.o", prog_node, &files, .{});
+ return comp.build_crt_file("dllcrt2", .Obj, .@"mingw-w64 dllcrt2.o", prog_node, &files, .{
+ .unwind_tables = unwind_tables,
+ });
},
.mingw32_lib => {
@@ -73,7 +81,6 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre
.owner = undefined,
});
}
- const target = comp.getTarget();
if (target.cpu.arch == .x86 or target.cpu.arch == .x86_64) {
for (mingw32_x86_src) |dep| {
try c_source_files.append(.{
@@ -118,7 +125,9 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre
} else {
@panic("unsupported arch");
}
- return comp.build_crt_file("mingw32", .Lib, .@"mingw-w64 mingw32.lib", prog_node, c_source_files.items, .{});
+ return comp.build_crt_file("mingw32", .Lib, .@"mingw-w64 mingw32.lib", prog_node, c_source_files.items, .{
+ .unwind_tables = unwind_tables,
+ });
},
}
}
src/target.zig
@@ -4,6 +4,7 @@ const assert = std.debug.assert;
const Type = @import("Type.zig");
const AddressSpace = std.builtin.AddressSpace;
const Alignment = @import("InternPool.zig").Alignment;
+const Compilation = @import("Compilation.zig");
const Feature = @import("Zcu.zig").Feature;
pub const default_stack_protector_buffer_size = 4;
@@ -408,8 +409,16 @@ pub fn clangSupportsNoImplicitFloatArg(target: std.Target) bool {
};
}
-pub fn needUnwindTables(target: std.Target) bool {
- return target.os.tag == .windows or target.isDarwin() or std.debug.Dwarf.abi.supportsUnwinding(target);
+pub fn needUnwindTables(target: std.Target, libunwind: bool, libtsan: bool) std.builtin.UnwindTables {
+ if (target.os.tag == .windows) {
+ // The old 32-bit x86 variant of SEH doesn't use tables.
+ return if (target.cpu.arch != .x86) .@"async" else .none;
+ }
+ if (target.os.tag.isDarwin()) return .@"async";
+ if (libunwind) return .@"async";
+ if (libtsan) return .@"async";
+ if (std.debug.Dwarf.abi.supportsUnwinding(target)) return .@"async";
+ return .none;
}
pub fn defaultAddressSpace(
test/standalone/stack_iterator/build.zig
@@ -23,7 +23,7 @@ pub fn build(b: *std.Build) void {
.root_source_file = b.path("unwind.zig"),
.target = target,
.optimize = optimize,
- .unwind_tables = if (target.result.isDarwin()) true else null,
+ .unwind_tables = if (target.result.isDarwin()) .@"async" else null,
.omit_frame_pointer = false,
});
@@ -46,7 +46,7 @@ pub fn build(b: *std.Build) void {
.root_source_file = b.path("unwind.zig"),
.target = target,
.optimize = optimize,
- .unwind_tables = true,
+ .unwind_tables = .@"async",
.omit_frame_pointer = true,
});
@@ -85,7 +85,7 @@ pub fn build(b: *std.Build) void {
.root_source_file = b.path("shared_lib_unwind.zig"),
.target = target,
.optimize = optimize,
- .unwind_tables = if (target.result.isDarwin()) true else null,
+ .unwind_tables = if (target.result.isDarwin()) .@"async" else null,
.omit_frame_pointer = true,
});
tools/update_clang_options.zig
@@ -110,6 +110,14 @@ const known_options = [_]KnownOpt{
.name = "fno-unwind-tables",
.ident = "no_unwind_tables",
},
+ .{
+ .name = "fasynchronous-unwind-tables",
+ .ident = "asynchronous_unwind_tables",
+ },
+ .{
+ .name = "fno-asynchronous-unwind-tables",
+ .ident = "no_asynchronous_unwind_tables",
+ },
.{
.name = "nolibc",
.ident = "nostdlib",