mirror of
https://github.com/ziglang/zig.git
synced 2025-12-24 07:03:11 +00:00
Merge pull request #22035 from alexrp/unwind-fixes
Better unwind table support + unwind protection in `_start()` and `clone()`
This commit is contained in:
commit
130f7c2ed8
3
lib/libc/musl/src/thread/aarch64/clone.s
vendored
3
lib/libc/musl/src/thread/aarch64/clone.s
vendored
@ -24,7 +24,8 @@ __clone:
|
|||||||
// parent
|
// parent
|
||||||
ret
|
ret
|
||||||
// child
|
// child
|
||||||
1: ldp x1,x0,[sp],#16
|
1: mov fp, 0
|
||||||
|
ldp x1,x0,[sp],#16
|
||||||
blr x1
|
blr x1
|
||||||
mov x8,#93 // SYS_exit
|
mov x8,#93 // SYS_exit
|
||||||
svc #0
|
svc #0
|
||||||
|
|||||||
3
lib/libc/musl/src/thread/arm/clone.s
vendored
3
lib/libc/musl/src/thread/arm/clone.s
vendored
@ -19,7 +19,8 @@ __clone:
|
|||||||
ldmfd sp!,{r4,r5,r6,r7}
|
ldmfd sp!,{r4,r5,r6,r7}
|
||||||
bx lr
|
bx lr
|
||||||
|
|
||||||
1: mov r0,r6
|
1: mov fp,#0
|
||||||
|
mov r0,r6
|
||||||
bl 3f
|
bl 3f
|
||||||
2: mov r7,#1
|
2: mov r7,#1
|
||||||
svc 0
|
svc 0
|
||||||
|
|||||||
17
lib/libc/musl/src/thread/i386/clone.s
vendored
17
lib/libc/musl/src/thread/i386/clone.s
vendored
@ -30,9 +30,15 @@ __clone:
|
|||||||
mov 8(%ebp),%ebp
|
mov 8(%ebp),%ebp
|
||||||
int $128
|
int $128
|
||||||
test %eax,%eax
|
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
|
xor %ebp,%ebp
|
||||||
call *%eax
|
call *%eax
|
||||||
mov %eax,%ebx
|
mov %eax,%ebx
|
||||||
@ -40,10 +46,3 @@ __clone:
|
|||||||
inc %eax
|
inc %eax
|
||||||
int $128
|
int $128
|
||||||
hlt
|
hlt
|
||||||
|
|
||||||
1: add $16,%esp
|
|
||||||
pop %edi
|
|
||||||
pop %esi
|
|
||||||
pop %ebx
|
|
||||||
pop %ebp
|
|
||||||
ret
|
|
||||||
|
|||||||
1
lib/libc/musl/src/thread/loongarch64/clone.s
vendored
1
lib/libc/musl/src/thread/loongarch64/clone.s
vendored
@ -22,6 +22,7 @@ __clone:
|
|||||||
beqz $a0, 1f # whether child process
|
beqz $a0, 1f # whether child process
|
||||||
jirl $zero, $ra, 0 # parent process return
|
jirl $zero, $ra, 0 # parent process return
|
||||||
1:
|
1:
|
||||||
|
move $fp, $zero
|
||||||
ld.d $t8, $sp, 0 # function pointer
|
ld.d $t8, $sp, 0 # function pointer
|
||||||
ld.d $a0, $sp, 8 # argument pointer
|
ld.d $a0, $sp, 8 # argument pointer
|
||||||
jirl $ra, $t8, 0 # call the user's function
|
jirl $ra, $t8, 0 # call the user's function
|
||||||
|
|||||||
3
lib/libc/musl/src/thread/m68k/clone.s
vendored
3
lib/libc/musl/src/thread/m68k/clone.s
vendored
@ -18,7 +18,8 @@ __clone:
|
|||||||
beq 1f
|
beq 1f
|
||||||
movem.l (%sp)+,%d2-%d5
|
movem.l (%sp)+,%d2-%d5
|
||||||
rts
|
rts
|
||||||
1: move.l %a1,-(%sp)
|
1: suba.l %%fp,%%fp
|
||||||
|
move.l %a1,-(%sp)
|
||||||
jsr (%a0)
|
jsr (%a0)
|
||||||
move.l #1,%d0
|
move.l #1,%d0
|
||||||
trap #0
|
trap #0
|
||||||
|
|||||||
3
lib/libc/musl/src/thread/microblaze/clone.s
vendored
3
lib/libc/musl/src/thread/microblaze/clone.s
vendored
@ -22,7 +22,8 @@ __clone:
|
|||||||
rtsd r15, 8
|
rtsd r15, 8
|
||||||
nop
|
nop
|
||||||
|
|
||||||
1: lwi r3, r1, 0
|
1: add r19, r0, r0
|
||||||
|
lwi r3, r1, 0
|
||||||
lwi r5, r1, 4
|
lwi r5, r1, 4
|
||||||
brald r15, r3
|
brald r15, r3
|
||||||
nop
|
nop
|
||||||
|
|||||||
3
lib/libc/musl/src/thread/mips/clone.s
vendored
3
lib/libc/musl/src/thread/mips/clone.s
vendored
@ -27,7 +27,8 @@ __clone:
|
|||||||
addu $sp, $sp, 16
|
addu $sp, $sp, 16
|
||||||
jr $ra
|
jr $ra
|
||||||
nop
|
nop
|
||||||
1: lw $25, 0($sp)
|
1: move $fp, $0
|
||||||
|
lw $25, 0($sp)
|
||||||
lw $4, 4($sp)
|
lw $4, 4($sp)
|
||||||
jalr $25
|
jalr $25
|
||||||
nop
|
nop
|
||||||
|
|||||||
3
lib/libc/musl/src/thread/mips64/clone.s
vendored
3
lib/libc/musl/src/thread/mips64/clone.s
vendored
@ -25,7 +25,8 @@ __clone:
|
|||||||
nop
|
nop
|
||||||
jr $ra
|
jr $ra
|
||||||
nop
|
nop
|
||||||
1: ld $25, 0($sp) # function pointer
|
1: move $fp, $0
|
||||||
|
ld $25, 0($sp) # function pointer
|
||||||
ld $4, 8($sp) # argument pointer
|
ld $4, 8($sp) # argument pointer
|
||||||
jalr $25 # call the user's function
|
jalr $25 # call the user's function
|
||||||
nop
|
nop
|
||||||
|
|||||||
3
lib/libc/musl/src/thread/mipsn32/clone.s
vendored
3
lib/libc/musl/src/thread/mipsn32/clone.s
vendored
@ -25,7 +25,8 @@ __clone:
|
|||||||
nop
|
nop
|
||||||
jr $ra
|
jr $ra
|
||||||
nop
|
nop
|
||||||
1: lw $25, 0($sp) # function pointer
|
1: move $fp, $0
|
||||||
|
lw $25, 0($sp) # function pointer
|
||||||
lw $4, 4($sp) # argument pointer
|
lw $4, 4($sp) # argument pointer
|
||||||
jalr $25 # call the user's function
|
jalr $25 # call the user's function
|
||||||
nop
|
nop
|
||||||
|
|||||||
3
lib/libc/musl/src/thread/or1k/clone.s
vendored
3
lib/libc/musl/src/thread/or1k/clone.s
vendored
@ -23,7 +23,8 @@ __clone:
|
|||||||
l.jr r9
|
l.jr r9
|
||||||
l.nop
|
l.nop
|
||||||
|
|
||||||
1: l.lwz r11, 0(r1)
|
1: l.ori r2, r0, 0
|
||||||
|
l.lwz r11, 0(r1)
|
||||||
l.jalr r11
|
l.jalr r11
|
||||||
l.lwz r3, 4(r1)
|
l.lwz r3, 4(r1)
|
||||||
|
|
||||||
|
|||||||
21
lib/libc/musl/src/thread/powerpc/clone.s
vendored
21
lib/libc/musl/src/thread/powerpc/clone.s
vendored
@ -48,9 +48,16 @@ neg 3, 3 #negate the result (errno)
|
|||||||
# compare sc result with 0
|
# compare sc result with 0
|
||||||
cmpwi cr7, 3, 0
|
cmpwi cr7, 3, 0
|
||||||
|
|
||||||
# if not 0, jump to end
|
# if not 0, restore stack and return
|
||||||
bne cr7, 2f
|
beq cr7, 2f
|
||||||
|
|
||||||
|
lwz 30, 0(1)
|
||||||
|
lwz 31, 4(1)
|
||||||
|
addi 1, 1, 16
|
||||||
|
|
||||||
|
blr
|
||||||
|
|
||||||
|
2:
|
||||||
#else: we're the child
|
#else: we're the child
|
||||||
#call funcptr: move arg (d) into r3
|
#call funcptr: move arg (d) into r3
|
||||||
mr 3, 31
|
mr 3, 31
|
||||||
@ -61,13 +68,3 @@ bctrl
|
|||||||
# mov SYS_exit into r0 (the exit param is already in r3)
|
# mov SYS_exit into r0 (the exit param is already in r3)
|
||||||
li 0, 1
|
li 0, 1
|
||||||
sc
|
sc
|
||||||
|
|
||||||
2:
|
|
||||||
|
|
||||||
# restore stack
|
|
||||||
lwz 30, 0(1)
|
|
||||||
lwz 31, 4(1)
|
|
||||||
addi 1, 1, 16
|
|
||||||
|
|
||||||
blr
|
|
||||||
|
|
||||||
|
|||||||
6
lib/libc/musl/src/thread/x32/clone.s
vendored
6
lib/libc/musl/src/thread/x32/clone.s
vendored
@ -15,12 +15,12 @@ __clone:
|
|||||||
mov %rcx,(%rsi)
|
mov %rcx,(%rsi)
|
||||||
syscall
|
syscall
|
||||||
test %eax,%eax
|
test %eax,%eax
|
||||||
jnz 1f
|
jz 1f
|
||||||
xor %ebp,%ebp
|
ret
|
||||||
|
1: xor %ebp,%ebp
|
||||||
pop %rdi
|
pop %rdi
|
||||||
call *%r9
|
call *%r9
|
||||||
mov %eax,%edi
|
mov %eax,%edi
|
||||||
movl $0x4000003c,%eax /* SYS_exit */
|
movl $0x4000003c,%eax /* SYS_exit */
|
||||||
syscall
|
syscall
|
||||||
hlt
|
hlt
|
||||||
1: ret
|
|
||||||
|
|||||||
6
lib/libc/musl/src/thread/x86_64/clone.s
vendored
6
lib/libc/musl/src/thread/x86_64/clone.s
vendored
@ -16,8 +16,9 @@ __clone:
|
|||||||
mov %rcx,(%rsi)
|
mov %rcx,(%rsi)
|
||||||
syscall
|
syscall
|
||||||
test %eax,%eax
|
test %eax,%eax
|
||||||
jnz 1f
|
jz 1f
|
||||||
xor %ebp,%ebp
|
ret
|
||||||
|
1: xor %ebp,%ebp
|
||||||
pop %rdi
|
pop %rdi
|
||||||
call *%r9
|
call *%r9
|
||||||
mov %eax,%edi
|
mov %eax,%edi
|
||||||
@ -25,4 +26,3 @@ __clone:
|
|||||||
mov $60,%al
|
mov $60,%al
|
||||||
syscall
|
syscall
|
||||||
hlt
|
hlt
|
||||||
1: ret
|
|
||||||
|
|||||||
@ -706,7 +706,7 @@ pub const ExecutableOptions = struct {
|
|||||||
single_threaded: ?bool = null,
|
single_threaded: ?bool = null,
|
||||||
pic: ?bool = null,
|
pic: ?bool = null,
|
||||||
strip: ?bool = null,
|
strip: ?bool = null,
|
||||||
unwind_tables: ?bool = null,
|
unwind_tables: ?std.builtin.UnwindTables = null,
|
||||||
omit_frame_pointer: ?bool = null,
|
omit_frame_pointer: ?bool = null,
|
||||||
sanitize_thread: ?bool = null,
|
sanitize_thread: ?bool = null,
|
||||||
error_tracing: ?bool = null,
|
error_tracing: ?bool = null,
|
||||||
@ -762,7 +762,7 @@ pub const ObjectOptions = struct {
|
|||||||
single_threaded: ?bool = null,
|
single_threaded: ?bool = null,
|
||||||
pic: ?bool = null,
|
pic: ?bool = null,
|
||||||
strip: ?bool = null,
|
strip: ?bool = null,
|
||||||
unwind_tables: ?bool = null,
|
unwind_tables: ?std.builtin.UnwindTables = null,
|
||||||
omit_frame_pointer: ?bool = null,
|
omit_frame_pointer: ?bool = null,
|
||||||
sanitize_thread: ?bool = null,
|
sanitize_thread: ?bool = null,
|
||||||
error_tracing: ?bool = null,
|
error_tracing: ?bool = null,
|
||||||
@ -810,7 +810,7 @@ pub const SharedLibraryOptions = struct {
|
|||||||
single_threaded: ?bool = null,
|
single_threaded: ?bool = null,
|
||||||
pic: ?bool = null,
|
pic: ?bool = null,
|
||||||
strip: ?bool = null,
|
strip: ?bool = null,
|
||||||
unwind_tables: ?bool = null,
|
unwind_tables: ?std.builtin.UnwindTables = null,
|
||||||
omit_frame_pointer: ?bool = null,
|
omit_frame_pointer: ?bool = null,
|
||||||
sanitize_thread: ?bool = null,
|
sanitize_thread: ?bool = null,
|
||||||
error_tracing: ?bool = null,
|
error_tracing: ?bool = null,
|
||||||
@ -867,7 +867,7 @@ pub const StaticLibraryOptions = struct {
|
|||||||
single_threaded: ?bool = null,
|
single_threaded: ?bool = null,
|
||||||
pic: ?bool = null,
|
pic: ?bool = null,
|
||||||
strip: ?bool = null,
|
strip: ?bool = null,
|
||||||
unwind_tables: ?bool = null,
|
unwind_tables: ?std.builtin.UnwindTables = null,
|
||||||
omit_frame_pointer: ?bool = null,
|
omit_frame_pointer: ?bool = null,
|
||||||
sanitize_thread: ?bool = null,
|
sanitize_thread: ?bool = null,
|
||||||
error_tracing: ?bool = null,
|
error_tracing: ?bool = null,
|
||||||
@ -919,7 +919,7 @@ pub const TestOptions = struct {
|
|||||||
single_threaded: ?bool = null,
|
single_threaded: ?bool = null,
|
||||||
pic: ?bool = null,
|
pic: ?bool = null,
|
||||||
strip: ?bool = null,
|
strip: ?bool = null,
|
||||||
unwind_tables: ?bool = null,
|
unwind_tables: ?std.builtin.UnwindTables = null,
|
||||||
omit_frame_pointer: ?bool = null,
|
omit_frame_pointer: ?bool = null,
|
||||||
sanitize_thread: ?bool = null,
|
sanitize_thread: ?bool = null,
|
||||||
error_tracing: ?bool = null,
|
error_tracing: ?bool = null,
|
||||||
|
|||||||
@ -22,7 +22,7 @@ frameworks: std.StringArrayHashMapUnmanaged(LinkFrameworkOptions),
|
|||||||
link_objects: std.ArrayListUnmanaged(LinkObject),
|
link_objects: std.ArrayListUnmanaged(LinkObject),
|
||||||
|
|
||||||
strip: ?bool,
|
strip: ?bool,
|
||||||
unwind_tables: ?bool,
|
unwind_tables: ?std.builtin.UnwindTables,
|
||||||
single_threaded: ?bool,
|
single_threaded: ?bool,
|
||||||
stack_protector: ?bool,
|
stack_protector: ?bool,
|
||||||
stack_check: ?bool,
|
stack_check: ?bool,
|
||||||
@ -218,7 +218,7 @@ pub const CreateOptions = struct {
|
|||||||
link_libcpp: ?bool = null,
|
link_libcpp: ?bool = null,
|
||||||
single_threaded: ?bool = null,
|
single_threaded: ?bool = null,
|
||||||
strip: ?bool = null,
|
strip: ?bool = null,
|
||||||
unwind_tables: ?bool = null,
|
unwind_tables: ?std.builtin.UnwindTables = null,
|
||||||
dwarf_format: ?std.dwarf.Format = null,
|
dwarf_format: ?std.dwarf.Format = null,
|
||||||
code_model: std.builtin.CodeModel = .default,
|
code_model: std.builtin.CodeModel = .default,
|
||||||
stack_protector: ?bool = null,
|
stack_protector: ?bool = null,
|
||||||
@ -675,7 +675,6 @@ pub fn appendZigProcessFlags(
|
|||||||
const b = m.owner;
|
const b = m.owner;
|
||||||
|
|
||||||
try addFlag(zig_args, m.strip, "-fstrip", "-fno-strip");
|
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.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_check, "-fstack-check", "-fno-stack-check");
|
||||||
try addFlag(zig_args, m.stack_protector, "-fstack-protector", "-fno-stack-protector");
|
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);
|
try zig_args.ensureUnusedCapacity(1);
|
||||||
if (m.optimize) |optimize| switch (optimize) {
|
if (m.optimize) |optimize| switch (optimize) {
|
||||||
.Debug => zig_args.appendAssumeCapacity("-ODebug"),
|
.Debug => zig_args.appendAssumeCapacity("-ODebug"),
|
||||||
|
|||||||
@ -804,6 +804,14 @@ pub const LinkMode = enum {
|
|||||||
dynamic,
|
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
|
/// This data structure is used by the Zig language code generation and
|
||||||
/// therefore must be kept in sync with the compiler implementation.
|
/// therefore must be kept in sync with the compiler implementation.
|
||||||
pub const WasiExecModel = enum {
|
pub const WasiExecModel = enum {
|
||||||
|
|||||||
@ -120,8 +120,13 @@ pub fn clone() callconv(.Naked) usize {
|
|||||||
\\ cbz x0,1f
|
\\ cbz x0,1f
|
||||||
\\ // parent
|
\\ // parent
|
||||||
\\ ret
|
\\ ret
|
||||||
|
\\
|
||||||
\\ // child
|
\\ // child
|
||||||
\\1: ldp x1,x0,[sp],#16
|
\\1: .cfi_undefined lr
|
||||||
|
\\ mov fp, 0
|
||||||
|
\\ mov lr, 0
|
||||||
|
\\
|
||||||
|
\\ ldp x1,x0,[sp],#16
|
||||||
\\ blr x1
|
\\ blr x1
|
||||||
\\ mov x8,#93 // SYS_exit
|
\\ mov x8,#93 // SYS_exit
|
||||||
\\ svc #0
|
\\ svc #0
|
||||||
|
|||||||
@ -120,11 +120,16 @@ pub fn clone() callconv(.Naked) usize {
|
|||||||
\\ ldmfd sp!,{r4,r5,r6,r7}
|
\\ ldmfd sp!,{r4,r5,r6,r7}
|
||||||
\\ bx lr
|
\\ 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
|
\\ bl 3f
|
||||||
\\2: mov r7,#1 // SYS_exit
|
\\ mov r7,#1 // SYS_exit
|
||||||
\\ svc 0
|
\\ svc 0
|
||||||
\\ b 2b
|
\\
|
||||||
\\3: bx r5
|
\\3: bx r5
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -118,6 +118,10 @@ pub fn clone() callconv(.Naked) usize {
|
|||||||
\\ p0 = cmp.eq(r0, #0)
|
\\ p0 = cmp.eq(r0, #0)
|
||||||
\\ if (!p0) dealloc_return
|
\\ if (!p0) dealloc_return
|
||||||
\\
|
\\
|
||||||
|
\\ .cfi_undefined r31
|
||||||
|
\\ r30 = #0
|
||||||
|
\\ r31 = #0
|
||||||
|
\\
|
||||||
\\ r0 = r10
|
\\ r0 = r10
|
||||||
\\ callr r11
|
\\ callr r11
|
||||||
\\
|
\\
|
||||||
|
|||||||
@ -121,6 +121,10 @@ pub fn clone() callconv(.Naked) usize {
|
|||||||
\\ beqz $a0, 1f # whether child process
|
\\ beqz $a0, 1f # whether child process
|
||||||
\\ jirl $zero, $ra, 0 # parent process return
|
\\ jirl $zero, $ra, 0 # parent process return
|
||||||
\\1:
|
\\1:
|
||||||
|
\\ .cfi_undefined 1
|
||||||
|
\\ move $fp, $zero
|
||||||
|
\\ move $ra, $zero
|
||||||
|
\\
|
||||||
\\ ld.d $t8, $sp, 0 # function pointer
|
\\ ld.d $t8, $sp, 0 # function pointer
|
||||||
\\ ld.d $a0, $sp, 8 # argument pointer
|
\\ ld.d $a0, $sp, 8 # argument pointer
|
||||||
\\ jirl $ra, $t8, 0 # call the user's function
|
\\ jirl $ra, $t8, 0 # call the user's function
|
||||||
|
|||||||
@ -231,6 +231,10 @@ pub fn clone() callconv(.Naked) usize {
|
|||||||
\\ jr $ra
|
\\ jr $ra
|
||||||
\\ nop
|
\\ nop
|
||||||
\\1:
|
\\1:
|
||||||
|
\\ .cfi_undefined $ra
|
||||||
|
\\ move $fp, $zero
|
||||||
|
\\ move $ra, $zero
|
||||||
|
\\
|
||||||
\\ lw $25, 0($sp)
|
\\ lw $25, 0($sp)
|
||||||
\\ lw $4, 4($sp)
|
\\ lw $4, 4($sp)
|
||||||
\\ jalr $25
|
\\ jalr $25
|
||||||
|
|||||||
@ -210,6 +210,10 @@ pub fn clone() callconv(.Naked) usize {
|
|||||||
\\ jr $ra
|
\\ jr $ra
|
||||||
\\ nop
|
\\ nop
|
||||||
\\1:
|
\\1:
|
||||||
|
\\ .cfi_undefined $ra
|
||||||
|
\\ move $fp, $zero
|
||||||
|
\\ move $ra, $zero
|
||||||
|
\\
|
||||||
\\ ld $25, 0($sp)
|
\\ ld $25, 0($sp)
|
||||||
\\ ld $4, 8($sp)
|
\\ ld $4, 8($sp)
|
||||||
\\ jalr $25
|
\\ jalr $25
|
||||||
|
|||||||
@ -133,14 +133,14 @@ pub fn clone() callconv(.Naked) usize {
|
|||||||
// syscall(SYS_clone, flags, stack, ptid, tls, ctid)
|
// syscall(SYS_clone, flags, stack, ptid, tls, ctid)
|
||||||
// 0 3, 4, 5, 6, 7
|
// 0 3, 4, 5, 6, 7
|
||||||
asm volatile (
|
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
|
\\ # start func and its arg there
|
||||||
\\ stwu 30, -16(1)
|
\\ stwu 29, -16(1)
|
||||||
\\ stw 31, 4(1)
|
\\ stw 30, 4(1)
|
||||||
\\
|
\\
|
||||||
\\ # save r3 (func) into r30, and r6(arg) into r31
|
\\ # save r3 (func) into r29, and r6(arg) into r30
|
||||||
\\ mr 30, 3
|
\\ mr 29, 3
|
||||||
\\ mr 31, 6
|
\\ mr 30, 6
|
||||||
\\
|
\\
|
||||||
\\ # create initial stack frame for new thread
|
\\ # create initial stack frame for new thread
|
||||||
\\ clrrwi 4, 4, 4
|
\\ clrrwi 4, 4, 4
|
||||||
@ -167,28 +167,28 @@ pub fn clone() callconv(.Naked) usize {
|
|||||||
\\ # compare sc result with 0
|
\\ # compare sc result with 0
|
||||||
\\ cmpwi cr7, 3, 0
|
\\ cmpwi cr7, 3, 0
|
||||||
\\
|
\\
|
||||||
\\ # if not 0, jump to end
|
\\ # if not 0, restore stack and return
|
||||||
\\ bne cr7, 2f
|
\\ beq cr7, 2f
|
||||||
|
\\ lwz 29, 0(1)
|
||||||
|
\\ lwz 30, 4(1)
|
||||||
|
\\ addi 1, 1, 16
|
||||||
|
\\ blr
|
||||||
\\
|
\\
|
||||||
\\ #else: we're the child
|
\\ #else: we're the child
|
||||||
|
\\ 2:
|
||||||
|
\\ .cfi_undefined lr
|
||||||
|
\\ li 31, 0
|
||||||
|
\\ mtlr 0
|
||||||
|
\\
|
||||||
\\ #call funcptr: move arg (d) into r3
|
\\ #call funcptr: move arg (d) into r3
|
||||||
\\ mr 3, 31
|
\\ mr 3, 30
|
||||||
\\ #move r30 (funcptr) into CTR reg
|
\\ #move r29 (funcptr) into CTR reg
|
||||||
\\ mtctr 30
|
\\ mtctr 29
|
||||||
\\ # call CTR reg
|
\\ # call CTR reg
|
||||||
\\ bctrl
|
\\ bctrl
|
||||||
\\ # mov SYS_exit into r0 (the exit param is already in r3)
|
\\ # mov SYS_exit into r0 (the exit param is already in r3)
|
||||||
\\ li 0, 1
|
\\ li 0, 1
|
||||||
\\ sc
|
\\ sc
|
||||||
\\
|
|
||||||
\\ 2:
|
|
||||||
\\
|
|
||||||
\\ # restore stack
|
|
||||||
\\ lwz 30, 0(1)
|
|
||||||
\\ lwz 31, 4(1)
|
|
||||||
\\ addi 1, 1, 16
|
|
||||||
\\
|
|
||||||
\\ blr
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -160,7 +160,12 @@ pub fn clone() callconv(.Naked) usize {
|
|||||||
\\ cmpwi cr7, 3, 0
|
\\ cmpwi cr7, 3, 0
|
||||||
\\ bnelr cr7
|
\\ 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 3, 16(1)
|
||||||
\\ ld 12, 8(1)
|
\\ ld 12, 8(1)
|
||||||
\\ mtctr 12
|
\\ mtctr 12
|
||||||
|
|||||||
@ -120,7 +120,11 @@ pub fn clone() callconv(.Naked) usize {
|
|||||||
\\ ret
|
\\ ret
|
||||||
\\
|
\\
|
||||||
\\ # Child
|
\\ # Child
|
||||||
\\1: lw a1, 0(sp)
|
\\1: .cfi_undefined ra
|
||||||
|
\\ mv fp, zero
|
||||||
|
\\ mv ra, zero
|
||||||
|
\\
|
||||||
|
\\ lw a1, 0(sp)
|
||||||
\\ lw a0, 4(sp)
|
\\ lw a0, 4(sp)
|
||||||
\\ jalr a1
|
\\ jalr a1
|
||||||
\\
|
\\
|
||||||
|
|||||||
@ -120,7 +120,11 @@ pub fn clone() callconv(.Naked) usize {
|
|||||||
\\ ret
|
\\ ret
|
||||||
\\
|
\\
|
||||||
\\ # Child
|
\\ # Child
|
||||||
\\1: ld a1, 0(sp)
|
\\1: .cfi_undefined ra
|
||||||
|
\\ mv fp, zero
|
||||||
|
\\ mv ra, zero
|
||||||
|
\\
|
||||||
|
\\ ld a1, 0(sp)
|
||||||
\\ ld a0, 8(sp)
|
\\ ld a0, 8(sp)
|
||||||
\\ jalr a1
|
\\ jalr a1
|
||||||
\\
|
\\
|
||||||
|
|||||||
@ -133,7 +133,12 @@ pub fn clone() callconv(.Naked) usize {
|
|||||||
\\ltgr %%r2, %%r2
|
\\ltgr %%r2, %%r2
|
||||||
\\bnzr %%r14
|
\\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 %%r1, 8(%%r15)
|
||||||
\\lg %%r2, 16(%%r15)
|
\\lg %%r2, 16(%%r15)
|
||||||
\\basr %%r14, %%r1
|
\\basr %%r14, %%r1
|
||||||
|
|||||||
@ -198,29 +198,34 @@ pub fn clone() callconv(.Naked) usize {
|
|||||||
\\ mov %%i5, %%o3
|
\\ mov %%i5, %%o3
|
||||||
\\ ldx [%%fp + 0x8af], %%o4
|
\\ ldx [%%fp + 0x8af], %%o4
|
||||||
\\ t 0x6d
|
\\ t 0x6d
|
||||||
\\ bcs,pn %%xcc, 2f
|
\\ bcs,pn %%xcc, 1f
|
||||||
\\ nop
|
\\ nop
|
||||||
\\ # The child pid is returned in o0 while o1 tells if this
|
\\ # The child pid is returned in o0 while o1 tells if this
|
||||||
\\ # process is # the child (=1) or the parent (=0).
|
\\ # process is # the child (=1) or the parent (=0).
|
||||||
\\ brnz %%o1, 1f
|
\\ brnz %%o1, 2f
|
||||||
\\ nop
|
\\ nop
|
||||||
\\ # Parent process, return the child pid
|
\\ # Parent process, return the child pid
|
||||||
\\ mov %%o0, %%i0
|
\\ mov %%o0, %%i0
|
||||||
\\ ret
|
\\ ret
|
||||||
\\ restore
|
\\ restore
|
||||||
\\1:
|
\\1:
|
||||||
\\ # Child process, call func(arg)
|
\\ # The syscall failed
|
||||||
|
\\ sub %%g0, %%o0, %%i0
|
||||||
|
\\ ret
|
||||||
|
\\ restore
|
||||||
|
\\2:
|
||||||
|
\\ # Child process
|
||||||
|
\\ .cfi_undefined %%i7
|
||||||
|
\\ mov %%g0, %%fp
|
||||||
|
\\ mov %%g0, %%i7
|
||||||
|
\\
|
||||||
|
\\ # call func(arg)
|
||||||
\\ mov %%g0, %%fp
|
\\ mov %%g0, %%fp
|
||||||
\\ call %%g2
|
\\ call %%g2
|
||||||
\\ mov %%g3, %%o0
|
\\ mov %%g3, %%o0
|
||||||
\\ # Exit
|
\\ # Exit
|
||||||
\\ mov 1, %%g1 // SYS_exit
|
\\ mov 1, %%g1 // SYS_exit
|
||||||
\\ t 0x6d
|
\\ t 0x6d
|
||||||
\\2:
|
|
||||||
\\ # The syscall failed
|
|
||||||
\\ sub %%g0, %%o0, %%i0
|
|
||||||
\\ ret
|
|
||||||
\\ restore
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -148,19 +148,22 @@ pub fn clone() callconv(.Naked) usize {
|
|||||||
\\ movl $120,%%eax // SYS_clone
|
\\ movl $120,%%eax // SYS_clone
|
||||||
\\ int $128
|
\\ int $128
|
||||||
\\ testl %%eax,%%eax
|
\\ testl %%eax,%%eax
|
||||||
\\ jnz 1f
|
\\ jz 1f
|
||||||
\\ popl %%eax
|
|
||||||
\\ xorl %%ebp,%%ebp
|
|
||||||
\\ calll *%%eax
|
|
||||||
\\ movl %%eax,%%ebx
|
|
||||||
\\ movl $1,%%eax // SYS_exit
|
|
||||||
\\ int $128
|
|
||||||
\\1:
|
|
||||||
\\ popl %%edi
|
\\ popl %%edi
|
||||||
\\ popl %%esi
|
\\ popl %%esi
|
||||||
\\ popl %%ebx
|
\\ popl %%ebx
|
||||||
\\ popl %%ebp
|
\\ popl %%ebp
|
||||||
\\ retl
|
\\ retl
|
||||||
|
\\
|
||||||
|
\\1:
|
||||||
|
\\ .cfi_undefined %%eip
|
||||||
|
\\ xorl %%ebp,%%ebp
|
||||||
|
\\
|
||||||
|
\\ popl %%eax
|
||||||
|
\\ calll *%%eax
|
||||||
|
\\ movl %%eax,%%ebx
|
||||||
|
\\ movl $1,%%eax // SYS_exit
|
||||||
|
\\ int $128
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -116,8 +116,10 @@ pub fn clone() callconv(.Naked) usize {
|
|||||||
\\ testq %%rax,%%rax
|
\\ testq %%rax,%%rax
|
||||||
\\ jz 1f
|
\\ jz 1f
|
||||||
\\ retq
|
\\ retq
|
||||||
|
\\
|
||||||
\\1: .cfi_undefined %%rip
|
\\1: .cfi_undefined %%rip
|
||||||
\\ xorl %%ebp,%%ebp
|
\\ xorl %%ebp,%%ebp
|
||||||
|
\\
|
||||||
\\ popq %%rdi
|
\\ popq %%rdi
|
||||||
\\ callq *%%r9
|
\\ callq *%%r9
|
||||||
\\ movl %%eax,%%edi
|
\\ movl %%eax,%%edi
|
||||||
|
|||||||
@ -230,6 +230,29 @@ 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) {
|
||||||
|
.arc => ".cfi_undefined blink",
|
||||||
|
.arm, .armeb, .thumb, .thumbeb => "", // https://github.com/llvm/llvm-project/issues/115891
|
||||||
|
.aarch64, .aarch64_be => ".cfi_undefined lr",
|
||||||
|
.csky => ".cfi_undefined lr",
|
||||||
|
.hexagon => ".cfi_undefined r31",
|
||||||
|
.loongarch32, .loongarch64 => ".cfi_undefined 1",
|
||||||
|
.m68k => ".cfi_undefined pc",
|
||||||
|
.mips, .mipsel, .mips64, .mips64el => ".cfi_undefined $ra",
|
||||||
|
.powerpc, .powerpcle, .powerpc64, .powerpc64le => ".cfi_undefined lr",
|
||||||
|
.riscv32, .riscv64 => if (builtin.zig_backend == .stage2_riscv64)
|
||||||
|
""
|
||||||
|
else
|
||||||
|
".cfi_undefined ra",
|
||||||
|
.s390x => ".cfi_undefined %%r14",
|
||||||
|
.sparc, .sparc64 => ".cfi_undefined %%i7",
|
||||||
|
.x86 => ".cfi_undefined %%eip",
|
||||||
|
.x86_64 => ".cfi_undefined %%rip",
|
||||||
|
else => @compileError("unsupported arch"),
|
||||||
|
});
|
||||||
|
|
||||||
// Move this to the riscv prong below when this is resolved: https://github.com/ziglang/zig/issues/20918
|
// Move this to the riscv prong below when this is resolved: https://github.com/ziglang/zig/issues/20918
|
||||||
if (builtin.cpu.arch.isRISCV() and builtin.zig_backend != .stage2_riscv64) asm volatile (
|
if (builtin.cpu.arch.isRISCV() and builtin.zig_backend != .stage2_riscv64) asm volatile (
|
||||||
\\ .weak __global_pointer$
|
\\ .weak __global_pointer$
|
||||||
@ -247,7 +270,6 @@ fn _start() callconv(.naked) noreturn {
|
|||||||
// linker explicitly.
|
// linker explicitly.
|
||||||
asm volatile (switch (native_arch) {
|
asm volatile (switch (native_arch) {
|
||||||
.x86_64 =>
|
.x86_64 =>
|
||||||
\\ .cfi_undefined %%rip
|
|
||||||
\\ xorl %%ebp, %%ebp
|
\\ xorl %%ebp, %%ebp
|
||||||
\\ movq %%rsp, %%rdi
|
\\ movq %%rsp, %%rdi
|
||||||
\\ andq $-16, %%rsp
|
\\ andq $-16, %%rsp
|
||||||
@ -279,8 +301,10 @@ fn _start() callconv(.naked) noreturn {
|
|||||||
,
|
,
|
||||||
.arm, .armeb, .thumb, .thumbeb =>
|
.arm, .armeb, .thumb, .thumbeb =>
|
||||||
// Note that this code must work for Thumb-1.
|
// Note that this code must work for Thumb-1.
|
||||||
|
// r7 = FP (local), r11 = FP (unwind)
|
||||||
\\ movs v1, #0
|
\\ movs v1, #0
|
||||||
\\ mov fp, v1
|
\\ mov r7, v1
|
||||||
|
\\ mov r11, v1
|
||||||
\\ mov lr, v1
|
\\ mov lr, v1
|
||||||
\\ mov a1, sp
|
\\ mov a1, sp
|
||||||
\\ subs v1, #16
|
\\ subs v1, #16
|
||||||
@ -290,20 +314,23 @@ fn _start() callconv(.naked) noreturn {
|
|||||||
,
|
,
|
||||||
.csky =>
|
.csky =>
|
||||||
// The CSKY ABI assumes that `gb` is set to the address of the GOT in order for
|
// The CSKY ABI assumes that `gb` is set to the address of the GOT in order for
|
||||||
// position-independent code to work. We depend on this in `std.os.linux.start_pie`
|
// position-independent code to work. We depend on this in `std.os.linux.pie` to locate
|
||||||
// to locate `_DYNAMIC` as well.
|
// `_DYNAMIC` as well.
|
||||||
|
// r8 = FP
|
||||||
\\ grs t0, 1f
|
\\ grs t0, 1f
|
||||||
\\ 1:
|
\\ 1:
|
||||||
\\ lrw gb, 1b@GOTPC
|
\\ lrw gb, 1b@GOTPC
|
||||||
\\ addu gb, t0
|
\\ addu gb, t0
|
||||||
|
\\ movi r8, 0
|
||||||
\\ movi lr, 0
|
\\ movi lr, 0
|
||||||
\\ mov a0, sp
|
\\ mov a0, sp
|
||||||
\\ andi sp, sp, -8
|
\\ andi sp, sp, -8
|
||||||
\\ jmpi %[posixCallMainAndExit]
|
\\ jmpi %[posixCallMainAndExit]
|
||||||
,
|
,
|
||||||
.hexagon =>
|
.hexagon =>
|
||||||
// r29 = SP, r30 = FP
|
// r29 = SP, r30 = FP, r31 = LR
|
||||||
\\ r30 = #0
|
\\ r30 = #0
|
||||||
|
\\ r31 = #0
|
||||||
\\ r0 = r29
|
\\ r0 = r29
|
||||||
\\ r29 = and(r29, #-16)
|
\\ r29 = and(r29, #-16)
|
||||||
\\ memw(r29 + #-8) = r29
|
\\ memw(r29 + #-8) = r29
|
||||||
@ -312,12 +339,13 @@ fn _start() callconv(.naked) noreturn {
|
|||||||
,
|
,
|
||||||
.loongarch32, .loongarch64 =>
|
.loongarch32, .loongarch64 =>
|
||||||
\\ move $fp, $zero
|
\\ move $fp, $zero
|
||||||
|
\\ move $ra, $zero
|
||||||
\\ move $a0, $sp
|
\\ move $a0, $sp
|
||||||
\\ bstrins.d $sp, $zero, 3, 0
|
\\ bstrins.d $sp, $zero, 3, 0
|
||||||
\\ b %[posixCallMainAndExit]
|
\\ b %[posixCallMainAndExit]
|
||||||
,
|
,
|
||||||
.riscv32, .riscv64 =>
|
.riscv32, .riscv64 =>
|
||||||
\\ li s0, 0
|
\\ li fp, 0
|
||||||
\\ li ra, 0
|
\\ li ra, 0
|
||||||
\\ mv a0, sp
|
\\ mv a0, sp
|
||||||
\\ andi sp, sp, -16
|
\\ andi sp, sp, -16
|
||||||
@ -371,28 +399,35 @@ fn _start() callconv(.naked) noreturn {
|
|||||||
,
|
,
|
||||||
.powerpc, .powerpcle =>
|
.powerpc, .powerpcle =>
|
||||||
// Set up the initial stack frame, and clear the back chain pointer.
|
// Set up the initial stack frame, and clear the back chain pointer.
|
||||||
|
// r1 = SP, r31 = FP
|
||||||
\\ mr 3, 1
|
\\ mr 3, 1
|
||||||
\\ clrrwi 1, 1, 4
|
\\ clrrwi 1, 1, 4
|
||||||
\\ li 0, 0
|
\\ li 0, 0
|
||||||
\\ stwu 1, -16(1)
|
\\ stwu 1, -16(1)
|
||||||
\\ stw 0, 0(1)
|
\\ stw 0, 0(1)
|
||||||
|
\\ li 31, 0
|
||||||
\\ mtlr 0
|
\\ mtlr 0
|
||||||
\\ b %[posixCallMainAndExit]
|
\\ b %[posixCallMainAndExit]
|
||||||
,
|
,
|
||||||
.powerpc64, .powerpc64le =>
|
.powerpc64, .powerpc64le =>
|
||||||
// Set up the ToC and initial stack frame, and clear the back chain pointer.
|
// Set up the ToC and initial stack frame, and clear the back chain pointer.
|
||||||
|
// r1 = SP, r2 = ToC, r31 = FP
|
||||||
\\ addis 2, 12, .TOC. - %[_start]@ha
|
\\ addis 2, 12, .TOC. - %[_start]@ha
|
||||||
\\ addi 2, 2, .TOC. - %[_start]@l
|
\\ addi 2, 2, .TOC. - %[_start]@l
|
||||||
\\ mr 3, 1
|
\\ mr 3, 1
|
||||||
\\ clrrdi 1, 1, 4
|
\\ clrrdi 1, 1, 4
|
||||||
\\ li 0, 0
|
\\ li 0, 0
|
||||||
\\ stdu 0, -32(1)
|
\\ stdu 0, -32(1)
|
||||||
|
\\ li 31, 0
|
||||||
\\ mtlr 0
|
\\ mtlr 0
|
||||||
\\ b %[posixCallMainAndExit]
|
\\ b %[posixCallMainAndExit]
|
||||||
\\ nop
|
\\ nop
|
||||||
,
|
,
|
||||||
.s390x =>
|
.s390x =>
|
||||||
// Set up the stack frame (register save area and cleared back-chain slot).
|
// Set up the stack frame (register save area and cleared back-chain slot).
|
||||||
|
// r11 = FP, r14 = LR, r15 = SP
|
||||||
|
\\ lghi %%r11, 0
|
||||||
|
\\ lghi %%r14, 0
|
||||||
\\ lgr %%r2, %%r15
|
\\ lgr %%r2, %%r15
|
||||||
\\ lghi %%r0, -16
|
\\ lghi %%r0, -16
|
||||||
\\ ngr %%r15, %%r0
|
\\ ngr %%r15, %%r0
|
||||||
@ -403,7 +438,9 @@ fn _start() callconv(.naked) noreturn {
|
|||||||
,
|
,
|
||||||
.sparc =>
|
.sparc =>
|
||||||
// argc is stored after a register window (16 registers * 4 bytes).
|
// argc is stored after a register window (16 registers * 4 bytes).
|
||||||
|
// i7 = LR
|
||||||
\\ mov %%g0, %%fp
|
\\ mov %%g0, %%fp
|
||||||
|
\\ mov %%g0, %%i7
|
||||||
\\ add %%sp, 64, %%o0
|
\\ add %%sp, 64, %%o0
|
||||||
\\ and %%sp, -8, %%sp
|
\\ and %%sp, -8, %%sp
|
||||||
\\ ba,a %[posixCallMainAndExit]
|
\\ ba,a %[posixCallMainAndExit]
|
||||||
@ -411,7 +448,9 @@ fn _start() callconv(.naked) noreturn {
|
|||||||
.sparc64 =>
|
.sparc64 =>
|
||||||
// argc is stored after a register window (16 registers * 8 bytes) plus the stack bias
|
// argc is stored after a register window (16 registers * 8 bytes) plus the stack bias
|
||||||
// (2047 bytes).
|
// (2047 bytes).
|
||||||
|
// i7 = LR
|
||||||
\\ mov %%g0, %%fp
|
\\ mov %%g0, %%fp
|
||||||
|
\\ mov %%g0, %%i7
|
||||||
\\ add %%sp, 2175, %%o0
|
\\ add %%sp, 2175, %%o0
|
||||||
\\ add %%sp, 2047, %%sp
|
\\ add %%sp, 2047, %%sp
|
||||||
\\ and %%sp, -16, %%sp
|
\\ and %%sp, -16, %%sp
|
||||||
|
|||||||
@ -2,6 +2,7 @@ target: std.Target,
|
|||||||
zig_backend: std.builtin.CompilerBackend,
|
zig_backend: std.builtin.CompilerBackend,
|
||||||
output_mode: std.builtin.OutputMode,
|
output_mode: std.builtin.OutputMode,
|
||||||
link_mode: std.builtin.LinkMode,
|
link_mode: std.builtin.LinkMode,
|
||||||
|
unwind_tables: std.builtin.UnwindTables,
|
||||||
is_test: bool,
|
is_test: bool,
|
||||||
single_threaded: bool,
|
single_threaded: bool,
|
||||||
link_libc: 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 output_mode: std.builtin.OutputMode = .{p_};
|
||||||
\\pub const link_mode: std.builtin.LinkMode = .{p_};
|
\\pub const link_mode: std.builtin.LinkMode = .{p_};
|
||||||
|
\\pub const unwind_tables: std.builtin.UnwindTables = .{p_};
|
||||||
\\pub const is_test = {};
|
\\pub const is_test = {};
|
||||||
\\pub const single_threaded = {};
|
\\pub const single_threaded = {};
|
||||||
\\pub const abi: std.Target.Abi = .{p_};
|
\\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(zig_backend)),
|
||||||
std.zig.fmtId(@tagName(opts.output_mode)),
|
std.zig.fmtId(@tagName(opts.output_mode)),
|
||||||
std.zig.fmtId(@tagName(opts.link_mode)),
|
std.zig.fmtId(@tagName(opts.link_mode)),
|
||||||
|
std.zig.fmtId(@tagName(opts.unwind_tables)),
|
||||||
opts.is_test,
|
opts.is_test,
|
||||||
opts.single_threaded,
|
opts.single_threaded,
|
||||||
std.zig.fmtId(@tagName(target.abi)),
|
std.zig.fmtId(@tagName(target.abi)),
|
||||||
|
|||||||
@ -1261,12 +1261,15 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil
|
|||||||
// The "any" values provided by resolved config only account for
|
// The "any" values provided by resolved config only account for
|
||||||
// explicitly-provided settings. We now make them additionally account
|
// explicitly-provided settings. We now make them additionally account
|
||||||
// for default setting resolution.
|
// 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_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_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 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 build_id = options.build_id orelse .none;
|
||||||
|
|
||||||
const link_libc = options.config.link_libc;
|
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.pie);
|
||||||
cache.hash.add(options.config.lto);
|
cache.hash.add(options.config.lto);
|
||||||
cache.hash.add(options.config.link_mode);
|
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.function_sections);
|
||||||
cache.hash.add(options.data_sections);
|
cache.hash.add(options.data_sections);
|
||||||
cache.hash.add(link_libc);
|
cache.hash.add(link_libc);
|
||||||
@ -5553,10 +5557,17 @@ pub fn addCCArgs(
|
|||||||
try argv.append("-Werror=date-time");
|
try argv.append("-Werror=date-time");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mod.unwind_tables) {
|
switch (mod.unwind_tables) {
|
||||||
try argv.append("-funwind-tables");
|
.none => {
|
||||||
} else {
|
try argv.append("-fno-unwind-tables");
|
||||||
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 => {},
|
.shared_library, .ll, .bc, .unknown, .static_library, .object, .def, .zig, .res, .manifest => {},
|
||||||
@ -6288,6 +6299,7 @@ pub const CrtFileOptions = struct {
|
|||||||
function_sections: ?bool = null,
|
function_sections: ?bool = null,
|
||||||
data_sections: ?bool = null,
|
data_sections: ?bool = null,
|
||||||
omit_frame_pointer: ?bool = null,
|
omit_frame_pointer: ?bool = null,
|
||||||
|
unwind_tables: ?std.builtin.UnwindTables = null,
|
||||||
pic: ?bool = null,
|
pic: ?bool = null,
|
||||||
no_builtin: ?bool = null,
|
no_builtin: ?bool = null,
|
||||||
};
|
};
|
||||||
@ -6349,7 +6361,8 @@ pub fn build_crt_file(
|
|||||||
// Some libcs (e.g. musl) are opinionated about -fomit-frame-pointer.
|
// 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,
|
.omit_frame_pointer = options.omit_frame_pointer orelse comp.root_mod.omit_frame_pointer,
|
||||||
.valgrind = false,
|
.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.
|
// Some CRT objects (e.g. musl's rcrt1.o and Scrt1.o) are opinionated about PIC.
|
||||||
.pic = options.pic orelse comp.root_mod.pic,
|
.pic = options.pic orelse comp.root_mod.pic,
|
||||||
.optimize_mode = comp.compilerRtOptMode(),
|
.optimize_mode = comp.compilerRtOptMode(),
|
||||||
|
|||||||
@ -12,13 +12,14 @@ link_libunwind: bool,
|
|||||||
/// True if and only if the c_source_files field will have nonzero length when
|
/// True if and only if the c_source_files field will have nonzero length when
|
||||||
/// calling Compilation.create.
|
/// calling Compilation.create.
|
||||||
any_c_source_files: bool,
|
any_c_source_files: bool,
|
||||||
/// This is true if any Module has unwind_tables set explicitly to true. Until
|
/// This is not `.none` if any `Module` has `unwind_tables` set explicitly to a
|
||||||
/// Compilation.create is called, it is possible for this to be false while in
|
/// value other than `.none`. Until `Compilation.create()` is called, it is
|
||||||
/// fact all Module instances have unwind_tables=true due to the default
|
/// possible for this to be `.none` while in fact all `Module` instances have
|
||||||
/// being unwind_tables=true. After Compilation.create is called this will
|
/// `unwind_tables != .none` due to the default. After `Compilation.create()` is
|
||||||
/// also take into account the default setting, making this value true if and
|
/// called, this will also take into account the default setting, making this
|
||||||
/// only if any Module has unwind_tables set to true.
|
/// value `.sync` or `.@"async"` if and only if any `Module` has
|
||||||
any_unwind_tables: bool,
|
/// `unwind_tables != .none`.
|
||||||
|
any_unwind_tables: std.builtin.UnwindTables,
|
||||||
/// This is true if any Module has single_threaded set explicitly to false. Until
|
/// 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
|
/// 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
|
/// 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_non_single_threaded: bool = false,
|
||||||
any_sanitize_thread: bool = false,
|
any_sanitize_thread: bool = false,
|
||||||
any_fuzz: bool = false,
|
any_fuzz: bool = false,
|
||||||
any_unwind_tables: bool = false,
|
any_unwind_tables: std.builtin.UnwindTables = .none,
|
||||||
any_dyn_libs: bool = false,
|
any_dyn_libs: bool = false,
|
||||||
any_c_source_files: bool = false,
|
any_c_source_files: bool = false,
|
||||||
any_non_stripped: bool = false,
|
any_non_stripped: bool = false,
|
||||||
@ -356,8 +357,11 @@ pub fn resolve(options: Options) ResolveError!Config {
|
|||||||
break :b false;
|
break :b false;
|
||||||
};
|
};
|
||||||
|
|
||||||
const any_unwind_tables = options.any_unwind_tables or
|
const any_unwind_tables = b: {
|
||||||
link_libunwind or target_util.needUnwindTables(target);
|
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 link_mode = b: {
|
||||||
const explicitly_exe_or_dyn_lib = switch (options.output_mode) {
|
const explicitly_exe_or_dyn_lib = switch (options.output_mode) {
|
||||||
|
|||||||
@ -27,7 +27,7 @@ red_zone: bool,
|
|||||||
sanitize_c: bool,
|
sanitize_c: bool,
|
||||||
sanitize_thread: bool,
|
sanitize_thread: bool,
|
||||||
fuzz: bool,
|
fuzz: bool,
|
||||||
unwind_tables: bool,
|
unwind_tables: std.builtin.UnwindTables,
|
||||||
cc_argv: []const []const u8,
|
cc_argv: []const []const u8,
|
||||||
/// (SPIR-V) whether to generate a structured control flow graph or not
|
/// (SPIR-V) whether to generate a structured control flow graph or not
|
||||||
structured_cfg: bool,
|
structured_cfg: bool,
|
||||||
@ -91,7 +91,7 @@ pub const CreateOptions = struct {
|
|||||||
/// other number means stack protection with that buffer size.
|
/// other number means stack protection with that buffer size.
|
||||||
stack_protector: ?u32 = null,
|
stack_protector: ?u32 = null,
|
||||||
red_zone: ?bool = null,
|
red_zone: ?bool = null,
|
||||||
unwind_tables: ?bool = null,
|
unwind_tables: ?std.builtin.UnwindTables = null,
|
||||||
sanitize_c: ?bool = null,
|
sanitize_c: ?bool = null,
|
||||||
sanitize_thread: ?bool = null,
|
sanitize_thread: ?bool = null,
|
||||||
fuzz: ?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.sanitize_thread == true) assert(options.global.any_sanitize_thread);
|
||||||
if (options.inherited.fuzz == true) assert(options.global.any_fuzz);
|
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.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);
|
if (options.inherited.error_tracing == true) assert(options.global.any_error_tracing);
|
||||||
|
|
||||||
const resolved_target = options.inherited.resolved_target orelse options.parent.?.resolved_target;
|
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,
|
.zig_backend = zig_backend,
|
||||||
.output_mode = options.global.output_mode,
|
.output_mode = options.global.output_mode,
|
||||||
.link_mode = options.global.link_mode,
|
.link_mode = options.global.link_mode,
|
||||||
|
.unwind_tables = options.global.any_unwind_tables,
|
||||||
.is_test = options.global.is_test,
|
.is_test = options.global.is_test,
|
||||||
.single_threaded = single_threaded,
|
.single_threaded = single_threaded,
|
||||||
.link_libc = options.global.link_libc,
|
.link_libc = options.global.link_libc,
|
||||||
|
|||||||
@ -8442,6 +8442,10 @@ fn failSymbol(func: *Func, comptime format: []const u8, args: anytype) InnerErro
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn parseRegName(name: []const u8) ?Register {
|
fn parseRegName(name: []const u8) ?Register {
|
||||||
|
// The `fp` alias for `s0` is awkward to fit into the current `Register` scheme, so for now we
|
||||||
|
// special-case it here.
|
||||||
|
if (std.mem.eql(u8, name, "fp")) return .s0;
|
||||||
|
|
||||||
return std.meta.stringToEnum(Register, name);
|
return std.meta.stringToEnum(Register, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -2757,7 +2757,14 @@ flagpd1("fast"),
|
|||||||
flagpd1("fastcp"),
|
flagpd1("fastcp"),
|
||||||
flagpd1("fastf"),
|
flagpd1("fastf"),
|
||||||
flagpd1("fasync-exceptions"),
|
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-import"),
|
||||||
flagpd1("fauto-profile"),
|
flagpd1("fauto-profile"),
|
||||||
flagpd1("fauto-profile-accurate"),
|
flagpd1("fauto-profile-accurate"),
|
||||||
@ -3247,7 +3254,14 @@ flagpd1("fno-assume-sane-operator-new"),
|
|||||||
flagpd1("fno-assume-unique-vtables"),
|
flagpd1("fno-assume-unique-vtables"),
|
||||||
flagpd1("fno-assumptions"),
|
flagpd1("fno-assumptions"),
|
||||||
flagpd1("fno-async-exceptions"),
|
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-import"),
|
||||||
flagpd1("fno-auto-profile"),
|
flagpd1("fno-auto-profile"),
|
||||||
flagpd1("fno-auto-profile-accurate"),
|
flagpd1("fno-auto-profile-accurate"),
|
||||||
|
|||||||
@ -3141,8 +3141,11 @@ pub const Object = struct {
|
|||||||
} }, &o.builder);
|
} }, &o.builder);
|
||||||
}
|
}
|
||||||
try attributes.addFnAttr(.nounwind, &o.builder);
|
try attributes.addFnAttr(.nounwind, &o.builder);
|
||||||
if (owner_mod.unwind_tables) {
|
if (owner_mod.unwind_tables != .none) {
|
||||||
try attributes.addFnAttr(.{ .uwtable = Builder.Attribute.UwTable.default }, &o.builder);
|
try attributes.addFnAttr(
|
||||||
|
.{ .uwtable = if (owner_mod.unwind_tables == .@"async") .@"async" else .sync },
|
||||||
|
&o.builder,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
if (owner_mod.no_builtin) {
|
if (owner_mod.no_builtin) {
|
||||||
// The intent here is for compiler-rt and libc functions to not generate
|
// The intent here is for compiler-rt and libc functions to not generate
|
||||||
|
|||||||
@ -397,7 +397,6 @@ pub fn buildLibCXXABI(comp: *Compilation, prog_node: std.Progress.Node) BuildErr
|
|||||||
|
|
||||||
const optimize_mode = comp.compilerRtOptMode();
|
const optimize_mode = comp.compilerRtOptMode();
|
||||||
const strip = comp.compilerRtStrip();
|
const strip = comp.compilerRtStrip();
|
||||||
const unwind_tables = true;
|
|
||||||
|
|
||||||
const config = Compilation.Config.resolve(.{
|
const config = Compilation.Config.resolve(.{
|
||||||
.output_mode = output_mode,
|
.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_optimize_mode = optimize_mode,
|
||||||
.root_strip = strip,
|
.root_strip = strip,
|
||||||
.link_libc = true,
|
.link_libc = true,
|
||||||
.any_unwind_tables = unwind_tables,
|
|
||||||
.lto = comp.config.lto,
|
.lto = comp.config.lto,
|
||||||
.any_sanitize_thread = comp.config.any_sanitize_thread,
|
.any_sanitize_thread = comp.config.any_sanitize_thread,
|
||||||
}) catch |err| {
|
}) catch |err| {
|
||||||
@ -440,7 +438,12 @@ pub fn buildLibCXXABI(comp: *Compilation, prog_node: std.Progress.Node) BuildErr
|
|||||||
.valgrind = false,
|
.valgrind = false,
|
||||||
.optimize_mode = optimize_mode,
|
.optimize_mode = optimize_mode,
|
||||||
.structured_cfg = comp.root_mod.structured_cfg,
|
.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,
|
.pic = comp.root_mod.pic,
|
||||||
},
|
},
|
||||||
.global = config,
|
.global = config,
|
||||||
|
|||||||
@ -65,7 +65,8 @@ pub fn buildStaticLib(comp: *Compilation, prog_node: std.Progress.Node) BuildErr
|
|||||||
.sanitize_c = false,
|
.sanitize_c = false,
|
||||||
.sanitize_thread = false,
|
.sanitize_thread = false,
|
||||||
// necessary so that libunwind can unwind through its own stack frames
|
// 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,
|
.pic = if (target_util.supports_fpic(target)) true else null,
|
||||||
.optimize_mode = comp.compilerRtOptMode(),
|
.optimize_mode = comp.compilerRtOptMode(),
|
||||||
},
|
},
|
||||||
|
|||||||
54
src/main.zig
54
src/main.zig
@ -510,6 +510,7 @@ const usage_build_generic =
|
|||||||
\\ -ffuzz Enable fuzz testing instrumentation
|
\\ -ffuzz Enable fuzz testing instrumentation
|
||||||
\\ -fno-fuzz Disable fuzz testing instrumentation
|
\\ -fno-fuzz Disable fuzz testing instrumentation
|
||||||
\\ -funwind-tables Always produce unwind table entries for all functions
|
\\ -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
|
\\ -fno-unwind-tables Never produce unwind table entries
|
||||||
\\ -ferror-tracing Enable error tracing in ReleaseFast mode
|
\\ -ferror-tracing Enable error tracing in ReleaseFast mode
|
||||||
\\ -fno-error-tracing Disable error tracing in Debug and ReleaseSafe 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")) {
|
} else if (mem.eql(u8, arg, "-fno-lto")) {
|
||||||
create_module.opts.lto = false;
|
create_module.opts.lto = false;
|
||||||
} else if (mem.eql(u8, arg, "-funwind-tables")) {
|
} 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")) {
|
} 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")) {
|
} else if (mem.eql(u8, arg, "-fstack-check")) {
|
||||||
mod_opts.stack_check = true;
|
mod_opts.stack_check = true;
|
||||||
} else if (mem.eql(u8, arg, "-fno-stack-check")) {
|
} else if (mem.eql(u8, arg, "-fno-stack-check")) {
|
||||||
@ -1973,8 +1976,27 @@ fn buildOutputType(
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
.no_stack_protector => mod_opts.stack_protector = 0,
|
.no_stack_protector => mod_opts.stack_protector = 0,
|
||||||
.unwind_tables => mod_opts.unwind_tables = true,
|
// The way these unwind table options are processed in GCC and Clang is crazy
|
||||||
.no_unwind_tables => mod_opts.unwind_tables = false,
|
// 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 => {
|
.nostdlib => {
|
||||||
create_module.opts.ensure_libc_on_non_freestanding = false;
|
create_module.opts.ensure_libc_on_non_freestanding = false;
|
||||||
create_module.opts.ensure_libcpp_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;
|
create_module.opts.any_sanitize_thread = true;
|
||||||
if (mod_opts.fuzz == true)
|
if (mod_opts.fuzz == true)
|
||||||
create_module.opts.any_fuzz = true;
|
create_module.opts.any_fuzz = true;
|
||||||
if (mod_opts.unwind_tables == true)
|
if (mod_opts.unwind_tables) |uwt| switch (uwt) {
|
||||||
create_module.opts.any_unwind_tables = true;
|
.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)
|
if (mod_opts.strip == false)
|
||||||
create_module.opts.any_non_stripped = true;
|
create_module.opts.any_non_stripped = true;
|
||||||
if (mod_opts.error_tracing == true)
|
if (mod_opts.error_tracing == true)
|
||||||
@ -5713,6 +5742,8 @@ pub const ClangArgIterator = struct {
|
|||||||
no_lto,
|
no_lto,
|
||||||
unwind_tables,
|
unwind_tables,
|
||||||
no_unwind_tables,
|
no_unwind_tables,
|
||||||
|
asynchronous_unwind_tables,
|
||||||
|
no_asynchronous_unwind_tables,
|
||||||
nostdlib,
|
nostdlib,
|
||||||
nostdlib_cpp,
|
nostdlib_cpp,
|
||||||
shared,
|
shared,
|
||||||
@ -7435,8 +7466,15 @@ fn handleModArg(
|
|||||||
create_module.opts.any_sanitize_thread = true;
|
create_module.opts.any_sanitize_thread = true;
|
||||||
if (mod_opts.fuzz == true)
|
if (mod_opts.fuzz == true)
|
||||||
create_module.opts.any_fuzz = true;
|
create_module.opts.any_fuzz = true;
|
||||||
if (mod_opts.unwind_tables == true)
|
if (mod_opts.unwind_tables) |uwt| switch (uwt) {
|
||||||
create_module.opts.any_unwind_tables = true;
|
.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)
|
if (mod_opts.strip == false)
|
||||||
create_module.opts.any_non_stripped = true;
|
create_module.opts.any_non_stripped = true;
|
||||||
if (mod_opts.error_tracing == true)
|
if (mod_opts.error_tracing == true)
|
||||||
|
|||||||
@ -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);
|
var arena_allocator = std.heap.ArenaAllocator.init(comp.gpa);
|
||||||
defer arena_allocator.deinit();
|
defer arena_allocator.deinit();
|
||||||
const arena = arena_allocator.allocator();
|
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) {
|
switch (crt_file) {
|
||||||
.crt2_o => {
|
.crt2_o => {
|
||||||
@ -41,7 +45,9 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre
|
|||||||
.owner = undefined,
|
.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 => {
|
.dllcrt2_o => {
|
||||||
@ -56,7 +62,9 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre
|
|||||||
.owner = undefined,
|
.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 => {
|
.mingw32_lib => {
|
||||||
@ -73,7 +81,6 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre
|
|||||||
.owner = undefined,
|
.owner = undefined,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
const target = comp.getTarget();
|
|
||||||
if (target.cpu.arch == .x86 or target.cpu.arch == .x86_64) {
|
if (target.cpu.arch == .x86 or target.cpu.arch == .x86_64) {
|
||||||
for (mingw32_x86_src) |dep| {
|
for (mingw32_x86_src) |dep| {
|
||||||
try c_source_files.append(.{
|
try c_source_files.append(.{
|
||||||
@ -118,7 +125,9 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre
|
|||||||
} else {
|
} else {
|
||||||
@panic("unsupported arch");
|
@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,
|
||||||
|
});
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,6 +4,7 @@ const assert = std.debug.assert;
|
|||||||
const Type = @import("Type.zig");
|
const Type = @import("Type.zig");
|
||||||
const AddressSpace = std.builtin.AddressSpace;
|
const AddressSpace = std.builtin.AddressSpace;
|
||||||
const Alignment = @import("InternPool.zig").Alignment;
|
const Alignment = @import("InternPool.zig").Alignment;
|
||||||
|
const Compilation = @import("Compilation.zig");
|
||||||
const Feature = @import("Zcu.zig").Feature;
|
const Feature = @import("Zcu.zig").Feature;
|
||||||
|
|
||||||
pub const default_stack_protector_buffer_size = 4;
|
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 {
|
pub fn needUnwindTables(target: std.Target, libunwind: bool, libtsan: bool) std.builtin.UnwindTables {
|
||||||
return target.os.tag == .windows or target.isDarwin() or std.debug.Dwarf.abi.supportsUnwinding(target);
|
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(
|
pub fn defaultAddressSpace(
|
||||||
|
|||||||
@ -23,7 +23,7 @@ pub fn build(b: *std.Build) void {
|
|||||||
.root_source_file = b.path("unwind.zig"),
|
.root_source_file = b.path("unwind.zig"),
|
||||||
.target = target,
|
.target = target,
|
||||||
.optimize = optimize,
|
.optimize = optimize,
|
||||||
.unwind_tables = if (target.result.isDarwin()) true else null,
|
.unwind_tables = if (target.result.isDarwin()) .@"async" else null,
|
||||||
.omit_frame_pointer = false,
|
.omit_frame_pointer = false,
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -46,7 +46,7 @@ pub fn build(b: *std.Build) void {
|
|||||||
.root_source_file = b.path("unwind.zig"),
|
.root_source_file = b.path("unwind.zig"),
|
||||||
.target = target,
|
.target = target,
|
||||||
.optimize = optimize,
|
.optimize = optimize,
|
||||||
.unwind_tables = true,
|
.unwind_tables = .@"async",
|
||||||
.omit_frame_pointer = true,
|
.omit_frame_pointer = true,
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -85,7 +85,7 @@ pub fn build(b: *std.Build) void {
|
|||||||
.root_source_file = b.path("shared_lib_unwind.zig"),
|
.root_source_file = b.path("shared_lib_unwind.zig"),
|
||||||
.target = target,
|
.target = target,
|
||||||
.optimize = optimize,
|
.optimize = optimize,
|
||||||
.unwind_tables = if (target.result.isDarwin()) true else null,
|
.unwind_tables = if (target.result.isDarwin()) .@"async" else null,
|
||||||
.omit_frame_pointer = true,
|
.omit_frame_pointer = true,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -110,6 +110,14 @@ const known_options = [_]KnownOpt{
|
|||||||
.name = "fno-unwind-tables",
|
.name = "fno-unwind-tables",
|
||||||
.ident = "no_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",
|
.name = "nolibc",
|
||||||
.ident = "nostdlib",
|
.ident = "nostdlib",
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user