authorgravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2024-11-05 10:03:44+01:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2024-11-05 10:03:44+01:00
logbd7dda0c5590e272a85711e8f90a90941566c988
tree0d38b922244a7d8d38d7f7af7f9d6d30384c136b
parentf25ea264b7391fde5bcfc253056cf9e0d91e9876
parent8a73a965d3185cadee2bd819daa12b5b3f1daafc
signaturebadge-check Signed by PGP key B5690EEEBB952194

Merge pull request #21907 from alexrp/valgrind-stuff

Add client request support for all architectures supported by Valgrind

4 files changed, 202 insertions(+), 78 deletions(-)

lib/std/valgrind.zig+92-46
......@@ -7,50 +7,96 @@ pub fn doClientRequest(default: usize, request: usize, a1: usize, a2: usize, a3:
77 return default;
88 }
99
10 switch (builtin.target.cpu.arch) {
11 .x86 => {
12 return asm volatile (
13 \\ roll $3, %%edi ; roll $13, %%edi
14 \\ roll $29, %%edi ; roll $19, %%edi
15 \\ xchgl %%ebx,%%ebx
16 : [_] "={edx}" (-> usize),
17 : [_] "{eax}" (&[_]usize{ request, a1, a2, a3, a4, a5 }),
18 [_] "0" (default),
19 : "cc", "memory"
20 );
21 },
22 .x86_64 => {
23 return asm volatile (
24 \\ rolq $3, %%rdi ; rolq $13, %%rdi
25 \\ rolq $61, %%rdi ; rolq $51, %%rdi
26 \\ xchgq %%rbx,%%rbx
27 : [_] "={rdx}" (-> usize),
28 : [_] "{rax}" (&[_]usize{ request, a1, a2, a3, a4, a5 }),
29 [_] "0" (default),
30 : "cc", "memory"
31 );
32 },
33 .aarch64 => {
34 return asm volatile (
35 \\ ror x12, x12, #3 ; ror x12, x12, #13
36 \\ ror x12, x12, #51 ; ror x12, x12, #61
37 \\ orr x10, x10, x10
38 : [_] "={x3}" (-> usize),
39 : [_] "{x4}" (&[_]usize{ request, a1, a2, a3, a4, a5 }),
40 [_] "0" (default),
41 : "cc", "memory"
42 );
43 },
44 // ppc32
45 // ppc64
46 // arm
47 // s390x
48 // mips32
49 // mips64
50 else => {
51 return default;
52 },
53 }
10 const args = &[_]usize{ request, a1, a2, a3, a4, a5 };
11
12 return switch (builtin.cpu.arch) {
13 .arm, .armeb, .thumb, .thumbeb => asm volatile (
14 \\ mov r12, r12, ror #3 ; mov r12, r12, ror #13
15 \\ mov r12, r12, ror #29 ; mov r12, r12, ror #19
16 \\ orr r10, r10, r10
17 : [_] "={r3}" (-> usize),
18 : [_] "{r4}" (args),
19 [_] "{r3}" (default),
20 : "cc", "memory"
21 ),
22 .aarch64, .aarch64_be => asm volatile (
23 \\ ror x12, x12, #3 ; ror x12, x12, #13
24 \\ ror x12, x12, #51 ; ror x12, x12, #61
25 \\ orr x10, x10, x10
26 : [_] "={x3}" (-> usize),
27 : [_] "{x4}" (args),
28 [_] "{x3}" (default),
29 : "cc", "memory"
30 ),
31 .mips, .mipsel => asm volatile (
32 \\ srl $0, $0, 13
33 \\ srl $0, $0, 29
34 \\ srl $0, $0, 3
35 \\ srl $0, $0, 19
36 \\ or $13, $13, $13
37 : [_] "={$11}" (-> usize),
38 : [_] "{$12}" (args),
39 [_] "{$11}" (default),
40 : "memory"
41 ),
42 .mips64, .mips64el => asm volatile (
43 \\ dsll $0, $0, 3 ; dsll $0, $0, 13
44 \\ dsll $0, $0, 29 ; dsll $0, $0, 19
45 \\ or $13, $13, $13
46 : [_] "={$11}" (-> usize),
47 : [_] "{$12}" (args),
48 [_] "{$11}" (default),
49 : "memory"
50 ),
51 .powerpc, .powerpcle => asm volatile (
52 \\ rlwinm 0, 0, 3, 0, 31 ; rlwinm 0, 0, 13, 0, 31
53 \\ rlwinm 0, 0, 29, 0, 31 ; rlwinm 0, 0, 19, 0, 31
54 \\ or 1, 1, 1
55 : [_] "={r3}" (-> usize),
56 : [_] "{r4}" (args),
57 [_] "{r3}" (default),
58 : "cc", "memory"
59 ),
60 .powerpc64, .powerpc64le => asm volatile (
61 \\ rotldi 0, 0, 3 ; rotldi 0, 0, 13
62 \\ rotldi 0, 0, 61 ; rotldi 0, 0, 51
63 \\ or 1, 1, 1
64 : [_] "={r3}" (-> usize),
65 : [_] "{r4}" (args),
66 [_] "{r3}" (default),
67 : "cc", "memory"
68 ),
69 .s390x => asm volatile (
70 \\ lr %%r15, %%r15
71 \\ lr %%r1, %%r1
72 \\ lr %%r2, %%r2
73 \\ lr %%r3, %%r3
74 \\ lr %%r2, %%r2
75 : [_] "={r3}" (-> usize),
76 : [_] "{r2}" (args),
77 [_] "{r3}" (default),
78 : "cc", "memory"
79 ),
80 .x86 => asm volatile (
81 \\ roll $3, %%edi ; roll $13, %%edi
82 \\ roll $29, %%edi ; roll $19, %%edi
83 \\ xchgl %%ebx, %%ebx
84 : [_] "={edx}" (-> usize),
85 : [_] "{eax}" (args),
86 [_] "{edx}" (default),
87 : "cc", "memory"
88 ),
89 .x86_64 => asm volatile (
90 \\ rolq $3, %%rdi ; rolq $13, %%rdi
91 \\ rolq $61, %%rdi ; rolq $51, %%rdi
92 \\ xchgq %%rbx, %%rbx
93 : [_] "={rdx}" (-> usize),
94 : [_] "{rax}" (args),
95 [_] "{rdx}" (default),
96 : "cc", "memory"
97 ),
98 else => default,
99 };
54100}
55101
56102pub const ClientRequest = enum(u32) {
......@@ -121,7 +167,7 @@ pub fn discardTranslations(qzz: []const u8) void {
121167}
122168
123169pub fn innerThreads(qzz: [*]u8) void {
124 doClientRequestStmt(.InnerThreads, qzz, 0, 0, 0, 0);
170 doClientRequestStmt(.InnerThreads, @intFromPtr(qzz), 0, 0, 0, 0);
125171}
126172
127173pub fn nonSimdCall0(func: fn (usize) usize) usize {
......@@ -273,7 +319,7 @@ pub fn enableErrorReporting() void {
273319/// If no connection is opened, output will go to the log output.
274320/// Returns 1 if command not recognised, 0 otherwise.
275321pub fn monitorCommand(command: [*]u8) bool {
276 return doClientRequestExpr(0, .GdbMonitorCommand, @intFromPtr(command.ptr), 0, 0, 0, 0) != 0;
322 return doClientRequestExpr(0, .GdbMonitorCommand, @intFromPtr(command), 0, 0, 0, 0) != 0;
277323}
278324
279325pub const memcheck = @import("valgrind/memcheck.zig");
lib/std/valgrind/memcheck.zig+6-6
......@@ -90,26 +90,26 @@ pub fn checkMemIsDefined(qzz: []const u8) usize {
9090
9191/// Do a full memory leak check (like --leak-check=full) mid-execution.
9292pub fn doLeakCheck() void {
93 doClientRequestStmt(.DO_LEAK_CHECK, 0, 0, 0, 0, 0);
93 doClientRequestStmt(.DoLeakCheck, 0, 0, 0, 0, 0);
9494}
9595
9696/// Same as doLeakCheck() but only showing the entries for
9797/// which there was an increase in leaked bytes or leaked nr of blocks
9898/// since the previous leak search.
9999pub fn doAddedLeakCheck() void {
100 doClientRequestStmt(.DO_LEAK_CHECK, 0, 1, 0, 0, 0);
100 doClientRequestStmt(.DoLeakCheck, 0, 1, 0, 0, 0);
101101}
102102
103103/// Same as doAddedLeakCheck() but showing entries with
104104/// increased or decreased leaked bytes/blocks since previous leak
105105/// search.
106106pub fn doChangedLeakCheck() void {
107 doClientRequestStmt(.DO_LEAK_CHECK, 0, 2, 0, 0, 0);
107 doClientRequestStmt(.DoLeakCheck, 0, 2, 0, 0, 0);
108108}
109109
110110/// Do a summary memory leak check (like --leak-check=summary) mid-execution.
111111pub fn doQuickLeakCheck() void {
112 doClientRequestStmt(.DO_LEAK_CHECK, 1, 0, 0, 0, 0);
112 doClientRequestStmt(.DoLeakCheck, 1, 0, 0, 0, 0);
113113}
114114
115115/// Return number of leaked, dubious, reachable and suppressed bytes found by
......@@ -191,7 +191,7 @@ test countLeakBlocks {
191191/// impossible to segfault your system by using this call.
192192pub fn getVbits(zza: []u8, zzvbits: []u8) u2 {
193193 std.debug.assert(zzvbits.len >= zza.len / 8);
194 return @as(u2, @intCast(doClientRequestExpr(0, .GetVbits, @intFromPtr(zza.ptr), @intFromPtr(zzvbits), zza.len, 0, 0)));
194 return @as(u2, @intCast(doClientRequestExpr(0, .GetVbits, @intFromPtr(zza.ptr), @intFromPtr(zzvbits.ptr), zza.len, 0, 0)));
195195}
196196
197197/// Set the validity data for addresses zza, copying it
......@@ -204,7 +204,7 @@ pub fn getVbits(zza: []u8, zzvbits: []u8) u2 {
204204/// impossible to segfault your system by using this call.
205205pub fn setVbits(zzvbits: []u8, zza: []u8) u2 {
206206 std.debug.assert(zzvbits.len >= zza.len / 8);
207 return @as(u2, @intCast(doClientRequestExpr(0, .SetVbits, @intFromPtr(zza.ptr), @intFromPtr(zzvbits), zza.len, 0, 0)));
207 return @as(u2, @intCast(doClientRequestExpr(0, .SetVbits, @intFromPtr(zza.ptr), @intFromPtr(zzvbits.ptr), zza.len, 0, 0)));
208208}
209209
210210/// Disable and re-enable reporting of addressing errors in the
src/codegen/llvm.zig+67-15
......@@ -11592,29 +11592,81 @@ pub const FuncGen = struct {
1159211592 template: [:0]const u8,
1159311593 constraints: [:0]const u8,
1159411594 } = switch (target.cpu.arch) {
11595 .x86 => .{
11595 .arm, .armeb, .thumb, .thumbeb => .{
1159611596 .template =
11597 \\roll $$3, %edi ; roll $$13, %edi
11598 \\roll $$61, %edi ; roll $$51, %edi
11599 \\xchgl %ebx,%ebx
11597 \\ mov r12, r12, ror #3 ; mov r12, r12, ror #13
11598 \\ mov r12, r12, ror #29 ; mov r12, r12, ror #19
11599 \\ orr r10, r10, r10
1160011600 ,
11601 .constraints = "={edx},{eax},0,~{cc},~{memory}",
11601 .constraints = "={r3},{r4},{r3},~{cc},~{memory}",
1160211602 },
11603 .x86_64 => .{
11603 .aarch64, .aarch64_be => .{
1160411604 .template =
11605 \\rolq $$3, %rdi ; rolq $$13, %rdi
11606 \\rolq $$61, %rdi ; rolq $$51, %rdi
11607 \\xchgq %rbx,%rbx
11605 \\ ror x12, x12, #3 ; ror x12, x12, #13
11606 \\ ror x12, x12, #51 ; ror x12, x12, #61
11607 \\ orr x10, x10, x10
1160811608 ,
11609 .constraints = "={rdx},{rax},0,~{cc},~{memory}",
11609 .constraints = "={x3},{x4},{x3},~{cc},~{memory}",
1161011610 },
11611 .aarch64, .aarch64_be => .{
11611 .mips, .mipsel => .{
11612 .template =
11613 \\ srl $$0, $$0, 13
11614 \\ srl $$0, $$0, 29
11615 \\ srl $$0, $$0, 3
11616 \\ srl $$0, $$0, 19
11617 \\ or $$13, $$13, $$13
11618 ,
11619 .constraints = "={$11},{$12},{$11},~{memory}",
11620 },
11621 .mips64, .mips64el => .{
11622 .template =
11623 \\ dsll $$0, $$0, 3 ; dsll $$0, $$0, 13
11624 \\ dsll $$0, $$0, 29 ; dsll $$0, $$0, 19
11625 \\ or $$13, $$13, $$13
11626 ,
11627 .constraints = "={$11},{$12},{$11},~{memory}",
11628 },
11629 .powerpc, .powerpcle => .{
11630 .template =
11631 \\ rlwinm 0, 0, 3, 0, 31 ; rlwinm 0, 0, 13, 0, 31
11632 \\ rlwinm 0, 0, 29, 0, 31 ; rlwinm 0, 0, 19, 0, 31
11633 \\ or 1, 1, 1
11634 ,
11635 .constraints = "={r3},{r4},{r3},~{cc},~{memory}",
11636 },
11637 .powerpc64, .powerpc64le => .{
11638 .template =
11639 \\ rotldi 0, 0, 3 ; rotldi 0, 0, 13
11640 \\ rotldi 0, 0, 61 ; rotldi 0, 0, 51
11641 \\ or 1, 1, 1
11642 ,
11643 .constraints = "={r3},{r4},{r3},~{cc},~{memory}",
11644 },
11645 .s390x => .{
11646 .template =
11647 \\ lr %r15, %r15
11648 \\ lr %r1, %r1
11649 \\ lr %r2, %r2
11650 \\ lr %r3, %r3
11651 \\ lr %r2, %r2
11652 ,
11653 .constraints = "={r3},{r2},{r3},~{cc},~{memory}",
11654 },
11655 .x86 => .{
11656 .template =
11657 \\ roll $$3, %edi ; roll $$13, %edi
11658 \\ roll $$61, %edi ; roll $$51, %edi
11659 \\ xchgl %ebx, %ebx
11660 ,
11661 .constraints = "={edx},{eax},{edx},~{cc},~{memory}",
11662 },
11663 .x86_64 => .{
1161211664 .template =
11613 \\ror x12, x12, #3 ; ror x12, x12, #13
11614 \\ror x12, x12, #51 ; ror x12, x12, #61
11615 \\orr x10, x10, x10
11665 \\ rolq $$3, %rdi ; rolq $$13, %rdi
11666 \\ rolq $$61, %rdi ; rolq $$51, %rdi
11667 \\ xchgq %rbx, %rbx
1161611668 ,
11617 .constraints = "={x3},{x4},0,~{cc},~{memory}",
11669 .constraints = "={rdx},{rax},{edx},~{cc},~{memory}",
1161811670 },
1161911671 else => unreachable,
1162011672 };
src/target.zig+37-11
......@@ -79,19 +79,45 @@ pub fn defaultSingleThreaded(target: std.Target) bool {
7979 return false;
8080}
8181
82/// Valgrind supports more, but Zig does not support them yet.
8382pub fn hasValgrindSupport(target: std.Target) bool {
84 switch (target.cpu.arch) {
85 .x86,
86 .x86_64,
87 .aarch64,
88 .aarch64_be,
89 => {
90 return target.os.tag == .linux or target.os.tag == .solaris or target.os.tag == .illumos or
91 (target.os.tag == .windows and target.abi.isGnu());
83 // We can't currently output the necessary Valgrind client request assembly when using the C
84 // backend and compiling with an MSVC-like compiler.
85 const ofmt_c_msvc = (target.abi == .msvc or target.abi == .itanium) and target.ofmt == .c;
86
87 return switch (target.cpu.arch) {
88 .arm, .armeb, .thumb, .thumbeb => switch (target.os.tag) {
89 .linux => true,
90 else => false,
9291 },
93 else => return false,
94 }
92 .aarch64, .aarch64_be => switch (target.os.tag) {
93 .linux, .freebsd => true,
94 else => false,
95 },
96 .mips, .mipsel, .mips64, .mips64el => switch (target.os.tag) {
97 .linux => true,
98 else => false,
99 },
100 .powerpc, .powerpcle, .powerpc64, .powerpc64le => switch (target.os.tag) {
101 .linux => true,
102 else => false,
103 },
104 .s390x => switch (target.os.tag) {
105 .linux => true,
106 else => false,
107 },
108 .x86 => switch (target.os.tag) {
109 .linux, .freebsd, .solaris, .illumos => true,
110 .windows => !ofmt_c_msvc,
111 else => false,
112 },
113 .x86_64 => switch (target.os.tag) {
114 .linux => target.abi != .gnux32 and target.abi != .muslx32,
115 .freebsd, .solaris, .illumos => true,
116 .windows => !ofmt_c_msvc,
117 else => false,
118 },
119 else => false,
120 };
95121}
96122
97123/// The set of targets that LLVM has non-experimental support for.