zig

fork of https://codeberg.org/ziglang/zig
Log | Files | Refs | README | LICENSE

commit d5db02728ce3ff3ba74a3e3f9050c3ea9ed34752 (tree)
parent 5cfcb015033864c769235726975ab9919c217ef9
Author: Alex Rønne Petersen <alex@alexrp.com>
Date:   Mon, 20 Jan 2025 07:24:12 +0100

Merge pull request #22530 from alexrp/omit-unwind-tables

Fix building the standard library without CFI directives
Diffstat:
Mlib/std/os/linux/aarch64.zig | 8+++++++-
Mlib/std/os/linux/hexagon.zig | 6+++++-
Mlib/std/os/linux/loongarch64.zig | 5+++++
Mlib/std/os/linux/mips.zig | 5+++++
Mlib/std/os/linux/mips64.zig | 5+++++
Mlib/std/os/linux/powerpc.zig | 5+++++
Mlib/std/os/linux/powerpc64.zig | 5+++++
Mlib/std/os/linux/riscv32.zig | 8+++++++-
Mlib/std/os/linux/riscv64.zig | 8+++++++-
Mlib/std/os/linux/s390x.zig | 5+++++
Mlib/std/os/linux/sparc64.zig | 5+++++
Mlib/std/os/linux/x86.zig | 5+++++
Mlib/std/os/linux/x86_64.zig | 8+++++++-
Mlib/std/start.zig | 4++--
Msrc/Package/Module.zig | 2+-
Mtest/standalone/build.zig.zon | 3+++
Atest/standalone/omit_cfi/build.zig | 67+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Atest/standalone/omit_cfi/main.zig | 1+
18 files changed, 147 insertions(+), 8 deletions(-)

