| author | |
| committer | |
| log | 130f7c2ed8e3358e24bb2fc7cca57f7a6f1f85c3 |
| tree | ebb88312b13fb8b1e67b852bcb0e42903ad11193 |
| parent | d48611ba67c7871cb348f28a01b89d8771170dd8 |
| parent | c666ebb1f8aac440a4d0d554e9f8aa836bf58060 |
| signature |
Better unwind table support + unwind protection in `_start()` and `clone()`45 files changed, 361 insertions(+), 138 deletions(-)
lib/libc/musl/src/thread/aarch64/clone.s+2-1| ... | @@ -24,7 +24,8 @@ __clone: | ... | @@ -24,7 +24,8 @@ __clone: |
| 24 | 	// parent | 24 | 	// parent |
| 25 | 	ret | 25 | 	ret |
| 26 | 	// child | 26 | 	// child |
| 27 | 1:	ldp x1,x0,[sp],#16 | 27 | 1:	mov fp, 0 |
| 28 | 	ldp x1,x0,[sp],#16 | ||
| 28 | 	blr x1 | 29 | 	blr x1 |
| 29 | 	mov x8,#93 // SYS_exit | 30 | 	mov x8,#93 // SYS_exit |
| 30 | 	svc #0 | 31 | 	svc #0 |
lib/libc/musl/src/thread/arm/clone.s+2-1| ... | @@ -19,7 +19,8 @@ __clone: | ... | @@ -19,7 +19,8 @@ __clone: |
| 19 | 	ldmfd sp!,{r4,r5,r6,r7} | 19 | 	ldmfd sp!,{r4,r5,r6,r7} |
| 20 | 	bx lr | 20 | 	bx lr |
| 21 | 21 | ||
| 22 | 1:	mov r0,r6 | 22 | 1:	mov fp,#0 |
| 23 | 	mov r0,r6 | ||
| 23 | 	bl 3f | 24 | 	bl 3f |
| 24 | 2:	mov r7,#1 | 25 | 2:	mov r7,#1 |
| 25 | 	svc 0 | 26 | 	svc 0 |
lib/libc/musl/src/thread/i386/clone.s+8-9| ... | @@ -30,9 +30,15 @@ __clone: | ... | @@ -30,9 +30,15 @@ __clone: |
| 30 | 	mov 8(%ebp),%ebp | 30 | 	mov 8(%ebp),%ebp |
| 31 | 	int $128 | 31 | 	int $128 |
| 32 | 	test %eax,%eax | 32 | 	test %eax,%eax |
| 33 | 	jnz 1f | 33 | 	jz 1f |
| 34 | 	add $16,%esp | ||
| 35 | 	pop %edi | ||
| 36 | 	pop %esi | ||
| 37 | 	pop %ebx | ||
| 38 | 	pop %ebp | ||
| 39 | 	ret | ||
| 34 | 40 | ||
| 35 | 	mov %ebp,%eax | 41 | 1:	mov %ebp,%eax |
| 36 | 	xor %ebp,%ebp | 42 | 	xor %ebp,%ebp |
| 37 | 	call *%eax | 43 | 	call *%eax |
| 38 | 	mov %eax,%ebx | 44 | 	mov %eax,%ebx |
| ... | @@ -40,10 +46,3 @@ __clone: | ... | @@ -40,10 +46,3 @@ __clone: |
| 40 | 	inc %eax | 46 | 	inc %eax |
| 41 | 	int $128 | 47 | 	int $128 |
| 42 | 	hlt | 48 | 	hlt |
| 43 | |||
| 44 | 1:	add $16,%esp | ||
| 45 | 	pop %edi | ||
| 46 | 	pop %esi | ||
| 47 | 	pop %ebx | ||
| 48 | 	pop %ebp | ||
| 49 | 	ret |
lib/libc/musl/src/thread/loongarch64/clone.s+1| ... | @@ -22,6 +22,7 @@ __clone: | ... | @@ -22,6 +22,7 @@ __clone: |
| 22 | 	beqz $a0, 1f # whether child process | 22 | 	beqz $a0, 1f # whether child process |
| 23 | 	jirl $zero, $ra, 0 # parent process return | 23 | 	jirl $zero, $ra, 0 # parent process return |
| 24 | 1: | 24 | 1: |
| 25 | 	move $fp, $zero | ||
| 25 | 	ld.d $t8, $sp, 0 # function pointer | 26 | 	ld.d $t8, $sp, 0 # function pointer |
| 26 | 	ld.d $a0, $sp, 8 # argument pointer | 27 | 	ld.d $a0, $sp, 8 # argument pointer |
| 27 | 	jirl $ra, $t8, 0 # call the user's function | 28 | 	jirl $ra, $t8, 0 # call the user's function |
lib/libc/musl/src/thread/m68k/clone.s+2-1| ... | @@ -18,7 +18,8 @@ __clone: | ... | @@ -18,7 +18,8 @@ __clone: |
| 18 | 	beq 1f | 18 | 	beq 1f |
| 19 | 	movem.l (%sp)+,%d2-%d5 | 19 | 	movem.l (%sp)+,%d2-%d5 |
| 20 | 	rts | 20 | 	rts |
| 21 | 1:	move.l %a1,-(%sp) | 21 | 1:	suba.l %%fp,%%fp |
| 22 | 	move.l %a1,-(%sp) | ||
| 22 | 	jsr (%a0) | 23 | 	jsr (%a0) |
| 23 | 	move.l #1,%d0 | 24 | 	move.l #1,%d0 |
| 24 | 	trap #0 | 25 | 	trap #0 |
lib/libc/musl/src/thread/microblaze/clone.s+2-1| ... | @@ -22,7 +22,8 @@ __clone: | ... | @@ -22,7 +22,8 @@ __clone: |
| 22 | 	rtsd r15, 8 | 22 | 	rtsd r15, 8 |
| 23 | 	nop | 23 | 	nop |
| 24 | 24 | ||
| 25 | 1:	lwi r3, r1, 0 | 25 | 1:	add r19, r0, r0 |
| 26 | 	lwi r3, r1, 0 | ||
| 26 | 	lwi r5, r1, 4 | 27 | 	lwi r5, r1, 4 |
| 27 | 	brald r15, r3 | 28 | 	brald r15, r3 |
| 28 | 	nop | 29 | 	nop |
lib/libc/musl/src/thread/mips/clone.s+2-1| ... | @@ -27,7 +27,8 @@ __clone: | ... | @@ -27,7 +27,8 @@ __clone: |
| 27 | 	addu $sp, $sp, 16 | 27 | 	addu $sp, $sp, 16 |
| 28 | 	jr $ra | 28 | 	jr $ra |
| 29 | 	nop | 29 | 	nop |
| 30 | 1:	lw $25, 0($sp) | 30 | 1:	move $fp, $0 |
| 31 | 	lw $25, 0($sp) | ||
| 31 | 	lw $4, 4($sp) | 32 | 	lw $4, 4($sp) |
| 32 | 	jalr $25 | 33 | 	jalr $25 |
| 33 | 	nop | 34 | 	nop |
lib/libc/musl/src/thread/mips64/clone.s+2-1| ... | @@ -25,7 +25,8 @@ __clone: | ... | @@ -25,7 +25,8 @@ __clone: |
| 25 | 	nop | 25 | 	nop |
| 26 | 	jr	$ra | 26 | 	jr	$ra |
| 27 | 	nop | 27 | 	nop |
| 28 | 1:	ld	$25, 0($sp)	# function pointer | 28 | 1:	move	$fp, $0 |
| 29 | 	ld	$25, 0($sp)	# function pointer | ||
| 29 | 	ld	$4, 8($sp)	# argument pointer | 30 | 	ld	$4, 8($sp)	# argument pointer |
| 30 | 	jalr	$25		# call the user's function | 31 | 	jalr	$25		# call the user's function |
| 31 | 	nop | 32 | 	nop |
lib/libc/musl/src/thread/mipsn32/clone.s+2-1| ... | @@ -25,7 +25,8 @@ __clone: | ... | @@ -25,7 +25,8 @@ __clone: |
| 25 | 	nop | 25 | 	nop |
| 26 | 	jr	$ra | 26 | 	jr	$ra |
| 27 | 	nop | 27 | 	nop |
| 28 | 1:	lw	$25, 0($sp)	# function pointer | 28 | 1:	move	$fp, $0 |
| 29 | 	lw	$25, 0($sp)	# function pointer | ||
| 29 | 	lw	$4, 4($sp)	# argument pointer | 30 | 	lw	$4, 4($sp)	# argument pointer |
| 30 | 	jalr	$25		# call the user's function | 31 | 	jalr	$25		# call the user's function |
| 31 | 	nop | 32 | 	nop |
lib/libc/musl/src/thread/or1k/clone.s+2-1| ... | @@ -23,7 +23,8 @@ __clone: | ... | @@ -23,7 +23,8 @@ __clone: |
| 23 | 	l.jr	r9 | 23 | 	l.jr	r9 |
| 24 | 	 l.nop | 24 | 	 l.nop |
| 25 | 25 | ||
| 26 | 1:	l.lwz	r11, 0(r1) | 26 | 1:	l.ori	r2, r0, 0 |
| 27 | 	l.lwz	r11, 0(r1) | ||
| 27 | 	l.jalr	r11 | 28 | 	l.jalr	r11 |
| 28 | 	 l.lwz	r3, 4(r1) | 29 | 	 l.lwz	r3, 4(r1) |
| 29 | 30 |
lib/libc/musl/src/thread/powerpc/clone.s+9-12| ... | @@ -48,9 +48,16 @@ neg 3, 3 #negate the result (errno) | ... | @@ -48,9 +48,16 @@ neg 3, 3 #negate the result (errno) |
| 48 | # compare sc result with 0 | 48 | # compare sc result with 0 |
| 49 | cmpwi cr7, 3, 0 | 49 | cmpwi cr7, 3, 0 |
| 50 | 50 | ||
| 51 | # if not 0, jump to end | 51 | # if not 0, restore stack and return |
| 52 | bne cr7, 2f | 52 | beq cr7, 2f |
| 53 | 53 | ||
| 54 | lwz 30, 0(1) | ||
| 55 | lwz 31, 4(1) | ||
| 56 | addi 1, 1, 16 | ||
| 57 | |||
| 58 | blr | ||
| 59 | |||
| 60 | 2: | ||
| 54 | #else: we're the child | 61 | #else: we're the child |
| 55 | #call funcptr: move arg (d) into r3 | 62 | #call funcptr: move arg (d) into r3 |
| 56 | mr 3, 31 | 63 | mr 3, 31 |
| ... | @@ -61,13 +68,3 @@ bctrl | ... | @@ -61,13 +68,3 @@ bctrl |
| 61 | # mov SYS_exit into r0 (the exit param is already in r3) | 68 | # mov SYS_exit into r0 (the exit param is already in r3) |
| 62 | li 0, 1 | 69 | li 0, 1 |
| 63 | sc | 70 | sc |
| 64 | |||
| 65 | 2: | ||
| 66 | |||
| 67 | # restore stack | ||
| 68 | lwz 30, 0(1) | ||
| 69 | lwz 31, 4(1) | ||
| 70 | addi 1, 1, 16 | ||
| 71 | |||
| 72 | blr | ||
| 73 |
lib/libc/musl/src/thread/x32/clone.s+3-3| ... | @@ -15,12 +15,12 @@ __clone: | ... | @@ -15,12 +15,12 @@ __clone: |
| 15 | 	mov %rcx,(%rsi) | 15 | 	mov %rcx,(%rsi) |
| 16 | 	syscall | 16 | 	syscall |
| 17 | 	test %eax,%eax | 17 | 	test %eax,%eax |
| 18 | 	jnz 1f | 18 | 	jz 1f |
| 19 | 	xor %ebp,%ebp | 19 | 	ret |
| 20 | 1:	xor %ebp,%ebp | ||
| 20 | 	pop %rdi | 21 | 	pop %rdi |
| 21 | 	call *%r9 | 22 | 	call *%r9 |
| 22 | 	mov %eax,%edi | 23 | 	mov %eax,%edi |
| 23 | 	movl $0x4000003c,%eax /* SYS_exit */ | 24 | 	movl $0x4000003c,%eax /* SYS_exit */ |
| 24 | 	syscall | 25 | 	syscall |
| 25 | 	hlt | 26 | 	hlt |
| 26 | 1:	ret |
lib/libc/musl/src/thread/x86_64/clone.s+3-3| ... | @@ -16,8 +16,9 @@ __clone: | ... | @@ -16,8 +16,9 @@ __clone: |
| 16 | 	mov %rcx,(%rsi) | 16 | 	mov %rcx,(%rsi) |
| 17 | 	syscall | 17 | 	syscall |
| 18 | 	test %eax,%eax | 18 | 	test %eax,%eax |
| 19 | 	jnz 1f | 19 | 	jz 1f |
| 20 | 	xor %ebp,%ebp | 20 | 	ret |
| 21 | 1:	xor %ebp,%ebp | ||
| 21 | 	pop %rdi | 22 | 	pop %rdi |
| 22 | 	call *%r9 | 23 | 	call *%r9 |
| 23 | 	mov %eax,%edi | 24 | 	mov %eax,%edi |
| ... | @@ -25,4 +26,3 @@ __clone: | ... | @@ -25,4 +26,3 @@ __clone: |
| 25 | 	mov $60,%al | 26 | 	mov $60,%al |
| 26 | 	syscall | 27 | 	syscall |
| 27 | 	hlt | 28 | 	hlt |
| 28 | 1:	ret |
lib/std/Build.zig+5-5| ... | @@ -706,7 +706,7 @@ pub const ExecutableOptions = struct { | ... | @@ -706,7 +706,7 @@ pub const ExecutableOptions = struct { |
| 706 | single_threaded: ?bool = null, | 706 | single_threaded: ?bool = null, |
| 707 | pic: ?bool = null, | 707 | pic: ?bool = null, |
| 708 | strip: ?bool = null, | 708 | strip: ?bool = null, |
| 709 | unwind_tables: ?bool = null, | 709 | unwind_tables: ?std.builtin.UnwindTables = null, |
| 710 | omit_frame_pointer: ?bool = null, | 710 | omit_frame_pointer: ?bool = null, |
| 711 | sanitize_thread: ?bool = null, | 711 | sanitize_thread: ?bool = null, |
| 712 | error_tracing: ?bool = null, | 712 | error_tracing: ?bool = null, |
| ... | @@ -762,7 +762,7 @@ pub const ObjectOptions = struct { | ... | @@ -762,7 +762,7 @@ pub const ObjectOptions = struct { |
| 762 | single_threaded: ?bool = null, | 762 | single_threaded: ?bool = null, |
| 763 | pic: ?bool = null, | 763 | pic: ?bool = null, |
| 764 | strip: ?bool = null, | 764 | strip: ?bool = null, |
| 765 | unwind_tables: ?bool = null, | 765 | unwind_tables: ?std.builtin.UnwindTables = null, |
| 766 | omit_frame_pointer: ?bool = null, | 766 | omit_frame_pointer: ?bool = null, |
| 767 | sanitize_thread: ?bool = null, | 767 | sanitize_thread: ?bool = null, |
| 768 | error_tracing: ?bool = null, | 768 | error_tracing: ?bool = null, |
| ... | @@ -810,7 +810,7 @@ pub const SharedLibraryOptions = struct { | ... | @@ -810,7 +810,7 @@ pub const SharedLibraryOptions = struct { |
| 810 | single_threaded: ?bool = null, | 810 | single_threaded: ?bool = null, |
| 811 | pic: ?bool = null, | 811 | pic: ?bool = null, |
| 812 | strip: ?bool = null, | 812 | strip: ?bool = null, |
| 813 | unwind_tables: ?bool = null, | 813 | unwind_tables: ?std.builtin.UnwindTables = null, |
| 814 | omit_frame_pointer: ?bool = null, | 814 | omit_frame_pointer: ?bool = null, |
| 815 | sanitize_thread: ?bool = null, | 815 | sanitize_thread: ?bool = null, |
| 816 | error_tracing: ?bool = null, | 816 | error_tracing: ?bool = null, |
| ... | @@ -867,7 +867,7 @@ pub const StaticLibraryOptions = struct { | ... | @@ -867,7 +867,7 @@ pub const StaticLibraryOptions = struct { |
| 867 | single_threaded: ?bool = null, | 867 | single_threaded: ?bool = null, |
| 868 | pic: ?bool = null, | 868 | pic: ?bool = null, |
| 869 | strip: ?bool = null, | 869 | strip: ?bool = null, |
| 870 | unwind_tables: ?bool = null, | 870 | unwind_tables: ?std.builtin.UnwindTables = null, |
| 871 | omit_frame_pointer: ?bool = null, | 871 | omit_frame_pointer: ?bool = null, |
| 872 | sanitize_thread: ?bool = null, | 872 | sanitize_thread: ?bool = null, |
| 873 | error_tracing: ?bool = null, | 873 | error_tracing: ?bool = null, |
| ... | @@ -919,7 +919,7 @@ pub const TestOptions = struct { | ... | @@ -919,7 +919,7 @@ pub const TestOptions = struct { |
| 919 | single_threaded: ?bool = null, | 919 | single_threaded: ?bool = null, |
| 920 | pic: ?bool = null, | 920 | pic: ?bool = null, |
| 921 | strip: ?bool = null, | 921 | strip: ?bool = null, |
| 922 | unwind_tables: ?bool = null, | 922 | unwind_tables: ?std.builtin.UnwindTables = null, |
| 923 | omit_frame_pointer: ?bool = null, | 923 | omit_frame_pointer: ?bool = null, |
| 924 | sanitize_thread: ?bool = null, | 924 | sanitize_thread: ?bool = null, |
| 925 | error_tracing: ?bool = null, | 925 | error_tracing: ?bool = null, |
lib/std/Build/Module.zig+10-3| ... | @@ -22,7 +22,7 @@ frameworks: std.StringArrayHashMapUnmanaged(LinkFrameworkOptions), | ... | @@ -22,7 +22,7 @@ frameworks: std.StringArrayHashMapUnmanaged(LinkFrameworkOptions), |
| 22 | link_objects: std.ArrayListUnmanaged(LinkObject), | 22 | link_objects: std.ArrayListUnmanaged(LinkObject), |
| 23 | 23 | ||
| 24 | strip: ?bool, | 24 | strip: ?bool, |
| 25 | unwind_tables: ?bool, | 25 | unwind_tables: ?std.builtin.UnwindTables, |
| 26 | single_threaded: ?bool, | 26 | single_threaded: ?bool, |
| 27 | stack_protector: ?bool, | 27 | stack_protector: ?bool, |
| 28 | stack_check: ?bool, | 28 | stack_check: ?bool, |
| ... | @@ -218,7 +218,7 @@ pub const CreateOptions = struct { | ... | @@ -218,7 +218,7 @@ pub const CreateOptions = struct { |
| 218 | link_libcpp: ?bool = null, | 218 | link_libcpp: ?bool = null, |
| 219 | single_threaded: ?bool = null, | 219 | single_threaded: ?bool = null, |
| 220 | strip: ?bool = null, | 220 | strip: ?bool = null, |
| 221 | unwind_tables: ?bool = null, | 221 | unwind_tables: ?std.builtin.UnwindTables = null, |
| 222 | dwarf_format: ?std.dwarf.Format = null, | 222 | dwarf_format: ?std.dwarf.Format = null, |
| 223 | code_model: std.builtin.CodeModel = .default, | 223 | code_model: std.builtin.CodeModel = .default, |
| 224 | stack_protector: ?bool = null, | 224 | stack_protector: ?bool = null, |
| ... | @@ -675,7 +675,6 @@ pub fn appendZigProcessFlags( | ... | @@ -675,7 +675,6 @@ pub fn appendZigProcessFlags( |
| 675 | const b = m.owner; | 675 | const b = m.owner; |
| 676 | 676 | ||
| 677 | try addFlag(zig_args, m.strip, "-fstrip", "-fno-strip"); | 677 | try addFlag(zig_args, m.strip, "-fstrip", "-fno-strip"); |
| 678 | try addFlag(zig_args, m.unwind_tables, "-funwind-tables", "-fno-unwind-tables"); | ||
| 679 | try addFlag(zig_args, m.single_threaded, "-fsingle-threaded", "-fno-single-threaded"); | 678 | try addFlag(zig_args, m.single_threaded, "-fsingle-threaded", "-fno-single-threaded"); |
| 680 | try addFlag(zig_args, m.stack_check, "-fstack-check", "-fno-stack-check"); | 679 | try addFlag(zig_args, m.stack_check, "-fstack-check", "-fno-stack-check"); |
| 681 | try addFlag(zig_args, m.stack_protector, "-fstack-protector", "-fno-stack-protector"); | 680 | try addFlag(zig_args, m.stack_protector, "-fstack-protector", "-fno-stack-protector"); |
| ... | @@ -695,6 +694,14 @@ pub fn appendZigProcessFlags( | ... | @@ -695,6 +694,14 @@ pub fn appendZigProcessFlags( |
| 695 | }); | 694 | }); |
| 696 | } | 695 | } |
| 697 | 696 | ||
| 697 | if (m.unwind_tables) |unwind_tables| { | ||
| 698 | try zig_args.append(switch (unwind_tables) { | ||
| 699 | .none => "-fno-unwind-tables", | ||
| 700 | .sync => "-funwind-tables", | ||
| 701 | .@"async" => "-fasync-unwind-tables", | ||
| 702 | }); | ||
| 703 | } | ||
| 704 | |||
| 698 | try zig_args.ensureUnusedCapacity(1); | 705 | try zig_args.ensureUnusedCapacity(1); |
| 699 | if (m.optimize) |optimize| switch (optimize) { | 706 | if (m.optimize) |optimize| switch (optimize) { |
| 700 | .Debug => zig_args.appendAssumeCapacity("-ODebug"), | 707 | .Debug => zig_args.appendAssumeCapacity("-ODebug"), |
lib/std/builtin.zig+8| ... | @@ -804,6 +804,14 @@ pub const LinkMode = enum { | ... | @@ -804,6 +804,14 @@ pub const LinkMode = enum { |
| 804 | dynamic, | 804 | dynamic, |
| 805 | }; | 805 | }; |
| 806 | 806 | ||
| 807 | /// This data structure is used by the Zig language code generation and | ||
| 808 | /// therefore must be kept in sync with the compiler implementation. | ||
| 809 | pub const UnwindTables = enum { | ||
| 810 | none, | ||
| 811 | sync, | ||
| 812 | @"async", | ||
| 813 | }; | ||
| 814 | |||
| 807 | /// This data structure is used by the Zig language code generation and | 815 | /// This data structure is used by the Zig language code generation and |
| 808 | /// therefore must be kept in sync with the compiler implementation. | 816 | /// therefore must be kept in sync with the compiler implementation. |
| 809 | pub const WasiExecModel = enum { | 817 | pub const WasiExecModel = enum { |
lib/std/os/linux/aarch64.zig+6-1| ... | @@ -120,8 +120,13 @@ pub fn clone() callconv(.Naked) usize { | ... | @@ -120,8 +120,13 @@ pub fn clone() callconv(.Naked) usize { |
| 120 | \\ cbz x0,1f | 120 | \\ cbz x0,1f |
| 121 | \\ // parent | 121 | \\ // parent |
| 122 | \\ ret | 122 | \\ ret |
| 123 | \\ | ||
| 123 | \\ // child | 124 | \\ // child |
| 124 | \\1: ldp x1,x0,[sp],#16 | 125 | \\1: .cfi_undefined lr |
| 126 | \\ mov fp, 0 | ||
| 127 | \\ mov lr, 0 | ||
| 128 | \\ | ||
| 129 | \\ ldp x1,x0,[sp],#16 | ||
| 125 | \\ blr x1 | 130 | \\ blr x1 |
| 126 | \\ mov x8,#93 // SYS_exit | 131 | \\ mov x8,#93 // SYS_exit |
| 127 | \\ svc #0 | 132 | \\ svc #0 |
lib/std/os/linux/arm.zig+8-3| ... | @@ -120,11 +120,16 @@ pub fn clone() callconv(.Naked) usize { | ... | @@ -120,11 +120,16 @@ pub fn clone() callconv(.Naked) usize { |
| 120 | \\ ldmfd sp!,{r4,r5,r6,r7} | 120 | \\ ldmfd sp!,{r4,r5,r6,r7} |
| 121 | \\ bx lr | 121 | \\ bx lr |
| 122 | \\ | 122 | \\ |
| 123 | \\1: mov r0,r6 | 123 | \\ // https://github.com/llvm/llvm-project/issues/115891 |
| 124 | \\1: mov r7, #0 | ||
| 125 | \\ mov r11, #0 | ||
| 126 | \\ mov lr, #0 | ||
| 127 | \\ | ||
| 128 | \\ mov r0,r6 | ||
| 124 | \\ bl 3f | 129 | \\ bl 3f |
| 125 | \\2: mov r7,#1 // SYS_exit | 130 | \\ mov r7,#1 // SYS_exit |
| 126 | \\ svc 0 | 131 | \\ svc 0 |
| 127 | \\ b 2b | 132 | \\ |
| 128 | \\3: bx r5 | 133 | \\3: bx r5 |
| 129 | ); | 134 | ); |
| 130 | } | 135 | } |
lib/std/os/linux/hexagon.zig+4| ... | @@ -118,6 +118,10 @@ pub fn clone() callconv(.Naked) usize { | ... | @@ -118,6 +118,10 @@ pub fn clone() callconv(.Naked) usize { |
| 118 | \\ p0 = cmp.eq(r0, #0) | 118 | \\ p0 = cmp.eq(r0, #0) |
| 119 | \\ if (!p0) dealloc_return | 119 | \\ if (!p0) dealloc_return |
| 120 | \\ | 120 | \\ |
| 121 | \\ .cfi_undefined r31 | ||
| 122 | \\ r30 = #0 | ||
| 123 | \\ r31 = #0 | ||
| 124 | \\ | ||
| 121 | \\ r0 = r10 | 125 | \\ r0 = r10 |
| 122 | \\ callr r11 | 126 | \\ callr r11 |
| 123 | \\ | 127 | \\ |
lib/std/os/linux/loongarch64.zig+4| ... | @@ -121,6 +121,10 @@ pub fn clone() callconv(.Naked) usize { | ... | @@ -121,6 +121,10 @@ pub fn clone() callconv(.Naked) usize { |
| 121 | \\ beqz $a0, 1f # whether child process | 121 | \\ beqz $a0, 1f # whether child process |
| 122 | \\ jirl $zero, $ra, 0 # parent process return | 122 | \\ jirl $zero, $ra, 0 # parent process return |
| 123 | \\1: | 123 | \\1: |
| 124 | \\ .cfi_undefined 1 | ||
| 125 | \\ move $fp, $zero | ||
| 126 | \\ move $ra, $zero | ||
| 127 | \\ | ||
| 124 | \\ ld.d $t8, $sp, 0 # function pointer | 128 | \\ ld.d $t8, $sp, 0 # function pointer |
| 125 | \\ ld.d $a0, $sp, 8 # argument pointer | 129 | \\ ld.d $a0, $sp, 8 # argument pointer |
| 126 | \\ jirl $ra, $t8, 0 # call the user's function | 130 | \\ jirl $ra, $t8, 0 # call the user's function |
lib/std/os/linux/mips.zig+4| ... | @@ -231,6 +231,10 @@ pub fn clone() callconv(.Naked) usize { | ... | @@ -231,6 +231,10 @@ pub fn clone() callconv(.Naked) usize { |
| 231 | \\ jr $ra | 231 | \\ jr $ra |
| 232 | \\ nop | 232 | \\ nop |
| 233 | \\1: | 233 | \\1: |
| 234 | \\ .cfi_undefined $ra | ||
| 235 | \\ move $fp, $zero | ||
| 236 | \\ move $ra, $zero | ||
| 237 | \\ | ||
| 234 | \\ lw $25, 0($sp) | 238 | \\ lw $25, 0($sp) |
| 235 | \\ lw $4, 4($sp) | 239 | \\ lw $4, 4($sp) |
| 236 | \\ jalr $25 | 240 | \\ jalr $25 |
lib/std/os/linux/mips64.zig+4| ... | @@ -210,6 +210,10 @@ pub fn clone() callconv(.Naked) usize { | ... | @@ -210,6 +210,10 @@ pub fn clone() callconv(.Naked) usize { |
| 210 | \\ jr $ra | 210 | \\ jr $ra |
| 211 | \\ nop | 211 | \\ nop |
| 212 | \\1: | 212 | \\1: |
| 213 | \\ .cfi_undefined $ra | ||
| 214 | \\ move $fp, $zero | ||
| 215 | \\ move $ra, $zero | ||
| 216 | \\ | ||
| 213 | \\ ld $25, 0($sp) | 217 | \\ ld $25, 0($sp) |
| 214 | \\ ld $4, 8($sp) | 218 | \\ ld $4, 8($sp) |
| 215 | \\ jalr $25 | 219 | \\ jalr $25 |
lib/std/os/linux/powerpc.zig+20-20| ... | @@ -133,14 +133,14 @@ pub fn clone() callconv(.Naked) usize { | ... | @@ -133,14 +133,14 @@ pub fn clone() callconv(.Naked) usize { |
| 133 | // syscall(SYS_clone, flags, stack, ptid, tls, ctid) | 133 | // syscall(SYS_clone, flags, stack, ptid, tls, ctid) |
| 134 | // 0 3, 4, 5, 6, 7 | 134 | // 0 3, 4, 5, 6, 7 |
| 135 | asm volatile ( | 135 | asm volatile ( |
| 136 | \\ # store non-volatile regs r30, r31 on stack in order to put our | 136 | \\ # store non-volatile regs r29, r30 on stack in order to put our |
| 137 | \\ # start func and its arg there | 137 | \\ # start func and its arg there |
| 138 | \\ stwu 30, -16(1) | 138 | \\ stwu 29, -16(1) |
| 139 | \\ stw 31, 4(1) | 139 | \\ stw 30, 4(1) |
| 140 | \\ | 140 | \\ |
| 141 | \\ # save r3 (func) into r30, and r6(arg) into r31 | 141 | \\ # save r3 (func) into r29, and r6(arg) into r30 |
| 142 | \\ mr 30, 3 | 142 | \\ mr 29, 3 |
| 143 | \\ mr 31, 6 | 143 | \\ mr 30, 6 |
| 144 | \\ | 144 | \\ |
| 145 | \\ # create initial stack frame for new thread | 145 | \\ # create initial stack frame for new thread |
| 146 | \\ clrrwi 4, 4, 4 | 146 | \\ clrrwi 4, 4, 4 |
| ... | @@ -167,28 +167,28 @@ pub fn clone() callconv(.Naked) usize { | ... | @@ -167,28 +167,28 @@ pub fn clone() callconv(.Naked) usize { |
| 167 | \\ # compare sc result with 0 | 167 | \\ # compare sc result with 0 |
| 168 | \\ cmpwi cr7, 3, 0 | 168 | \\ cmpwi cr7, 3, 0 |
| 169 | \\ | 169 | \\ |
| 170 | \\ # if not 0, jump to end | 170 | \\ # if not 0, restore stack and return |
| 171 | \\ bne cr7, 2f | 171 | \\ beq cr7, 2f |
| 172 | \\ lwz 29, 0(1) | ||
| 173 | \\ lwz 30, 4(1) | ||
| 174 | \\ addi 1, 1, 16 | ||
| 175 | \\ blr | ||
| 172 | \\ | 176 | \\ |
| 173 | \\ #else: we're the child | 177 | \\ #else: we're the child |
| 178 | \\ 2: | ||
| 179 | \\ .cfi_undefined lr | ||
| 180 | \\ li 31, 0 | ||
| 181 | \\ mtlr 0 | ||
| 182 | \\ | ||
| 174 | \\ #call funcptr: move arg (d) into r3 | 183 | \\ #call funcptr: move arg (d) into r3 |
| 175 | \\ mr 3, 31 | 184 | \\ mr 3, 30 |
| 176 | \\ #move r30 (funcptr) into CTR reg | 185 | \\ #move r29 (funcptr) into CTR reg |
| 177 | \\ mtctr 30 | 186 | \\ mtctr 29 |
| 178 | \\ # call CTR reg | 187 | \\ # call CTR reg |
| 179 | \\ bctrl | 188 | \\ bctrl |
| 180 | \\ # mov SYS_exit into r0 (the exit param is already in r3) | 189 | \\ # mov SYS_exit into r0 (the exit param is already in r3) |
| 181 | \\ li 0, 1 | 190 | \\ li 0, 1 |
| 182 | \\ sc | 191 | \\ sc |
| 183 | \\ | ||
| 184 | \\ 2: | ||
| 185 | \\ | ||
| 186 | \\ # restore stack | ||
| 187 | \\ lwz 30, 0(1) | ||
| 188 | \\ lwz 31, 4(1) | ||
| 189 | \\ addi 1, 1, 16 | ||
| 190 | \\ | ||
| 191 | \\ blr | ||
| 192 | ); | 192 | ); |
| 193 | } | 193 | } |
| 194 | 194 |
lib/std/os/linux/powerpc64.zig+6-1| ... | @@ -160,7 +160,12 @@ pub fn clone() callconv(.Naked) usize { | ... | @@ -160,7 +160,12 @@ pub fn clone() callconv(.Naked) usize { |
| 160 | \\ cmpwi cr7, 3, 0 | 160 | \\ cmpwi cr7, 3, 0 |
| 161 | \\ bnelr cr7 | 161 | \\ bnelr cr7 |
| 162 | \\ | 162 | \\ |
| 163 | \\ # we're the child. call fn(arg) | 163 | \\ # we're the child |
| 164 | \\ .cfi_undefined lr | ||
| 165 | \\ li 31, 0 | ||
| 166 | \\ mtlr 0 | ||
| 167 | \\ | ||
| 168 | \\ # call fn(arg) | ||
| 164 | \\ ld 3, 16(1) | 169 | \\ ld 3, 16(1) |
| 165 | \\ ld 12, 8(1) | 170 | \\ ld 12, 8(1) |
| 166 | \\ mtctr 12 | 171 | \\ mtctr 12 |
lib/std/os/linux/riscv32.zig+5-1| ... | @@ -120,7 +120,11 @@ pub fn clone() callconv(.Naked) usize { | ... | @@ -120,7 +120,11 @@ pub fn clone() callconv(.Naked) usize { |
| 120 | \\ ret | 120 | \\ ret |
| 121 | \\ | 121 | \\ |
| 122 | \\ # Child | 122 | \\ # Child |
| 123 | \\1: lw a1, 0(sp) | 123 | \\1: .cfi_undefined ra |
| 124 | \\ mv fp, zero | ||
| 125 | \\ mv ra, zero | ||
| 126 | \\ | ||
| 127 | \\ lw a1, 0(sp) | ||
| 124 | \\ lw a0, 4(sp) | 128 | \\ lw a0, 4(sp) |
| 125 | \\ jalr a1 | 129 | \\ jalr a1 |
| 126 | \\ | 130 | \\ |
lib/std/os/linux/riscv64.zig+5-1| ... | @@ -120,7 +120,11 @@ pub fn clone() callconv(.Naked) usize { | ... | @@ -120,7 +120,11 @@ pub fn clone() callconv(.Naked) usize { |
| 120 | \\ ret | 120 | \\ ret |
| 121 | \\ | 121 | \\ |
| 122 | \\ # Child | 122 | \\ # Child |
| 123 | \\1: ld a1, 0(sp) | 123 | \\1: .cfi_undefined ra |
| 124 | \\ mv fp, zero | ||
| 125 | \\ mv ra, zero | ||
| 126 | \\ | ||
| 127 | \\ ld a1, 0(sp) | ||
| 124 | \\ ld a0, 8(sp) | 128 | \\ ld a0, 8(sp) |
| 125 | \\ jalr a1 | 129 | \\ jalr a1 |
| 126 | \\ | 130 | \\ |
lib/std/os/linux/s390x.zig+6-1| ... | @@ -133,7 +133,12 @@ pub fn clone() callconv(.Naked) usize { | ... | @@ -133,7 +133,12 @@ pub fn clone() callconv(.Naked) usize { |
| 133 | \\ltgr %%r2, %%r2 | 133 | \\ltgr %%r2, %%r2 |
| 134 | \\bnzr %%r14 | 134 | \\bnzr %%r14 |
| 135 | \\ | 135 | \\ |
| 136 | \\# we're the child. call fn(arg) | 136 | \\# we're the child |
| 137 | \\.cfi_undefined %%r14 | ||
| 138 | \\lghi %%r11, 0 | ||
| 139 | \\lghi %%r14, 0 | ||
| 140 | \\ | ||
| 141 | \\# call fn(arg) | ||
| 137 | \\lg %%r1, 8(%%r15) | 142 | \\lg %%r1, 8(%%r15) |
| 138 | \\lg %%r2, 16(%%r15) | 143 | \\lg %%r2, 16(%%r15) |
| 139 | \\basr %%r14, %%r1 | 144 | \\basr %%r14, %%r1 |
lib/std/os/linux/sparc64.zig+13-8| ... | @@ -198,29 +198,34 @@ pub fn clone() callconv(.Naked) usize { | ... | @@ -198,29 +198,34 @@ pub fn clone() callconv(.Naked) usize { |
| 198 | \\ mov %%i5, %%o3 | 198 | \\ mov %%i5, %%o3 |
| 199 | \\ ldx [%%fp + 0x8af], %%o4 | 199 | \\ ldx [%%fp + 0x8af], %%o4 |
| 200 | \\ t 0x6d | 200 | \\ t 0x6d |
| 201 | \\ bcs,pn %%xcc, 2f | 201 | \\ bcs,pn %%xcc, 1f |
| 202 | \\ nop | 202 | \\ nop |
| 203 | \\ # The child pid is returned in o0 while o1 tells if this | 203 | \\ # The child pid is returned in o0 while o1 tells if this |
| 204 | \\ # process is # the child (=1) or the parent (=0). | 204 | \\ # process is # the child (=1) or the parent (=0). |
| 205 | \\ brnz %%o1, 1f | 205 | \\ brnz %%o1, 2f |
| 206 | \\ nop | 206 | \\ nop |
| 207 | \\ # Parent process, return the child pid | 207 | \\ # Parent process, return the child pid |
| 208 | \\ mov %%o0, %%i0 | 208 | \\ mov %%o0, %%i0 |
| 209 | \\ ret | 209 | \\ ret |
| 210 | \\ restore | 210 | \\ restore |
| 211 | \\1: | 211 | \\1: |
| 212 | \\ # Child process, call func(arg) | 212 | \\ # The syscall failed |
| 213 | \\ sub %%g0, %%o0, %%i0 | ||
| 214 | \\ ret | ||
| 215 | \\ restore | ||
| 216 | \\2: | ||
| 217 | \\ # Child process | ||
| 218 | \\ .cfi_undefined %%i7 | ||
| 219 | \\ mov %%g0, %%fp | ||
| 220 | \\ mov %%g0, %%i7 | ||
| 221 | \\ | ||
| 222 | \\ # call func(arg) | ||
| 213 | \\ mov %%g0, %%fp | 223 | \\ mov %%g0, %%fp |
| 214 | \\ call %%g2 | 224 | \\ call %%g2 |
| 215 | \\ mov %%g3, %%o0 | 225 | \\ mov %%g3, %%o0 |
| 216 | \\ # Exit | 226 | \\ # Exit |
| 217 | \\ mov 1, %%g1 // SYS_exit | 227 | \\ mov 1, %%g1 // SYS_exit |
| 218 | \\ t 0x6d | 228 | \\ t 0x6d |
| 219 | \\2: | ||
| 220 | \\ # The syscall failed | ||
| 221 | \\ sub %%g0, %%o0, %%i0 | ||
| 222 | \\ ret | ||
| 223 | \\ restore | ||
| 224 | ); | 229 | ); |
| 225 | } | 230 | } |
| 226 | 231 |
lib/std/os/linux/x86.zig+11-8| ... | @@ -148,19 +148,22 @@ pub fn clone() callconv(.Naked) usize { | ... | @@ -148,19 +148,22 @@ pub fn clone() callconv(.Naked) usize { |
| 148 | \\ movl $120,%%eax // SYS_clone | 148 | \\ movl $120,%%eax // SYS_clone |
| 149 | \\ int $128 | 149 | \\ int $128 |
| 150 | \\ testl %%eax,%%eax | 150 | \\ testl %%eax,%%eax |
| 151 | \\ jnz 1f | 151 | \\ jz 1f |
| 152 | \\ popl %%eax | ||
| 153 | \\ xorl %%ebp,%%ebp | ||
| 154 | \\ calll *%%eax | ||
| 155 | \\ movl %%eax,%%ebx | ||
| 156 | \\ movl $1,%%eax // SYS_exit | ||
| 157 | \\ int $128 | ||
| 158 | \\1: | ||
| 159 | \\ popl %%edi | 152 | \\ popl %%edi |
| 160 | \\ popl %%esi | 153 | \\ popl %%esi |
| 161 | \\ popl %%ebx | 154 | \\ popl %%ebx |
| 162 | \\ popl %%ebp | 155 | \\ popl %%ebp |
| 163 | \\ retl | 156 | \\ retl |
| 157 | \\ | ||
| 158 | \\1: | ||
| 159 | \\ .cfi_undefined %%eip | ||
| 160 | \\ xorl %%ebp,%%ebp | ||
| 161 | \\ | ||
| 162 | \\ popl %%eax | ||
| 163 | \\ calll *%%eax | ||
| 164 | \\ movl %%eax,%%ebx | ||
| 165 | \\ movl $1,%%eax // SYS_exit | ||
| 166 | \\ int $128 | ||
| 164 | ); | 167 | ); |
| 165 | } | 168 | } |
| 166 | 169 |
lib/std/os/linux/x86_64.zig+2| ... | @@ -116,8 +116,10 @@ pub fn clone() callconv(.Naked) usize { | ... | @@ -116,8 +116,10 @@ pub fn clone() callconv(.Naked) usize { |
| 116 | \\ testq %%rax,%%rax | 116 | \\ testq %%rax,%%rax |
| 117 | \\ jz 1f | 117 | \\ jz 1f |
| 118 | \\ retq | 118 | \\ retq |
| 119 | \\ | ||
| 119 | \\1: .cfi_undefined %%rip | 120 | \\1: .cfi_undefined %%rip |
| 120 | \\ xorl %%ebp,%%ebp | 121 | \\ xorl %%ebp,%%ebp |
| 122 | \\ | ||
| 121 | \\ popq %%rdi | 123 | \\ popq %%rdi |
| 122 | \\ callq *%%r9 | 124 | \\ callq *%%r9 |
| 123 | \\ movl %%eax,%%edi | 125 | \\ movl %%eax,%%edi |
lib/std/start.zig+45-6| ... | @@ -230,6 +230,29 @@ fn _start() callconv(.naked) noreturn { | ... | @@ -230,6 +230,29 @@ fn _start() callconv(.naked) noreturn { |
| 230 | ); | 230 | ); |
| 231 | } | 231 | } |
| 232 | 232 | ||
| 233 | // 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. | ||
| 235 | asm volatile (switch (native_arch) { | ||
| 236 | .arc => ".cfi_undefined blink", | ||
| 237 | .arm, .armeb, .thumb, .thumbeb => "", // https://github.com/llvm/llvm-project/issues/115891 | ||
| 238 | .aarch64, .aarch64_be => ".cfi_undefined lr", | ||
| 239 | .csky => ".cfi_undefined lr", | ||
| 240 | .hexagon => ".cfi_undefined r31", | ||
| 241 | .loongarch32, .loongarch64 => ".cfi_undefined 1", | ||
| 242 | .m68k => ".cfi_undefined pc", | ||
| 243 | .mips, .mipsel, .mips64, .mips64el => ".cfi_undefined $ra", | ||
| 244 | .powerpc, .powerpcle, .powerpc64, .powerpc64le => ".cfi_undefined lr", | ||
| 245 | .riscv32, .riscv64 => if (builtin.zig_backend == .stage2_riscv64) | ||
| 246 | "" | ||
| 247 | else | ||
| 248 | ".cfi_undefined ra", | ||
| 249 | .s390x => ".cfi_undefined %%r14", | ||
| 250 | .sparc, .sparc64 => ".cfi_undefined %%i7", | ||
| 251 | .x86 => ".cfi_undefined %%eip", | ||
| 252 | .x86_64 => ".cfi_undefined %%rip", | ||
| 253 | else => @compileError("unsupported arch"), | ||
| 254 | }); | ||
| 255 | |||
| 233 | // Move this to the riscv prong below when this is resolved: https://github.com/ziglang/zig/issues/20918 | 256 | // Move this to the riscv prong below when this is resolved: https://github.com/ziglang/zig/issues/20918 |
| 234 | if (builtin.cpu.arch.isRISCV() and builtin.zig_backend != .stage2_riscv64) asm volatile ( | 257 | if (builtin.cpu.arch.isRISCV() and builtin.zig_backend != .stage2_riscv64) asm volatile ( |
| 235 | \\ .weak __global_pointer$ | 258 | \\ .weak __global_pointer$ |
| ... | @@ -247,7 +270,6 @@ fn _start() callconv(.naked) noreturn { | ... | @@ -247,7 +270,6 @@ fn _start() callconv(.naked) noreturn { |
| 247 | // linker explicitly. | 270 | // linker explicitly. |
| 248 | asm volatile (switch (native_arch) { | 271 | asm volatile (switch (native_arch) { |
| 249 | .x86_64 => | 272 | .x86_64 => |
| 250 | \\ .cfi_undefined %%rip | ||
| 251 | \\ xorl %%ebp, %%ebp | 273 | \\ xorl %%ebp, %%ebp |
| 252 | \\ movq %%rsp, %%rdi | 274 | \\ movq %%rsp, %%rdi |
| 253 | \\ andq $-16, %%rsp | 275 | \\ andq $-16, %%rsp |
| ... | @@ -279,8 +301,10 @@ fn _start() callconv(.naked) noreturn { | ... | @@ -279,8 +301,10 @@ fn _start() callconv(.naked) noreturn { |
| 279 | , | 301 | , |
| 280 | .arm, .armeb, .thumb, .thumbeb => | 302 | .arm, .armeb, .thumb, .thumbeb => |
| 281 | // Note that this code must work for Thumb-1. | 303 | // Note that this code must work for Thumb-1. |
| 304 | // r7 = FP (local), r11 = FP (unwind) | ||
| 282 | \\ movs v1, #0 | 305 | \\ movs v1, #0 |
| 283 | \\ mov fp, v1 | 306 | \\ mov r7, v1 |
| 307 | \\ mov r11, v1 | ||
| 284 | \\ mov lr, v1 | 308 | \\ mov lr, v1 |
| 285 | \\ mov a1, sp | 309 | \\ mov a1, sp |
| 286 | \\ subs v1, #16 | 310 | \\ subs v1, #16 |
| ... | @@ -290,20 +314,23 @@ fn _start() callconv(.naked) noreturn { | ... | @@ -290,20 +314,23 @@ fn _start() callconv(.naked) noreturn { |
| 290 | , | 314 | , |
| 291 | .csky => | 315 | .csky => |
| 292 | // The CSKY ABI assumes that `gb` is set to the address of the GOT in order for | 316 | // The CSKY ABI assumes that `gb` is set to the address of the GOT in order for |
| 293 | // position-independent code to work. We depend on this in `std.os.linux.start_pie` | 317 | // position-independent code to work. We depend on this in `std.os.linux.pie` to locate |
| 294 | // to locate `_DYNAMIC` as well. | 318 | // `_DYNAMIC` as well. |
| 319 | // r8 = FP | ||
| 295 | \\ grs t0, 1f | 320 | \\ grs t0, 1f |
| 296 | \\ 1: | 321 | \\ 1: |
| 297 | \\ lrw gb, 1b@GOTPC | 322 | \\ lrw gb, 1b@GOTPC |
| 298 | \\ addu gb, t0 | 323 | \\ addu gb, t0 |
| 324 | \\ movi r8, 0 | ||
| 299 | \\ movi lr, 0 | 325 | \\ movi lr, 0 |
| 300 | \\ mov a0, sp | 326 | \\ mov a0, sp |
| 301 | \\ andi sp, sp, -8 | 327 | \\ andi sp, sp, -8 |
| 302 | \\ jmpi %[posixCallMainAndExit] | 328 | \\ jmpi %[posixCallMainAndExit] |
| 303 | , | 329 | , |
| 304 | .hexagon => | 330 | .hexagon => |
| 305 | // r29 = SP, r30 = FP | 331 | // r29 = SP, r30 = FP, r31 = LR |
| 306 | \\ r30 = #0 | 332 | \\ r30 = #0 |
| 333 | \\ r31 = #0 | ||
| 307 | \\ r0 = r29 | 334 | \\ r0 = r29 |
| 308 | \\ r29 = and(r29, #-16) | 335 | \\ r29 = and(r29, #-16) |
| 309 | \\ memw(r29 + #-8) = r29 | 336 | \\ memw(r29 + #-8) = r29 |
| ... | @@ -312,12 +339,13 @@ fn _start() callconv(.naked) noreturn { | ... | @@ -312,12 +339,13 @@ fn _start() callconv(.naked) noreturn { |
| 312 | , | 339 | , |
| 313 | .loongarch32, .loongarch64 => | 340 | .loongarch32, .loongarch64 => |
| 314 | \\ move $fp, $zero | 341 | \\ move $fp, $zero |
| 342 | \\ move $ra, $zero | ||
| 315 | \\ move $a0, $sp | 343 | \\ move $a0, $sp |
| 316 | \\ bstrins.d $sp, $zero, 3, 0 | 344 | \\ bstrins.d $sp, $zero, 3, 0 |
| 317 | \\ b %[posixCallMainAndExit] | 345 | \\ b %[posixCallMainAndExit] |
| 318 | , | 346 | , |
| 319 | .riscv32, .riscv64 => | 347 | .riscv32, .riscv64 => |
| 320 | \\ li s0, 0 | 348 | \\ li fp, 0 |
| 321 | \\ li ra, 0 | 349 | \\ li ra, 0 |
| 322 | \\ mv a0, sp | 350 | \\ mv a0, sp |
| 323 | \\ andi sp, sp, -16 | 351 | \\ andi sp, sp, -16 |
| ... | @@ -371,28 +399,35 @@ fn _start() callconv(.naked) noreturn { | ... | @@ -371,28 +399,35 @@ fn _start() callconv(.naked) noreturn { |
| 371 | , | 399 | , |
| 372 | .powerpc, .powerpcle => | 400 | .powerpc, .powerpcle => |
| 373 | // Set up the initial stack frame, and clear the back chain pointer. | 401 | // Set up the initial stack frame, and clear the back chain pointer. |
| 402 | // r1 = SP, r31 = FP | ||
| 374 | \\ mr 3, 1 | 403 | \\ mr 3, 1 |
| 375 | \\ clrrwi 1, 1, 4 | 404 | \\ clrrwi 1, 1, 4 |
| 376 | \\ li 0, 0 | 405 | \\ li 0, 0 |
| 377 | \\ stwu 1, -16(1) | 406 | \\ stwu 1, -16(1) |
| 378 | \\ stw 0, 0(1) | 407 | \\ stw 0, 0(1) |
| 408 | \\ li 31, 0 | ||
| 379 | \\ mtlr 0 | 409 | \\ mtlr 0 |
| 380 | \\ b %[posixCallMainAndExit] | 410 | \\ b %[posixCallMainAndExit] |
| 381 | , | 411 | , |
| 382 | .powerpc64, .powerpc64le => | 412 | .powerpc64, .powerpc64le => |
| 383 | // Set up the ToC and initial stack frame, and clear the back chain pointer. | 413 | // Set up the ToC and initial stack frame, and clear the back chain pointer. |
| 414 | // r1 = SP, r2 = ToC, r31 = FP | ||
| 384 | \\ addis 2, 12, .TOC. - %[_start]@ha | 415 | \\ addis 2, 12, .TOC. - %[_start]@ha |
| 385 | \\ addi 2, 2, .TOC. - %[_start]@l | 416 | \\ addi 2, 2, .TOC. - %[_start]@l |
| 386 | \\ mr 3, 1 | 417 | \\ mr 3, 1 |
| 387 | \\ clrrdi 1, 1, 4 | 418 | \\ clrrdi 1, 1, 4 |
| 388 | \\ li 0, 0 | 419 | \\ li 0, 0 |
| 389 | \\ stdu 0, -32(1) | 420 | \\ stdu 0, -32(1) |
| 421 | \\ li 31, 0 | ||
| 390 | \\ mtlr 0 | 422 | \\ mtlr 0 |
| 391 | \\ b %[posixCallMainAndExit] | 423 | \\ b %[posixCallMainAndExit] |
| 392 | \\ nop | 424 | \\ nop |
| 393 | , | 425 | , |
| 394 | .s390x => | 426 | .s390x => |
| 395 | // Set up the stack frame (register save area and cleared back-chain slot). | 427 | // Set up the stack frame (register save area and cleared back-chain slot). |
| 428 | // r11 = FP, r14 = LR, r15 = SP | ||
| 429 | \\ lghi %%r11, 0 | ||
| 430 | \\ lghi %%r14, 0 | ||
| 396 | \\ lgr %%r2, %%r15 | 431 | \\ lgr %%r2, %%r15 |
| 397 | \\ lghi %%r0, -16 | 432 | \\ lghi %%r0, -16 |
| 398 | \\ ngr %%r15, %%r0 | 433 | \\ ngr %%r15, %%r0 |
| ... | @@ -403,7 +438,9 @@ fn _start() callconv(.naked) noreturn { | ... | @@ -403,7 +438,9 @@ fn _start() callconv(.naked) noreturn { |
| 403 | , | 438 | , |
| 404 | .sparc => | 439 | .sparc => |
| 405 | // argc is stored after a register window (16 registers * 4 bytes). | 440 | // argc is stored after a register window (16 registers * 4 bytes). |
| 441 | // i7 = LR | ||
| 406 | \\ mov %%g0, %%fp | 442 | \\ mov %%g0, %%fp |
| 443 | \\ mov %%g0, %%i7 | ||
| 407 | \\ add %%sp, 64, %%o0 | 444 | \\ add %%sp, 64, %%o0 |
| 408 | \\ and %%sp, -8, %%sp | 445 | \\ and %%sp, -8, %%sp |
| 409 | \\ ba,a %[posixCallMainAndExit] | 446 | \\ ba,a %[posixCallMainAndExit] |
| ... | @@ -411,7 +448,9 @@ fn _start() callconv(.naked) noreturn { | ... | @@ -411,7 +448,9 @@ fn _start() callconv(.naked) noreturn { |
| 411 | .sparc64 => | 448 | .sparc64 => |
| 412 | // argc is stored after a register window (16 registers * 8 bytes) plus the stack bias | 449 | // argc is stored after a register window (16 registers * 8 bytes) plus the stack bias |
| 413 | // (2047 bytes). | 450 | // (2047 bytes). |
| 451 | // i7 = LR | ||
| 414 | \\ mov %%g0, %%fp | 452 | \\ mov %%g0, %%fp |
| 453 | \\ mov %%g0, %%i7 | ||
| 415 | \\ add %%sp, 2175, %%o0 | 454 | \\ add %%sp, 2175, %%o0 |
| 416 | \\ add %%sp, 2047, %%sp | 455 | \\ add %%sp, 2047, %%sp |
| 417 | \\ and %%sp, -16, %%sp | 456 | \\ and %%sp, -16, %%sp |
src/Builtin.zig+3| ... | @@ -2,6 +2,7 @@ target: std.Target, | ... | @@ -2,6 +2,7 @@ target: std.Target, |
| 2 | zig_backend: std.builtin.CompilerBackend, | 2 | zig_backend: std.builtin.CompilerBackend, |
| 3 | output_mode: std.builtin.OutputMode, | 3 | output_mode: std.builtin.OutputMode, |
| 4 | link_mode: std.builtin.LinkMode, | 4 | link_mode: std.builtin.LinkMode, |
| 5 | unwind_tables: std.builtin.UnwindTables, | ||
| 5 | is_test: bool, | 6 | is_test: bool, |
| 6 | single_threaded: bool, | 7 | single_threaded: bool, |
| 7 | link_libc: bool, | 8 | link_libc: bool, |
| ... | @@ -40,6 +41,7 @@ pub fn append(opts: @This(), buffer: *std.ArrayList(u8)) Allocator.Error!void { | ... | @@ -40,6 +41,7 @@ pub fn append(opts: @This(), buffer: *std.ArrayList(u8)) Allocator.Error!void { |
| 40 | \\ | 41 | \\ |
| 41 | \\pub const output_mode: std.builtin.OutputMode = .{p_}; | 42 | \\pub const output_mode: std.builtin.OutputMode = .{p_}; |
| 42 | \\pub const link_mode: std.builtin.LinkMode = .{p_}; | 43 | \\pub const link_mode: std.builtin.LinkMode = .{p_}; |
| 44 | \\pub const unwind_tables: std.builtin.UnwindTables = .{p_}; | ||
| 43 | \\pub const is_test = {}; | 45 | \\pub const is_test = {}; |
| 44 | \\pub const single_threaded = {}; | 46 | \\pub const single_threaded = {}; |
| 45 | \\pub const abi: std.Target.Abi = .{p_}; | 47 | \\pub const abi: std.Target.Abi = .{p_}; |
| ... | @@ -53,6 +55,7 @@ pub fn append(opts: @This(), buffer: *std.ArrayList(u8)) Allocator.Error!void { | ... | @@ -53,6 +55,7 @@ pub fn append(opts: @This(), buffer: *std.ArrayList(u8)) Allocator.Error!void { |
| 53 | std.zig.fmtId(@tagName(zig_backend)), | 55 | std.zig.fmtId(@tagName(zig_backend)), |
| 54 | std.zig.fmtId(@tagName(opts.output_mode)), | 56 | std.zig.fmtId(@tagName(opts.output_mode)), |
| 55 | std.zig.fmtId(@tagName(opts.link_mode)), | 57 | std.zig.fmtId(@tagName(opts.link_mode)), |
| 58 | std.zig.fmtId(@tagName(opts.unwind_tables)), | ||
| 56 | opts.is_test, | 59 | opts.is_test, |
| 57 | opts.single_threaded, | 60 | opts.single_threaded, |
| 58 | std.zig.fmtId(@tagName(target.abi)), | 61 | std.zig.fmtId(@tagName(target.abi)), |
src/Compilation.zig+20-7| ... | @@ -1261,12 +1261,15 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil | ... | @@ -1261,12 +1261,15 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil |
| 1261 | // The "any" values provided by resolved config only account for | 1261 | // The "any" values provided by resolved config only account for |
| 1262 | // explicitly-provided settings. We now make them additionally account | 1262 | // explicitly-provided settings. We now make them additionally account |
| 1263 | // for default setting resolution. | 1263 | // for default setting resolution. |
| 1264 | const any_unwind_tables = options.config.any_unwind_tables or options.root_mod.unwind_tables; | 1264 | const any_unwind_tables = switch (options.config.any_unwind_tables) { |
| 1265 | .none => options.root_mod.unwind_tables, | ||
| 1266 | .sync, .@"async" => |uwt| uwt, | ||
| 1267 | }; | ||
| 1265 | const any_non_single_threaded = options.config.any_non_single_threaded or !options.root_mod.single_threaded; | 1268 | const any_non_single_threaded = options.config.any_non_single_threaded or !options.root_mod.single_threaded; |
| 1266 | const any_sanitize_thread = options.config.any_sanitize_thread or options.root_mod.sanitize_thread; | 1269 | const any_sanitize_thread = options.config.any_sanitize_thread or options.root_mod.sanitize_thread; |
| 1267 | const any_fuzz = options.config.any_fuzz or options.root_mod.fuzz; | 1270 | const any_fuzz = options.config.any_fuzz or options.root_mod.fuzz; |
| 1268 | 1271 | ||
| 1269 | const link_eh_frame_hdr = options.link_eh_frame_hdr or any_unwind_tables; | 1272 | const link_eh_frame_hdr = options.link_eh_frame_hdr or any_unwind_tables != .none; |
| 1270 | const build_id = options.build_id orelse .none; | 1273 | const build_id = options.build_id orelse .none; |
| 1271 | 1274 | ||
| 1272 | const link_libc = options.config.link_libc; | 1275 | const link_libc = options.config.link_libc; |
| ... | @@ -1354,6 +1357,7 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil | ... | @@ -1354,6 +1357,7 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil |
| 1354 | cache.hash.add(options.config.pie); | 1357 | cache.hash.add(options.config.pie); |
| 1355 | cache.hash.add(options.config.lto); | 1358 | cache.hash.add(options.config.lto); |
| 1356 | cache.hash.add(options.config.link_mode); | 1359 | cache.hash.add(options.config.link_mode); |
| 1360 | cache.hash.add(options.config.any_unwind_tables); | ||
| 1357 | cache.hash.add(options.function_sections); | 1361 | cache.hash.add(options.function_sections); |
| 1358 | cache.hash.add(options.data_sections); | 1362 | cache.hash.add(options.data_sections); |
| 1359 | cache.hash.add(link_libc); | 1363 | cache.hash.add(link_libc); |
| ... | @@ -5553,10 +5557,17 @@ pub fn addCCArgs( | ... | @@ -5553,10 +5557,17 @@ pub fn addCCArgs( |
| 5553 | try argv.append("-Werror=date-time"); | 5557 | try argv.append("-Werror=date-time"); |
| 5554 | } | 5558 | } |
| 5555 | 5559 | ||
| 5556 | if (mod.unwind_tables) { | 5560 | switch (mod.unwind_tables) { |
| 5557 | try argv.append("-funwind-tables"); | 5561 | .none => { |
| 5558 | } else { | 5562 | try argv.append("-fno-unwind-tables"); |
| 5559 | try argv.append("-fno-unwind-tables"); | 5563 | try argv.append("-fno-asynchronous-unwind-tables"); |
| 5564 | }, | ||
| 5565 | .sync => { | ||
| 5566 | // Need to override Clang's convoluted default logic. | ||
| 5567 | try argv.append("-fno-asynchronous-unwind-tables"); | ||
| 5568 | try argv.append("-funwind-tables"); | ||
| 5569 | }, | ||
| 5570 | .@"async" => try argv.append("-fasynchronous-unwind-tables"), | ||
| 5560 | } | 5571 | } |
| 5561 | }, | 5572 | }, |
| 5562 | .shared_library, .ll, .bc, .unknown, .static_library, .object, .def, .zig, .res, .manifest => {}, | 5573 | .shared_library, .ll, .bc, .unknown, .static_library, .object, .def, .zig, .res, .manifest => {}, |
| ... | @@ -6288,6 +6299,7 @@ pub const CrtFileOptions = struct { | ... | @@ -6288,6 +6299,7 @@ pub const CrtFileOptions = struct { |
| 6288 | function_sections: ?bool = null, | 6299 | function_sections: ?bool = null, |
| 6289 | data_sections: ?bool = null, | 6300 | data_sections: ?bool = null, |
| 6290 | omit_frame_pointer: ?bool = null, | 6301 | omit_frame_pointer: ?bool = null, |
| 6302 | unwind_tables: ?std.builtin.UnwindTables = null, | ||
| 6291 | pic: ?bool = null, | 6303 | pic: ?bool = null, |
| 6292 | no_builtin: ?bool = null, | 6304 | no_builtin: ?bool = null, |
| 6293 | }; | 6305 | }; |
| ... | @@ -6349,7 +6361,8 @@ pub fn build_crt_file( | ... | @@ -6349,7 +6361,8 @@ pub fn build_crt_file( |
| 6349 | // Some libcs (e.g. musl) are opinionated about -fomit-frame-pointer. | 6361 | // Some libcs (e.g. musl) are opinionated about -fomit-frame-pointer. |
| 6350 | .omit_frame_pointer = options.omit_frame_pointer orelse comp.root_mod.omit_frame_pointer, | 6362 | .omit_frame_pointer = options.omit_frame_pointer orelse comp.root_mod.omit_frame_pointer, |
| 6351 | .valgrind = false, | 6363 | .valgrind = false, |
| 6352 | .unwind_tables = false, | 6364 | // Some libcs (e.g. MinGW) are opinionated about -funwind-tables. |
| 6365 | .unwind_tables = options.unwind_tables orelse .none, | ||
| 6353 | // Some CRT objects (e.g. musl's rcrt1.o and Scrt1.o) are opinionated about PIC. | 6366 | // Some CRT objects (e.g. musl's rcrt1.o and Scrt1.o) are opinionated about PIC. |
| 6354 | .pic = options.pic orelse comp.root_mod.pic, | 6367 | .pic = options.pic orelse comp.root_mod.pic, |
| 6355 | .optimize_mode = comp.compilerRtOptMode(), | 6368 | .optimize_mode = comp.compilerRtOptMode(), |
src/Compilation/Config.zig+14-10| ... | @@ -12,13 +12,14 @@ link_libunwind: bool, | ... | @@ -12,13 +12,14 @@ link_libunwind: bool, |
| 12 | /// True if and only if the c_source_files field will have nonzero length when | 12 | /// True if and only if the c_source_files field will have nonzero length when |
| 13 | /// calling Compilation.create. | 13 | /// calling Compilation.create. |
| 14 | any_c_source_files: bool, | 14 | any_c_source_files: bool, |
| 15 | /// This is true if any Module has unwind_tables set explicitly to true. Until | 15 | /// This is not `.none` if any `Module` has `unwind_tables` set explicitly to a |
| 16 | /// Compilation.create is called, it is possible for this to be false while in | 16 | /// value other than `.none`. Until `Compilation.create()` is called, it is |
| 17 | /// fact all Module instances have unwind_tables=true due to the default | 17 | /// possible for this to be `.none` while in fact all `Module` instances have |
| 18 | /// being unwind_tables=true. After Compilation.create is called this will | 18 | /// `unwind_tables != .none` due to the default. After `Compilation.create()` is |
| 19 | /// also take into account the default setting, making this value true if and | 19 | /// called, this will also take into account the default setting, making this |
| 20 | /// only if any Module has unwind_tables set to true. | 20 | /// value `.sync` or `.@"async"` if and only if any `Module` has |
| 21 | any_unwind_tables: bool, | 21 | /// `unwind_tables != .none`. |
| 22 | any_unwind_tables: std.builtin.UnwindTables, | ||
| 22 | /// This is true if any Module has single_threaded set explicitly to false. Until | 23 | /// This is true if any Module has single_threaded set explicitly to false. Until |
| 23 | /// Compilation.create is called, it is possible for this to be false while in | 24 | /// Compilation.create is called, it is possible for this to be false while in |
| 24 | /// fact all Module instances have single_threaded=false due to the default | 25 | /// fact all Module instances have single_threaded=false due to the default |
| ... | @@ -85,7 +86,7 @@ pub const Options = struct { | ... | @@ -85,7 +86,7 @@ pub const Options = struct { |
| 85 | any_non_single_threaded: bool = false, | 86 | any_non_single_threaded: bool = false, |
| 86 | any_sanitize_thread: bool = false, | 87 | any_sanitize_thread: bool = false, |
| 87 | any_fuzz: bool = false, | 88 | any_fuzz: bool = false, |
| 88 | any_unwind_tables: bool = false, | 89 | any_unwind_tables: std.builtin.UnwindTables = .none, |
| 89 | any_dyn_libs: bool = false, | 90 | any_dyn_libs: bool = false, |
| 90 | any_c_source_files: bool = false, | 91 | any_c_source_files: bool = false, |
| 91 | any_non_stripped: bool = false, | 92 | any_non_stripped: bool = false, |
| ... | @@ -356,8 +357,11 @@ pub fn resolve(options: Options) ResolveError!Config { | ... | @@ -356,8 +357,11 @@ pub fn resolve(options: Options) ResolveError!Config { |
| 356 | break :b false; | 357 | break :b false; |
| 357 | }; | 358 | }; |
| 358 | 359 | ||
| 359 | const any_unwind_tables = options.any_unwind_tables or | 360 | const any_unwind_tables = b: { |
| 360 | link_libunwind or target_util.needUnwindTables(target); | 361 | if (options.any_unwind_tables != .none) break :b options.any_unwind_tables; |
| 362 | |||
| 363 | break :b target_util.needUnwindTables(target, link_libunwind, options.any_sanitize_thread); | ||
| 364 | }; | ||
| 361 | 365 | ||
| 362 | const link_mode = b: { | 366 | const link_mode = b: { |
| 363 | const explicitly_exe_or_dyn_lib = switch (options.output_mode) { | 367 | const explicitly_exe_or_dyn_lib = switch (options.output_mode) { |
src/Package/Module.zig+4-3| ... | @@ -27,7 +27,7 @@ red_zone: bool, | ... | @@ -27,7 +27,7 @@ red_zone: bool, |
| 27 | sanitize_c: bool, | 27 | sanitize_c: bool, |
| 28 | sanitize_thread: bool, | 28 | sanitize_thread: bool, |
| 29 | fuzz: bool, | 29 | fuzz: bool, |
| 30 | unwind_tables: bool, | 30 | unwind_tables: std.builtin.UnwindTables, |
| 31 | cc_argv: []const []const u8, | 31 | cc_argv: []const []const u8, |
| 32 | /// (SPIR-V) whether to generate a structured control flow graph or not | 32 | /// (SPIR-V) whether to generate a structured control flow graph or not |
| 33 | structured_cfg: bool, | 33 | structured_cfg: bool, |
| ... | @@ -91,7 +91,7 @@ pub const CreateOptions = struct { | ... | @@ -91,7 +91,7 @@ pub const CreateOptions = struct { |
| 91 | /// other number means stack protection with that buffer size. | 91 | /// other number means stack protection with that buffer size. |
| 92 | stack_protector: ?u32 = null, | 92 | stack_protector: ?u32 = null, |
| 93 | red_zone: ?bool = null, | 93 | red_zone: ?bool = null, |
| 94 | unwind_tables: ?bool = null, | 94 | unwind_tables: ?std.builtin.UnwindTables = null, |
| 95 | sanitize_c: ?bool = null, | 95 | sanitize_c: ?bool = null, |
| 96 | sanitize_thread: ?bool = null, | 96 | sanitize_thread: ?bool = null, |
| 97 | fuzz: ?bool = null, | 97 | fuzz: ?bool = null, |
| ... | @@ -112,7 +112,7 @@ pub fn create(arena: Allocator, options: CreateOptions) !*Package.Module { | ... | @@ -112,7 +112,7 @@ pub fn create(arena: Allocator, options: CreateOptions) !*Package.Module { |
| 112 | if (options.inherited.sanitize_thread == true) assert(options.global.any_sanitize_thread); | 112 | if (options.inherited.sanitize_thread == true) assert(options.global.any_sanitize_thread); |
| 113 | if (options.inherited.fuzz == true) assert(options.global.any_fuzz); | 113 | if (options.inherited.fuzz == true) assert(options.global.any_fuzz); |
| 114 | if (options.inherited.single_threaded == false) assert(options.global.any_non_single_threaded); | 114 | if (options.inherited.single_threaded == false) assert(options.global.any_non_single_threaded); |
| 115 | if (options.inherited.unwind_tables == true) assert(options.global.any_unwind_tables); | 115 | if (options.inherited.unwind_tables) |uwt| if (uwt != .none) assert(options.global.any_unwind_tables != .none); |
| 116 | if (options.inherited.error_tracing == true) assert(options.global.any_error_tracing); | 116 | if (options.inherited.error_tracing == true) assert(options.global.any_error_tracing); |
| 117 | 117 | ||
| 118 | const resolved_target = options.inherited.resolved_target orelse options.parent.?.resolved_target; | 118 | 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 { | ... | @@ -382,6 +382,7 @@ pub fn create(arena: Allocator, options: CreateOptions) !*Package.Module { |
| 382 | .zig_backend = zig_backend, | 382 | .zig_backend = zig_backend, |
| 383 | .output_mode = options.global.output_mode, | 383 | .output_mode = options.global.output_mode, |
| 384 | .link_mode = options.global.link_mode, | 384 | .link_mode = options.global.link_mode, |
| 385 | .unwind_tables = options.global.any_unwind_tables, | ||
| 385 | .is_test = options.global.is_test, | 386 | .is_test = options.global.is_test, |
| 386 | .single_threaded = single_threaded, | 387 | .single_threaded = single_threaded, |
| 387 | .link_libc = options.global.link_libc, | 388 | .link_libc = options.global.link_libc, |
src/arch/riscv64/CodeGen.zig+4| ... | @@ -8442,6 +8442,10 @@ fn failSymbol(func: *Func, comptime format: []const u8, args: anytype) InnerErro | ... | @@ -8442,6 +8442,10 @@ fn failSymbol(func: *Func, comptime format: []const u8, args: anytype) InnerErro |
| 8442 | } | 8442 | } |
| 8443 | 8443 | ||
| 8444 | fn parseRegName(name: []const u8) ?Register { | 8444 | fn parseRegName(name: []const u8) ?Register { |
| 8445 | // The `fp` alias for `s0` is awkward to fit into the current `Register` scheme, so for now we | ||
| 8446 | // special-case it here. | ||
| 8447 | if (std.mem.eql(u8, name, "fp")) return .s0; | ||
| 8448 | |||
| 8445 | return std.meta.stringToEnum(Register, name); | 8449 | return std.meta.stringToEnum(Register, name); |
| 8446 | } | 8450 | } |
| 8447 | 8451 |
src/clang_options_data.zig+16-2| ... | @@ -2757,7 +2757,14 @@ flagpd1("fast"), | ... | @@ -2757,7 +2757,14 @@ flagpd1("fast"), |
| 2757 | flagpd1("fastcp"), | 2757 | flagpd1("fastcp"), |
| 2758 | flagpd1("fastf"), | 2758 | flagpd1("fastf"), |
| 2759 | flagpd1("fasync-exceptions"), | 2759 | flagpd1("fasync-exceptions"), |
| 2760 | flagpd1("fasynchronous-unwind-tables"), | 2760 | .{ |
| 2761 | .name = "fasynchronous-unwind-tables", | ||
| 2762 | .syntax = .flag, | ||
| 2763 | .zig_equivalent = .asynchronous_unwind_tables, | ||
| 2764 | .pd1 = true, | ||
| 2765 | .pd2 = false, | ||
| 2766 | .psl = false, | ||
| 2767 | }, | ||
| 2761 | flagpd1("fauto-import"), | 2768 | flagpd1("fauto-import"), |
| 2762 | flagpd1("fauto-profile"), | 2769 | flagpd1("fauto-profile"), |
| 2763 | flagpd1("fauto-profile-accurate"), | 2770 | flagpd1("fauto-profile-accurate"), |
| ... | @@ -3247,7 +3254,14 @@ flagpd1("fno-assume-sane-operator-new"), | ... | @@ -3247,7 +3254,14 @@ flagpd1("fno-assume-sane-operator-new"), |
| 3247 | flagpd1("fno-assume-unique-vtables"), | 3254 | flagpd1("fno-assume-unique-vtables"), |
| 3248 | flagpd1("fno-assumptions"), | 3255 | flagpd1("fno-assumptions"), |
| 3249 | flagpd1("fno-async-exceptions"), | 3256 | flagpd1("fno-async-exceptions"), |
| 3250 | flagpd1("fno-asynchronous-unwind-tables"), | 3257 | .{ |
| 3258 | .name = "fno-asynchronous-unwind-tables", | ||
| 3259 | .syntax = .flag, | ||
| 3260 | .zig_equivalent = .no_asynchronous_unwind_tables, | ||
| 3261 | .pd1 = true, | ||
| 3262 | .pd2 = false, | ||
| 3263 | .psl = false, | ||
| 3264 | }, | ||
| 3251 | flagpd1("fno-auto-import"), | 3265 | flagpd1("fno-auto-import"), |
| 3252 | flagpd1("fno-auto-profile"), | 3266 | flagpd1("fno-auto-profile"), |
| 3253 | flagpd1("fno-auto-profile-accurate"), | 3267 | flagpd1("fno-auto-profile-accurate"), |
src/codegen/llvm.zig+5-2| ... | @@ -3141,8 +3141,11 @@ pub const Object = struct { | ... | @@ -3141,8 +3141,11 @@ pub const Object = struct { |
| 3141 | } }, &o.builder); | 3141 | } }, &o.builder); |
| 3142 | } | 3142 | } |
| 3143 | try attributes.addFnAttr(.nounwind, &o.builder); | 3143 | try attributes.addFnAttr(.nounwind, &o.builder); |
| 3144 | if (owner_mod.unwind_tables) { | 3144 | if (owner_mod.unwind_tables != .none) { |
| 3145 | try attributes.addFnAttr(.{ .uwtable = Builder.Attribute.UwTable.default }, &o.builder); | 3145 | try attributes.addFnAttr( |
| 3146 | .{ .uwtable = if (owner_mod.unwind_tables == .@"async") .@"async" else .sync }, | ||
| 3147 | &o.builder, | ||
| 3148 | ); | ||
| 3146 | } | 3149 | } |
| 3147 | if (owner_mod.no_builtin) { | 3150 | if (owner_mod.no_builtin) { |
| 3148 | // The intent here is for compiler-rt and libc functions to not generate | 3151 | // The intent here is for compiler-rt and libc functions to not generate |
src/libcxx.zig+6-3| ... | @@ -397,7 +397,6 @@ pub fn buildLibCXXABI(comp: *Compilation, prog_node: std.Progress.Node) BuildErr | ... | @@ -397,7 +397,6 @@ pub fn buildLibCXXABI(comp: *Compilation, prog_node: std.Progress.Node) BuildErr |
| 397 | 397 | ||
| 398 | const optimize_mode = comp.compilerRtOptMode(); | 398 | const optimize_mode = comp.compilerRtOptMode(); |
| 399 | const strip = comp.compilerRtStrip(); | 399 | const strip = comp.compilerRtStrip(); |
| 400 | const unwind_tables = true; | ||
| 401 | 400 | ||
| 402 | const config = Compilation.Config.resolve(.{ | 401 | const config = Compilation.Config.resolve(.{ |
| 403 | .output_mode = output_mode, | 402 | .output_mode = output_mode, |
| ... | @@ -409,7 +408,6 @@ pub fn buildLibCXXABI(comp: *Compilation, prog_node: std.Progress.Node) BuildErr | ... | @@ -409,7 +408,6 @@ pub fn buildLibCXXABI(comp: *Compilation, prog_node: std.Progress.Node) BuildErr |
| 409 | .root_optimize_mode = optimize_mode, | 408 | .root_optimize_mode = optimize_mode, |
| 410 | .root_strip = strip, | 409 | .root_strip = strip, |
| 411 | .link_libc = true, | 410 | .link_libc = true, |
| 412 | .any_unwind_tables = unwind_tables, | ||
| 413 | .lto = comp.config.lto, | 411 | .lto = comp.config.lto, |
| 414 | .any_sanitize_thread = comp.config.any_sanitize_thread, | 412 | .any_sanitize_thread = comp.config.any_sanitize_thread, |
| 415 | }) catch |err| { | 413 | }) catch |err| { |
| ... | @@ -440,7 +438,12 @@ pub fn buildLibCXXABI(comp: *Compilation, prog_node: std.Progress.Node) BuildErr | ... | @@ -440,7 +438,12 @@ pub fn buildLibCXXABI(comp: *Compilation, prog_node: std.Progress.Node) BuildErr |
| 440 | .valgrind = false, | 438 | .valgrind = false, |
| 441 | .optimize_mode = optimize_mode, | 439 | .optimize_mode = optimize_mode, |
| 442 | .structured_cfg = comp.root_mod.structured_cfg, | 440 | .structured_cfg = comp.root_mod.structured_cfg, |
| 443 | .unwind_tables = unwind_tables, | 441 | // See the `-fno-exceptions` logic for WASI. |
| 442 | // The old 32-bit x86 variant of SEH doesn't use tables. | ||
| 443 | .unwind_tables = if (target.os.tag == .wasi or (target.cpu.arch == .x86 and target.os.tag == .windows)) | ||
| 444 | .none | ||
| 445 | else | ||
| 446 | .@"async", | ||
| 444 | .pic = comp.root_mod.pic, | 447 | .pic = comp.root_mod.pic, |
| 445 | }, | 448 | }, |
| 446 | .global = config, | 449 | .global = config, |
src/libunwind.zig+2-1| ... | @@ -65,7 +65,8 @@ pub fn buildStaticLib(comp: *Compilation, prog_node: std.Progress.Node) BuildErr | ... | @@ -65,7 +65,8 @@ pub fn buildStaticLib(comp: *Compilation, prog_node: std.Progress.Node) BuildErr |
| 65 | .sanitize_c = false, | 65 | .sanitize_c = false, |
| 66 | .sanitize_thread = false, | 66 | .sanitize_thread = false, |
| 67 | // necessary so that libunwind can unwind through its own stack frames | 67 | // necessary so that libunwind can unwind through its own stack frames |
| 68 | .unwind_tables = true, | 68 | // The old 32-bit x86 variant of SEH doesn't use tables. |
| 69 | .unwind_tables = if (target.cpu.arch == .x86 and target.os.tag == .windows) .none else .@"async", | ||
| 69 | .pic = if (target_util.supports_fpic(target)) true else null, | 70 | .pic = if (target_util.supports_fpic(target)) true else null, |
| 70 | .optimize_mode = comp.compilerRtOptMode(), | 71 | .optimize_mode = comp.compilerRtOptMode(), |
| 71 | }, | 72 | }, |
src/main.zig+46-8| ... | @@ -510,6 +510,7 @@ const usage_build_generic = | ... | @@ -510,6 +510,7 @@ const usage_build_generic = |
| 510 | \\ -ffuzz Enable fuzz testing instrumentation | 510 | \\ -ffuzz Enable fuzz testing instrumentation |
| 511 | \\ -fno-fuzz Disable fuzz testing instrumentation | 511 | \\ -fno-fuzz Disable fuzz testing instrumentation |
| 512 | \\ -funwind-tables Always produce unwind table entries for all functions | 512 | \\ -funwind-tables Always produce unwind table entries for all functions |
| 513 | \\ -fasync-unwind-tables Always produce asynchronous unwind table entries for all functions | ||
| 513 | \\ -fno-unwind-tables Never produce unwind table entries | 514 | \\ -fno-unwind-tables Never produce unwind table entries |
| 514 | \\ -ferror-tracing Enable error tracing in ReleaseFast mode | 515 | \\ -ferror-tracing Enable error tracing in ReleaseFast mode |
| 515 | \\ -fno-error-tracing Disable error tracing in Debug and ReleaseSafe mode | 516 | \\ -fno-error-tracing Disable error tracing in Debug and ReleaseSafe mode |
| ... | @@ -1385,9 +1386,11 @@ fn buildOutputType( | ... | @@ -1385,9 +1386,11 @@ fn buildOutputType( |
| 1385 | } else if (mem.eql(u8, arg, "-fno-lto")) { | 1386 | } else if (mem.eql(u8, arg, "-fno-lto")) { |
| 1386 | create_module.opts.lto = false; | 1387 | create_module.opts.lto = false; |
| 1387 | } else if (mem.eql(u8, arg, "-funwind-tables")) { | 1388 | } else if (mem.eql(u8, arg, "-funwind-tables")) { |
| 1388 | mod_opts.unwind_tables = true; | 1389 | mod_opts.unwind_tables = .sync; |
| 1390 | } else if (mem.eql(u8, arg, "-fasync-unwind-tables")) { | ||
| 1391 | mod_opts.unwind_tables = .@"async"; | ||
| 1389 | } else if (mem.eql(u8, arg, "-fno-unwind-tables")) { | 1392 | } else if (mem.eql(u8, arg, "-fno-unwind-tables")) { |
| 1390 | mod_opts.unwind_tables = false; | 1393 | mod_opts.unwind_tables = .none; |
| 1391 | } else if (mem.eql(u8, arg, "-fstack-check")) { | 1394 | } else if (mem.eql(u8, arg, "-fstack-check")) { |
| 1392 | mod_opts.stack_check = true; | 1395 | mod_opts.stack_check = true; |
| 1393 | } else if (mem.eql(u8, arg, "-fno-stack-check")) { | 1396 | } else if (mem.eql(u8, arg, "-fno-stack-check")) { |
| ... | @@ -1973,8 +1976,27 @@ fn buildOutputType( | ... | @@ -1973,8 +1976,27 @@ fn buildOutputType( |
| 1973 | } | 1976 | } |
| 1974 | }, | 1977 | }, |
| 1975 | .no_stack_protector => mod_opts.stack_protector = 0, | 1978 | .no_stack_protector => mod_opts.stack_protector = 0, |
| 1976 | .unwind_tables => mod_opts.unwind_tables = true, | 1979 | // The way these unwind table options are processed in GCC and Clang is crazy |
| 1977 | .no_unwind_tables => mod_opts.unwind_tables = false, | 1980 | // convoluted, and we also don't know the target triple here, so this is all |
| 1981 | // best-effort. | ||
| 1982 | .unwind_tables => if (mod_opts.unwind_tables) |uwt| switch (uwt) { | ||
| 1983 | .none => { | ||
| 1984 | mod_opts.unwind_tables = .sync; | ||
| 1985 | }, | ||
| 1986 | .sync, .@"async" => {}, | ||
| 1987 | } else { | ||
| 1988 | mod_opts.unwind_tables = .sync; | ||
| 1989 | }, | ||
| 1990 | .no_unwind_tables => mod_opts.unwind_tables = .none, | ||
| 1991 | .asynchronous_unwind_tables => mod_opts.unwind_tables = .@"async", | ||
| 1992 | .no_asynchronous_unwind_tables => if (mod_opts.unwind_tables) |uwt| switch (uwt) { | ||
| 1993 | .none, .sync => {}, | ||
| 1994 | .@"async" => { | ||
| 1995 | mod_opts.unwind_tables = .sync; | ||
| 1996 | }, | ||
| 1997 | } else { | ||
| 1998 | mod_opts.unwind_tables = .sync; | ||
| 1999 | }, | ||
| 1978 | .nostdlib => { | 2000 | .nostdlib => { |
| 1979 | create_module.opts.ensure_libc_on_non_freestanding = false; | 2001 | create_module.opts.ensure_libc_on_non_freestanding = false; |
| 1980 | create_module.opts.ensure_libcpp_on_non_freestanding = false; | 2002 | create_module.opts.ensure_libcpp_on_non_freestanding = false; |
| ... | @@ -2788,8 +2810,15 @@ fn buildOutputType( | ... | @@ -2788,8 +2810,15 @@ fn buildOutputType( |
| 2788 | create_module.opts.any_sanitize_thread = true; | 2810 | create_module.opts.any_sanitize_thread = true; |
| 2789 | if (mod_opts.fuzz == true) | 2811 | if (mod_opts.fuzz == true) |
| 2790 | create_module.opts.any_fuzz = true; | 2812 | create_module.opts.any_fuzz = true; |
| 2791 | if (mod_opts.unwind_tables == true) | 2813 | if (mod_opts.unwind_tables) |uwt| switch (uwt) { |
| 2792 | create_module.opts.any_unwind_tables = true; | 2814 | .none => {}, |
| 2815 | .sync => if (create_module.opts.any_unwind_tables == .none) { | ||
| 2816 | create_module.opts.any_unwind_tables = .sync; | ||
| 2817 | }, | ||
| 2818 | .@"async" => { | ||
| 2819 | create_module.opts.any_unwind_tables = .@"async"; | ||
| 2820 | }, | ||
| 2821 | }; | ||
| 2793 | if (mod_opts.strip == false) | 2822 | if (mod_opts.strip == false) |
| 2794 | create_module.opts.any_non_stripped = true; | 2823 | create_module.opts.any_non_stripped = true; |
| 2795 | if (mod_opts.error_tracing == true) | 2824 | if (mod_opts.error_tracing == true) |
| ... | @@ -5713,6 +5742,8 @@ pub const ClangArgIterator = struct { | ... | @@ -5713,6 +5742,8 @@ pub const ClangArgIterator = struct { |
| 5713 | no_lto, | 5742 | no_lto, |
| 5714 | unwind_tables, | 5743 | unwind_tables, |
| 5715 | no_unwind_tables, | 5744 | no_unwind_tables, |
| 5745 | asynchronous_unwind_tables, | ||
| 5746 | no_asynchronous_unwind_tables, | ||
| 5716 | nostdlib, | 5747 | nostdlib, |
| 5717 | nostdlib_cpp, | 5748 | nostdlib_cpp, |
| 5718 | shared, | 5749 | shared, |
| ... | @@ -7435,8 +7466,15 @@ fn handleModArg( | ... | @@ -7435,8 +7466,15 @@ fn handleModArg( |
| 7435 | create_module.opts.any_sanitize_thread = true; | 7466 | create_module.opts.any_sanitize_thread = true; |
| 7436 | if (mod_opts.fuzz == true) | 7467 | if (mod_opts.fuzz == true) |
| 7437 | create_module.opts.any_fuzz = true; | 7468 | create_module.opts.any_fuzz = true; |
| 7438 | if (mod_opts.unwind_tables == true) | 7469 | if (mod_opts.unwind_tables) |uwt| switch (uwt) { |
| 7439 | create_module.opts.any_unwind_tables = true; | 7470 | .none => {}, |
| 7471 | .sync => if (create_module.opts.any_unwind_tables == .none) { | ||
| 7472 | create_module.opts.any_unwind_tables = .sync; | ||
| 7473 | }, | ||
| 7474 | .@"async" => { | ||
| 7475 | create_module.opts.any_unwind_tables = .@"async"; | ||
| 7476 | }, | ||
| 7477 | }; | ||
| 7440 | if (mod_opts.strip == false) | 7478 | if (mod_opts.strip == false) |
| 7441 | create_module.opts.any_non_stripped = true; | 7479 | create_module.opts.any_non_stripped = true; |
| 7442 | if (mod_opts.error_tracing == true) | 7480 | if (mod_opts.error_tracing == true) |
src/mingw.zig+13-4| ... | @@ -24,6 +24,10 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre | ... | @@ -24,6 +24,10 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre |
| 24 | var arena_allocator = std.heap.ArenaAllocator.init(comp.gpa); | 24 | var arena_allocator = std.heap.ArenaAllocator.init(comp.gpa); |
| 25 | defer arena_allocator.deinit(); | 25 | defer arena_allocator.deinit(); |
| 26 | const arena = arena_allocator.allocator(); | 26 | const arena = arena_allocator.allocator(); |
| 27 | const target = comp.getTarget(); | ||
| 28 | |||
| 29 | // The old 32-bit x86 variant of SEH doesn't use tables. | ||
| 30 | const unwind_tables: std.builtin.UnwindTables = if (target.cpu.arch != .x86) .@"async" else .none; | ||
| 27 | 31 | ||
| 28 | switch (crt_file) { | 32 | switch (crt_file) { |
| 29 | .crt2_o => { | 33 | .crt2_o => { |
| ... | @@ -41,7 +45,9 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre | ... | @@ -41,7 +45,9 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre |
| 41 | .owner = undefined, | 45 | .owner = undefined, |
| 42 | }, | 46 | }, |
| 43 | }; | 47 | }; |
| 44 | return comp.build_crt_file("crt2", .Obj, .@"mingw-w64 crt2.o", prog_node, &files, .{}); | 48 | return comp.build_crt_file("crt2", .Obj, .@"mingw-w64 crt2.o", prog_node, &files, .{ |
| 49 | .unwind_tables = unwind_tables, | ||
| 50 | }); | ||
| 45 | }, | 51 | }, |
| 46 | 52 | ||
| 47 | .dllcrt2_o => { | 53 | .dllcrt2_o => { |
| ... | @@ -56,7 +62,9 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre | ... | @@ -56,7 +62,9 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre |
| 56 | .owner = undefined, | 62 | .owner = undefined, |
| 57 | }, | 63 | }, |
| 58 | }; | 64 | }; |
| 59 | return comp.build_crt_file("dllcrt2", .Obj, .@"mingw-w64 dllcrt2.o", prog_node, &files, .{}); | 65 | return comp.build_crt_file("dllcrt2", .Obj, .@"mingw-w64 dllcrt2.o", prog_node, &files, .{ |
| 66 | .unwind_tables = unwind_tables, | ||
| 67 | }); | ||
| 60 | }, | 68 | }, |
| 61 | 69 | ||
| 62 | .mingw32_lib => { | 70 | .mingw32_lib => { |
| ... | @@ -73,7 +81,6 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre | ... | @@ -73,7 +81,6 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre |
| 73 | .owner = undefined, | 81 | .owner = undefined, |
| 74 | }); | 82 | }); |
| 75 | } | 83 | } |
| 76 | const target = comp.getTarget(); | ||
| 77 | if (target.cpu.arch == .x86 or target.cpu.arch == .x86_64) { | 84 | if (target.cpu.arch == .x86 or target.cpu.arch == .x86_64) { |
| 78 | for (mingw32_x86_src) |dep| { | 85 | for (mingw32_x86_src) |dep| { |
| 79 | try c_source_files.append(.{ | 86 | try c_source_files.append(.{ |
| ... | @@ -118,7 +125,9 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre | ... | @@ -118,7 +125,9 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre |
| 118 | } else { | 125 | } else { |
| 119 | @panic("unsupported arch"); | 126 | @panic("unsupported arch"); |
| 120 | } | 127 | } |
| 121 | return comp.build_crt_file("mingw32", .Lib, .@"mingw-w64 mingw32.lib", prog_node, c_source_files.items, .{}); | 128 | return comp.build_crt_file("mingw32", .Lib, .@"mingw-w64 mingw32.lib", prog_node, c_source_files.items, .{ |
| 129 | .unwind_tables = unwind_tables, | ||
| 130 | }); | ||
| 122 | }, | 131 | }, |
| 123 | } | 132 | } |
| 124 | } | 133 | } |
src/target.zig+11-2| ... | @@ -4,6 +4,7 @@ const assert = std.debug.assert; | ... | @@ -4,6 +4,7 @@ const assert = std.debug.assert; |
| 4 | const Type = @import("Type.zig"); | 4 | const Type = @import("Type.zig"); |
| 5 | const AddressSpace = std.builtin.AddressSpace; | 5 | const AddressSpace = std.builtin.AddressSpace; |
| 6 | const Alignment = @import("InternPool.zig").Alignment; | 6 | const Alignment = @import("InternPool.zig").Alignment; |
| 7 | const Compilation = @import("Compilation.zig"); | ||
| 7 | const Feature = @import("Zcu.zig").Feature; | 8 | const Feature = @import("Zcu.zig").Feature; |
| 8 | 9 | ||
| 9 | pub const default_stack_protector_buffer_size = 4; | 10 | pub const default_stack_protector_buffer_size = 4; |
| ... | @@ -408,8 +409,16 @@ pub fn clangSupportsNoImplicitFloatArg(target: std.Target) bool { | ... | @@ -408,8 +409,16 @@ pub fn clangSupportsNoImplicitFloatArg(target: std.Target) bool { |
| 408 | }; | 409 | }; |
| 409 | } | 410 | } |
| 410 | 411 | ||
| 411 | pub fn needUnwindTables(target: std.Target) bool { | 412 | pub fn needUnwindTables(target: std.Target, libunwind: bool, libtsan: bool) std.builtin.UnwindTables { |
| 412 | return target.os.tag == .windows or target.isDarwin() or std.debug.Dwarf.abi.supportsUnwinding(target); | 413 | if (target.os.tag == .windows) { |
| 414 | // The old 32-bit x86 variant of SEH doesn't use tables. | ||
| 415 | return if (target.cpu.arch != .x86) .@"async" else .none; | ||
| 416 | } | ||
| 417 | if (target.os.tag.isDarwin()) return .@"async"; | ||
| 418 | if (libunwind) return .@"async"; | ||
| 419 | if (libtsan) return .@"async"; | ||
| 420 | if (std.debug.Dwarf.abi.supportsUnwinding(target)) return .@"async"; | ||
| 421 | return .none; | ||
| 413 | } | 422 | } |
| 414 | 423 | ||
| 415 | pub fn defaultAddressSpace( | 424 | pub fn defaultAddressSpace( |
test/standalone/stack_iterator/build.zig+3-3| ... | @@ -23,7 +23,7 @@ pub fn build(b: *std.Build) void { | ... | @@ -23,7 +23,7 @@ pub fn build(b: *std.Build) void { |
| 23 | .root_source_file = b.path("unwind.zig"), | 23 | .root_source_file = b.path("unwind.zig"), |
| 24 | .target = target, | 24 | .target = target, |
| 25 | .optimize = optimize, | 25 | .optimize = optimize, |
| 26 | .unwind_tables = if (target.result.isDarwin()) true else null, | 26 | .unwind_tables = if (target.result.isDarwin()) .@"async" else null, |
| 27 | .omit_frame_pointer = false, | 27 | .omit_frame_pointer = false, |
| 28 | }); | 28 | }); |
| 29 | 29 | ||
| ... | @@ -46,7 +46,7 @@ pub fn build(b: *std.Build) void { | ... | @@ -46,7 +46,7 @@ pub fn build(b: *std.Build) void { |
| 46 | .root_source_file = b.path("unwind.zig"), | 46 | .root_source_file = b.path("unwind.zig"), |
| 47 | .target = target, | 47 | .target = target, |
| 48 | .optimize = optimize, | 48 | .optimize = optimize, |
| 49 | .unwind_tables = true, | 49 | .unwind_tables = .@"async", |
| 50 | .omit_frame_pointer = true, | 50 | .omit_frame_pointer = true, |
| 51 | }); | 51 | }); |
| 52 | 52 | ||
| ... | @@ -85,7 +85,7 @@ pub fn build(b: *std.Build) void { | ... | @@ -85,7 +85,7 @@ pub fn build(b: *std.Build) void { |
| 85 | .root_source_file = b.path("shared_lib_unwind.zig"), | 85 | .root_source_file = b.path("shared_lib_unwind.zig"), |
| 86 | .target = target, | 86 | .target = target, |
| 87 | .optimize = optimize, | 87 | .optimize = optimize, |
| 88 | .unwind_tables = if (target.result.isDarwin()) true else null, | 88 | .unwind_tables = if (target.result.isDarwin()) .@"async" else null, |
| 89 | .omit_frame_pointer = true, | 89 | .omit_frame_pointer = true, |
| 90 | }); | 90 | }); |
| 91 | 91 |
tools/update_clang_options.zig+8| ... | @@ -110,6 +110,14 @@ const known_options = [_]KnownOpt{ | ... | @@ -110,6 +110,14 @@ const known_options = [_]KnownOpt{ |
| 110 | .name = "fno-unwind-tables", | 110 | .name = "fno-unwind-tables", |
| 111 | .ident = "no_unwind_tables", | 111 | .ident = "no_unwind_tables", |
| 112 | }, | 112 | }, |
| 113 | .{ | ||
| 114 | .name = "fasynchronous-unwind-tables", | ||
| 115 | .ident = "asynchronous_unwind_tables", | ||
| 116 | }, | ||
| 117 | .{ | ||
| 118 | .name = "fno-asynchronous-unwind-tables", | ||
| 119 | .ident = "no_asynchronous_unwind_tables", | ||
| 120 | }, | ||
| 113 | .{ | 121 | .{ |
| 114 | .name = "nolibc", | 122 | .name = "nolibc", |
| 115 | .ident = "nostdlib", | 123 | .ident = "nostdlib", |