Skip to content

Commit

Permalink
Merge pull request #22035 from alexrp/unwind-fixes
Browse files Browse the repository at this point in the history
Better unwind table support + unwind protection in `_start()` and `clone()`
  • Loading branch information
alexrp authored Dec 13, 2024
2 parents d48611b + c666ebb commit 130f7c2
Show file tree
Hide file tree
Showing 45 changed files with 361 additions and 138 deletions.
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
17 changes: 8 additions & 9 deletions lib/libc/musl/src/thread/i386/clone.s
Original file line number Diff line number Diff line change
Expand Up @@ -30,20 +30,19 @@ __clone:
mov 8(%ebp),%ebp
int $128
test %eax,%eax
jnz 1f
jz 1f
add $16,%esp
pop %edi
pop %esi
pop %ebx
pop %ebp
ret

mov %ebp,%eax
1: mov %ebp,%eax
xor %ebp,%ebp
call *%eax
mov %eax,%ebx
xor %eax,%eax
inc %eax
int $128
hlt

1: add $16,%esp
pop %edi
pop %esi
pop %ebx
pop %ebp
ret
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
21 changes: 9 additions & 12 deletions lib/libc/musl/src/thread/powerpc/clone.s
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,16 @@ neg 3, 3 #negate the result (errno)
# compare sc result with 0
cmpwi cr7, 3, 0

# if not 0, jump to end
bne cr7, 2f
# if not 0, restore stack and return
beq cr7, 2f

lwz 30, 0(1)
lwz 31, 4(1)
addi 1, 1, 16

blr

2:
#else: we're the child
#call funcptr: move arg (d) into r3
mr 3, 31
Expand All @@ -61,13 +68,3 @@ bctrl
# mov SYS_exit into r0 (the exit param is already in r3)
li 0, 1
sc

2:

# restore stack
lwz 30, 0(1)
lwz 31, 4(1)
addi 1, 1, 16

blr

6 changes: 3 additions & 3 deletions lib/libc/musl/src/thread/x32/clone.s
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,12 @@ __clone:
mov %rcx,(%rsi)
syscall
test %eax,%eax
jnz 1f
xor %ebp,%ebp
jz 1f
ret
1: xor %ebp,%ebp
pop %rdi
call *%r9
mov %eax,%edi
movl $0x4000003c,%eax /* SYS_exit */
syscall
hlt
1: ret
6 changes: 3 additions & 3 deletions lib/libc/musl/src/thread/x86_64/clone.s
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,13 @@ __clone:
mov %rcx,(%rsi)
syscall
test %eax,%eax
jnz 1f
xor %ebp,%ebp
jz 1f
ret
1: xor %ebp,%ebp
pop %rdi
call *%r9
mov %eax,%edi
xor %eax,%eax
mov $60,%al
syscall
hlt
1: ret
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 @@ -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 {
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
Loading

0 comments on commit 130f7c2

Please sign in to comment.