njn | 75b65aa | 2005-06-19 19:25:44 +0000 | [diff] [blame] | 1 | |
| 2 | /*--------------------------------------------------------------------*/ |
| 3 | /*--- Attaching a debugger. m_debugger.c ---*/ |
| 4 | /*--------------------------------------------------------------------*/ |
| 5 | |
| 6 | /* |
| 7 | This file is part of Valgrind, a dynamic binary instrumentation |
| 8 | framework. |
| 9 | |
sewardj | 03f8d3f | 2012-08-05 15:46:46 +0000 | [diff] [blame] | 10 | Copyright (C) 2000-2012 Julian Seward |
njn | 75b65aa | 2005-06-19 19:25:44 +0000 | [diff] [blame] | 11 | jseward@acm.org |
| 12 | |
| 13 | This program is free software; you can redistribute it and/or |
| 14 | modify it under the terms of the GNU General Public License as |
| 15 | published by the Free Software Foundation; either version 2 of the |
| 16 | License, or (at your option) any later version. |
| 17 | |
| 18 | This program is distributed in the hope that it will be useful, but |
| 19 | WITHOUT ANY WARRANTY; without even the implied warranty of |
| 20 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| 21 | General Public License for more details. |
| 22 | |
| 23 | You should have received a copy of the GNU General Public License |
| 24 | along with this program; if not, write to the Free Software |
| 25 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA |
| 26 | 02111-1307, USA. |
| 27 | |
| 28 | The GNU General Public License is contained in the file COPYING. |
| 29 | */ |
| 30 | |
| 31 | #include "pub_core_basics.h" |
sewardj | 4cfea4f | 2006-10-14 19:26:10 +0000 | [diff] [blame] | 32 | #include "pub_core_vki.h" |
sewardj | 6c591e1 | 2011-04-11 16:17:51 +0000 | [diff] [blame] | 33 | #include "pub_core_libcsetjmp.h" |
njn | 75b65aa | 2005-06-19 19:25:44 +0000 | [diff] [blame] | 34 | #include "pub_core_threadstate.h" |
sewardj | 14c7cc5 | 2007-02-25 15:08:24 +0000 | [diff] [blame] | 35 | #include "pub_core_xarray.h" |
sewardj | 45f4e7c | 2005-09-27 19:20:21 +0000 | [diff] [blame] | 36 | #include "pub_core_clientstate.h" |
njn | 75b65aa | 2005-06-19 19:25:44 +0000 | [diff] [blame] | 37 | #include "pub_core_debugger.h" |
| 38 | #include "pub_core_libcbase.h" |
njn | 75b65aa | 2005-06-19 19:25:44 +0000 | [diff] [blame] | 39 | #include "pub_core_libcprint.h" |
| 40 | #include "pub_core_libcproc.h" |
| 41 | #include "pub_core_libcsignal.h" |
sewardj | 2c48c7b | 2005-11-29 13:05:56 +0000 | [diff] [blame] | 42 | #include "pub_core_libcassert.h" |
njn | 75b65aa | 2005-06-19 19:25:44 +0000 | [diff] [blame] | 43 | #include "pub_core_options.h" |
| 44 | |
sewardj | ccc89d9 | 2005-11-09 14:43:03 +0000 | [diff] [blame] | 45 | |
sewardj | 45f4e7c | 2005-09-27 19:20:21 +0000 | [diff] [blame] | 46 | #define WIFSTOPPED(status) (((status) & 0xff) == 0x7f) |
| 47 | #define WSTOPSIG(status) (((status) & 0xff00) >> 8) |
njn | 75b65aa | 2005-06-19 19:25:44 +0000 | [diff] [blame] | 48 | |
| 49 | static Int ptrace_setregs(Int pid, VexGuestArchState* vex) |
| 50 | { |
sewardj | 957ee5d | 2006-10-17 01:54:20 +0000 | [diff] [blame] | 51 | #if defined(VGP_x86_linux) |
sewardj | c9e73dc | 2005-11-09 15:14:16 +0000 | [diff] [blame] | 52 | struct vki_user_regs_struct regs; |
sewardj | 0313b1e | 2007-11-19 14:54:09 +0000 | [diff] [blame] | 53 | VG_(memset)(®s, 0, sizeof(regs)); |
njn | 75b65aa | 2005-06-19 19:25:44 +0000 | [diff] [blame] | 54 | regs.cs = vex->guest_CS; |
| 55 | regs.ss = vex->guest_SS; |
| 56 | regs.ds = vex->guest_DS; |
| 57 | regs.es = vex->guest_ES; |
| 58 | regs.fs = vex->guest_FS; |
| 59 | regs.gs = vex->guest_GS; |
| 60 | regs.eax = vex->guest_EAX; |
| 61 | regs.ebx = vex->guest_EBX; |
| 62 | regs.ecx = vex->guest_ECX; |
| 63 | regs.edx = vex->guest_EDX; |
| 64 | regs.esi = vex->guest_ESI; |
| 65 | regs.edi = vex->guest_EDI; |
| 66 | regs.ebp = vex->guest_EBP; |
| 67 | regs.esp = vex->guest_ESP; |
| 68 | regs.eflags = LibVEX_GuestX86_get_eflags(vex); |
| 69 | regs.eip = vex->guest_EIP; |
sewardj | 45f4e7c | 2005-09-27 19:20:21 +0000 | [diff] [blame] | 70 | return VG_(ptrace)(VKI_PTRACE_SETREGS, pid, NULL, ®s); |
sewardj | c9e73dc | 2005-11-09 15:14:16 +0000 | [diff] [blame] | 71 | |
sewardj | 957ee5d | 2006-10-17 01:54:20 +0000 | [diff] [blame] | 72 | #elif defined(VGP_amd64_linux) |
sewardj | c9e73dc | 2005-11-09 15:14:16 +0000 | [diff] [blame] | 73 | struct vki_user_regs_struct regs; |
sewardj | 0313b1e | 2007-11-19 14:54:09 +0000 | [diff] [blame] | 74 | VG_(memset)(®s, 0, sizeof(regs)); |
tom | e4fed1c | 2005-07-19 18:19:48 +0000 | [diff] [blame] | 75 | regs.rax = vex->guest_RAX; |
| 76 | regs.rbx = vex->guest_RBX; |
| 77 | regs.rcx = vex->guest_RCX; |
| 78 | regs.rdx = vex->guest_RDX; |
| 79 | regs.rsi = vex->guest_RSI; |
| 80 | regs.rdi = vex->guest_RDI; |
| 81 | regs.rbp = vex->guest_RBP; |
| 82 | regs.rsp = vex->guest_RSP; |
| 83 | regs.r8 = vex->guest_R8; |
| 84 | regs.r9 = vex->guest_R9; |
| 85 | regs.r10 = vex->guest_R10; |
| 86 | regs.r11 = vex->guest_R11; |
| 87 | regs.r12 = vex->guest_R12; |
| 88 | regs.r13 = vex->guest_R13; |
| 89 | regs.r14 = vex->guest_R14; |
| 90 | regs.r15 = vex->guest_R15; |
| 91 | regs.eflags = LibVEX_GuestAMD64_get_rflags(vex); |
| 92 | regs.rip = vex->guest_RIP; |
sewardj | fc9bf72 | 2007-11-19 00:58:18 +0000 | [diff] [blame] | 93 | /* Set %{c,d,e,f,s,g}s and %{fs,gs}_base (whatever those are) to |
| 94 | values which don't fail the kernel's sanity checks. I have no |
| 95 | idea what these should really be set to. Anyway, mostly it |
| 96 | seems that zero is an allowable value, except for %cs and %ss |
| 97 | which have to have their lowest 2 bits be 11. See putreg() in |
| 98 | linux-2.6.23/arch/x86_64/kernel/ptrace.c for the apparently |
| 99 | relevant sanity checks. This fixes #145622. */ |
| 100 | regs.cs = 3; |
| 101 | regs.ds = 0; |
| 102 | regs.es = 0; |
| 103 | regs.fs = 0; |
| 104 | regs.ss = 3; |
| 105 | regs.gs = 0; |
| 106 | regs.fs_base = 0; |
| 107 | regs.gs_base = 0; |
sewardj | 45f4e7c | 2005-09-27 19:20:21 +0000 | [diff] [blame] | 108 | return VG_(ptrace)(VKI_PTRACE_SETREGS, pid, NULL, ®s); |
sewardj | c9e73dc | 2005-11-09 15:14:16 +0000 | [diff] [blame] | 109 | |
sewardj | 957ee5d | 2006-10-17 01:54:20 +0000 | [diff] [blame] | 110 | #elif defined(VGP_ppc32_linux) |
tom | 0109322 | 2005-11-09 08:52:56 +0000 | [diff] [blame] | 111 | Int rc = 0; |
sewardj | c9e73dc | 2005-11-09 15:14:16 +0000 | [diff] [blame] | 112 | /* apparently the casting to void* is the Right Thing To Do */ |
| 113 | rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R0 * 4), (void*)vex->guest_GPR0); |
| 114 | rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R1 * 4), (void*)vex->guest_GPR1); |
| 115 | rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R2 * 4), (void*)vex->guest_GPR2); |
| 116 | rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R3 * 4), (void*)vex->guest_GPR3); |
| 117 | rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R4 * 4), (void*)vex->guest_GPR4); |
| 118 | rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R5 * 4), (void*)vex->guest_GPR5); |
| 119 | rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R6 * 4), (void*)vex->guest_GPR6); |
| 120 | rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R7 * 4), (void*)vex->guest_GPR7); |
| 121 | rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R8 * 4), (void*)vex->guest_GPR8); |
| 122 | rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R9 * 4), (void*)vex->guest_GPR9); |
| 123 | rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R10 * 4), (void*)vex->guest_GPR10); |
| 124 | rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R11 * 4), (void*)vex->guest_GPR11); |
| 125 | rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R12 * 4), (void*)vex->guest_GPR12); |
| 126 | rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R13 * 4), (void*)vex->guest_GPR13); |
| 127 | rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R14 * 4), (void*)vex->guest_GPR14); |
| 128 | rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R15 * 4), (void*)vex->guest_GPR15); |
| 129 | rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R16 * 4), (void*)vex->guest_GPR16); |
| 130 | rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R17 * 4), (void*)vex->guest_GPR17); |
| 131 | rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R18 * 4), (void*)vex->guest_GPR18); |
| 132 | rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R19 * 4), (void*)vex->guest_GPR19); |
| 133 | rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R20 * 4), (void*)vex->guest_GPR20); |
| 134 | rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R21 * 4), (void*)vex->guest_GPR21); |
| 135 | rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R22 * 4), (void*)vex->guest_GPR22); |
| 136 | rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R23 * 4), (void*)vex->guest_GPR23); |
| 137 | rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R24 * 4), (void*)vex->guest_GPR24); |
| 138 | rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R25 * 4), (void*)vex->guest_GPR25); |
| 139 | rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R26 * 4), (void*)vex->guest_GPR26); |
| 140 | rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R27 * 4), (void*)vex->guest_GPR27); |
| 141 | rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R28 * 4), (void*)vex->guest_GPR28); |
| 142 | rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R29 * 4), (void*)vex->guest_GPR29); |
| 143 | rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R30 * 4), (void*)vex->guest_GPR30); |
| 144 | rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R31 * 4), (void*)vex->guest_GPR31); |
| 145 | rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_NIP * 4), (void*)vex->guest_CIA); |
| 146 | rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_CCR * 4), |
| 147 | (void*)LibVEX_GuestPPC32_get_CR(vex)); |
| 148 | rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_LNK * 4), (void*)vex->guest_LR); |
| 149 | rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_CTR * 4), (void*)vex->guest_CTR); |
| 150 | rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_XER * 4), |
| 151 | (void*)LibVEX_GuestPPC32_get_XER(vex)); |
tom | 0109322 | 2005-11-09 08:52:56 +0000 | [diff] [blame] | 152 | return rc; |
sewardj | c9e73dc | 2005-11-09 15:14:16 +0000 | [diff] [blame] | 153 | |
sewardj | 957ee5d | 2006-10-17 01:54:20 +0000 | [diff] [blame] | 154 | #elif defined(VGP_ppc64_linux) |
sewardj | 62c9aa7 | 2007-11-19 02:29:07 +0000 | [diff] [blame] | 155 | Int rc = 0; |
| 156 | /* FRJ: copied nearly verbatim from the ppc32 case. I compared the |
| 157 | vki-ppc64-linux.h with its ppc32 counterpart and saw no |
| 158 | appreciable differences, other than the registers being 8 bytes |
| 159 | instead of 4. No idea why we don't set all of the entries |
| 160 | declared in vki_pt_regs, but ppc32 doesn't so there must be a |
| 161 | reason. |
| 162 | |
| 163 | Finally, note that CR and XER are 32 bits even for ppc64 (see |
| 164 | libvex_guest_ppc64.h), but the vki_pt_regs struct still gives |
| 165 | them 64 bits. |
| 166 | */ |
| 167 | /* apparently the casting to void* is the Right Thing To Do */ |
| 168 | rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R0 * 8), (void*)vex->guest_GPR0); |
| 169 | rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R1 * 8), (void*)vex->guest_GPR1); |
| 170 | rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R2 * 8), (void*)vex->guest_GPR2); |
| 171 | rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R3 * 8), (void*)vex->guest_GPR3); |
| 172 | rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R4 * 8), (void*)vex->guest_GPR4); |
| 173 | rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R5 * 8), (void*)vex->guest_GPR5); |
| 174 | rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R6 * 8), (void*)vex->guest_GPR6); |
| 175 | rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R7 * 8), (void*)vex->guest_GPR7); |
| 176 | rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R8 * 8), (void*)vex->guest_GPR8); |
| 177 | rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R9 * 8), (void*)vex->guest_GPR9); |
| 178 | rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R10 * 8), (void*)vex->guest_GPR10); |
| 179 | rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R11 * 8), (void*)vex->guest_GPR11); |
| 180 | rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R12 * 8), (void*)vex->guest_GPR12); |
| 181 | rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R13 * 8), (void*)vex->guest_GPR13); |
| 182 | rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R14 * 8), (void*)vex->guest_GPR14); |
| 183 | rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R15 * 8), (void*)vex->guest_GPR15); |
| 184 | rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R16 * 8), (void*)vex->guest_GPR16); |
| 185 | rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R17 * 8), (void*)vex->guest_GPR17); |
| 186 | rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R18 * 8), (void*)vex->guest_GPR18); |
| 187 | rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R19 * 8), (void*)vex->guest_GPR19); |
| 188 | rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R20 * 8), (void*)vex->guest_GPR20); |
| 189 | rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R21 * 8), (void*)vex->guest_GPR21); |
| 190 | rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R22 * 8), (void*)vex->guest_GPR22); |
| 191 | rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R23 * 8), (void*)vex->guest_GPR23); |
| 192 | rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R24 * 8), (void*)vex->guest_GPR24); |
| 193 | rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R25 * 8), (void*)vex->guest_GPR25); |
| 194 | rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R26 * 8), (void*)vex->guest_GPR26); |
| 195 | rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R27 * 8), (void*)vex->guest_GPR27); |
| 196 | rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R28 * 8), (void*)vex->guest_GPR28); |
| 197 | rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R29 * 8), (void*)vex->guest_GPR29); |
| 198 | rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R30 * 8), (void*)vex->guest_GPR30); |
| 199 | rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R31 * 8), (void*)vex->guest_GPR31); |
| 200 | rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_NIP * 8), (void*)vex->guest_CIA); |
| 201 | rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_CCR * 8), |
| 202 | (void*)(long)LibVEX_GuestPPC64_get_CR(vex)); |
| 203 | rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_LNK * 8), (void*)vex->guest_LR); |
| 204 | rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_CTR * 8), (void*)vex->guest_CTR); |
| 205 | rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_XER * 8), |
| 206 | (void*)(long)LibVEX_GuestPPC64_get_XER(vex)); |
| 207 | return rc; |
sewardj | 957ee5d | 2006-10-17 01:54:20 +0000 | [diff] [blame] | 208 | |
sewardj | 59570ff | 2010-01-01 11:59:33 +0000 | [diff] [blame] | 209 | #elif defined(VGP_arm_linux) |
| 210 | struct vki_user_regs_struct uregs; |
| 211 | VG_(memset)(&uregs, 0, sizeof(uregs)); |
| 212 | uregs.ARM_r0 = vex->guest_R0; |
| 213 | uregs.ARM_r1 = vex->guest_R1; |
| 214 | uregs.ARM_r2 = vex->guest_R2; |
| 215 | uregs.ARM_r3 = vex->guest_R3; |
| 216 | uregs.ARM_r4 = vex->guest_R4; |
| 217 | uregs.ARM_r5 = vex->guest_R5; |
| 218 | uregs.ARM_r6 = vex->guest_R6; |
| 219 | uregs.ARM_r7 = vex->guest_R7; |
| 220 | uregs.ARM_r8 = vex->guest_R8; |
| 221 | uregs.ARM_r9 = vex->guest_R9; |
| 222 | uregs.ARM_r10 = vex->guest_R10; |
| 223 | uregs.ARM_fp = vex->guest_R11; |
| 224 | uregs.ARM_ip = vex->guest_R12; |
| 225 | uregs.ARM_sp = vex->guest_R13; |
| 226 | uregs.ARM_lr = vex->guest_R14; |
sewardj | 234bd48 | 2010-09-23 11:02:48 +0000 | [diff] [blame] | 227 | // Remove the T bit from the bottom of R15T. It will get shipped |
| 228 | // over in CPSR.T instead, since LibVEX_GuestARM_get_cpsr copies |
| 229 | // it from R15T[0]. |
| 230 | uregs.ARM_pc = vex->guest_R15T & 0xFFFFFFFE; |
sewardj | 59570ff | 2010-01-01 11:59:33 +0000 | [diff] [blame] | 231 | uregs.ARM_cpsr = LibVEX_GuestARM_get_cpsr(vex); |
| 232 | return VG_(ptrace)(VKI_PTRACE_SETREGS, pid, NULL, &uregs); |
| 233 | |
njn | f76d27a | 2009-05-28 01:53:07 +0000 | [diff] [blame] | 234 | #elif defined(VGP_x86_darwin) |
| 235 | I_die_here; |
| 236 | |
| 237 | #elif defined(VGP_amd64_darwin) |
| 238 | I_die_here; |
| 239 | |
sewardj | b5b8740 | 2011-03-07 16:05:35 +0000 | [diff] [blame] | 240 | #elif defined(VGP_s390x_linux) |
| 241 | struct vki_user_regs_struct regs; |
| 242 | vki_ptrace_area pa; |
| 243 | |
| 244 | /* We don't set the psw mask and start at offset 8 */ |
| 245 | pa.vki_len = (unsigned long) ®s.per_info - (unsigned long) ®s.psw.addr; |
| 246 | pa.vki_process_addr = (unsigned long) ®s.psw.addr; |
| 247 | pa.vki_kernel_addr = 8; |
| 248 | |
| 249 | VG_(memset)(®s, 0, sizeof(regs)); |
| 250 | regs.psw.addr = vex->guest_IA; |
| 251 | |
| 252 | /* We don't set the mask */ |
| 253 | regs.gprs[0] = vex->guest_r0; |
| 254 | regs.gprs[1] = vex->guest_r1; |
| 255 | regs.gprs[2] = vex->guest_r2; |
| 256 | regs.gprs[3] = vex->guest_r3; |
| 257 | regs.gprs[4] = vex->guest_r4; |
| 258 | regs.gprs[5] = vex->guest_r5; |
| 259 | regs.gprs[6] = vex->guest_r6; |
| 260 | regs.gprs[7] = vex->guest_r7; |
| 261 | regs.gprs[8] = vex->guest_r8; |
| 262 | regs.gprs[9] = vex->guest_r9; |
| 263 | regs.gprs[10] = vex->guest_r10; |
| 264 | regs.gprs[11] = vex->guest_r11; |
| 265 | regs.gprs[12] = vex->guest_r12; |
| 266 | regs.gprs[13] = vex->guest_r13; |
| 267 | regs.gprs[14] = vex->guest_r14; |
| 268 | regs.gprs[15] = vex->guest_r15; |
| 269 | |
| 270 | regs.acrs[0] = vex->guest_a0; |
| 271 | regs.acrs[1] = vex->guest_a1; |
| 272 | regs.acrs[2] = vex->guest_a2; |
| 273 | regs.acrs[3] = vex->guest_a3; |
| 274 | regs.acrs[4] = vex->guest_a4; |
| 275 | regs.acrs[5] = vex->guest_a5; |
| 276 | regs.acrs[6] = vex->guest_a6; |
| 277 | regs.acrs[7] = vex->guest_a7; |
| 278 | regs.acrs[8] = vex->guest_a8; |
| 279 | regs.acrs[9] = vex->guest_a9; |
| 280 | regs.acrs[10] = vex->guest_a10; |
| 281 | regs.acrs[11] = vex->guest_a11; |
| 282 | regs.acrs[12] = vex->guest_a12; |
| 283 | regs.acrs[13] = vex->guest_a13; |
| 284 | regs.acrs[14] = vex->guest_a14; |
| 285 | regs.acrs[15] = vex->guest_a15; |
| 286 | |
| 287 | /* only used for system call restart and friends, just use r2 */ |
| 288 | regs.orig_gpr2 = vex->guest_r2; |
| 289 | |
| 290 | regs.fp_regs.fprs[0].ui = vex->guest_f0; |
| 291 | regs.fp_regs.fprs[1].ui = vex->guest_f1; |
| 292 | regs.fp_regs.fprs[2].ui = vex->guest_f2; |
| 293 | regs.fp_regs.fprs[3].ui = vex->guest_f3; |
| 294 | regs.fp_regs.fprs[4].ui = vex->guest_f4; |
| 295 | regs.fp_regs.fprs[5].ui = vex->guest_f5; |
| 296 | regs.fp_regs.fprs[6].ui = vex->guest_f6; |
| 297 | regs.fp_regs.fprs[7].ui = vex->guest_f7; |
| 298 | regs.fp_regs.fprs[8].ui = vex->guest_f8; |
| 299 | regs.fp_regs.fprs[9].ui = vex->guest_f9; |
| 300 | regs.fp_regs.fprs[10].ui = vex->guest_f10; |
| 301 | regs.fp_regs.fprs[11].ui = vex->guest_f11; |
| 302 | regs.fp_regs.fprs[12].ui = vex->guest_f12; |
| 303 | regs.fp_regs.fprs[13].ui = vex->guest_f13; |
| 304 | regs.fp_regs.fprs[14].ui = vex->guest_f14; |
| 305 | regs.fp_regs.fprs[15].ui = vex->guest_f15; |
| 306 | regs.fp_regs.fpc = vex->guest_fpc; |
| 307 | |
| 308 | return VG_(ptrace)(VKI_PTRACE_POKEUSR_AREA, pid, &pa, NULL); |
| 309 | |
sewardj | 5db1540 | 2012-06-07 09:13:21 +0000 | [diff] [blame] | 310 | #elif defined(VGP_mips32_linux) |
| 311 | struct vki_user_regs_struct regs; |
| 312 | VG_(memset)(®s, 0, sizeof(regs)); |
| 313 | regs.MIPS_r0 = vex->guest_r0; |
| 314 | regs.MIPS_r1 = vex->guest_r1; |
| 315 | regs.MIPS_r2 = vex->guest_r2; |
| 316 | regs.MIPS_r3 = vex->guest_r3; |
| 317 | regs.MIPS_r4 = vex->guest_r4; |
| 318 | regs.MIPS_r5 = vex->guest_r5; |
| 319 | regs.MIPS_r6 = vex->guest_r6; |
| 320 | regs.MIPS_r7 = vex->guest_r7; |
| 321 | regs.MIPS_r8 = vex->guest_r8; |
| 322 | regs.MIPS_r9 = vex->guest_r9; |
| 323 | regs.MIPS_r10 = vex->guest_r10; |
| 324 | regs.MIPS_r11 = vex->guest_r11; |
| 325 | regs.MIPS_r12 = vex->guest_r12; |
| 326 | regs.MIPS_r13 = vex->guest_r13; |
| 327 | regs.MIPS_r14 = vex->guest_r14; |
| 328 | regs.MIPS_r15 = vex->guest_r15; |
| 329 | regs.MIPS_r16 = vex->guest_r16; |
| 330 | regs.MIPS_r17 = vex->guest_r17; |
| 331 | regs.MIPS_r18 = vex->guest_r18; |
| 332 | regs.MIPS_r19 = vex->guest_r19; |
| 333 | regs.MIPS_r20 = vex->guest_r20; |
| 334 | regs.MIPS_r21 = vex->guest_r21; |
| 335 | regs.MIPS_r22 = vex->guest_r22; |
| 336 | regs.MIPS_r23 = vex->guest_r23; |
| 337 | regs.MIPS_r24 = vex->guest_r24; |
| 338 | regs.MIPS_r25 = vex->guest_r25; |
| 339 | regs.MIPS_r26 = vex->guest_r26; |
| 340 | regs.MIPS_r27 = vex->guest_r27; |
| 341 | regs.MIPS_r28 = vex->guest_r28; |
| 342 | regs.MIPS_r29 = vex->guest_r29; |
| 343 | regs.MIPS_r30 = vex->guest_r30; |
| 344 | regs.MIPS_r31 = vex->guest_r31; |
| 345 | return VG_(ptrace)(VKI_PTRACE_SETREGS, pid, NULL, ®s); |
| 346 | |
njn | 75b65aa | 2005-06-19 19:25:44 +0000 | [diff] [blame] | 347 | #else |
| 348 | # error Unknown arch |
| 349 | #endif |
| 350 | } |
| 351 | |
| 352 | /* Start debugger and get it to attach to this process. Called if the |
| 353 | user requests this service after an error has been shown, so she can |
| 354 | poke around and look at parameters, memory, etc. You can't |
| 355 | meaningfully get the debugger to continue the program, though; to |
| 356 | continue, quit the debugger. */ |
| 357 | void VG_(start_debugger) ( ThreadId tid ) |
| 358 | { |
sewardj | 7289274 | 2005-12-18 03:22:50 +0000 | [diff] [blame] | 359 | # define N_BUF 4096 |
sewardj | 7d7ddd2 | 2007-11-19 02:01:01 +0000 | [diff] [blame] | 360 | Int pid, rc; |
njn | 75b65aa | 2005-06-19 19:25:44 +0000 | [diff] [blame] | 361 | |
sewardj | 7d7ddd2 | 2007-11-19 02:01:01 +0000 | [diff] [blame] | 362 | pid = VG_(fork)(); |
| 363 | |
| 364 | if (pid == 0) { |
sewardj | 7d7ddd2 | 2007-11-19 02:01:01 +0000 | [diff] [blame] | 365 | /* child */ |
| 366 | rc = VG_(ptrace)(VKI_PTRACE_TRACEME, 0, NULL, NULL); |
| 367 | vg_assert(rc == 0); |
| 368 | rc = VG_(kill)(VG_(getpid)(), VKI_SIGSTOP); |
| 369 | vg_assert(rc == 0); |
njn | 75b65aa | 2005-06-19 19:25:44 +0000 | [diff] [blame] | 370 | |
| 371 | } else if (pid > 0) { |
sewardj | 7d7ddd2 | 2007-11-19 02:01:01 +0000 | [diff] [blame] | 372 | /* parent */ |
njn | 75b65aa | 2005-06-19 19:25:44 +0000 | [diff] [blame] | 373 | Int status; |
| 374 | Int res; |
| 375 | |
| 376 | if ((res = VG_(waitpid)(pid, &status, 0)) == pid && |
sewardj | 45f4e7c | 2005-09-27 19:20:21 +0000 | [diff] [blame] | 377 | WIFSTOPPED(status) && WSTOPSIG(status) == VKI_SIGSTOP && |
njn | 75b65aa | 2005-06-19 19:25:44 +0000 | [diff] [blame] | 378 | ptrace_setregs(pid, &(VG_(threads)[tid].arch.vex)) == 0 && |
sewardj | 45f4e7c | 2005-09-27 19:20:21 +0000 | [diff] [blame] | 379 | VG_(kill)(pid, VKI_SIGSTOP) == 0 && |
| 380 | VG_(ptrace)(VKI_PTRACE_DETACH, pid, NULL, 0) == 0) |
njn | 75b65aa | 2005-06-19 19:25:44 +0000 | [diff] [blame] | 381 | { |
florian | dbb3584 | 2012-10-27 18:39:11 +0000 | [diff] [blame] | 382 | HChar pidbuf[15]; |
| 383 | HChar file[50]; |
| 384 | HChar buf[N_BUF]; |
| 385 | HChar *bufptr; |
florian | 19f91bb | 2012-11-10 22:29:54 +0000 | [diff] [blame] | 386 | const HChar *cmdptr; |
njn | 75b65aa | 2005-06-19 19:25:44 +0000 | [diff] [blame] | 387 | |
| 388 | VG_(sprintf)(pidbuf, "%d", pid); |
sewardj | 45f4e7c | 2005-09-27 19:20:21 +0000 | [diff] [blame] | 389 | VG_(sprintf)(file, "/proc/%d/fd/%d", pid, VG_(cl_exec_fd)); |
njn | 75b65aa | 2005-06-19 19:25:44 +0000 | [diff] [blame] | 390 | |
| 391 | bufptr = buf; |
| 392 | cmdptr = VG_(clo_db_command); |
| 393 | |
| 394 | while (*cmdptr) { |
sewardj | 7289274 | 2005-12-18 03:22:50 +0000 | [diff] [blame] | 395 | /* each iteration can advance bufptr by at most the length |
| 396 | of file[], so the following assertion is generously |
| 397 | over-paranoid. */ |
| 398 | vg_assert(bufptr - buf < N_BUF-15-50-10/*paranoia*/); |
njn | 75b65aa | 2005-06-19 19:25:44 +0000 | [diff] [blame] | 399 | switch (*cmdptr) { |
| 400 | case '%': |
| 401 | switch (*++cmdptr) { |
| 402 | case 'f': |
| 403 | VG_(memcpy)(bufptr, file, VG_(strlen)(file)); |
| 404 | bufptr += VG_(strlen)(file); |
| 405 | cmdptr++; |
| 406 | break; |
sewardj | 7289274 | 2005-12-18 03:22:50 +0000 | [diff] [blame] | 407 | case 'p': |
| 408 | VG_(memcpy)(bufptr, pidbuf, VG_(strlen)(pidbuf)); |
| 409 | bufptr += VG_(strlen)(pidbuf); |
| 410 | cmdptr++; |
| 411 | break; |
| 412 | default: |
| 413 | *bufptr++ = *cmdptr++; |
| 414 | break; |
njn | 75b65aa | 2005-06-19 19:25:44 +0000 | [diff] [blame] | 415 | } |
| 416 | break; |
| 417 | default: |
| 418 | *bufptr++ = *cmdptr++; |
| 419 | break; |
| 420 | } |
sewardj | 7289274 | 2005-12-18 03:22:50 +0000 | [diff] [blame] | 421 | vg_assert(bufptr - buf < N_BUF-15-50-10/*paranoia*/); |
njn | 75b65aa | 2005-06-19 19:25:44 +0000 | [diff] [blame] | 422 | } |
| 423 | |
| 424 | *bufptr++ = '\0'; |
| 425 | |
sewardj | 738856f | 2009-07-15 14:48:32 +0000 | [diff] [blame] | 426 | VG_(message)(Vg_UserMsg, "starting debugger with cmd: %s\n", buf); |
njn | 75b65aa | 2005-06-19 19:25:44 +0000 | [diff] [blame] | 427 | res = VG_(system)(buf); |
| 428 | if (res == 0) { |
sewardj | 738856f | 2009-07-15 14:48:32 +0000 | [diff] [blame] | 429 | VG_(message)(Vg_UserMsg, "\n"); |
njn | 75b65aa | 2005-06-19 19:25:44 +0000 | [diff] [blame] | 430 | VG_(message)(Vg_UserMsg, |
sewardj | 5b9b441 | 2007-11-24 21:24:25 +0000 | [diff] [blame] | 431 | "Debugger has detached. Valgrind regains control." |
sewardj | 738856f | 2009-07-15 14:48:32 +0000 | [diff] [blame] | 432 | " We continue.\n"); |
njn | 75b65aa | 2005-06-19 19:25:44 +0000 | [diff] [blame] | 433 | } else { |
sewardj | 5b9b441 | 2007-11-24 21:24:25 +0000 | [diff] [blame] | 434 | VG_(message)(Vg_UserMsg, |
sewardj | 738856f | 2009-07-15 14:48:32 +0000 | [diff] [blame] | 435 | "Warning: Debugger attach failed! (sys_system)\n"); |
| 436 | VG_(message)(Vg_UserMsg, "\n"); |
njn | 75b65aa | 2005-06-19 19:25:44 +0000 | [diff] [blame] | 437 | } |
sewardj | 5b9b441 | 2007-11-24 21:24:25 +0000 | [diff] [blame] | 438 | } else { |
| 439 | VG_(message)(Vg_UserMsg, |
sewardj | 738856f | 2009-07-15 14:48:32 +0000 | [diff] [blame] | 440 | "Warning: Debugger attach failed! (ptrace problem?)\n"); |
| 441 | VG_(message)(Vg_UserMsg, "\n"); |
njn | 75b65aa | 2005-06-19 19:25:44 +0000 | [diff] [blame] | 442 | } |
| 443 | |
| 444 | VG_(kill)(pid, VKI_SIGKILL); |
| 445 | VG_(waitpid)(pid, &status, 0); |
| 446 | } |
sewardj | 7289274 | 2005-12-18 03:22:50 +0000 | [diff] [blame] | 447 | # undef N_BUF |
njn | 75b65aa | 2005-06-19 19:25:44 +0000 | [diff] [blame] | 448 | } |
| 449 | |
| 450 | |
| 451 | |
| 452 | /*--------------------------------------------------------------------*/ |
| 453 | /*--- end ---*/ |
| 454 | /*--------------------------------------------------------------------*/ |