Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Better unwind table support + unwind protection in _start() and clone() #22035

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion lib/libc/musl/src/thread/aarch64/clone.s
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ __clone:
// parent
ret
// child
1: ldp x1,x0,[sp],#16
1: mov fp, 0
ldp x1,x0,[sp],#16
blr x1
mov x8,#93 // SYS_exit
svc #0
3 changes: 2 additions & 1 deletion lib/libc/musl/src/thread/arm/clone.s
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ __clone:
ldmfd sp!,{r4,r5,r6,r7}
bx lr

1: mov r0,r6
1: mov fp,#0
mov r0,r6
bl 3f
2: mov r7,#1
svc 0
Expand Down
1 change: 1 addition & 0 deletions lib/libc/musl/src/thread/loongarch64/clone.s
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ __clone:
beqz $a0, 1f # whether child process
jirl $zero, $ra, 0 # parent process return
1:
move $fp, $zero
ld.d $t8, $sp, 0 # function pointer
ld.d $a0, $sp, 8 # argument pointer
jirl $ra, $t8, 0 # call the user's function
Expand Down
3 changes: 2 additions & 1 deletion lib/libc/musl/src/thread/m68k/clone.s
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ __clone:
beq 1f
movem.l (%sp)+,%d2-%d5
rts
1: move.l %a1,-(%sp)
1: suba.l %%fp,%%fp
move.l %a1,-(%sp)
jsr (%a0)
move.l #1,%d0
trap #0
Expand Down
3 changes: 2 additions & 1 deletion lib/libc/musl/src/thread/microblaze/clone.s
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ __clone:
rtsd r15, 8
nop

1: lwi r3, r1, 0
1: add r19, r0, r0
lwi r3, r1, 0
lwi r5, r1, 4
brald r15, r3
nop
Expand Down
3 changes: 2 additions & 1 deletion lib/libc/musl/src/thread/mips/clone.s
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ __clone:
addu $sp, $sp, 16
jr $ra
nop
1: lw $25, 0($sp)
1: move $fp, $0
lw $25, 0($sp)
lw $4, 4($sp)
jalr $25
nop
Expand Down
3 changes: 2 additions & 1 deletion lib/libc/musl/src/thread/mips64/clone.s
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ __clone:
nop
jr $ra
nop
1: ld $25, 0($sp) # function pointer
1: move $fp, $0
ld $25, 0($sp) # function pointer
ld $4, 8($sp) # argument pointer
jalr $25 # call the user's function
nop
Expand Down
3 changes: 2 additions & 1 deletion lib/libc/musl/src/thread/mipsn32/clone.s
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ __clone:
nop
jr $ra
nop
1: lw $25, 0($sp) # function pointer
1: move $fp, $0
lw $25, 0($sp) # function pointer
lw $4, 4($sp) # argument pointer
jalr $25 # call the user's function
nop
Expand Down
3 changes: 2 additions & 1 deletion lib/libc/musl/src/thread/or1k/clone.s
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ __clone:
l.jr r9
l.nop

1: l.lwz r11, 0(r1)
1: l.ori r2, r0, 0
l.lwz r11, 0(r1)
l.jalr r11
l.lwz r3, 4(r1)

