authorgravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2025-01-20 07:24:12+01:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2025-01-20 07:24:12+01:00
logd5db02728ce3ff3ba74a3e3f9050c3ea9ed34752
treeff3cdbf992c1072f5e72b856d3fb53d7cd6dd9e3
parent5cfcb015033864c769235726975ab9919c217ef9
parent45bb4f955c8c8be40ed8b2247eaaa70661cf1b3d
signaturebadge-check Signed by PGP key B5690EEEBB952194

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

Fix building the standard library without CFI directives

18 files changed, 147 insertions(+), 8 deletions(-)

lib/std/os/linux/aarch64.zig+7-1
...@@ -1,3 +1,4 @@...@@ -1,3 +1,4 @@
1const builtin = @import("builtin");
1const std = @import("../../std.zig");2const std = @import("../../std.zig");
2const maxInt = std.math.maxInt;3const maxInt = std.math.maxInt;
3const linux = std.os.linux;4const linux = std.os.linux;
...@@ -122,7 +123,12 @@ pub fn clone() callconv(.Naked) usize {...@@ -122,7 +123,12 @@ pub fn clone() callconv(.Naked) usize {
122 \\ ret123 \\ ret
123 \\124 \\
124 \\ // child125 \\ // child
125 \\1: .cfi_undefined lr126 \\1:
127 );
128 if (builtin.unwind_tables != .none or !builtin.strip_debug_info) asm volatile (
129 \\ .cfi_undefined lr
130 );
131 asm volatile (
126 \\ mov fp, 0132 \\ mov fp, 0
127 \\ mov lr, 0133 \\ mov lr, 0
128 \\134 \\
lib/std/os/linux/hexagon.zig+5-1
...@@ -1,3 +1,4 @@...@@ -1,3 +1,4 @@
1const builtin = @import("builtin");
1const std = @import("../../std.zig");2const std = @import("../../std.zig");
2const iovec = std.posix.iovec;3const iovec = std.posix.iovec;
3const iovec_const = std.posix.iovec_const;4const iovec_const = std.posix.iovec_const;
...@@ -117,8 +118,11 @@ pub fn clone() callconv(.Naked) usize {...@@ -117,8 +118,11 @@ pub fn clone() callconv(.Naked) usize {
117 \\118 \\
118 \\ p0 = cmp.eq(r0, #0)119 \\ p0 = cmp.eq(r0, #0)
119 \\ if (!p0) dealloc_return120 \\ if (!p0) dealloc_return
120 \\121 );
122 if (builtin.unwind_tables != .none or !builtin.strip_debug_info) asm volatile (
121 \\ .cfi_undefined r31123 \\ .cfi_undefined r31
124 );
125 asm volatile (
122 \\ r30 = #0126 \\ r30 = #0
123 \\ r31 = #0127 \\ r31 = #0
124 \\128 \\
lib/std/os/linux/loongarch64.zig+5
...@@ -1,3 +1,4 @@...@@ -1,3 +1,4 @@
1const builtin = @import("builtin");
1const std = @import("../../std.zig");2const std = @import("../../std.zig");
2const linux = std.os.linux;3const linux = std.os.linux;
3const SYS = linux.SYS;4const SYS = linux.SYS;
...@@ -121,7 +122,11 @@ pub fn clone() callconv(.Naked) usize {...@@ -121,7 +122,11 @@ pub fn clone() callconv(.Naked) usize {
121 \\ beqz $a0, 1f # whether child process122 \\ beqz $a0, 1f # whether child process
122 \\ jirl $zero, $ra, 0 # parent process return123 \\ jirl $zero, $ra, 0 # parent process return
123 \\1:124 \\1:
125 );
126 if (builtin.unwind_tables != .none or !builtin.strip_debug_info) asm volatile (
124 \\ .cfi_undefined 1127 \\ .cfi_undefined 1
128 );
129 asm volatile (
125 \\ move $fp, $zero130 \\ move $fp, $zero
126 \\ move $ra, $zero131 \\ move $ra, $zero
127 \\132 \\
lib/std/os/linux/mips.zig+5
...@@ -1,3 +1,4 @@...@@ -1,3 +1,4 @@
1const builtin = @import("builtin");
1const std = @import("../../std.zig");2const std = @import("../../std.zig");
2const maxInt = std.math.maxInt;3const maxInt = std.math.maxInt;
3const linux = std.os.linux;4const linux = std.os.linux;
...@@ -231,7 +232,11 @@ pub fn clone() callconv(.Naked) usize {...@@ -231,7 +232,11 @@ pub fn clone() callconv(.Naked) usize {
231 \\ jr $ra232 \\ jr $ra
232 \\ nop233 \\ nop
233 \\1:234 \\1:
235 );
236 if (builtin.unwind_tables != .none or !builtin.strip_debug_info) asm volatile (
234 \\ .cfi_undefined $ra237 \\ .cfi_undefined $ra
238 );
239 asm volatile (
235 \\ move $fp, $zero240 \\ move $fp, $zero
236 \\ move $ra, $zero241 \\ move $ra, $zero
237 \\242 \\
lib/std/os/linux/mips64.zig+5
...@@ -1,3 +1,4 @@...@@ -1,3 +1,4 @@
1const builtin = @import("builtin");
1const std = @import("../../std.zig");2const std = @import("../../std.zig");
2const maxInt = std.math.maxInt;3const maxInt = std.math.maxInt;
3const linux = std.os.linux;4const linux = std.os.linux;
...@@ -210,7 +211,11 @@ pub fn clone() callconv(.Naked) usize {...@@ -210,7 +211,11 @@ pub fn clone() callconv(.Naked) usize {
210 \\ jr $ra211 \\ jr $ra
211 \\ nop212 \\ nop
212 \\1:213 \\1:
214 );
215 if (builtin.unwind_tables != .none or !builtin.strip_debug_info) asm volatile (
213 \\ .cfi_undefined $ra216 \\ .cfi_undefined $ra
217 );
218 asm volatile (
214 \\ move $fp, $zero219 \\ move $fp, $zero
215 \\ move $ra, $zero220 \\ move $ra, $zero
216 \\221 \\
lib/std/os/linux/powerpc.zig+5
...@@ -1,3 +1,4 @@...@@ -1,3 +1,4 @@
1const builtin = @import("builtin");
1const std = @import("../../std.zig");2const std = @import("../../std.zig");
2const maxInt = std.math.maxInt;3const maxInt = std.math.maxInt;
3const linux = std.os.linux;4const linux = std.os.linux;
...@@ -176,7 +177,11 @@ pub fn clone() callconv(.Naked) usize {...@@ -176,7 +177,11 @@ pub fn clone() callconv(.Naked) usize {
176 \\177 \\
177 \\ #else: we're the child178 \\ #else: we're the child
178 \\ 2:179 \\ 2:
180 );
181 if (builtin.unwind_tables != .none or !builtin.strip_debug_info) asm volatile (
179 \\ .cfi_undefined lr182 \\ .cfi_undefined lr
183 );
184 asm volatile (
180 \\ li 31, 0185 \\ li 31, 0
181 \\ mtlr 0186 \\ mtlr 0
182 \\187 \\
lib/std/os/linux/powerpc64.zig+5
...@@ -1,3 +1,4 @@...@@ -1,3 +1,4 @@
1const builtin = @import("builtin");
1const std = @import("../../std.zig");2const std = @import("../../std.zig");
2const maxInt = std.math.maxInt;3const maxInt = std.math.maxInt;
3const linux = std.os.linux;4const linux = std.os.linux;
...@@ -161,7 +162,11 @@ pub fn clone() callconv(.Naked) usize {...@@ -161,7 +162,11 @@ pub fn clone() callconv(.Naked) usize {
161 \\ bnelr cr7162 \\ bnelr cr7
162 \\163 \\
163 \\ # we're the child164 \\ # we're the child
165 );
166 if (builtin.unwind_tables != .none or !builtin.strip_debug_info) asm volatile (
164 \\ .cfi_undefined lr167 \\ .cfi_undefined lr
168 );
169 asm volatile (
165 \\ li 31, 0170 \\ li 31, 0
166 \\ mtlr 0171 \\ mtlr 0
167 \\172 \\
lib/std/os/linux/riscv32.zig+7-1
...@@ -1,3 +1,4 @@...@@ -1,3 +1,4 @@
1const builtin = @import("builtin");
1const std = @import("../../std.zig");2const std = @import("../../std.zig");
2const iovec = std.posix.iovec;3const iovec = std.posix.iovec;
3const iovec_const = std.posix.iovec_const;4const iovec_const = std.posix.iovec_const;
...@@ -120,7 +121,12 @@ pub fn clone() callconv(.Naked) usize {...@@ -120,7 +121,12 @@ pub fn clone() callconv(.Naked) usize {
120 \\ ret121 \\ ret
121 \\122 \\
122 \\ # Child123 \\ # Child
123 \\1: .cfi_undefined ra124 \\1:
125 );
126 if (builtin.unwind_tables != .none or !builtin.strip_debug_info) asm volatile (
127 \\ .cfi_undefined ra
128 );
129 asm volatile (
124 \\ mv fp, zero130 \\ mv fp, zero
125 \\ mv ra, zero131 \\ mv ra, zero
126 \\132 \\
lib/std/os/linux/riscv64.zig+7-1
...@@ -1,3 +1,4 @@...@@ -1,3 +1,4 @@
1const builtin = @import("builtin");
1const std = @import("../../std.zig");2const std = @import("../../std.zig");
2const iovec = std.posix.iovec;3const iovec = std.posix.iovec;
3const iovec_const = std.posix.iovec_const;4const iovec_const = std.posix.iovec_const;
...@@ -120,7 +121,12 @@ pub fn clone() callconv(.Naked) usize {...@@ -120,7 +121,12 @@ pub fn clone() callconv(.Naked) usize {
120 \\ ret121 \\ ret
121 \\122 \\
122 \\ # Child123 \\ # Child
123 \\1: .cfi_undefined ra124 \\1:
125 );
126 if (builtin.unwind_tables != .none or !builtin.strip_debug_info) asm volatile (
127 \\ .cfi_undefined ra
128 );
129 asm volatile (
124 \\ mv fp, zero130 \\ mv fp, zero
125 \\ mv ra, zero131 \\ mv ra, zero
126 \\132 \\
lib/std/os/linux/s390x.zig+5
...@@ -1,3 +1,4 @@...@@ -1,3 +1,4 @@
1const builtin = @import("builtin");
1const std = @import("../../std.zig");2const std = @import("../../std.zig");
2const iovec = std.posix.iovec;3const iovec = std.posix.iovec;
3const iovec_const = std.posix.iovec_const;4const iovec_const = std.posix.iovec_const;
...@@ -134,7 +135,11 @@ pub fn clone() callconv(.Naked) usize {...@@ -134,7 +135,11 @@ pub fn clone() callconv(.Naked) usize {
134 \\bnzr %%r14135 \\bnzr %%r14
135 \\136 \\
136 \\# we're the child137 \\# we're the child
138 );
139 if (builtin.unwind_tables != .none or !builtin.strip_debug_info) asm volatile (
137 \\.cfi_undefined %%r14140 \\.cfi_undefined %%r14
141 );
142 asm volatile (
138 \\lghi %%r11, 0143 \\lghi %%r11, 0
139 \\lghi %%r14, 0144 \\lghi %%r14, 0
140 \\145 \\
lib/std/os/linux/sparc64.zig+5
...@@ -1,3 +1,4 @@...@@ -1,3 +1,4 @@
1const builtin = @import("builtin");
1const std = @import("../../std.zig");2const std = @import("../../std.zig");
2const maxInt = std.math.maxInt;3const maxInt = std.math.maxInt;
3const pid_t = linux.pid_t;4const pid_t = linux.pid_t;
...@@ -215,7 +216,11 @@ pub fn clone() callconv(.Naked) usize {...@@ -215,7 +216,11 @@ pub fn clone() callconv(.Naked) usize {
215 \\ restore216 \\ restore
216 \\2:217 \\2:
217 \\ # Child process218 \\ # Child process
219 );
220 if (builtin.unwind_tables != .none or !builtin.strip_debug_info) asm volatile (
218 \\ .cfi_undefined %%i7221 \\ .cfi_undefined %%i7
222 );
223 asm volatile (
219 \\ mov %%g0, %%fp224 \\ mov %%g0, %%fp
220 \\ mov %%g0, %%i7225 \\ mov %%g0, %%i7
221 \\226 \\
lib/std/os/linux/x86.zig+5
...@@ -1,3 +1,4 @@...@@ -1,3 +1,4 @@
1const builtin = @import("builtin");
1const std = @import("../../std.zig");2const std = @import("../../std.zig");
2const maxInt = std.math.maxInt;3const maxInt = std.math.maxInt;
3const linux = std.os.linux;4const linux = std.os.linux;
...@@ -156,7 +157,11 @@ pub fn clone() callconv(.Naked) usize {...@@ -156,7 +157,11 @@ pub fn clone() callconv(.Naked) usize {
156 \\ retl157 \\ retl
157 \\158 \\
158 \\1:159 \\1:
160 );
161 if (builtin.unwind_tables != .none or !builtin.strip_debug_info) asm volatile (
159 \\ .cfi_undefined %%eip162 \\ .cfi_undefined %%eip
163 );
164 asm volatile (
160 \\ xorl %%ebp,%%ebp165 \\ xorl %%ebp,%%ebp
161 \\166 \\
162 \\ popl %%eax167 \\ popl %%eax
lib/std/os/linux/x86_64.zig+7-1
...@@ -1,3 +1,4 @@...@@ -1,3 +1,4 @@
1const builtin = @import("builtin");
1const std = @import("../../std.zig");2const std = @import("../../std.zig");
2const maxInt = std.math.maxInt;3const maxInt = std.math.maxInt;
3const linux = std.os.linux;4const linux = std.os.linux;
...@@ -117,7 +118,12 @@ pub fn clone() callconv(.Naked) usize {...@@ -117,7 +118,12 @@ pub fn clone() callconv(.Naked) usize {
117 \\ jz 1f118 \\ jz 1f
118 \\ retq119 \\ retq
119 \\120 \\
120 \\1: .cfi_undefined %%rip121 \\1:
122 );
123 if (builtin.unwind_tables != .none or !builtin.strip_debug_info) asm volatile (
124 \\ .cfi_undefined %%rip
125 );
126 asm volatile (
121 \\ xorl %%ebp,%%ebp127 \\ xorl %%ebp,%%ebp
122 \\128 \\
123 \\ popq %%rdi129 \\ popq %%rdi
lib/std/start.zig+2-2
...@@ -231,8 +231,8 @@ fn _start() callconv(.naked) noreturn {...@@ -231,8 +231,8 @@ fn _start() callconv(.naked) noreturn {
231 }231 }
232232
233 // This is the first userspace frame. Prevent DWARF-based unwinders from unwinding further. We233 // This is the first userspace frame. Prevent DWARF-based unwinders from unwinding further. We
234 // prevent FP-based unwinders from unwinding further by zeroing the register further below.234 // prevent FP-based unwinders from unwinding further by zeroing the register below.
235 asm volatile (switch (native_arch) {235 if (builtin.unwind_tables != .none or !builtin.strip_debug_info) asm volatile (switch (native_arch) {
236 .arc => ".cfi_undefined blink",236 .arc => ".cfi_undefined blink",
237 .arm, .armeb, .thumb, .thumbeb => "", // https://github.com/llvm/llvm-project/issues/115891237 .arm, .armeb, .thumb, .thumbeb => "", // https://github.com/llvm/llvm-project/issues/115891
238 .aarch64, .aarch64_be => ".cfi_undefined lr",238 .aarch64, .aarch64_be => ".cfi_undefined lr",
src/Package/Module.zig+1-1
...@@ -387,7 +387,7 @@ pub fn create(arena: Allocator, options: CreateOptions) !*Package.Module {...@@ -387,7 +387,7 @@ pub fn create(arena: Allocator, options: CreateOptions) !*Package.Module {
387 .zig_backend = zig_backend,387 .zig_backend = zig_backend,
388 .output_mode = options.global.output_mode,388 .output_mode = options.global.output_mode,
389 .link_mode = options.global.link_mode,389 .link_mode = options.global.link_mode,
390 .unwind_tables = options.global.any_unwind_tables,390 .unwind_tables = unwind_tables,
391 .is_test = options.global.is_test,391 .is_test = options.global.is_test,
392 .single_threaded = single_threaded,392 .single_threaded = single_threaded,
393 .link_libc = options.global.link_libc,393 .link_libc = options.global.link_libc,
test/standalone/build.zig.zon+3
...@@ -183,6 +183,9 @@...@@ -183,6 +183,9 @@
183 .empty_global_error_set = .{183 .empty_global_error_set = .{
184 .path = "empty_global_error_set",184 .path = "empty_global_error_set",
185 },185 },
186 .omit_cfi = .{
187 .path = "omit_cfi",
188 },
186 },189 },
187 .paths = .{190 .paths = .{
188 "build.zig",191 "build.zig",
test/standalone/omit_cfi/build.zig created+67
...@@ -0,0 +1,67 @@
1const std = @import("std");
2
3pub fn build(b: *std.Build) void {
4 inline for (.{
5 .aarch64,
6 .aarch64_be,
7 .hexagon,
8 .loongarch64,
9 .mips,
10 .mipsel,
11 .mips64,
12 .mips64el,
13 .powerpc,
14 .powerpcle,
15 .powerpc64,
16 .powerpc64le,
17 .riscv32,
18 .riscv64,
19 .s390x,
20 .sparc64,
21 .x86,
22 .x86_64,
23 }) |arch| {
24 const target = b.resolveTargetQuery(.{
25 .cpu_arch = arch,
26 .os_tag = .linux,
27 });
28
29 const omit_dbg = b.addExecutable(.{
30 .name = b.fmt("{s}-linux-omit-dbg", .{@tagName(arch)}),
31 .root_module = b.createModule(.{
32 .root_source_file = b.path("main.zig"),
33 .target = target,
34 .optimize = .Debug,
35 // We are mainly concerned with CFI directives in our non-libc startup code and syscall
36 // code, so make it explicit that we don't want libc.
37 .link_libc = false,
38 .strip = true,
39 }),
40 });
41
42 const omit_uwt = b.addExecutable(.{
43 .name = b.fmt("{s}-linux-omit-uwt", .{@tagName(arch)}),
44 .root_module = b.createModule(.{
45 .root_source_file = b.path("main.zig"),
46 .target = target,
47 .optimize = .Debug,
48 .link_libc = false,
49 .unwind_tables = .none,
50 }),
51 });
52
53 const omit_both = b.addExecutable(.{
54 .name = b.fmt("{s}-linux-omit-both", .{@tagName(arch)}),
55 .root_module = b.createModule(.{
56 .root_source_file = b.path("main.zig"),
57 .target = target,
58 .optimize = .Debug,
59 .link_libc = false,
60 .strip = true,
61 .unwind_tables = .none,
62 }),
63 });
64
65 inline for (.{ omit_dbg, omit_uwt, omit_both }) |step| b.installArtifact(step);
66 }
67}
test/standalone/omit_cfi/main.zig created+1
...@@ -0,0 +1 @@
1pub fn main() void {}