GDBserver
|
00001 /* Target operations for the remote server for GDB. 00002 Copyright (C) 2002-2013 Free Software Foundation, Inc. 00003 00004 Contributed by MontaVista Software. 00005 00006 This file is part of GDB. 00007 00008 This program is free software; you can redistribute it and/or modify 00009 it under the terms of the GNU General Public License as published by 00010 the Free Software Foundation; either version 3 of the License, or 00011 (at your option) any later version. 00012 00013 This program is distributed in the hope that it will be useful, 00014 but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00016 GNU General Public License for more details. 00017 00018 You should have received a copy of the GNU General Public License 00019 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 00020 00021 #include "server.h" 00022 #include "tracepoint.h" 00023 00024 struct target_ops *the_target; 00025 00026 void 00027 set_desired_inferior (int use_general) 00028 { 00029 struct thread_info *found; 00030 00031 if (use_general == 1) 00032 found = find_thread_ptid (general_thread); 00033 else 00034 found = find_thread_ptid (cont_thread); 00035 00036 if (found == NULL) 00037 current_inferior = (struct thread_info *) all_threads.head; 00038 else 00039 current_inferior = found; 00040 } 00041 00042 int 00043 read_inferior_memory (CORE_ADDR memaddr, unsigned char *myaddr, int len) 00044 { 00045 int res; 00046 res = (*the_target->read_memory) (memaddr, myaddr, len); 00047 check_mem_read (memaddr, myaddr, len); 00048 return res; 00049 } 00050 00051 int 00052 write_inferior_memory (CORE_ADDR memaddr, const unsigned char *myaddr, 00053 int len) 00054 { 00055 /* Lacking cleanups, there is some potential for a memory leak if the 00056 write fails and we go through error(). Make sure that no more than 00057 one buffer is ever pending by making BUFFER static. */ 00058 static unsigned char *buffer = 0; 00059 int res; 00060 00061 if (buffer != NULL) 00062 free (buffer); 00063 00064 buffer = xmalloc (len); 00065 memcpy (buffer, myaddr, len); 00066 check_mem_write (memaddr, buffer, myaddr, len); 00067 res = (*the_target->write_memory) (memaddr, buffer, len); 00068 free (buffer); 00069 buffer = NULL; 00070 00071 return res; 00072 } 00073 00074 ptid_t 00075 mywait (ptid_t ptid, struct target_waitstatus *ourstatus, int options, 00076 int connected_wait) 00077 { 00078 ptid_t ret; 00079 00080 if (connected_wait) 00081 server_waiting = 1; 00082 00083 ret = (*the_target->wait) (ptid, ourstatus, options); 00084 00085 /* If GDB is connected through TCP/serial, then GDBserver will most 00086 probably be running on its own terminal/console, so it's nice to 00087 print there why is GDBserver exiting. If however, GDB is 00088 connected through stdio, then there's no need to spam the GDB 00089 console with this -- the user will already see the exit through 00090 regular GDB output, in that same terminal. */ 00091 if (!remote_connection_is_stdio ()) 00092 { 00093 if (ourstatus->kind == TARGET_WAITKIND_EXITED) 00094 fprintf (stderr, 00095 "\nChild exited with status %d\n", ourstatus->value.integer); 00096 else if (ourstatus->kind == TARGET_WAITKIND_SIGNALLED) 00097 fprintf (stderr, "\nChild terminated with signal = 0x%x (%s)\n", 00098 gdb_signal_to_host (ourstatus->value.sig), 00099 gdb_signal_to_name (ourstatus->value.sig)); 00100 } 00101 00102 if (connected_wait) 00103 server_waiting = 0; 00104 00105 return ret; 00106 } 00107 00108 int 00109 start_non_stop (int nonstop) 00110 { 00111 if (the_target->start_non_stop == NULL) 00112 { 00113 if (nonstop) 00114 return -1; 00115 else 00116 return 0; 00117 } 00118 00119 return (*the_target->start_non_stop) (nonstop); 00120 } 00121 00122 void 00123 set_target_ops (struct target_ops *target) 00124 { 00125 the_target = (struct target_ops *) xmalloc (sizeof (*the_target)); 00126 memcpy (the_target, target, sizeof (*the_target)); 00127 } 00128 00129 /* Convert pid to printable format. */ 00130 00131 const char * 00132 target_pid_to_str (ptid_t ptid) 00133 { 00134 static char buf[80]; 00135 00136 if (ptid_equal (ptid, minus_one_ptid)) 00137 xsnprintf (buf, sizeof (buf), "<all threads>"); 00138 else if (ptid_equal (ptid, null_ptid)) 00139 xsnprintf (buf, sizeof (buf), "<null thread>"); 00140 else if (ptid_get_tid (ptid) != 0) 00141 xsnprintf (buf, sizeof (buf), "Thread %d.0x%lx", 00142 ptid_get_pid (ptid), ptid_get_tid (ptid)); 00143 else if (ptid_get_lwp (ptid) != 0) 00144 xsnprintf (buf, sizeof (buf), "LWP %d.%ld", 00145 ptid_get_pid (ptid), ptid_get_lwp (ptid)); 00146 else 00147 xsnprintf (buf, sizeof (buf), "Process %d", 00148 ptid_get_pid (ptid)); 00149 00150 return buf; 00151 } 00152 00153 int 00154 kill_inferior (int pid) 00155 { 00156 gdb_agent_about_to_close (pid); 00157 00158 return (*the_target->kill) (pid); 00159 }