1b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* Target operations for the remote server for GDB. 2b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Copyright (C) 2002, 2004, 2005, 2011 3b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Free Software Foundation, Inc. 4b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 5b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Contributed by MontaVista Software. 6b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 7b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov This file is part of GDB. 8b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov It has been modified to integrate it in valgrind 9b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 10b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov This program is free software; you can redistribute it and/or modify 11b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov it under the terms of the GNU General Public License as published by 12b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov the Free Software Foundation; either version 2 of the License, or 13b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov (at your option) any later version. 14b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 15b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov This program is distributed in the hope that it will be useful, 16b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov but WITHOUT ANY WARRANTY; without even the implied warranty of 17b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov GNU General Public License for more details. 19b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 20b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov You should have received a copy of the GNU General Public License 21b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov along with this program; if not, write to the Free Software 22b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Foundation, Inc., 51 Franklin Street, Fifth Floor, 23b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Boston, MA 02110-1301, USA. */ 24b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 25b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include "server.h" 26663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#include "target.h" 27663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#include "regdef.h" 28663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#include "regcache.h" 29663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#include "valgrind_low.h" 30663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#include "gdb/signals.h" 31663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#include "pub_core_aspacemgr.h" 32436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#include "pub_core_machine.h" 33663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#include "pub_core_threadstate.h" 34663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#include "pub_core_transtab.h" 35663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#include "pub_core_gdbserver.h" 36436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#include "pub_core_debuginfo.h" 37b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 38663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 39663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* the_low_target defines the architecture specific aspects depending 40663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng on the cpu */ 41663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic struct valgrind_target_ops the_low_target; 42663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 43663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic 44663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengchar *image_ptid(unsigned long ptid) 45663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{ 46663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng static char result[100]; 47663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VG_(sprintf) (result, "id %ld", ptid); 48663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return result; 49663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng} 50663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#define get_thread(inf) ((struct thread_info *)(inf)) 51663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic 52663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengvoid remove_thread_if_not_in_vg_threads (struct inferior_list_entry *inf) 53663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{ 54663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng struct thread_info *thread = get_thread (inf); 55663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (!VG_(lwpid_to_vgtid)(thread_to_gdb_id(thread))) { 56663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng dlog(1, "removing gdb ptid %s\n", 57663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng image_ptid(thread_to_gdb_id(thread))); 58663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng remove_thread (thread); 59663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 60663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng} 61663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 62663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* synchronize threads known by valgrind and threads known by gdbserver */ 63663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic 64663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengvoid valgrind_update_threads (int pid) 65663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{ 66663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ThreadId tid; 67663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ThreadState *ts; 68663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng unsigned long ptid; 69663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng struct thread_info *ti; 70663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 71663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* call remove_thread for all gdb threads not in valgrind threads */ 72663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng for_each_inferior (&all_threads, remove_thread_if_not_in_vg_threads); 73663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 74663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* call add_thread for all valgrind threads not known in gdb all_threads */ 75663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng for (tid = 1; tid < VG_N_THREADS; tid++) { 76663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 77663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#define LOCAL_THREAD_TRACE " ti* %p vgtid %d status %s as gdb ptid %s lwpid %d\n", \ 78663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ti, tid, VG_(name_of_ThreadStatus) (ts->status), \ 79663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng image_ptid (ptid), ts->os_state.lwpid 80663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 81663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (VG_(is_valid_tid) (tid)) { 82663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ts = VG_(get_ThreadState) (tid); 83663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ptid = ts->os_state.lwpid; 84663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ti = gdb_id_to_thread (ptid); 85663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (!ti) { 86663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* we do not report the threads which are not yet fully 87663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng initialized otherwise this creates duplicated threads 88663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng in gdb: once with pid xxx lwpid 0, then after that 89663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng with pid xxx lwpid yyy. */ 90663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (ts->status != VgTs_Init) { 91663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng dlog(1, "adding_thread" LOCAL_THREAD_TRACE); 92663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng add_thread (ptid, ts, ptid); 93663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 94663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } else { 95663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng dlog(2, "(known thread)" LOCAL_THREAD_TRACE); 96663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 97663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 98663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#undef LOCAL_THREAD_TRACE 99663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 100663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng} 101663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 102663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic 103663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstruct reg* build_shadow_arch (struct reg *reg_defs, int n) { 104663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng int i, r; 105436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov static const char *postfix[3] = { "", "s1", "s2" }; 106663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng struct reg *new_regs = malloc(3 * n * sizeof(reg_defs[0])); 107663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng int reg_set_len = reg_defs[n-1].offset + reg_defs[n-1].size; 108663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 109663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng for (i = 0; i < 3; i++) { 110663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng for (r = 0; r < n; r++) { 111436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov char *regname = malloc(strlen(reg_defs[r].name) 112436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov + strlen (postfix[i]) + 1); 113436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov strcpy (regname, reg_defs[r].name); 114436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov strcat (regname, postfix[i]); 115436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov new_regs[i*n + r].name = regname; 116663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng new_regs[i*n + r].offset = i*reg_set_len + reg_defs[r].offset; 117663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng new_regs[i*n + r].size = reg_defs[r].size; 118663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng dlog(1, 119663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "%10s Nr %d offset(bit) %d offset(byte) %d size(bit) %d\n", 120663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng new_regs[i*n + r].name, i*n + r, new_regs[i*n + r].offset, 121663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng (new_regs[i*n + r].offset) / 8, new_regs[i*n + r].size); 122663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 123663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 124663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 125663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return new_regs; 126663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng} 127663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 128663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 129663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic CORE_ADDR stopped_data_address = 0; 130663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengvoid VG_(set_watchpoint_stop_address) (Addr addr) 131663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{ 132663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng stopped_data_address = addr; 133663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng} 134663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 135663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengint valgrind_stopped_by_watchpoint (void) 136663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{ 137663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return stopped_data_address != 0; 138663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng} 139663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 140663860b1408516d02ebfcb3a9999a134e6cfb223Ben ChengCORE_ADDR valgrind_stopped_data_address (void) 141663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{ 142663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return stopped_data_address; 143663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng} 144663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 145663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* pc at which we last stopped */ 146663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic CORE_ADDR stop_pc; 147663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 148663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* pc at which we resume. 149663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng If stop_pc != resume_pc, it means 150663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng gdb/gdbserver has changed the pc so as to have either 151663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng a "continue by jumping at that address" 152663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng or a "continue at that address to call some code from gdb". 153663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng*/ 154663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic CORE_ADDR resume_pc; 155663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 156663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic int vki_signal_to_report; 157663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 158663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengvoid gdbserver_signal_encountered (Int vki_sigNo) 159663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{ 160663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vki_signal_to_report = vki_sigNo; 161663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng} 162663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 163663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic int vki_signal_to_deliver; 164663860b1408516d02ebfcb3a9999a134e6cfb223Ben ChengBool gdbserver_deliver_signal (Int vki_sigNo) 165663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{ 166663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return vki_sigNo == vki_signal_to_deliver; 167663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng} 168663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 169436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovstatic unsigned char exit_status_to_report; 170436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovstatic int exit_code_to_report; 171436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovvoid gdbserver_process_exit_encountered (unsigned char status, Int code) 172436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov{ 173436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov vg_assert (status == 'W' || status == 'X'); 174436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov exit_status_to_report = status; 175436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov exit_code_to_report = code; 176436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov} 177436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 178663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic 179663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengchar* sym (Addr addr) 180663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{ 181663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng static char buf[200]; 182663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VG_(describe_IP) (addr, buf, 200); 183663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return buf; 184663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng} 185663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 186663860b1408516d02ebfcb3a9999a134e6cfb223Ben ChengThreadId vgdb_interrupted_tid = 0; 187663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 188663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* 0 => not single stepping. 189663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1 => single stepping asked by gdb 190663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 2 => single stepping asked by valgrind (watchpoint) */ 191663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic int stepping = 0; 192663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 193663860b1408516d02ebfcb3a9999a134e6cfb223Ben ChengAddr valgrind_get_ignore_break_once(void) 194663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{ 195663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (valgrind_single_stepping()) 196663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return resume_pc; 197663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng else 198663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return 0; 199663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng} 200663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 201663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengvoid valgrind_set_single_stepping(Bool set) 202663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{ 203663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (set) 204663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng stepping = 2; 205663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng else 206663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng stepping = 0; 207663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng} 208663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 209663860b1408516d02ebfcb3a9999a134e6cfb223Ben ChengBool valgrind_single_stepping(void) 210663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{ 211663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (stepping) 212663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return True; 213663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng else 214663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return False; 215663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng} 216663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 217663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengint valgrind_thread_alive (unsigned long tid) 218663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{ 219663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng struct thread_info *ti = gdb_id_to_thread(tid); 220663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ThreadState *tst; 221663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 222663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (ti != NULL) { 223663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng tst = (ThreadState *) inferior_target_data (ti); 224663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return tst->status != VgTs_Zombie; 225663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 226663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng else { 227663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return 0; 228663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 229663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng} 230663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 231663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengvoid valgrind_resume (struct thread_resume *resume_info) 232663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{ 233663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng dlog(1, 234663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "resume_info step %d sig %d stepping %d\n", 235663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng resume_info->step, 236663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng resume_info->sig, 237663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng stepping); 238663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (valgrind_stopped_by_watchpoint()) { 239663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng dlog(1, "clearing watchpoint stopped_data_address %p\n", 240663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng C2v(stopped_data_address)); 241663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VG_(set_watchpoint_stop_address) ((Addr) 0); 242663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 243663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vki_signal_to_deliver = resume_info->sig; 244663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 245663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng stepping = resume_info->step; 246663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng resume_pc = (*the_low_target.get_pc) (); 247663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (resume_pc != stop_pc) { 248663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng dlog(1, 249663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "stop_pc %p changed to be resume_pc %s\n", 250663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng C2v(stop_pc), sym(resume_pc)); 251663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 252663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng regcache_invalidate(); 253663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng} 254663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 255663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengunsigned char valgrind_wait (char *ourstatus) 256663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{ 257663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng int pid; 258663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng unsigned long wptid; 259663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ThreadState *tst; 260663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng enum target_signal sig; 261436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov int code; 262663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 263663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng pid = VG_(getpid) (); 264663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng dlog(1, "enter valgrind_wait pid %d\n", pid); 265663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 266663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng regcache_invalidate(); 267663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng valgrind_update_threads(pid); 268663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 269436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* First see if we are done with this process. */ 270436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (exit_status_to_report != 0) { 271436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov *ourstatus = exit_status_to_report; 272436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov exit_status_to_report = 0; 273436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 274436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (*ourstatus == 'W') { 275436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov code = exit_code_to_report; 276436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov exit_code_to_report = 0; 277436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov dlog(1, "exit valgrind_wait status W exit code %d\n", code); 278436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return code; 279436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 280436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 281436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (*ourstatus == 'X') { 282436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov sig = target_signal_from_host(exit_code_to_report); 283436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov exit_code_to_report = 0; 284436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov dlog(1, "exit valgrind_wait status X signal %d\n", sig); 285436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return sig; 286436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 287436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 288436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 289663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* in valgrind, we consider that a wait always succeeds with STOPPED 'T' 290663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng and with a signal TRAP (i.e. a breakpoint), unless there is 291663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng a signal to report. */ 292663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng *ourstatus = 'T'; 293663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (vki_signal_to_report == 0) 294663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng sig = TARGET_SIGNAL_TRAP; 295663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng else { 296663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng sig = target_signal_from_host(vki_signal_to_report); 297663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vki_signal_to_report = 0; 298663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 299663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 300663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (vgdb_interrupted_tid != 0) 301663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng tst = VG_(get_ThreadState) (vgdb_interrupted_tid); 302663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng else 303663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng tst = VG_(get_ThreadState) (VG_(running_tid)); 304663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng wptid = tst->os_state.lwpid; 305663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* we can only change the current_inferior when the wptid references 306663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng an existing thread. Otherwise, we are still in the init phase. 307663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng (hack similar to main thread hack in valgrind_update_threads) */ 308663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (tst->os_state.lwpid) 309663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng current_inferior = gdb_id_to_thread (wptid); 310663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng stop_pc = (*the_low_target.get_pc) (); 311663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 312663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng dlog(1, 313436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov "exit valgrind_wait status T ptid %s stop_pc %s signal %d\n", 314663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng image_ptid (wptid), sym (stop_pc), sig); 315663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return sig; 316663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng} 317663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 318663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* Fetch one register from valgrind VEX guest state. */ 319663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic 320663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengvoid fetch_register (int regno) 321663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{ 322663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng int size; 323663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ThreadState *tst = (ThreadState *) inferior_target_data (current_inferior); 324663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ThreadId tid = tst->tid; 325663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 326663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (regno >= the_low_target.num_regs) { 327663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng dlog(0, "error fetch_register regno %d max %d\n", 328663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng regno, the_low_target.num_regs); 329663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return; 330663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 331663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng size = register_size (regno); 332663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (size > 0) { 333663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Bool mod; 334663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng char buf [size]; 335663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VG_(memset) (buf, 0, size); // registers not fetched will be seen as 0. 336663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng (*the_low_target.transfer_register) (tid, regno, buf, 337663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng valgrind_to_gdbserver, size, &mod); 338663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng // Note: the *mod received from transfer_register is not interesting. 339663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng // We are interested to see if the register data in the register cache is modified. 340663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng supply_register (regno, buf, &mod); 341663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (mod && VG_(debugLog_getLevel)() > 1) { 342663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng char bufimage [2*size + 1]; 343663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng heximage (bufimage, buf, size); 344663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng dlog(2, "fetched register %d size %d name %s value %s tid %d status %s\n", 345663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng regno, size, the_low_target.reg_defs[regno].name, bufimage, 346663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng tid, VG_(name_of_ThreadStatus) (tst->status)); 347663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 348663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 349663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng} 350663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 351663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* Fetch all registers, or just one, from the child process. */ 352663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic 353663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengvoid usr_fetch_inferior_registers (int regno) 354663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{ 355663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (regno == -1 || regno == 0) 356663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng for (regno = 0; regno < the_low_target.num_regs; regno++) 357663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng fetch_register (regno); 358663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng else 359663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng fetch_register (regno); 360663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng} 361663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 362663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* Store our register values back into the inferior. 363663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng If REGNO is -1, do this for all registers. 364663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Otherwise, REGNO specifies which register (so we can save time). */ 365663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic 366663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengvoid usr_store_inferior_registers (int regno) 367663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{ 368663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng int size; 369663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ThreadState *tst = (ThreadState *) inferior_target_data (current_inferior); 370663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ThreadId tid = tst->tid; 371663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 372663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (regno >= 0) { 373663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 374663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (regno >= the_low_target.num_regs) { 375663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng dlog(0, "error store_register regno %d max %d\n", 376663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng regno, the_low_target.num_regs); 377663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return; 378663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 379663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 380663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng size = register_size (regno); 381663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (size > 0) { 382663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Bool mod; 383663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Addr old_SP, new_SP; 384663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng char buf[size]; 385663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 386663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (regno == the_low_target.stack_pointer_regno) { 387663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* When the stack pointer register is changed such that 388663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng the stack is extended, we better inform the tool of the 389663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng stack increase. This is needed in particular to avoid 390663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng spurious Memcheck errors during Inferior calls. So, we 391663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng save in old_SP the SP before the change. A change of 392663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng stack pointer is also assumed to have initialised this 393663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng new stack space. For the typical example of an inferior 394663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng call, gdb writes arguments on the stack, and then 395663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng changes the stack pointer. As the stack increase tool 396663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng function might mark it as undefined, we have to call it 397663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng at the good moment. */ 398663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VG_(memset) ((void *) &old_SP, 0, size); 399663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng (*the_low_target.transfer_register) (tid, regno, (void *) &old_SP, 400663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng valgrind_to_gdbserver, size, &mod); 401663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 402663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 403663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VG_(memset) (buf, 0, size); 404663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng collect_register (regno, buf); 405663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng (*the_low_target.transfer_register) (tid, regno, buf, 406663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng gdbserver_to_valgrind, size, &mod); 407663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (mod && VG_(debugLog_getLevel)() > 1) { 408663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng char bufimage [2*size + 1]; 409663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng heximage (bufimage, buf, size); 410663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng dlog(2, 411663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "stored register %d size %d name %s value %s " 412663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "tid %d status %s\n", 413663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng regno, size, the_low_target.reg_defs[regno].name, bufimage, 414663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng tid, VG_(name_of_ThreadStatus) (tst->status)); 415663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 416663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (regno == the_low_target.stack_pointer_regno) { 417663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VG_(memcpy) (&new_SP, buf, size); 418663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (old_SP > new_SP) { 419663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Word delta = (Word)new_SP - (Word)old_SP; 420663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng dlog(1, 421663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng " stack increase by stack pointer changed from %p to %p " 422663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "delta %ld\n", 423663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng (void*) old_SP, (void *) new_SP, 424663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng delta); 425663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VG_TRACK( new_mem_stack_w_ECU, new_SP, -delta, 0 ); 426663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VG_TRACK( new_mem_stack, new_SP, -delta ); 427663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VG_TRACK( post_mem_write, Vg_CoreClientReq, tid, 428663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng new_SP, -delta); 429663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 430663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 431663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 432663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 433663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng else { 434663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng for (regno = 0; regno < the_low_target.num_regs; regno++) 435663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng usr_store_inferior_registers (regno); 436663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 437663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng} 438663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 439663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengvoid valgrind_fetch_registers (int regno) 440663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{ 441663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng usr_fetch_inferior_registers (regno); 442663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng} 443663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 444663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengvoid valgrind_store_registers (int regno) 445663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{ 446663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng usr_store_inferior_registers (regno); 447663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng} 448663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 449eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy IvanovBool hostvisibility = False; 450eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov 451663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengint valgrind_read_memory (CORE_ADDR memaddr, unsigned char *myaddr, int len) 452663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{ 453663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng const void *sourceaddr = C2v (memaddr); 454663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng dlog(2, "reading memory %p size %d\n", sourceaddr, len); 455eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov if (VG_(am_is_valid_for_client) ((Addr) sourceaddr, 456eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov len, VKI_PROT_READ) 457eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov || (hostvisibility 458eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov && VG_(am_is_valid_for_valgrind) ((Addr) sourceaddr, 459eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov len, VKI_PROT_READ))) { 460eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov VG_(memcpy) (myaddr, sourceaddr, len); 461eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov return 0; 462eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov } else { 463663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng dlog(1, "error reading memory %p size %d\n", sourceaddr, len); 464663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return -1; 465663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 466663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng} 467663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 468663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengint valgrind_write_memory (CORE_ADDR memaddr, const unsigned char *myaddr, int len) 469663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{ 470eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov Bool is_valid_client_memory; 471663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng void *targetaddr = C2v (memaddr); 472663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng dlog(2, "writing memory %p size %d\n", targetaddr, len); 473eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov is_valid_client_memory 474eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov = VG_(am_is_valid_for_client) ((Addr)targetaddr, len, VKI_PROT_WRITE); 475eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov if (is_valid_client_memory 476eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov || (hostvisibility 477eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov && VG_(am_is_valid_for_valgrind) ((Addr) targetaddr, 478eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov len, VKI_PROT_READ))) { 479eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov if (len > 0) { 480eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov VG_(memcpy) (targetaddr, myaddr, len); 481eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov if (is_valid_client_memory && VG_(tdict).track_post_mem_write) { 482eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov /* Inform the tool of the post memwrite. Note that we do the 483eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov minimum necessary to avoid complains from e.g. 484eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov memcheck. The idea is that the debugger is as least 485eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov intrusive as possible. So, we do not inform of the pre 486eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov mem write (and in any case, this would cause problems with 487eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov memcheck that does not like our CorePart in 488eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov pre_mem_write. */ 489eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov ThreadState *tst = 490eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov (ThreadState *) inferior_target_data (current_inferior); 491eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov ThreadId tid = tst->tid; 492eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov VG_(tdict).track_post_mem_write( Vg_CoreClientReq, tid, 493eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov (Addr) targetaddr, len ); 494eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov } 495eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov } 496eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov return 0; 497eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov } else { 498663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng dlog(1, "error writing memory %p size %d\n", targetaddr, len); 499663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return -1; 500663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 501663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng} 502663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 503663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* insert or remove a breakpoint */ 504663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic 505663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengint valgrind_point (Bool insert, char type, CORE_ADDR addr, int len) 506663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{ 507663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng PointKind kind; 508663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng switch (type) { 509663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case '0': /* implemented by inserting checks at each instruction in sb */ 510663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng kind = software_breakpoint; 511663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 512663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case '1': /* hw breakpoint, same implementation as sw breakpoint */ 513663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng kind = hardware_breakpoint; 514663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 515663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case '2': 516663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng kind = write_watchpoint; 517663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 518663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case '3': 519663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng kind = read_watchpoint; 520663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 521663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case '4': 522663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng kind = access_watchpoint; 523663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 524663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng default: 525663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vg_assert (0); 526663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 527663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 528663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* Attention: gdbserver convention differs: 0 means ok; 1 means not ok */ 529663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (VG_(gdbserver_point) (kind, insert, addr, len)) 530663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return 0; 531663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng else 532663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return 1; /* error or unsupported */ 533663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng} 534663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 535436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovconst char* valgrind_target_xml (Bool shadow_mode) 536663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{ 537663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return (*the_low_target.target_xml) (shadow_mode); 538663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng} 539663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 540663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengint valgrind_insert_watchpoint (char type, CORE_ADDR addr, int len) 541663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{ 542663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return valgrind_point (/* insert */ True, type, addr, len); 543663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng} 544663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 545663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengint valgrind_remove_watchpoint (char type, CORE_ADDR addr, int len) 546663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{ 547663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return valgrind_point (/* insert*/ False, type, addr, len); 548663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng} 549663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 550663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* returns a pointer to the architecture state corresponding to 551663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng the provided register set: 0 => normal guest registers, 552663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1 => shadow1 553663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 2 => shadow2 554663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng*/ 555663860b1408516d02ebfcb3a9999a134e6cfb223Ben ChengVexGuestArchState* get_arch (int set, ThreadState* tst) 556663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{ 557663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng switch (set) { 558663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case 0: return &tst->arch.vex; 559663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case 1: return &tst->arch.vex_shadow1; 560663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case 2: return &tst->arch.vex_shadow2; 561663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng default: vg_assert(0); 562663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 563663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng} 564663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 565663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic int non_shadow_num_regs = 0; 566663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic struct reg *non_shadow_reg_defs = NULL; 567663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengvoid initialize_shadow_low(Bool shadow_mode) 568663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{ 569663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (non_shadow_reg_defs == NULL) { 570663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng non_shadow_reg_defs = the_low_target.reg_defs; 571663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng non_shadow_num_regs = the_low_target.num_regs; 572663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 573663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 574663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng regcache_invalidate(); 575663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (the_low_target.reg_defs != non_shadow_reg_defs) { 576663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng free (the_low_target.reg_defs); 577663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 578663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (shadow_mode) { 579663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng the_low_target.num_regs = 3 * non_shadow_num_regs; 580663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng the_low_target.reg_defs = build_shadow_arch (non_shadow_reg_defs, non_shadow_num_regs); 581663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } else { 582663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng the_low_target.num_regs = non_shadow_num_regs; 583663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng the_low_target.reg_defs = non_shadow_reg_defs; 584663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 585663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng set_register_cache (the_low_target.reg_defs, the_low_target.num_regs); 586663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng} 587b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 588b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovvoid set_desired_inferior (int use_general) 589b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{ 590b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov struct thread_info *found; 591b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 592b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (use_general == 1) { 593b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov found = (struct thread_info *) find_inferior_id (&all_threads, 594b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov general_thread); 595b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } else { 596b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov found = NULL; 597b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 598b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* If we are continuing any (all) thread(s), use step_thread 599b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov to decide which thread to step and/or send the specified 600b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov signal to. */ 601b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if ((step_thread != 0 && step_thread != -1) 602b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov && (cont_thread == 0 || cont_thread == -1)) 603b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov found = (struct thread_info *) find_inferior_id (&all_threads, 604b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov step_thread); 605b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 606b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (found == NULL) 607b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov found = (struct thread_info *) find_inferior_id (&all_threads, 608b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov cont_thread); 609b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 610b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 611b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (found == NULL) 612b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov current_inferior = (struct thread_info *) all_threads.head; 613b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov else 614b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov current_inferior = found; 615b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov { 616b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ThreadState *tst = (ThreadState *) inferior_target_data (current_inferior); 617b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ThreadId tid = tst->tid; 618b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov dlog(1, "set_desired_inferior use_general %d found %p tid %d lwpid %d\n", 619b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov use_general, found, tid, tst->os_state.lwpid); 620b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 621b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 622b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 623b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovvoid* VG_(dmemcpy) ( void *d, const void *s, SizeT sz, Bool *mod ) 624b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{ 625b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (VG_(memcmp) (d, s, sz)) { 626b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov *mod = True; 627b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov return VG_(memcpy) (d, s, sz); 628b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } else { 629b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov *mod = False; 630b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov return d; 631b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 632b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 633b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 634b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovvoid VG_(transfer) (void *valgrind, 635b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov void *gdbserver, 636b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov transfer_direction dir, 637b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov SizeT sz, 638b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Bool *mod) 639b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{ 640b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (dir == valgrind_to_gdbserver) 641b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov VG_(dmemcpy) (gdbserver, valgrind, sz, mod); 642b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov else if (dir == gdbserver_to_valgrind) 643b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov VG_(dmemcpy) (valgrind, gdbserver, sz, mod); 644b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov else 645b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov vg_assert (0); 646b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 647663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 648663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengvoid valgrind_initialize_target(void) 649663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{ 650663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#if defined(VGA_x86) 651663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng x86_init_architecture(&the_low_target); 652663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#elif defined(VGA_amd64) 653663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng amd64_init_architecture(&the_low_target); 654663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#elif defined(VGA_arm) 655663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng arm_init_architecture(&the_low_target); 656436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#elif defined(VGA_arm64) 657436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov arm64_init_architecture(&the_low_target); 658663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#elif defined(VGA_ppc32) 659663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ppc32_init_architecture(&the_low_target); 660663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#elif defined(VGA_ppc64) 661663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ppc64_init_architecture(&the_low_target); 662663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#elif defined(VGA_s390x) 663663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng s390x_init_architecture(&the_low_target); 664663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#elif defined(VGA_mips32) 665663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng mips32_init_architecture(&the_low_target); 666436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#elif defined(VGA_mips64) 667436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov mips64_init_architecture(&the_low_target); 668663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#else 669436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov #error "architecture missing in target.c valgrind_initialize_target" 670663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#endif 671663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng} 672