Expand Down
10 changes: 5 additions & 5 deletions lib/std/Build.zig
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand Down
13 changes: 10 additions & 3 deletions lib/std/Build/Module.zig
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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");
Expand All @@ -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"),
Expand Down
8 changes: 8 additions & 0 deletions lib/std/builtin.zig
Original file line number Diff line number Diff line change
Expand Up @@ -803,6 +803,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 {
Expand Down
7 changes: 6 additions & 1 deletion lib/std/os/linux/aarch64.zig
Original file line number Diff line number Diff line change
Expand Up @@ -120,8 +120,13 @@ pub fn clone() callconv(.Naked) usize {
\\ cbz x0,1f
\\ // parent
\\ ret
\\
\\ // child
\\1: ldp x1,x0,[sp],#16
\\1: .cfi_undefined lr
\\ mov fp, 0
\\ mov lr, 0
\\
\\ ldp x1,x0,[sp],#16
\\ blr x1
\\ mov x8,#93 // SYS_exit
\\ svc #0
Expand Down
11 changes: 8 additions & 3 deletions lib/std/os/linux/arm.zig
Original file line number Diff line number Diff line change
Expand Up @@ -120,11 +120,16 @@ pub fn clone() callconv(.Naked) usize {
\\ ldmfd sp!,{r4,r5,r6,r7}
\\ bx lr
\\
\\1: mov r0,r6
\\ // https://github.com/llvm/llvm-project/issues/115891
\\1: mov r7, #0
\\ mov r11, #0
\\ mov lr, #0
\\
\\ mov r0,r6
\\ bl 3f
\\2: mov r7,#1 // SYS_exit
\\ mov r7,#1 // SYS_exit
\\ svc 0
\\ b 2b
\\
\\3: bx r5
);
}
Expand Down
4 changes: 4 additions & 0 deletions lib/std/os/linux/hexagon.zig
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,10 @@ pub fn clone() callconv(.Naked) usize {
\\ p0 = cmp.eq(r0, #0)
\\ if (!p0) dealloc_return
\\
\\ .cfi_undefined r31
\\ r30 = #0
\\ r31 = #0
\\
\\ r0 = r10
\\ callr r11
\\
Expand Down
4 changes: 4 additions & 0 deletions lib/std/os/linux/loongarch64.zig
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,10 @@ pub fn clone() callconv(.Naked) usize {
\\ beqz $a0, 1f # whether child process
\\ jirl $zero, $ra, 0 # parent process return
\\1:
\\ .cfi_undefined 1
\\ move $fp, $zero
\\ move $ra, $zero
\\
\\ ld.d $t8, $sp, 0 # function pointer
\\ ld.d $a0, $sp, 8 # argument pointer
\\ jirl $ra, $t8, 0 # call the user's function
Expand Down
4 changes: 4 additions & 0 deletions lib/std/os/linux/mips.zig
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,10 @@ pub fn clone() callconv(.Naked) usize {
\\ jr $ra
\\ nop
\\1:
\\ .cfi_undefined $ra
\\ move $fp, $zero
\\ move $ra, $zero
\\
\\ lw $25, 0($sp)
\\ lw $4, 4($sp)
\\ jalr $25
Expand Down
4 changes: 4 additions & 0 deletions lib/std/os/linux/mips64.zig
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,10 @@ pub fn clone() callconv(.Naked) usize {
\\ jr $ra
\\ nop
\\1:
\\ .cfi_undefined $ra
\\ move $fp, $zero
\\ move $ra, $zero
\\
\\ ld $25, 0($sp)
\\ ld $4, 8($sp)
\\ jalr $25
Expand Down
26 changes: 15 additions & 11 deletions lib/std/os/linux/powerpc.zig
Original file line number Diff line number Diff line change
Expand Up @@ -133,14 +133,14 @@ pub fn clone() callconv(.Naked) usize {
// syscall(SYS_clone, flags, stack, ptid, tls, ctid)
// 0 3, 4, 5, 6, 7
asm volatile (
\\ # store non-volatile regs r30, r31 on stack in order to put our
\\ # store non-volatile regs r29, r30 on stack in order to put our
\\ # start func and its arg there
\\ stwu 30, -16(1)
\\ stw 31, 4(1)
\\ stwu 29, -16(1)
\\ stw 30, 4(1)
\\
\\ # save r3 (func) into r30, and r6(arg) into r31
\\ mr 30, 3
\\ mr 31, 6
\\ # save r3 (func) into r29, and r6(arg) into r30
\\ mr 29, 3
\\ mr 30, 6
\\
\\ # create initial stack frame for new thread
\\ clrrwi 4, 4, 4
Expand Down Expand Up @@ -171,10 +171,14 @@ pub fn clone() callconv(.Naked) usize {
\\ bne cr7, 2f
\\
\\ #else: we're the child
\\ .cfi_undefined lr
\\ li 31, 0
\\ mtlr 0
\\
\\ #call funcptr: move arg (d) into r3
\\ mr 3, 31
\\ #move r30 (funcptr) into CTR reg
\\ mtctr 30
\\ mr 3, 30
\\ #move r29 (funcptr) into CTR reg
\\ mtctr 29
\\ # call CTR reg
\\ bctrl
\\ # mov SYS_exit into r0 (the exit param is already in r3)
Expand All @@ -184,8 +188,8 @@ pub fn clone() callconv(.Naked) usize {
\\ 2:
\\
\\ # restore stack
\\ lwz 30, 0(1)
\\ lwz 31, 4(1)
\\ lwz 29, 0(1)
\\ lwz 30, 4(1)
\\ addi 1, 1, 16
\\
\\ blr
Expand Down
7 changes: 6 additions & 1 deletion lib/std/os/linux/powerpc64.zig
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,12 @@ pub fn clone() callconv(.Naked) usize {
\\ cmpwi cr7, 3, 0
\\ bnelr cr7
\\
\\ # we're the child. call fn(arg)
\\ # we're the child
\\ .cfi_undefined lr
\\ li 31, 0
\\ mtlr 0
\\
\\ # call fn(arg)
\\ ld 3, 16(1)
\\ ld 12, 8(1)
\\ mtctr 12
Expand Down
6 changes: 5 additions & 1 deletion lib/std/os/linux/riscv32.zig
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,11 @@ pub fn clone() callconv(.Naked) usize {
\\ ret
\\
\\ # Child
\\1: lw a1, 0(sp)
\\1: .cfi_undefined ra
\\ mv fp, zero
\\ mv ra, zero
\\
\\ lw a1, 0(sp)
\\ lw a0, 4(sp)
\\ jalr a1
\\
Expand Down
6 changes: 5 additions & 1 deletion lib/std/os/linux/riscv64.zig
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,11 @@ pub fn clone() callconv(.Naked) usize {
\\ ret
\\
\\ # Child
\\1: ld a1, 0(sp)
\\1: .cfi_undefined ra
\\ mv fp, zero
\\ mv ra, zero
\\
\\ ld a1, 0(sp)
\\ ld a0, 8(sp)
\\ jalr a1
\\
Expand Down
7 changes: 6 additions & 1 deletion lib/std/os/linux/s390x.zig
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,12 @@ pub fn clone() callconv(.Naked) usize {
\\ltgr %%r2, %%r2
\\bnzr %%r14
\\
\\# we're the child. call fn(arg)
\\# we're the child
\\.cfi_undefined %%r14
\\lghi %%r11, 0
\\lghi %%r14, 0
\\
\\# call fn(arg)
\\lg %%r1, 8(%%r15)
\\lg %%r2, 16(%%r15)
\\basr %%r14, %%r1
Expand Down
7 changes: 6 additions & 1 deletion lib/std/os/linux/sparc64.zig
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,12 @@ pub fn clone() callconv(.Naked) usize {
\\ ret
\\ restore
\\1:
\\ # Child process, call func(arg)
\\ # Child process
\\ .cfi_undefined %%i7
\\ mov %%g0, %%fp
\\ mov %%g0, %%i7
\\
\\ # call func(arg)
\\ mov %%g0, %%fp
\\ call %%g2
\\ mov %%g3, %%o0
Expand Down
5 changes: 4 additions & 1 deletion lib/std/os/linux/x86.zig
Original file line number Diff line number Diff line change
Expand Up @@ -149,8 +149,11 @@ pub fn clone() callconv(.Naked) usize {
\\ int $128
\\ testl %%eax,%%eax
\\ jnz 1f
\\ popl %%eax
\\
\\ .cfi_undefined %%eip
\\ xorl %%ebp,%%ebp
\\
\\ popl %%eax
\\ calll *%%eax
\\ movl %%eax,%%ebx
\\ movl $1,%%eax // SYS_exit
Expand Down
Loading
Loading