| author | |
| committer | |
| log | bd7dda0c5590e272a85711e8f90a90941566c988 |
| tree | 0d38b922244a7d8d38d7f7af7f9d6d30384c136b |
| parent | f25ea264b7391fde5bcfc253056cf9e0d91e9876 |
| parent | 8a73a965d3185cadee2bd819daa12b5b3f1daafc |
| signature |
Add client request support for all architectures supported by Valgrind4 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 | } |
| 9 | 9 | ||
| 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, %%edi | 13 | .arm, .armeb, .thumb, .thumbeb => asm volatile ( |
| 14 | \\ roll $29, %%edi ; roll $19, %%edi | 14 | \\ mov r12, r12, ror #3 ; mov r12, r12, ror #13 |
| 15 | \\ xchgl %%ebx,%%ebx | 15 | \\ 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, %%rdi | 24 | \\ ror x12, x12, #51 ; ror x12, x12, #61 |
| 25 | \\ rolq $61, %%rdi ; rolq $51, %%rdi | 25 | \\ orr x10, x10, x10 |
| 26 | \\ xchgq %%rbx,%%rbx | 26 | : [_] "={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, #13 | 35 | \\ srl $0, $0, 19 |
| 36 | \\ ror x12, x12, #51 ; ror x12, x12, #61 | 36 | \\ or $13, $13, $13 |
| 37 | \\ orr x10, x10, x10 | 37 | : [_] "={$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 | // ppc32 | 44 | \\ dsll $0, $0, 29 ; dsll $0, $0, 19 |
| 45 | // ppc64 | 45 | \\ or $13, $13, $13 |
| 46 | // arm | 46 | : [_] "={$11}" (-> usize), |
| 47 | // s390x | 47 | : [_] "{$12}" (args), |
| 48 | // mips32 | 48 | [_] "{$11}" (default), |
| 49 | // mips64 | 49 | : "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 | } |
| 55 | 101 | ||
| 56 | pub const ClientRequest = enum(u32) { | 102 | pub 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 | } |
| 122 | 168 | ||
| 123 | pub fn innerThreads(qzz: [*]u8) void { | 169 | pub fn innerThreads(qzz: [*]u8) void { |
| 124 | doClientRequestStmt(.InnerThreads, qzz, 0, 0, 0, 0); | 170 | doClientRequestStmt(.InnerThreads, @intFromPtr(qzz), 0, 0, 0, 0); |
| 125 | } | 171 | } |
| 126 | 172 | ||
| 127 | pub fn nonSimdCall0(func: fn (usize) usize) usize { | 173 | pub 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. |
| 275 | pub fn monitorCommand(command: [*]u8) bool { | 321 | pub 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 | } |
| 278 | 324 | ||
| 279 | pub const memcheck = @import("valgrind/memcheck.zig"); | 325 | pub 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 { |
| 90 | 90 | ||
| 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. |
| 92 | pub fn doLeakCheck() void { | 92 | pub fn doLeakCheck() void { |
| 93 | doClientRequestStmt(.DO_LEAK_CHECK, 0, 0, 0, 0, 0); | 93 | doClientRequestStmt(.DoLeakCheck, 0, 0, 0, 0, 0); |
| 94 | } | 94 | } |
| 95 | 95 | ||
| 96 | /// Same as doLeakCheck() but only showing the entries for | 96 | /// Same as doLeakCheck() but only showing the entries for |
| 97 | /// which there was an increase in leaked bytes or leaked nr of blocks | 97 | /// 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. |
| 99 | pub fn doAddedLeakCheck() void { | 99 | pub fn doAddedLeakCheck() void { |
| 100 | doClientRequestStmt(.DO_LEAK_CHECK, 0, 1, 0, 0, 0); | 100 | doClientRequestStmt(.DoLeakCheck, 0, 1, 0, 0, 0); |
| 101 | } | 101 | } |
| 102 | 102 | ||
| 103 | /// Same as doAddedLeakCheck() but showing entries with | 103 | /// Same as doAddedLeakCheck() but showing entries with |
| 104 | /// increased or decreased leaked bytes/blocks since previous leak | 104 | /// increased or decreased leaked bytes/blocks since previous leak |
| 105 | /// search. | 105 | /// search. |
| 106 | pub fn doChangedLeakCheck() void { | 106 | pub fn doChangedLeakCheck() void { |
| 107 | doClientRequestStmt(.DO_LEAK_CHECK, 0, 2, 0, 0, 0); | 107 | doClientRequestStmt(.DoLeakCheck, 0, 2, 0, 0, 0); |
| 108 | } | 108 | } |
| 109 | 109 | ||
| 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. |
| 111 | pub fn doQuickLeakCheck() void { | 111 | pub fn doQuickLeakCheck() void { |
| 112 | doClientRequestStmt(.DO_LEAK_CHECK, 1, 0, 0, 0, 0); | 112 | doClientRequestStmt(.DoLeakCheck, 1, 0, 0, 0, 0); |
| 113 | } | 113 | } |
| 114 | 114 | ||
| 115 | /// Return number of leaked, dubious, reachable and suppressed bytes found by | 115 | /// 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. |
| 192 | pub fn getVbits(zza: []u8, zzvbits: []u8) u2 { | 192 | pub 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 | } |
| 196 | 196 | ||
| 197 | /// Set the validity data for addresses zza, copying it | 197 | /// 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. |
| 205 | pub fn setVbits(zzvbits: []u8, zza: []u8) u2 { | 205 | pub 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 | } |
| 209 | 209 | ||
| 210 | /// Disable and re-enable reporting of addressing errors in the | 210 | /// 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, %edi | 11597 | \\ mov r12, r12, ror #3 ; mov r12, r12, ror #13 |
| 11598 | \\roll $$61, %edi ; roll $$51, %edi | 11598 | \\ mov r12, r12, ror #29 ; mov r12, r12, ror #19 |
| 11599 | \\xchgl %ebx,%ebx | 11599 | \\ 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, %rdi | 11605 | \\ ror x12, x12, #3 ; ror x12, x12, #13 |
| 11606 | \\rolq $$61, %rdi ; rolq $$51, %rdi | 11606 | \\ ror x12, x12, #51 ; ror x12, x12, #61 |
| 11607 | \\xchgq %rbx,%rbx | 11607 | \\ 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, #13 | 11665 | \\ rolq $$3, %rdi ; rolq $$13, %rdi |
| 11614 | \\ror x12, x12, #51 ; ror x12, x12, #61 | 11666 | \\ rolq $$61, %rdi ; rolq $$51, %rdi |
| 11615 | \\orr x10, x10, x10 | 11667 | \\ 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 | } |
| 81 | 81 | ||
| 82 | /// Valgrind supports more, but Zig does not support them yet. | ||
| 83 | pub fn hasValgrindSupport(target: std.Target) bool { | 82 | pub 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 or | 89 | .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 | } |
| 96 | 122 | ||
| 97 | /// The set of targets that LLVM has non-experimental support for. | 123 | /// The set of targets that LLVM has non-experimental support for. |