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:...@@ -7,50 +7,96 @@ pub fn doClientRequest(default: usize, request: usize, a1: usize, a2: usize, a3:
7 return default;7 return default;
8 }8 }
99
10 switch (builtin.target.cpu.arch) {10 const args = &[_]usize{ request, a1, a2, a3, a4, a5 };
11 .x86 => {11
12 return asm volatile (12 return switch (builtin.cpu.arch) {
13 \\ roll $3, %%edi ; roll $13, %%edi13 .arm, .armeb, .thumb, .thumbeb => asm volatile (
14 \\ roll $29, %%edi ; roll $19, %%edi14 \\ mov r12, r12, ror #3 ; mov r12, r12, ror #13
15 \\ xchgl %%ebx,%%ebx15 \\ mov r12, r12, ror #29 ; mov r12, r12, ror #19
16 : [_] "={edx}" (-> usize),16 \\ orr r10, r10, r10
17 : [_] "{eax}" (&[_]usize{ request, a1, a2, a3, a4, a5 }),17 : [_] "={r3}" (-> usize),
18 [_] "0" (default),18 : [_] "{r4}" (args),
19 : "cc", "memory"19 [_] "{r3}" (default),
20 );20 : "cc", "memory"
21 },21 ),
22 .x86_64 => {22 .aarch64, .aarch64_be => asm volatile (
23 return asm volatile (23 \\ ror x12, x12, #3 ; ror x12, x12, #13
24 \\ rolq $3, %%rdi ; rolq $13, %%rdi24 \\ ror x12, x12, #51 ; ror x12, x12, #61
25 \\ rolq $61, %%rdi ; rolq $51, %%rdi25 \\ orr x10, x10, x10
26 \\ xchgq %%rbx,%%rbx26 : [_] "={x3}" (-> usize),
27 : [_] "={rdx}" (-> usize),27 : [_] "{x4}" (args),
28 : [_] "{rax}" (&[_]usize{ request, a1, a2, a3, a4, a5 }),28 [_] "{x3}" (default),
29 [_] "0" (default),29 : "cc", "memory"
30 : "cc", "memory"30 ),
31 );31 .mips, .mipsel => asm volatile (
32 },32 \\ srl $0, $0, 13
33 .aarch64 => {33 \\ srl $0, $0, 29
34 return asm volatile (34 \\ srl $0, $0, 3
35 \\ ror x12, x12, #3 ; ror x12, x12, #1335 \\ srl $0, $0, 19
36 \\ ror x12, x12, #51 ; ror x12, x12, #6136 \\ or $13, $13, $13
37 \\ orr x10, x10, x1037 : [_] "={$11}" (-> usize),
38 : [_] "={x3}" (-> usize),38 : [_] "{$12}" (args),
39 : [_] "{x4}" (&[_]usize{ request, a1, a2, a3, a4, a5 }),39 [_] "{$11}" (default),
40 [_] "0" (default),40 : "memory"
41 : "cc", "memory"41 ),
42 );42 .mips64, .mips64el => asm volatile (
43 },43 \\ dsll $0, $0, 3 ; dsll $0, $0, 13
44 // ppc3244 \\ dsll $0, $0, 29 ; dsll $0, $0, 19
45 // ppc6445 \\ or $13, $13, $13
46 // arm46 : [_] "={$11}" (-> usize),
47 // s390x47 : [_] "{$12}" (args),
48 // mips3248 [_] "{$11}" (default),
49 // mips6449 : "memory"
50 else => {50 ),
51 return default;51 .powerpc, .powerpcle => asm volatile (
52 },52 \\ rlwinm 0, 0, 3, 0, 31 ; rlwinm 0, 0, 13, 0, 31
53 }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 };
54}100}
55101
56pub const ClientRequest = enum(u32) {102pub const ClientRequest = enum(u32) {
...@@ -121,7 +167,7 @@ pub fn discardTranslations(qzz: []const u8) void {...@@ -121,7 +167,7 @@ pub fn discardTranslations(qzz: []const u8) void {
121}167}
122168
123pub fn innerThreads(qzz: [*]u8) void {169pub fn innerThreads(qzz: [*]u8) void {
124 doClientRequestStmt(.InnerThreads, qzz, 0, 0, 0, 0);170 doClientRequestStmt(.InnerThreads, @intFromPtr(qzz), 0, 0, 0, 0);
125}171}
126172
127pub fn nonSimdCall0(func: fn (usize) usize) usize {173pub fn nonSimdCall0(func: fn (usize) usize) usize {
...@@ -273,7 +319,7 @@ pub fn enableErrorReporting() void {...@@ -273,7 +319,7 @@ pub fn enableErrorReporting() void {
273/// If no connection is opened, output will go to the log output.319/// If no connection is opened, output will go to the log output.
274/// Returns 1 if command not recognised, 0 otherwise.320/// Returns 1 if command not recognised, 0 otherwise.
275pub fn monitorCommand(command: [*]u8) bool {321pub 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;
277}323}
278324
279pub const memcheck = @import("valgrind/memcheck.zig");325pub const memcheck = @import("valgrind/memcheck.zig");
lib/std/valgrind/memcheck.zig+6-6
...@@ -90,26 +90,26 @@ pub fn checkMemIsDefined(qzz: []const u8) usize {...@@ -90,26 +90,26 @@ pub fn checkMemIsDefined(qzz: []const u8) usize {
9090
91/// Do a full memory leak check (like --leak-check=full) mid-execution.91/// Do a full memory leak check (like --leak-check=full) mid-execution.
92pub fn doLeakCheck() void {92pub fn doLeakCheck() void {
93 doClientRequestStmt(.DO_LEAK_CHECK, 0, 0, 0, 0, 0);93 doClientRequestStmt(.DoLeakCheck, 0, 0, 0, 0, 0);
94}94}
9595
96/// Same as doLeakCheck() but only showing the entries for96/// Same as doLeakCheck() but only showing the entries for
97/// which there was an increase in leaked bytes or leaked nr of blocks97/// which there was an increase in leaked bytes or leaked nr of blocks
98/// since the previous leak search.98/// since the previous leak search.
99pub fn doAddedLeakCheck() void {99pub fn doAddedLeakCheck() void {
100 doClientRequestStmt(.DO_LEAK_CHECK, 0, 1, 0, 0, 0);100 doClientRequestStmt(.DoLeakCheck, 0, 1, 0, 0, 0);
101}101}
102102
103/// Same as doAddedLeakCheck() but showing entries with103/// Same as doAddedLeakCheck() but showing entries with
104/// increased or decreased leaked bytes/blocks since previous leak104/// increased or decreased leaked bytes/blocks since previous leak
105/// search.105/// search.
106pub fn doChangedLeakCheck() void {106pub fn doChangedLeakCheck() void {
107 doClientRequestStmt(.DO_LEAK_CHECK, 0, 2, 0, 0, 0);107 doClientRequestStmt(.DoLeakCheck, 0, 2, 0, 0, 0);
108}108}
109109
110/// Do a summary memory leak check (like --leak-check=summary) mid-execution.110/// Do a summary memory leak check (like --leak-check=summary) mid-execution.
111pub fn doQuickLeakCheck() void {111pub fn doQuickLeakCheck() void {
112 doClientRequestStmt(.DO_LEAK_CHECK, 1, 0, 0, 0, 0);112 doClientRequestStmt(.DoLeakCheck, 1, 0, 0, 0, 0);
113}113}
114114
115/// Return number of leaked, dubious, reachable and suppressed bytes found by115/// Return number of leaked, dubious, reachable and suppressed bytes found by
...@@ -191,7 +191,7 @@ test countLeakBlocks {...@@ -191,7 +191,7 @@ test countLeakBlocks {
191/// impossible to segfault your system by using this call.191/// impossible to segfault your system by using this call.
192pub fn getVbits(zza: []u8, zzvbits: []u8) u2 {192pub fn getVbits(zza: []u8, zzvbits: []u8) u2 {
193 std.debug.assert(zzvbits.len >= zza.len / 8);193 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)));
195}195}
196196
197/// Set the validity data for addresses zza, copying it197/// Set the validity data for addresses zza, copying it
...@@ -204,7 +204,7 @@ pub fn getVbits(zza: []u8, zzvbits: []u8) u2 {...@@ -204,7 +204,7 @@ pub fn getVbits(zza: []u8, zzvbits: []u8) u2 {
204/// impossible to segfault your system by using this call.204/// impossible to segfault your system by using this call.
205pub fn setVbits(zzvbits: []u8, zza: []u8) u2 {205pub fn setVbits(zzvbits: []u8, zza: []u8) u2 {
206 std.debug.assert(zzvbits.len >= zza.len / 8);206 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)));
208}208}
209209
210/// Disable and re-enable reporting of addressing errors in the210/// Disable and re-enable reporting of addressing errors in the
src/codegen/llvm.zig+67-15
...@@ -11592,29 +11592,81 @@ pub const FuncGen = struct {...@@ -11592,29 +11592,81 @@ pub const FuncGen = struct {
11592 template: [:0]const u8,11592 template: [:0]const u8,
11593 constraints: [:0]const u8,11593 constraints: [:0]const u8,
11594 } = switch (target.cpu.arch) {11594 } = switch (target.cpu.arch) {
11595 .x86 => .{11595 .arm, .armeb, .thumb, .thumbeb => .{
11596 .template =11596 .template =
11597 \\roll $$3, %edi ; roll $$13, %edi11597 \\ mov r12, r12, ror #3 ; mov r12, r12, ror #13
11598 \\roll $$61, %edi ; roll $$51, %edi11598 \\ mov r12, r12, ror #29 ; mov r12, r12, ror #19
11599 \\xchgl %ebx,%ebx11599 \\ orr r10, r10, r10
11600 ,11600 ,
11601 .constraints = "={edx},{eax},0,~{cc},~{memory}",11601 .constraints = "={r3},{r4},{r3},~{cc},~{memory}",
11602 },11602 },
11603 .x86_64 => .{11603 .aarch64, .aarch64_be => .{
11604 .template =11604 .template =
11605 \\rolq $$3, %rdi ; rolq $$13, %rdi11605 \\ ror x12, x12, #3 ; ror x12, x12, #13
11606 \\rolq $$61, %rdi ; rolq $$51, %rdi11606 \\ ror x12, x12, #51 ; ror x12, x12, #61
11607 \\xchgq %rbx,%rbx11607 \\ orr x10, x10, x10
11608 ,11608 ,
11609 .constraints = "={rdx},{rax},0,~{cc},~{memory}",11609 .constraints = "={x3},{x4},{x3},~{cc},~{memory}",
11610 },11610 },
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 => .{
11612 .template =11664 .template =
11613 \\ror x12, x12, #3 ; ror x12, x12, #1311665 \\ rolq $$3, %rdi ; rolq $$13, %rdi
11614 \\ror x12, x12, #51 ; ror x12, x12, #6111666 \\ rolq $$61, %rdi ; rolq $$51, %rdi
11615 \\orr x10, x10, x1011667 \\ xchgq %rbx, %rbx
11616 ,11668 ,
11617 .constraints = "={x3},{x4},0,~{cc},~{memory}",11669 .constraints = "={rdx},{rax},{edx},~{cc},~{memory}",
11618 },11670 },
11619 else => unreachable,11671 else => unreachable,
11620 };11672 };
src/target.zig+37-11
...@@ -79,19 +79,45 @@ pub fn defaultSingleThreaded(target: std.Target) bool {...@@ -79,19 +79,45 @@ pub fn defaultSingleThreaded(target: std.Target) bool {
79 return false;79 return false;
80}80}
8181
82/// Valgrind supports more, but Zig does not support them yet.
83pub fn hasValgrindSupport(target: std.Target) bool {82pub fn hasValgrindSupport(target: std.Target) bool {
84 switch (target.cpu.arch) {83 // We can't currently output the necessary Valgrind client request assembly when using the C
85 .x86,84 // backend and compiling with an MSVC-like compiler.
86 .x86_64,85 const ofmt_c_msvc = (target.abi == .msvc or target.abi == .itanium) and target.ofmt == .c;
87 .aarch64,86
88 .aarch64_be,87 return switch (target.cpu.arch) {
89 => {88 .arm, .armeb, .thumb, .thumbeb => switch (target.os.tag) {
90 return target.os.tag == .linux or target.os.tag == .solaris or target.os.tag == .illumos or89 .linux => true,
91 (target.os.tag == .windows and target.abi.isGnu());90 else => false,
92 },91 },
93 else => return false,92 .aarch64, .aarch64_be => switch (target.os.tag) {
94 }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 };
95}121}
96122
97/// The set of targets that LLVM has non-experimental support for.123/// The set of targets that LLVM has non-experimental support for.