xref: /openbsd-src/gnu/usr.bin/binutils/gdb/gdbserver/server.c (revision b2ea75c1b17e1a9a339660e7ed45cd24946b230e)
1 /* Main code for remote server for GDB.
2    Copyright (C) 1989, 1993 Free Software Foundation, Inc.
3 
4 This file is part of GDB.
5 
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10 
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 GNU General Public License for more details.
15 
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
19 
20 #include "server.h"
21 
22 int cont_thread;
23 int general_thread;
24 int thread_from_wait;
25 int old_thread_from_wait;
26 int extended_protocol;
27 
28 int
29 main (argc, argv)
30      int argc;
31      char *argv[];
32 {
33   char ch, status, own_buf[2000], mem_buf[2000];
34   int i = 0;
35   unsigned char signal;
36   unsigned int mem_addr, len;
37 
38   if (setjmp(toplevel))
39     {
40       fprintf(stderr, "Exiting\n");
41       exit(1);
42     }
43 
44   if (argc < 3)
45     error("Usage: gdbserver tty prog [args ...]");
46 
47   inferior_pid = create_inferior (argv[2], &argv[2]);
48   fprintf (stderr, "Process %s created; pid = %d\n", argv[2], inferior_pid);
49 
50   signal = mywait (&status);	/* Wait till we are at 1st instr in prog */
51 
52   /* We are now stopped at the first instruction of the target process */
53 
54   while (1)
55     {
56       remote_open (argv[1]);
57 
58 restart:
59       setjmp(toplevel);
60       while (getpkt (own_buf) > 0)
61 	{
62 	  unsigned char sig;
63 	  i = 0;
64 	  ch = own_buf[i++];
65 	  switch (ch)
66 	    {
67 	    case '!':
68 	      extended_protocol = 1;
69 	      prepare_resume_reply (own_buf, status, signal);
70 	      break;
71 	    case '?':
72 	      prepare_resume_reply (own_buf, status, signal);
73 	      break;
74 	    case 'H':
75 	      switch (own_buf[1])
76 		{
77 		case 'g':
78 		  general_thread = strtol (&own_buf[2], NULL, 16);
79 		  write_ok (own_buf);
80 		  fetch_inferior_registers (0);
81 		  break;
82 		case 'c':
83 		  cont_thread = strtol (&own_buf[2], NULL, 16);
84 		  write_ok (own_buf);
85 		  break;
86 		default:
87 		  /* Silently ignore it so that gdb can extend the protocol
88 		     without compatibility headaches.  */
89 		  own_buf[0] = '\0';
90 		  break;
91 		}
92 	      break;
93 	    case 'g':
94 	      convert_int_to_ascii (registers, own_buf, REGISTER_BYTES);
95 	      break;
96 	    case 'G':
97 	      convert_ascii_to_int (&own_buf[1], registers, REGISTER_BYTES);
98 	      store_inferior_registers (-1);
99 	      write_ok (own_buf);
100 	      break;
101 	    case 'm':
102 	      decode_m_packet (&own_buf[1], &mem_addr, &len);
103 	      read_inferior_memory (mem_addr, mem_buf, len);
104 	      convert_int_to_ascii (mem_buf, own_buf, len);
105 	      break;
106 	    case 'M':
107 	      decode_M_packet (&own_buf[1], &mem_addr, &len, mem_buf);
108 	      if (write_inferior_memory (mem_addr, mem_buf, len) == 0)
109 		write_ok (own_buf);
110 	      else
111 		write_enn (own_buf);
112 	      break;
113 	    case 'C':
114 	      convert_ascii_to_int (own_buf + 1, &sig, 1);
115 	      myresume (0, sig);
116 	      signal = mywait (&status);
117 	      prepare_resume_reply (own_buf, status, signal);
118 	      break;
119 	    case 'S':
120 	      convert_ascii_to_int (own_buf + 1, &sig, 1);
121 	      myresume (1, sig);
122 	      signal = mywait (&status);
123 	      prepare_resume_reply (own_buf, status, signal);
124 	      break;
125 	    case 'c':
126 	      myresume (0, 0);
127 	      signal = mywait (&status);
128 	      prepare_resume_reply (own_buf, status, signal);
129 	      break;
130 	    case 's':
131 	      myresume (1, 0);
132 	      signal = mywait (&status);
133 	      prepare_resume_reply (own_buf, status, signal);
134 	      break;
135 	    case 'k':
136 	      fprintf (stderr, "Killing inferior\n");
137 	      kill_inferior ();
138 	      /* When using the extended protocol, we start up a new
139 		 debugging session.   The traditional protocol will
140 	         exit instead.  */
141 	      if (extended_protocol)
142 		{
143 		  write_ok (own_buf);
144 		  fprintf (stderr, "GDBserver restarting\n");
145 		  inferior_pid = create_inferior (argv[2], &argv[2]);
146 		  fprintf (stderr, "Process %s created; pid = %d\n",
147 			   argv[2], inferior_pid);
148 
149 		  /* Wait till we are at 1st instruction in prog.  */
150 		  signal = mywait (&status);
151 		  goto restart;
152 		  break;
153 		}
154 	      else
155 		{
156 		  exit (0);
157 		  break;
158 		}
159 	    case 'T':
160 	      if (mythread_alive (strtol (&own_buf[1], NULL, 16)))
161 		write_ok (own_buf);
162 	      else
163 		write_enn (own_buf);
164 	      break;
165 	    case 'R':
166 	      /* Restarting the inferior is only supported in the
167 		 extended protocol.  */
168 	      if (extended_protocol)
169 		{
170 		  kill_inferior ();
171 		  write_ok (own_buf);
172 		  fprintf (stderr, "GDBserver restarting\n");
173 		  inferior_pid = create_inferior (argv[2], &argv[2]);
174 		  fprintf (stderr, "Process %s created; pid = %d\n",
175 			   argv[2], inferior_pid);
176 
177 		  /* Wait till we are at 1st instruction in prog.  */
178 		  signal = mywait (&status);
179 		  goto restart;
180 		  break;
181 		}
182 	      else
183 		{
184 		  /* It is a request we don't understand.  Respond with an
185 		     empty packet so that gdb knows that we don't support this
186 		     request.  */
187 		  own_buf[0] = '\0';
188 		  break;
189 		}
190 	    default:
191 	      /* It is a request we don't understand.  Respond with an
192 		 empty packet so that gdb knows that we don't support this
193 		 request.  */
194 	      own_buf[0] = '\0';
195 	      break;
196 	    }
197 
198 	  putpkt (own_buf);
199 
200 	  if (status == 'W')
201 	    fprintf (stderr,
202 		     "\nChild exited with status %d\n", sig);
203 	  if (status == 'X')
204 	    fprintf (stderr, "\nChild terminated with signal = 0x%x\n", sig);
205 	  if (status == 'W' || status == 'X')
206 	    {
207 	      if (extended_protocol)
208 		{
209 		  fprintf (stderr, "Killing inferior\n");
210 		  kill_inferior ();
211 		  write_ok (own_buf);
212 		  fprintf (stderr, "GDBserver restarting\n");
213 		  inferior_pid = create_inferior (argv[2], &argv[2]);
214 		  fprintf (stderr, "Process %s created; pid = %d\n",
215 			   argv[2], inferior_pid);
216 
217 		  /* Wait till we are at 1st instruction in prog.  */
218 		  signal = mywait (&status);
219 		  goto restart;
220 		  break;
221 		}
222 	      else
223 		{
224 		  fprintf (stderr, "GDBserver exiting\n");
225 		  exit (0);
226 		}
227 	    }
228 	}
229 
230       /* We come here when getpkt fails.
231 
232 	 For the extended remote protocol we exit (and this is the only
233 	 way we gracefully exit!).
234 
235 	 For the traditional remote protocol close the connection,
236 	 and re-open it at the top of the loop.  */
237       if (extended_protocol)
238 	{
239 	  remote_close ();
240 	  exit (0);
241 	}
242       else
243 	{
244 	  fprintf (stderr, "Remote side has terminated connection.  GDBserver will reopen the connection.\n");
245 
246 	  remote_close ();
247 	}
248     }
249 }
250