1 /* Target operations for the remote server for GDB. 2 Copyright (C) 2002, 2004, 2005, 2011 3 Free Software Foundation, Inc. 4 5 Contributed by MontaVista Software. 6 7 This file is part of GDB. 8 It has been modified to integrate it in valgrind 9 10 This program is free software; you can redistribute it and/or modify 11 it under the terms of the GNU General Public License as published by 12 the Free Software Foundation; either version 2 of the License, or 13 (at your option) any later version. 14 15 This program is distributed in the hope that it will be useful, 16 but WITHOUT ANY WARRANTY; without even the implied warranty of 17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 GNU General Public License for more details. 19 20 You should have received a copy of the GNU General Public License 21 along with this program; if not, write to the Free Software 22 Foundation, Inc., 51 Franklin Street, Fifth Floor, 23 Boston, MA 02110-1301, USA. */ 24 25 #include "server.h" 26 27 struct target_ops *the_target; 28 29 void set_desired_inferior (int use_general) 30 { 31 struct thread_info *found; 32 33 if (use_general == 1) { 34 found = (struct thread_info *) find_inferior_id (&all_threads, 35 general_thread); 36 } else { 37 found = NULL; 38 39 /* If we are continuing any (all) thread(s), use step_thread 40 to decide which thread to step and/or send the specified 41 signal to. */ 42 if ((step_thread != 0 && step_thread != -1) 43 && (cont_thread == 0 || cont_thread == -1)) 44 found = (struct thread_info *) find_inferior_id (&all_threads, 45 step_thread); 46 47 if (found == NULL) 48 found = (struct thread_info *) find_inferior_id (&all_threads, 49 cont_thread); 50 } 51 52 if (found == NULL) 53 current_inferior = (struct thread_info *) all_threads.head; 54 else 55 current_inferior = found; 56 { 57 ThreadState *tst = (ThreadState *) inferior_target_data (current_inferior); 58 ThreadId tid = tst->tid; 59 dlog(1, "set_desired_inferior use_general %d found %p tid %d lwpid %d\n", 60 use_general, found, tid, tst->os_state.lwpid); 61 } 62 } 63 64 int read_inferior_memory (CORE_ADDR memaddr, unsigned char *myaddr, int len) 65 { 66 int res; 67 res = (*the_target->read_memory) (memaddr, myaddr, len); 68 return res; 69 } 70 71 int write_inferior_memory (CORE_ADDR memaddr, const unsigned char *myaddr, 72 int len) 73 { 74 /* Lacking cleanups, there is some potential for a memory leak if the 75 write fails and we go through error(). Make sure that no more than 76 one buffer is ever pending by making BUFFER static. */ 77 static unsigned char *buffer = 0; 78 int res; 79 80 if (buffer != NULL) 81 free (buffer); 82 83 buffer = malloc (len); 84 VG_(memcpy) (buffer, myaddr, len); 85 res = (*the_target->write_memory) (memaddr, buffer, len); 86 free (buffer); 87 buffer = NULL; 88 89 return res; 90 } 91 92 void set_target_ops (struct target_ops *target) 93 { 94 the_target = (struct target_ops *) malloc (sizeof (*the_target)); 95 VG_(memcpy) (the_target, target, sizeof (*the_target)); 96 } 97 98 void* VG_(dmemcpy) ( void *d, const void *s, SizeT sz, Bool *mod ) 99 { 100 if (VG_(memcmp) (d, s, sz)) { 101 *mod = True; 102 return VG_(memcpy) (d, s, sz); 103 } else { 104 *mod = False; 105 return d; 106 } 107 } 108 109 void VG_(transfer) (void *valgrind, 110 void *gdbserver, 111 transfer_direction dir, 112 SizeT sz, 113 Bool *mod) 114 { 115 if (dir == valgrind_to_gdbserver) 116 VG_(dmemcpy) (gdbserver, valgrind, sz, mod); 117 else if (dir == gdbserver_to_valgrind) 118 VG_(dmemcpy) (valgrind, gdbserver, sz, mod); 119 else 120 vg_assert (0); 121 } 122