diff --git a/lib/std/os/linux/aarch64.zig b/lib/std/os/linux/aarch64.zig @@ -1,3 +1,4 @@ +const builtin = @import("builtin"); const std = @import("../../std.zig"); const maxInt = std.math.maxInt; const linux = std.os.linux; @@ -122,7 +123,12 @@ pub fn clone() callconv(.Naked) usize { \\ ret \\ \\ // child - \\1: .cfi_undefined lr + \\1: + ); + if (builtin.unwind_tables != .none or !builtin.strip_debug_info) asm volatile ( + \\ .cfi_undefined lr + ); + asm volatile ( \\ mov fp, 0 \\ mov lr, 0 \\ diff --git a/lib/std/os/linux/hexagon.zig b/lib/std/os/linux/hexagon.zig @@ -1,3 +1,4 @@ +const builtin = @import("builtin"); const std = @import("../../std.zig"); const iovec = std.posix.iovec; const iovec_const = std.posix.iovec_const; @@ -117,8 +118,11 @@ pub fn clone() callconv(.Naked) usize { \\ \\ p0 = cmp.eq(r0, #0) \\ if (!p0) dealloc_return - \\ + ); + if (builtin.unwind_tables != .none or !builtin.strip_debug_info) asm volatile ( \\ .cfi_undefined r31 + ); + asm volatile ( \\ r30 = #0 \\ r31 = #0 \\ diff --git a/lib/std/os/linux/loongarch64.zig b/lib/std/os/linux/loongarch64.zig @@ -1,3 +1,4 @@ +const builtin = @import("builtin"); const std = @import("../../std.zig"); const linux = std.os.linux; const SYS = linux.SYS; @@ -121,7 +122,11 @@ pub fn clone() callconv(.Naked) usize { \\ beqz $a0, 1f # whether child process \\ jirl $zero, $ra, 0 # parent process return \\1: + ); + if (builtin.unwind_tables != .none or !builtin.strip_debug_info) asm volatile ( \\ .cfi_undefined 1 + ); + asm volatile ( \\ move $fp, $zero \\ move $ra, $zero \\ diff --git a/lib/std/os/linux/mips.zig b/lib/std/os/linux/mips.zig @@ -1,3 +1,4 @@ +const builtin = @import("builtin"); const std = @import("../../std.zig"); const maxInt = std.math.maxInt; const linux = std.os.linux; @@ -231,7 +232,11 @@ pub fn clone() callconv(.Naked) usize { \\ jr $ra \\ nop \\1: + ); + if (builtin.unwind_tables != .none or !builtin.strip_debug_info) asm volatile ( \\ .cfi_undefined $ra + ); + asm volatile ( \\ move $fp, $zero \\ move $ra, $zero \\ diff --git a/lib/std/os/linux/mips64.zig b/lib/std/os/linux/mips64.zig @@ -1,3 +1,4 @@ +const builtin = @import("builtin"); const std = @import("../../std.zig"); const maxInt = std.math.maxInt; const linux = std.os.linux; @@ -210,7 +211,11 @@ pub fn clone() callconv(.Naked) usize { \\ jr $ra \\ nop \\1: + ); + if (builtin.unwind_tables != .none or !builtin.strip_debug_info) asm volatile ( \\ .cfi_undefined $ra + ); + asm volatile ( \\ move $fp, $zero \\ move $ra, $zero \\ diff --git a/lib/std/os/linux/powerpc.zig b/lib/std/os/linux/powerpc.zig @@ -1,3 +1,4 @@ +const builtin = @import("builtin"); const std = @import("../../std.zig"); const maxInt = std.math.maxInt; const linux = std.os.linux; @@ -176,7 +177,11 @@ pub fn clone() callconv(.Naked) usize { \\ \\ #else: we're the child \\ 2: + ); + if (builtin.unwind_tables != .none or !builtin.strip_debug_info) asm volatile ( \\ .cfi_undefined lr + ); + asm volatile ( \\ li 31, 0 \\ mtlr 0 \\ diff --git a/lib/std/os/linux/powerpc64.zig b/lib/std/os/linux/powerpc64.zig @@ -1,3 +1,4 @@ +const builtin = @import("builtin"); const std = @import("../../std.zig"); const maxInt = std.math.maxInt; const linux = std.os.linux; @@ -161,7 +162,11 @@ pub fn clone() callconv(.Naked) usize { \\ bnelr cr7 \\ \\ # we're the child + ); + if (builtin.unwind_tables != .none or !builtin.strip_debug_info) asm volatile ( \\ .cfi_undefined lr + ); + asm volatile ( \\ li 31, 0 \\ mtlr 0 \\ diff --git a/lib/std/os/linux/riscv32.zig b/lib/std/os/linux/riscv32.zig @@ -1,3 +1,4 @@ +const builtin = @import("builtin"); const std = @import("../../std.zig"); const iovec = std.posix.iovec; const iovec_const = std.posix.iovec_const; @@ -120,7 +121,12 @@ pub fn clone() callconv(.Naked) usize { \\ ret \\ \\ # Child - \\1: .cfi_undefined ra + \\1: + ); + if (builtin.unwind_tables != .none or !builtin.strip_debug_info) asm volatile ( + \\ .cfi_undefined ra + ); + asm volatile ( \\ mv fp, zero \\ mv ra, zero \\ diff --git a/lib/std/os/linux/riscv64.zig b/lib/std/os/linux/riscv64.zig @@ -1,3 +1,4 @@ +const builtin = @import("builtin"); const std = @import("../../std.zig"); const iovec = std.posix.iovec; const iovec_const = std.posix.iovec_const; @@ -120,7 +121,12 @@ pub fn clone() callconv(.Naked) usize { \\ ret \\ \\ # Child - \\1: .cfi_undefined ra + \\1: + ); + if (builtin.unwind_tables != .none or !builtin.strip_debug_info) asm volatile ( + \\ .cfi_undefined ra + ); + asm volatile ( \\ mv fp, zero \\ mv ra, zero \\ diff --git a/lib/std/os/linux/s390x.zig b/lib/std/os/linux/s390x.zig @@ -1,3 +1,4 @@ +const builtin = @import("builtin"); const std = @import("../../std.zig"); const iovec = std.posix.iovec; const iovec_const = std.posix.iovec_const; @@ -134,7 +135,11 @@ pub fn clone() callconv(.Naked) usize { \\bnzr %%r14 \\ \\# we're the child + ); + if (builtin.unwind_tables != .none or !builtin.strip_debug_info) asm volatile ( \\.cfi_undefined %%r14 + ); + asm volatile ( \\lghi %%r11, 0 \\lghi %%r14, 0 \\ diff --git a/lib/std/os/linux/sparc64.zig b/lib/std/os/linux/sparc64.zig @@ -1,3 +1,4 @@ +const builtin = @import("builtin"); const std = @import("../../std.zig"); const maxInt = std.math.maxInt; const pid_t = linux.pid_t; @@ -215,7 +216,11 @@ pub fn clone() callconv(.Naked) usize { \\ restore \\2: \\ # Child process + ); + if (builtin.unwind_tables != .none or !builtin.strip_debug_info) asm volatile ( \\ .cfi_undefined %%i7 + ); + asm volatile ( \\ mov %%g0, %%fp \\ mov %%g0, %%i7 \\ diff --git a/lib/std/os/linux/x86.zig b/lib/std/os/linux/x86.zig @@ -1,3 +1,4 @@ +const builtin = @import("builtin"); const std = @import("../../std.zig"); const maxInt = std.math.maxInt; const linux = std.os.linux; @@ -156,7 +157,11 @@ pub fn clone() callconv(.Naked) usize { \\ retl \\ \\1: + ); + if (builtin.unwind_tables != .none or !builtin.strip_debug_info) asm volatile ( \\ .cfi_undefined %%eip + ); + asm volatile ( \\ xorl %%ebp,%%ebp \\ \\ popl %%eax diff --git a/lib/std/os/linux/x86_64.zig b/lib/std/os/linux/x86_64.zig @@ -1,3 +1,4 @@ +const builtin = @import("builtin"); const std = @import("../../std.zig"); const maxInt = std.math.maxInt; const linux = std.os.linux; @@ -117,7 +118,12 @@ pub fn clone() callconv(.Naked) usize { \\ jz 1f \\ retq \\ - \\1: .cfi_undefined %%rip + \\1: + ); + if (builtin.unwind_tables != .none or !builtin.strip_debug_info) asm volatile ( + \\ .cfi_undefined %%rip + ); + asm volatile ( \\ xorl %%ebp,%%ebp \\ \\ popq %%rdi diff --git a/lib/std/start.zig b/lib/std/start.zig @@ -231,8 +231,8 @@ fn _start() callconv(.naked) noreturn { } // This is the first userspace frame. Prevent DWARF-based unwinders from unwinding further. We - // prevent FP-based unwinders from unwinding further by zeroing the register further below. - asm volatile (switch (native_arch) { + // prevent FP-based unwinders from unwinding further by zeroing the register below. + if (builtin.unwind_tables != .none or !builtin.strip_debug_info) asm volatile (switch (native_arch) { .arc => ".cfi_undefined blink", .arm, .armeb, .thumb, .thumbeb => "", // https://github.com/llvm/llvm-project/issues/115891 .aarch64, .aarch64_be => ".cfi_undefined lr", diff --git a/src/Package/Module.zig b/src/Package/Module.zig @@ -387,7 +387,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, + .unwind_tables = unwind_tables, .is_test = options.global.is_test, .single_threaded = single_threaded, .link_libc = options.global.link_libc, diff --git a/test/standalone/build.zig.zon b/test/standalone/build.zig.zon @@ -183,6 +183,9 @@ .empty_global_error_set = .{ .path = "empty_global_error_set", }, + .omit_cfi = .{ + .path = "omit_cfi", + }, }, .paths = .{ "build.zig", diff --git a/test/standalone/omit_cfi/build.zig b/test/standalone/omit_cfi/build.zig @@ -0,0 +1,67 @@ +const std = @import("std"); + +pub fn build(b: *std.Build) void { + inline for (.{ + .aarch64, + .aarch64_be, + .hexagon, + .loongarch64, + .mips, + .mipsel, + .mips64, + .mips64el, + .powerpc, + .powerpcle, + .powerpc64, + .powerpc64le, + .riscv32, + .riscv64, + .s390x, + .sparc64, + .x86, + .x86_64, + }) |arch| { + const target = b.resolveTargetQuery(.{ + .cpu_arch = arch, + .os_tag = .linux, + }); + + const omit_dbg = b.addExecutable(.{ + .name = b.fmt("{s}-linux-omit-dbg", .{@tagName(arch)}), + .root_module = b.createModule(.{ + .root_source_file = b.path("main.zig"), + .target = target, + .optimize = .Debug, + // We are mainly concerned with CFI directives in our non-libc startup code and syscall + // code, so make it explicit that we don't want libc. + .link_libc = false, + .strip = true, + }), + }); + + const omit_uwt = b.addExecutable(.{ + .name = b.fmt("{s}-linux-omit-uwt", .{@tagName(arch)}), + .root_module = b.createModule(.{ + .root_source_file = b.path("main.zig"), + .target = target, + .optimize = .Debug, + .link_libc = false, + .unwind_tables = .none, + }), + }); + + const omit_both = b.addExecutable(.{ + .name = b.fmt("{s}-linux-omit-both", .{@tagName(arch)}), + .root_module = b.createModule(.{ + .root_source_file = b.path("main.zig"), + .target = target, + .optimize = .Debug, + .link_libc = false, + .strip = true, + .unwind_tables = .none, + }), + }); + + inline for (.{ omit_dbg, omit_uwt, omit_both }) |step| b.installArtifact(step); + } +} diff --git a/test/standalone/omit_cfi/main.zig b/test/standalone/omit_cfi/main.zig @@ -0,0 +1 @@ +pub fn main() void {}