OpenCores
URL https://opencores.org/ocsvn/openrisc_me/openrisc_me/trunk

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [gdb-6.8/] [gdb/] [gdbserver/] [server.c] - Blame information for rev 178

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 24 jeremybenn
/* Main code for remote server for GDB.
2
   Copyright (C) 1989, 1993, 1994, 1995, 1997, 1998, 1999, 2000, 2002, 2003,
3
   2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
4
 
5
   This file is part of GDB.
6
 
7
   This program is free software; you can redistribute it and/or modify
8
   it under the terms of the GNU General Public License as published by
9
   the Free Software Foundation; either version 3 of the License, or
10
   (at your option) any later version.
11
 
12
   This program is distributed in the hope that it will be useful,
13
   but WITHOUT ANY WARRANTY; without even the implied warranty of
14
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
   GNU General Public License for more details.
16
 
17
   You should have received a copy of the GNU General Public License
18
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
19
 
20
#include "server.h"
21
 
22
#if HAVE_UNISTD_H
23
#include <unistd.h>
24
#endif
25
#if HAVE_SIGNAL_H
26
#include <signal.h>
27
#endif
28
#if HAVE_SYS_WAIT_H
29
#include <sys/wait.h>
30
#endif
31
 
32
unsigned long cont_thread;
33
unsigned long general_thread;
34
unsigned long step_thread;
35
unsigned long thread_from_wait;
36
unsigned long old_thread_from_wait;
37
int server_waiting;
38
 
39
static int extended_protocol;
40
static int attached;
41
static int response_needed;
42
static int exit_requested;
43
 
44
static char **program_argv;
45
 
46
/* Enable miscellaneous debugging output.  The name is historical - it
47
   was originally used to debug LinuxThreads support.  */
48
int debug_threads;
49
 
50
int pass_signals[TARGET_SIGNAL_LAST];
51
 
52
jmp_buf toplevel;
53
 
54
/* The PID of the originally created or attached inferior.  Used to
55
   send signals to the process when GDB sends us an asynchronous interrupt
56
   (user hitting Control-C in the client), and to wait for the child to exit
57
   when no longer debugging it.  */
58
 
59
unsigned long signal_pid;
60
 
61
#ifdef SIGTTOU
62
/* A file descriptor for the controlling terminal.  */
63
int terminal_fd;
64
 
65
/* TERMINAL_FD's original foreground group.  */
66
pid_t old_foreground_pgrp;
67
 
68
/* Hand back terminal ownership to the original foreground group.  */
69
 
70
static void
71
restore_old_foreground_pgrp (void)
72
{
73
  tcsetpgrp (terminal_fd, old_foreground_pgrp);
74
}
75
#endif
76
 
77
static int
78
target_running (void)
79
{
80
  return all_threads.head != NULL;
81
}
82
 
83
static int
84
start_inferior (char *argv[], char *statusptr)
85
{
86
  attached = 0;
87
 
88
#ifdef SIGTTOU
89
  signal (SIGTTOU, SIG_DFL);
90
  signal (SIGTTIN, SIG_DFL);
91
#endif
92
 
93
  signal_pid = create_inferior (argv[0], argv);
94
 
95
  /* FIXME: we don't actually know at this point that the create
96
     actually succeeded.  We won't know that until we wait.  */
97
  fprintf (stderr, "Process %s created; pid = %ld\n", argv[0],
98
           signal_pid);
99
  fflush (stderr);
100
 
101
#ifdef SIGTTOU
102
  signal (SIGTTOU, SIG_IGN);
103
  signal (SIGTTIN, SIG_IGN);
104
  terminal_fd = fileno (stderr);
105
  old_foreground_pgrp = tcgetpgrp (terminal_fd);
106
  tcsetpgrp (terminal_fd, signal_pid);
107
  atexit (restore_old_foreground_pgrp);
108
#endif
109
 
110
  /* Wait till we are at 1st instruction in program, return signal
111
     number (assuming success).  */
112
  return mywait (statusptr, 0);
113
}
114
 
115
static int
116
attach_inferior (int pid, char *statusptr, int *sigptr)
117
{
118
  /* myattach should return -1 if attaching is unsupported,
119
 
120
 
121
  if (myattach (pid) != 0)
122
    return -1;
123
 
124
  attached = 1;
125
 
126
  fprintf (stderr, "Attached; pid = %d\n", pid);
127
  fflush (stderr);
128
 
129
  /* FIXME - It may be that we should get the SIGNAL_PID from the
130
     attach function, so that it can be the main thread instead of
131
     whichever we were told to attach to.  */
132
  signal_pid = pid;
133
 
134
  *sigptr = mywait (statusptr, 0);
135
 
136
  /* GDB knows to ignore the first SIGSTOP after attaching to a running
137
     process using the "attach" command, but this is different; it's
138
     just using "target remote".  Pretend it's just starting up.  */
139
  if (*statusptr == 'T' && *sigptr == TARGET_SIGNAL_STOP)
140
    *sigptr = TARGET_SIGNAL_TRAP;
141
 
142
  return 0;
143
}
144
 
145
extern int remote_debug;
146
 
147
/* Decode a qXfer read request.  Return 0 if everything looks OK,
148
   or -1 otherwise.  */
149
 
150
static int
151
decode_xfer_read (char *buf, char **annex, CORE_ADDR *ofs, unsigned int *len)
152
{
153
  /* Extract and NUL-terminate the annex.  */
154
  *annex = buf;
155
  while (*buf && *buf != ':')
156
    buf++;
157
  if (*buf == '\0')
158
    return -1;
159
  *buf++ = 0;
160
 
161
  /* After the read marker and annex, qXfer looks like a
162
     traditional 'm' packet.  */
163
  decode_m_packet (buf, ofs, len);
164
 
165
  return 0;
166
}
167
 
168
/* Write the response to a successful qXfer read.  Returns the
169
   length of the (binary) data stored in BUF, corresponding
170
   to as much of DATA/LEN as we could fit.  IS_MORE controls
171
   the first character of the response.  */
172
static int
173
write_qxfer_response (char *buf, const void *data, int len, int is_more)
174
{
175
  int out_len;
176
 
177
  if (is_more)
178
    buf[0] = 'm';
179
  else
180
    buf[0] = 'l';
181
 
182
  return remote_escape_output (data, len, (unsigned char *) buf + 1, &out_len,
183
                               PBUFSIZ - 2) + 1;
184
}
185
 
186
/* Handle all of the extended 'Q' packets.  */
187
void
188
handle_general_set (char *own_buf)
189
{
190
  if (strncmp ("QPassSignals:", own_buf, strlen ("QPassSignals:")) == 0)
191
    {
192
      int numsigs = (int) TARGET_SIGNAL_LAST, i;
193
      const char *p = own_buf + strlen ("QPassSignals:");
194
      CORE_ADDR cursig;
195
 
196
      p = decode_address_to_semicolon (&cursig, p);
197
      for (i = 0; i < numsigs; i++)
198
        {
199
          if (i == cursig)
200
            {
201
              pass_signals[i] = 1;
202
              if (*p == '\0')
203
                /* Keep looping, to clear the remaining signals.  */
204
                cursig = -1;
205
              else
206
                p = decode_address_to_semicolon (&cursig, p);
207
            }
208
          else
209
            pass_signals[i] = 0;
210
        }
211
      strcpy (own_buf, "OK");
212
      return;
213
    }
214
 
215
  /* Otherwise we didn't know what packet it was.  Say we didn't
216
     understand it.  */
217
  own_buf[0] = 0;
218
}
219
 
220
static const char *
221
get_features_xml (const char *annex)
222
{
223
  static int features_supported = -1;
224
  static char *document;
225
 
226
#ifdef USE_XML
227
  extern const char *const xml_builtin[][2];
228
  int i;
229
 
230
  /* Look for the annex.  */
231
  for (i = 0; xml_builtin[i][0] != NULL; i++)
232
    if (strcmp (annex, xml_builtin[i][0]) == 0)
233
      break;
234
 
235
  if (xml_builtin[i][0] != NULL)
236
    return xml_builtin[i][1];
237
#endif
238
 
239
  if (strcmp (annex, "target.xml") != 0)
240
    return NULL;
241
 
242
  if (features_supported == -1)
243
    {
244
      const char *arch = NULL;
245
      if (the_target->arch_string != NULL)
246
        arch = (*the_target->arch_string) ();
247
 
248
      if (arch == NULL)
249
        features_supported = 0;
250
      else
251
        {
252
          features_supported = 1;
253
          document = malloc (64 + strlen (arch));
254
          snprintf (document, 64 + strlen (arch),
255
                    "<target><architecture>%s</architecture></target>",
256
                    arch);
257
        }
258
    }
259
 
260
  return document;
261
}
262
 
263
void
264
monitor_show_help (void)
265
{
266
  monitor_output ("The following monitor commands are supported:\n");
267
  monitor_output ("  set debug <0|1>\n");
268
  monitor_output ("    Enable general debugging messages\n");
269
  monitor_output ("  set remote-debug <0|1>\n");
270
  monitor_output ("    Enable remote protocol debugging messages\n");
271
  monitor_output ("  exit\n");
272
  monitor_output ("    Quit GDBserver\n");
273
}
274
 
275
#define require_running(BUF)                    \
276
  if (!target_running ())                       \
277
    {                                           \
278
      write_enn (BUF);                          \
279
      return;                                   \
280
    }
281
 
282
/* Handle all of the extended 'q' packets.  */
283
void
284
handle_query (char *own_buf, int packet_len, int *new_packet_len_p)
285
{
286
  static struct inferior_list_entry *thread_ptr;
287
 
288
  /* Reply the current thread id.  */
289
  if (strcmp ("qC", own_buf) == 0)
290
    {
291
      require_running (own_buf);
292
      thread_ptr = all_threads.head;
293
      sprintf (own_buf, "QC%x",
294
        thread_to_gdb_id ((struct thread_info *)thread_ptr));
295
      return;
296
    }
297
 
298
  if (strcmp ("qSymbol::", own_buf) == 0)
299
    {
300
      if (target_running () && the_target->look_up_symbols != NULL)
301
        (*the_target->look_up_symbols) ();
302
 
303
      strcpy (own_buf, "OK");
304
      return;
305
    }
306
 
307
  if (strcmp ("qfThreadInfo", own_buf) == 0)
308
    {
309
      require_running (own_buf);
310
      thread_ptr = all_threads.head;
311
      sprintf (own_buf, "m%x", thread_to_gdb_id ((struct thread_info *)thread_ptr));
312
      thread_ptr = thread_ptr->next;
313
      return;
314
    }
315
 
316
  if (strcmp ("qsThreadInfo", own_buf) == 0)
317
    {
318
      require_running (own_buf);
319
      if (thread_ptr != NULL)
320
        {
321
          sprintf (own_buf, "m%x", thread_to_gdb_id ((struct thread_info *)thread_ptr));
322
          thread_ptr = thread_ptr->next;
323
          return;
324
        }
325
      else
326
        {
327
          sprintf (own_buf, "l");
328
          return;
329
        }
330
    }
331
 
332
  if (the_target->read_offsets != NULL
333
      && strcmp ("qOffsets", own_buf) == 0)
334
    {
335
      CORE_ADDR text, data;
336
 
337
      require_running (own_buf);
338
      if (the_target->read_offsets (&text, &data))
339
        sprintf (own_buf, "Text=%lX;Data=%lX;Bss=%lX",
340
                 (long)text, (long)data, (long)data);
341
      else
342
        write_enn (own_buf);
343
 
344
      return;
345
    }
346
 
347
  if (the_target->qxfer_spu != NULL
348
      && strncmp ("qXfer:spu:read:", own_buf, 15) == 0)
349
    {
350
      char *annex;
351
      int n;
352
      unsigned int len;
353
      CORE_ADDR ofs;
354
      unsigned char *spu_buf;
355
 
356
      require_running (own_buf);
357
      strcpy (own_buf, "E00");
358
      if (decode_xfer_read (own_buf + 15, &annex, &ofs, &len) < 0)
359
          return;
360
      if (len > PBUFSIZ - 2)
361
        len = PBUFSIZ - 2;
362
      spu_buf = malloc (len + 1);
363
      if (!spu_buf)
364
        return;
365
 
366
      n = (*the_target->qxfer_spu) (annex, spu_buf, NULL, ofs, len + 1);
367
      if (n < 0)
368
        write_enn (own_buf);
369
      else if (n > len)
370
        *new_packet_len_p = write_qxfer_response
371
                              (own_buf, spu_buf, len, 1);
372
      else
373
        *new_packet_len_p = write_qxfer_response
374
                              (own_buf, spu_buf, n, 0);
375
 
376
      free (spu_buf);
377
      return;
378
    }
379
 
380
  if (the_target->qxfer_spu != NULL
381
      && strncmp ("qXfer:spu:write:", own_buf, 16) == 0)
382
    {
383
      char *annex;
384
      int n;
385
      unsigned int len;
386
      CORE_ADDR ofs;
387
      unsigned char *spu_buf;
388
 
389
      require_running (own_buf);
390
      strcpy (own_buf, "E00");
391
      spu_buf = malloc (packet_len - 15);
392
      if (!spu_buf)
393
        return;
394
      if (decode_xfer_write (own_buf + 16, packet_len - 16, &annex,
395
                             &ofs, &len, spu_buf) < 0)
396
        {
397
          free (spu_buf);
398
          return;
399
        }
400
 
401
      n = (*the_target->qxfer_spu)
402
        (annex, NULL, (unsigned const char *)spu_buf, ofs, len);
403
      if (n < 0)
404
        write_enn (own_buf);
405
      else
406
        sprintf (own_buf, "%x", n);
407
 
408
      free (spu_buf);
409
      return;
410
    }
411
 
412
  if (the_target->read_auxv != NULL
413
      && strncmp ("qXfer:auxv:read:", own_buf, 16) == 0)
414
    {
415
      unsigned char *data;
416
      int n;
417
      CORE_ADDR ofs;
418
      unsigned int len;
419
      char *annex;
420
 
421
      require_running (own_buf);
422
 
423
      /* Reject any annex; grab the offset and length.  */
424
      if (decode_xfer_read (own_buf + 16, &annex, &ofs, &len) < 0
425
          || annex[0] != '\0')
426
        {
427
          strcpy (own_buf, "E00");
428
          return;
429
        }
430
 
431
      /* Read one extra byte, as an indicator of whether there is
432
         more.  */
433
      if (len > PBUFSIZ - 2)
434
        len = PBUFSIZ - 2;
435
      data = malloc (len + 1);
436
      n = (*the_target->read_auxv) (ofs, data, len + 1);
437
      if (n < 0)
438
        write_enn (own_buf);
439
      else if (n > len)
440
        *new_packet_len_p = write_qxfer_response (own_buf, data, len, 1);
441
      else
442
        *new_packet_len_p = write_qxfer_response (own_buf, data, n, 0);
443
 
444
      free (data);
445
 
446
      return;
447
    }
448
 
449
  if (strncmp ("qXfer:features:read:", own_buf, 20) == 0)
450
    {
451
      CORE_ADDR ofs;
452
      unsigned int len, total_len;
453
      const char *document;
454
      char *annex;
455
 
456
      require_running (own_buf);
457
 
458
      /* Check for support.  */
459
      document = get_features_xml ("target.xml");
460
      if (document == NULL)
461
        {
462
          own_buf[0] = '\0';
463
          return;
464
        }
465
 
466
      /* Grab the annex, offset, and length.  */
467
      if (decode_xfer_read (own_buf + 20, &annex, &ofs, &len) < 0)
468
        {
469
          strcpy (own_buf, "E00");
470
          return;
471
        }
472
 
473
      /* Now grab the correct annex.  */
474
      document = get_features_xml (annex);
475
      if (document == NULL)
476
        {
477
          strcpy (own_buf, "E00");
478
          return;
479
        }
480
 
481
      total_len = strlen (document);
482
      if (len > PBUFSIZ - 2)
483
        len = PBUFSIZ - 2;
484
 
485
      if (ofs > total_len)
486
        write_enn (own_buf);
487
      else if (len < total_len - ofs)
488
        *new_packet_len_p = write_qxfer_response (own_buf, document + ofs,
489
                                                  len, 1);
490
      else
491
        *new_packet_len_p = write_qxfer_response (own_buf, document + ofs,
492
                                                  total_len - ofs, 0);
493
 
494
      return;
495
    }
496
 
497
  if (strncmp ("qXfer:libraries:read:", own_buf, 21) == 0)
498
    {
499
      CORE_ADDR ofs;
500
      unsigned int len, total_len;
501
      char *document, *p;
502
      struct inferior_list_entry *dll_ptr;
503
      char *annex;
504
 
505
      require_running (own_buf);
506
 
507
      /* Reject any annex; grab the offset and length.  */
508
      if (decode_xfer_read (own_buf + 21, &annex, &ofs, &len) < 0
509
          || annex[0] != '\0')
510
        {
511
          strcpy (own_buf, "E00");
512
          return;
513
        }
514
 
515
      /* Over-estimate the necessary memory.  Assume that every character
516
         in the library name must be escaped.  */
517
      total_len = 64;
518
      for (dll_ptr = all_dlls.head; dll_ptr != NULL; dll_ptr = dll_ptr->next)
519
        total_len += 128 + 6 * strlen (((struct dll_info *) dll_ptr)->name);
520
 
521
      document = malloc (total_len);
522
      strcpy (document, "<library-list>\n");
523
      p = document + strlen (document);
524
 
525
      for (dll_ptr = all_dlls.head; dll_ptr != NULL; dll_ptr = dll_ptr->next)
526
        {
527
          struct dll_info *dll = (struct dll_info *) dll_ptr;
528
          char *name;
529
 
530
          strcpy (p, "  <library name=\"");
531
          p = p + strlen (p);
532
          name = xml_escape_text (dll->name);
533
          strcpy (p, name);
534
          free (name);
535
          p = p + strlen (p);
536
          strcpy (p, "\"><segment address=\"");
537
          p = p + strlen (p);
538
          sprintf (p, "0x%lx", (long) dll->base_addr);
539
          p = p + strlen (p);
540
          strcpy (p, "\"/></library>\n");
541
          p = p + strlen (p);
542
        }
543
 
544
      strcpy (p, "</library-list>\n");
545
 
546
      total_len = strlen (document);
547
      if (len > PBUFSIZ - 2)
548
        len = PBUFSIZ - 2;
549
 
550
      if (ofs > total_len)
551
        write_enn (own_buf);
552
      else if (len < total_len - ofs)
553
        *new_packet_len_p = write_qxfer_response (own_buf, document + ofs,
554
                                                  len, 1);
555
      else
556
        *new_packet_len_p = write_qxfer_response (own_buf, document + ofs,
557
                                                  total_len - ofs, 0);
558
 
559
      free (document);
560
      return;
561
    }
562
 
563
  /* Protocol features query.  */
564
  if (strncmp ("qSupported", own_buf, 10) == 0
565
      && (own_buf[10] == ':' || own_buf[10] == '\0'))
566
    {
567
      sprintf (own_buf, "PacketSize=%x;QPassSignals+", PBUFSIZ - 1);
568
 
569
      /* We do not have any hook to indicate whether the target backend
570
         supports qXfer:libraries:read, so always report it.  */
571
      strcat (own_buf, ";qXfer:libraries:read+");
572
 
573
      if (the_target->read_auxv != NULL)
574
        strcat (own_buf, ";qXfer:auxv:read+");
575
 
576
      if (the_target->qxfer_spu != NULL)
577
        strcat (own_buf, ";qXfer:spu:read+;qXfer:spu:write+");
578
 
579
      if (get_features_xml ("target.xml") != NULL)
580
        strcat (own_buf, ";qXfer:features:read+");
581
 
582
      return;
583
    }
584
 
585
  /* Thread-local storage support.  */
586
  if (the_target->get_tls_address != NULL
587
      && strncmp ("qGetTLSAddr:", own_buf, 12) == 0)
588
    {
589
      char *p = own_buf + 12;
590
      CORE_ADDR parts[3], address = 0;
591
      int i, err;
592
 
593
      require_running (own_buf);
594
 
595
      for (i = 0; i < 3; i++)
596
        {
597
          char *p2;
598
          int len;
599
 
600
          if (p == NULL)
601
            break;
602
 
603
          p2 = strchr (p, ',');
604
          if (p2)
605
            {
606
              len = p2 - p;
607
              p2++;
608
            }
609
          else
610
            {
611
              len = strlen (p);
612
              p2 = NULL;
613
            }
614
 
615
          decode_address (&parts[i], p, len);
616
          p = p2;
617
        }
618
 
619
      if (p != NULL || i < 3)
620
        err = 1;
621
      else
622
        {
623
          struct thread_info *thread = gdb_id_to_thread (parts[0]);
624
 
625
          if (thread == NULL)
626
            err = 2;
627
          else
628
            err = the_target->get_tls_address (thread, parts[1], parts[2],
629
                                               &address);
630
        }
631
 
632
      if (err == 0)
633
        {
634
          sprintf (own_buf, "%llx", address);
635
          return;
636
        }
637
      else if (err > 0)
638
        {
639
          write_enn (own_buf);
640
          return;
641
        }
642
 
643
      /* Otherwise, pretend we do not understand this packet.  */
644
    }
645
 
646
  /* Handle "monitor" commands.  */
647
  if (strncmp ("qRcmd,", own_buf, 6) == 0)
648
    {
649
      char *mon = malloc (PBUFSIZ);
650
      int len = strlen (own_buf + 6);
651
 
652
      if ((len % 2) != 0 || unhexify (mon, own_buf + 6, len / 2) != len / 2)
653
        {
654
          write_enn (own_buf);
655
          free (mon);
656
          return;
657
        }
658
      mon[len / 2] = '\0';
659
 
660
      write_ok (own_buf);
661
 
662
      if (strcmp (mon, "set debug 1") == 0)
663
        {
664
          debug_threads = 1;
665
          monitor_output ("Debug output enabled.\n");
666
        }
667
      else if (strcmp (mon, "set debug 0") == 0)
668
        {
669
          debug_threads = 0;
670
          monitor_output ("Debug output disabled.\n");
671
        }
672
      else if (strcmp (mon, "set remote-debug 1") == 0)
673
        {
674
          remote_debug = 1;
675
          monitor_output ("Protocol debug output enabled.\n");
676
        }
677
      else if (strcmp (mon, "set remote-debug 0") == 0)
678
        {
679
          remote_debug = 0;
680
          monitor_output ("Protocol debug output disabled.\n");
681
        }
682
      else if (strcmp (mon, "help") == 0)
683
        monitor_show_help ();
684
      else if (strcmp (mon, "exit") == 0)
685
        exit_requested = 1;
686
      else
687
        {
688
          monitor_output ("Unknown monitor command.\n\n");
689
          monitor_show_help ();
690
          write_enn (own_buf);
691
        }
692
 
693
      free (mon);
694
      return;
695
    }
696
 
697
  /* Otherwise we didn't know what packet it was.  Say we didn't
698
     understand it.  */
699
  own_buf[0] = 0;
700
}
701
 
702
/* Parse vCont packets.  */
703
void
704
handle_v_cont (char *own_buf, char *status, int *signal)
705
{
706
  char *p, *q;
707
  int n = 0, i = 0;
708
  struct thread_resume *resume_info, default_action;
709
 
710
  /* Count the number of semicolons in the packet.  There should be one
711
     for every action.  */
712
  p = &own_buf[5];
713
  while (p)
714
    {
715
      n++;
716
      p++;
717
      p = strchr (p, ';');
718
    }
719
  /* Allocate room for one extra action, for the default remain-stopped
720
     behavior; if no default action is in the list, we'll need the extra
721
     slot.  */
722
  resume_info = malloc ((n + 1) * sizeof (resume_info[0]));
723
 
724
  default_action.thread = -1;
725
  default_action.leave_stopped = 1;
726
  default_action.step = 0;
727
  default_action.sig = 0;
728
 
729
  p = &own_buf[5];
730
  i = 0;
731
  while (*p)
732
    {
733
      p++;
734
 
735
      resume_info[i].leave_stopped = 0;
736
 
737
      if (p[0] == 's' || p[0] == 'S')
738
        resume_info[i].step = 1;
739
      else if (p[0] == 'c' || p[0] == 'C')
740
        resume_info[i].step = 0;
741
      else
742
        goto err;
743
 
744
      if (p[0] == 'S' || p[0] == 'C')
745
        {
746
          int sig;
747
          sig = strtol (p + 1, &q, 16);
748
          if (p == q)
749
            goto err;
750
          p = q;
751
 
752
          if (!target_signal_to_host_p (sig))
753
            goto err;
754
          resume_info[i].sig = target_signal_to_host (sig);
755
        }
756
      else
757
        {
758
          resume_info[i].sig = 0;
759
          p = p + 1;
760
        }
761
 
762
      if (p[0] == 0)
763
        {
764
          resume_info[i].thread = -1;
765
          default_action = resume_info[i];
766
 
767
          /* Note: we don't increment i here, we'll overwrite this entry
768
             the next time through.  */
769
        }
770
      else if (p[0] == ':')
771
        {
772
          unsigned int gdb_id = strtoul (p + 1, &q, 16);
773
          unsigned long thread_id;
774
 
775
          if (p == q)
776
            goto err;
777
          p = q;
778
          if (p[0] != ';' && p[0] != 0)
779
            goto err;
780
 
781
          thread_id = gdb_id_to_thread_id (gdb_id);
782
          if (thread_id)
783
            resume_info[i].thread = thread_id;
784
          else
785
            goto err;
786
 
787
          i++;
788
        }
789
    }
790
 
791
  resume_info[i] = default_action;
792
 
793
  /* Still used in occasional places in the backend.  */
794
  if (n == 1 && resume_info[0].thread != -1)
795
    cont_thread = resume_info[0].thread;
796
  else
797
    cont_thread = -1;
798
  set_desired_inferior (0);
799
 
800
  enable_async_io ();
801
  (*the_target->resume) (resume_info);
802
 
803
  free (resume_info);
804
 
805
  *signal = mywait (status, 1);
806
  prepare_resume_reply (own_buf, *status, *signal);
807
  disable_async_io ();
808
  return;
809
 
810
err:
811
  write_enn (own_buf);
812
  free (resume_info);
813
  return;
814
}
815
 
816
/* Attach to a new program.  Return 1 if successful, 0 if failure.  */
817
int
818
handle_v_attach (char *own_buf, char *status, int *signal)
819
{
820
  int pid;
821
 
822
  pid = strtol (own_buf + 8, NULL, 16);
823
  if (pid != 0 && attach_inferior (pid, status, signal) == 0)
824
    {
825
      prepare_resume_reply (own_buf, *status, *signal);
826
      return 1;
827
    }
828
  else
829
    {
830
      write_enn (own_buf);
831
      return 0;
832
    }
833
}
834
 
835
/* Run a new program.  Return 1 if successful, 0 if failure.  */
836
static int
837
handle_v_run (char *own_buf, char *status, int *signal)
838
{
839
  char *p, **pp, *next_p, **new_argv;
840
  int i, new_argc;
841
 
842
  new_argc = 0;
843
  for (p = own_buf + strlen ("vRun;"); p && *p; p = strchr (p, ';'))
844
    {
845
      p++;
846
      new_argc++;
847
    }
848
 
849
  new_argv = malloc ((new_argc + 2) * sizeof (char *));
850
  i = 0;
851
  for (p = own_buf + strlen ("vRun;"); *p; p = next_p)
852
    {
853
      next_p = strchr (p, ';');
854
      if (next_p == NULL)
855
        next_p = p + strlen (p);
856
 
857
      if (i == 0 && p == next_p)
858
        new_argv[i] = NULL;
859
      else
860
        {
861
          new_argv[i] = malloc (1 + (next_p - p) / 2);
862
          unhexify (new_argv[i], p, (next_p - p) / 2);
863
          new_argv[i][(next_p - p) / 2] = '\0';
864
        }
865
 
866
      if (*next_p)
867
        next_p++;
868
      i++;
869
    }
870
  new_argv[i] = NULL;
871
 
872
  if (new_argv[0] == NULL)
873
    {
874
      if (program_argv == NULL)
875
        {
876
          write_enn (own_buf);
877
          return 0;
878
        }
879
 
880
      new_argv[0] = strdup (program_argv[0]);
881
    }
882
 
883
  /* Free the old argv.  */
884
  if (program_argv)
885
    {
886
      for (pp = program_argv; *pp != NULL; pp++)
887
        free (*pp);
888
      free (program_argv);
889
    }
890
  program_argv = new_argv;
891
 
892
  *signal = start_inferior (program_argv, status);
893
  if (*status == 'T')
894
    {
895
      prepare_resume_reply (own_buf, *status, *signal);
896
      return 1;
897
    }
898
  else
899
    {
900
      write_enn (own_buf);
901
      return 0;
902
    }
903
}
904
 
905
/* Handle all of the extended 'v' packets.  */
906
void
907
handle_v_requests (char *own_buf, char *status, int *signal,
908
                   int packet_len, int *new_packet_len)
909
{
910
  if (strncmp (own_buf, "vCont;", 6) == 0)
911
    {
912
      require_running (own_buf);
913
      handle_v_cont (own_buf, status, signal);
914
      return;
915
    }
916
 
917
  if (strncmp (own_buf, "vCont?", 6) == 0)
918
    {
919
      strcpy (own_buf, "vCont;c;C;s;S");
920
      return;
921
    }
922
 
923
  if (strncmp (own_buf, "vFile:", 6) == 0
924
      && handle_vFile (own_buf, packet_len, new_packet_len))
925
    return;
926
 
927
  if (strncmp (own_buf, "vAttach;", 8) == 0)
928
    {
929
      if (target_running ())
930
        {
931
          fprintf (stderr, "Already debugging a process\n");
932
          write_enn (own_buf);
933
          return;
934
        }
935
      handle_v_attach (own_buf, status, signal);
936
      return;
937
    }
938
 
939
  if (strncmp (own_buf, "vRun;", 5) == 0)
940
    {
941
      if (target_running ())
942
        {
943
          fprintf (stderr, "Already debugging a process\n");
944
          write_enn (own_buf);
945
          return;
946
        }
947
      handle_v_run (own_buf, status, signal);
948
      return;
949
    }
950
 
951
  /* Otherwise we didn't know what packet it was.  Say we didn't
952
     understand it.  */
953
  own_buf[0] = 0;
954
  return;
955
}
956
 
957
void
958
myresume (char *own_buf, int step, int *signalp, char *statusp)
959
{
960
  struct thread_resume resume_info[2];
961
  int n = 0;
962
  int sig = *signalp;
963
 
964
  set_desired_inferior (0);
965
 
966
  if (step || sig || (cont_thread != 0 && cont_thread != -1))
967
    {
968
      resume_info[0].thread
969
        = ((struct inferior_list_entry *) current_inferior)->id;
970
      resume_info[0].step = step;
971
      resume_info[0].sig = sig;
972
      resume_info[0].leave_stopped = 0;
973
      n++;
974
    }
975
  resume_info[n].thread = -1;
976
  resume_info[n].step = 0;
977
  resume_info[n].sig = 0;
978
  resume_info[n].leave_stopped = (cont_thread != 0 && cont_thread != -1);
979
 
980
  enable_async_io ();
981
  (*the_target->resume) (resume_info);
982
  *signalp = mywait (statusp, 1);
983
  prepare_resume_reply (own_buf, *statusp, *signalp);
984
  disable_async_io ();
985
}
986
 
987
static void
988
gdbserver_version (void)
989
{
990
  printf ("GNU gdbserver %s\n"
991
          "Copyright (C) 2007 Free Software Foundation, Inc.\n"
992
          "gdbserver is free software, covered by the GNU General Public License.\n"
993
          "This gdbserver was configured as \"%s\"\n",
994
          version, host_name);
995
}
996
 
997
static void
998
gdbserver_usage (void)
999
{
1000
  printf ("Usage:\tgdbserver [OPTIONS] COMM PROG [ARGS ...]\n"
1001
          "\tgdbserver [OPTIONS] --attach COMM PID\n"
1002
          "\tgdbserver [OPTIONS] --multi COMM\n"
1003
          "\n"
1004
          "COMM may either be a tty device (for serial debugging), or \n"
1005
          "HOST:PORT to listen for a TCP connection.\n"
1006
          "\n"
1007
          "Options:\n"
1008
          "  --debug\t\tEnable debugging output.\n");
1009
}
1010
 
1011
#undef require_running
1012
#define require_running(BUF)                    \
1013
  if (!target_running ())                       \
1014
    {                                           \
1015
      write_enn (BUF);                          \
1016
      break;                                    \
1017
    }
1018
 
1019
int
1020
main (int argc, char *argv[])
1021
{
1022
  char ch, status, *own_buf;
1023
  unsigned char *mem_buf;
1024
  int i = 0;
1025
  int signal;
1026
  unsigned int len;
1027
  CORE_ADDR mem_addr;
1028
  int bad_attach;
1029
  int pid;
1030
  char *arg_end, *port;
1031
  char **next_arg = &argv[1];
1032
  int multi_mode = 0;
1033
  int attach = 0;
1034
  int was_running;
1035
 
1036
  while (*next_arg != NULL && **next_arg == '-')
1037
    {
1038
      if (strcmp (*next_arg, "--version") == 0)
1039
        {
1040
          gdbserver_version ();
1041
          exit (0);
1042
        }
1043
      else if (strcmp (*next_arg, "--help") == 0)
1044
        {
1045
          gdbserver_usage ();
1046
          exit (0);
1047
        }
1048
      else if (strcmp (*next_arg, "--attach") == 0)
1049
        attach = 1;
1050
      else if (strcmp (*next_arg, "--multi") == 0)
1051
        multi_mode = 1;
1052
      else if (strcmp (*next_arg, "--debug") == 0)
1053
        debug_threads = 1;
1054
      else
1055
        {
1056
          fprintf (stderr, "Unknown argument: %s\n", *next_arg);
1057
          exit (1);
1058
        }
1059
 
1060
      next_arg++;
1061
      continue;
1062
    }
1063
 
1064
  if (setjmp (toplevel))
1065
    {
1066
      fprintf (stderr, "Exiting\n");
1067
      exit (1);
1068
    }
1069
 
1070
  port = *next_arg;
1071
  next_arg++;
1072
  if (port == NULL || (!attach && !multi_mode && *next_arg == NULL))
1073
    {
1074
      gdbserver_usage ();
1075
      exit (1);
1076
    }
1077
 
1078
  bad_attach = 0;
1079
  pid = 0;
1080
 
1081
  /* --attach used to come after PORT, so allow it there for
1082
       compatibility.  */
1083
  if (*next_arg != NULL && strcmp (*next_arg, "--attach") == 0)
1084
    {
1085
      attach = 1;
1086
      next_arg++;
1087
    }
1088
 
1089
  if (attach
1090
      && (*next_arg == NULL
1091
          || (*next_arg)[0] == '\0'
1092
          || (pid = strtoul (*next_arg, &arg_end, 0)) == 0
1093
          || *arg_end != '\0'
1094
          || next_arg[1] != NULL))
1095
    bad_attach = 1;
1096
 
1097
  if (bad_attach)
1098
    {
1099
      gdbserver_usage ();
1100
      exit (1);
1101
    }
1102
 
1103
  initialize_async_io ();
1104
  initialize_low ();
1105
 
1106
  own_buf = malloc (PBUFSIZ + 1);
1107
  mem_buf = malloc (PBUFSIZ);
1108
 
1109
  if (pid == 0 && *next_arg != NULL)
1110
    {
1111
      int i, n;
1112
 
1113
      n = argc - (next_arg - argv);
1114
      program_argv = malloc (sizeof (char *) * (n + 1));
1115
      for (i = 0; i < n; i++)
1116
        program_argv[i] = strdup (next_arg[i]);
1117
      program_argv[i] = NULL;
1118
 
1119
      /* Wait till we are at first instruction in program.  */
1120
      signal = start_inferior (program_argv, &status);
1121
 
1122
      /* We are now (hopefully) stopped at the first instruction of
1123
         the target process.  This assumes that the target process was
1124
         successfully created.  */
1125
    }
1126
  else if (pid != 0)
1127
    {
1128
      if (attach_inferior (pid, &status, &signal) == -1)
1129
        error ("Attaching not supported on this target");
1130
 
1131
      /* Otherwise succeeded.  */
1132
    }
1133
  else
1134
    {
1135
      status = 'W';
1136
      signal = 0;
1137
    }
1138
 
1139
  /* Don't report shared library events on the initial connection,
1140
     even if some libraries are preloaded.  Avoids the "stopped by
1141
     shared library event" notice on gdb side.  */
1142
  dlls_changed = 0;
1143
 
1144
  if (setjmp (toplevel))
1145
    {
1146
      fprintf (stderr, "Killing inferior\n");
1147
      kill_inferior ();
1148
      exit (1);
1149
    }
1150
 
1151
  if (status == 'W' || status == 'X')
1152
    was_running = 0;
1153
  else
1154
    was_running = 1;
1155
 
1156
  if (!was_running && !multi_mode)
1157
    {
1158
      fprintf (stderr, "No program to debug.  GDBserver exiting.\n");
1159
      exit (1);
1160
    }
1161
 
1162
  while (1)
1163
    {
1164
      remote_open (port);
1165
 
1166
    restart:
1167
      if (setjmp (toplevel) != 0)
1168
        {
1169
          /* An error occurred.  */
1170
          if (response_needed)
1171
            {
1172
              write_enn (own_buf);
1173
              putpkt (own_buf);
1174
            }
1175
        }
1176
 
1177
      disable_async_io ();
1178
      while (!exit_requested)
1179
        {
1180
          unsigned char sig;
1181
          int packet_len;
1182
          int new_packet_len = -1;
1183
 
1184
          response_needed = 0;
1185
          packet_len = getpkt (own_buf);
1186
          if (packet_len <= 0)
1187
            break;
1188
          response_needed = 1;
1189
 
1190
          i = 0;
1191
          ch = own_buf[i++];
1192
          switch (ch)
1193
            {
1194
            case 'q':
1195
              handle_query (own_buf, packet_len, &new_packet_len);
1196
              break;
1197
            case 'Q':
1198
              handle_general_set (own_buf);
1199
              break;
1200
            case 'D':
1201
              require_running (own_buf);
1202
              fprintf (stderr, "Detaching from inferior\n");
1203
              if (detach_inferior () != 0)
1204
                write_enn (own_buf);
1205
              else
1206
                {
1207
                  write_ok (own_buf);
1208
 
1209
                  if (extended_protocol)
1210
                    {
1211
                      /* Treat this like a normal program exit.  */
1212
                      signal = 0;
1213
                      status = 'W';
1214
                    }
1215
                  else
1216
                    {
1217
                      putpkt (own_buf);
1218
                      remote_close ();
1219
 
1220
                      /* If we are attached, then we can exit.  Otherwise, we
1221
                         need to hang around doing nothing, until the child
1222
                         is gone.  */
1223
                      if (!attached)
1224
                        join_inferior ();
1225
 
1226
                      exit (0);
1227
                    }
1228
                }
1229
              break;
1230
            case '!':
1231
              extended_protocol = 1;
1232
              write_ok (own_buf);
1233
              break;
1234
            case '?':
1235
              prepare_resume_reply (own_buf, status, signal);
1236
              break;
1237
            case 'H':
1238
              if (own_buf[1] == 'c' || own_buf[1] == 'g' || own_buf[1] == 's')
1239
                {
1240
                  unsigned long gdb_id, thread_id;
1241
 
1242
                  require_running (own_buf);
1243
                  gdb_id = strtoul (&own_buf[2], NULL, 16);
1244
                  if (gdb_id == 0 || gdb_id == -1)
1245
                    thread_id = gdb_id;
1246
                  else
1247
                    {
1248
                      thread_id = gdb_id_to_thread_id (gdb_id);
1249
                      if (thread_id == 0)
1250
                        {
1251
                          write_enn (own_buf);
1252
                          break;
1253
                        }
1254
                    }
1255
 
1256
                  if (own_buf[1] == 'g')
1257
                    {
1258
                      general_thread = thread_id;
1259
                      set_desired_inferior (1);
1260
                    }
1261
                  else if (own_buf[1] == 'c')
1262
                    cont_thread = thread_id;
1263
                  else if (own_buf[1] == 's')
1264
                    step_thread = thread_id;
1265
 
1266
                  write_ok (own_buf);
1267
                }
1268
              else
1269
                {
1270
                  /* Silently ignore it so that gdb can extend the protocol
1271
                     without compatibility headaches.  */
1272
                  own_buf[0] = '\0';
1273
                }
1274
              break;
1275
            case 'g':
1276
              require_running (own_buf);
1277
              set_desired_inferior (1);
1278
              registers_to_string (own_buf);
1279
              break;
1280
            case 'G':
1281
              require_running (own_buf);
1282
              set_desired_inferior (1);
1283
              registers_from_string (&own_buf[1]);
1284
              write_ok (own_buf);
1285
              break;
1286
            case 'm':
1287
              require_running (own_buf);
1288
              decode_m_packet (&own_buf[1], &mem_addr, &len);
1289
              if (read_inferior_memory (mem_addr, mem_buf, len) == 0)
1290
                convert_int_to_ascii (mem_buf, own_buf, len);
1291
              else
1292
                write_enn (own_buf);
1293
              break;
1294
            case 'M':
1295
              require_running (own_buf);
1296
              decode_M_packet (&own_buf[1], &mem_addr, &len, mem_buf);
1297
              if (write_inferior_memory (mem_addr, mem_buf, len) == 0)
1298
                write_ok (own_buf);
1299
              else
1300
                write_enn (own_buf);
1301
              break;
1302
            case 'X':
1303
              require_running (own_buf);
1304
              if (decode_X_packet (&own_buf[1], packet_len - 1,
1305
                                   &mem_addr, &len, mem_buf) < 0
1306
                  || write_inferior_memory (mem_addr, mem_buf, len) != 0)
1307
                write_enn (own_buf);
1308
              else
1309
                write_ok (own_buf);
1310
              break;
1311
            case 'C':
1312
              require_running (own_buf);
1313
              convert_ascii_to_int (own_buf + 1, &sig, 1);
1314
              if (target_signal_to_host_p (sig))
1315
                signal = target_signal_to_host (sig);
1316
              else
1317
                signal = 0;
1318
              myresume (own_buf, 0, &signal, &status);
1319
              break;
1320
            case 'S':
1321
              require_running (own_buf);
1322
              convert_ascii_to_int (own_buf + 1, &sig, 1);
1323
              if (target_signal_to_host_p (sig))
1324
                signal = target_signal_to_host (sig);
1325
              else
1326
                signal = 0;
1327
              myresume (own_buf, 1, &signal, &status);
1328
              break;
1329
            case 'c':
1330
              require_running (own_buf);
1331
              signal = 0;
1332
              myresume (own_buf, 0, &signal, &status);
1333
              break;
1334
            case 's':
1335
              require_running (own_buf);
1336
              signal = 0;
1337
              myresume (own_buf, 1, &signal, &status);
1338
              break;
1339
            case 'Z':
1340
              {
1341
                char *lenptr;
1342
                char *dataptr;
1343
                CORE_ADDR addr = strtoul (&own_buf[3], &lenptr, 16);
1344
                int len = strtol (lenptr + 1, &dataptr, 16);
1345
                char type = own_buf[1];
1346
 
1347
                if (the_target->insert_watchpoint == NULL
1348
                    || (type < '2' || type > '4'))
1349
                  {
1350
                    /* No watchpoint support or not a watchpoint command;
1351
                       unrecognized either way.  */
1352
                    own_buf[0] = '\0';
1353
                  }
1354
                else
1355
                  {
1356
                    int res;
1357
 
1358
                    require_running (own_buf);
1359
                    res = (*the_target->insert_watchpoint) (type, addr, len);
1360
                    if (res == 0)
1361
                      write_ok (own_buf);
1362
                    else if (res == 1)
1363
                      /* Unsupported.  */
1364
                      own_buf[0] = '\0';
1365
                    else
1366
                      write_enn (own_buf);
1367
                  }
1368
                break;
1369
              }
1370
            case 'z':
1371
              {
1372
                char *lenptr;
1373
                char *dataptr;
1374
                CORE_ADDR addr = strtoul (&own_buf[3], &lenptr, 16);
1375
                int len = strtol (lenptr + 1, &dataptr, 16);
1376
                char type = own_buf[1];
1377
 
1378
                if (the_target->remove_watchpoint == NULL
1379
                    || (type < '2' || type > '4'))
1380
                  {
1381
                    /* No watchpoint support or not a watchpoint command;
1382
                       unrecognized either way.  */
1383
                    own_buf[0] = '\0';
1384
                  }
1385
                else
1386
                  {
1387
                    int res;
1388
 
1389
                    require_running (own_buf);
1390
                    res = (*the_target->remove_watchpoint) (type, addr, len);
1391
                    if (res == 0)
1392
                      write_ok (own_buf);
1393
                    else if (res == 1)
1394
                      /* Unsupported.  */
1395
                      own_buf[0] = '\0';
1396
                    else
1397
                      write_enn (own_buf);
1398
                  }
1399
                break;
1400
              }
1401
            case 'k':
1402
              response_needed = 0;
1403
              if (!target_running ())
1404
                /* The packet we received doesn't make sense - but we
1405
                   can't reply to it, either.  */
1406
                goto restart;
1407
 
1408
              fprintf (stderr, "Killing inferior\n");
1409
              kill_inferior ();
1410
 
1411
              /* When using the extended protocol, we wait with no
1412
                 program running.  The traditional protocol will exit
1413
                 instead.  */
1414
              if (extended_protocol)
1415
                {
1416
                  status = 'X';
1417
                  signal = TARGET_SIGNAL_KILL;
1418
                  was_running = 0;
1419
                  goto restart;
1420
                }
1421
              else
1422
                {
1423
                  exit (0);
1424
                  break;
1425
                }
1426
            case 'T':
1427
              {
1428
                unsigned long gdb_id, thread_id;
1429
 
1430
                require_running (own_buf);
1431
                gdb_id = strtoul (&own_buf[1], NULL, 16);
1432
                thread_id = gdb_id_to_thread_id (gdb_id);
1433
                if (thread_id == 0)
1434
                  {
1435
                    write_enn (own_buf);
1436
                    break;
1437
                  }
1438
 
1439
                if (mythread_alive (thread_id))
1440
                  write_ok (own_buf);
1441
                else
1442
                  write_enn (own_buf);
1443
              }
1444
              break;
1445
            case 'R':
1446
              response_needed = 0;
1447
 
1448
              /* Restarting the inferior is only supported in the
1449
                 extended protocol.  */
1450
              if (extended_protocol)
1451
                {
1452
                  if (target_running ())
1453
                    kill_inferior ();
1454
                  fprintf (stderr, "GDBserver restarting\n");
1455
 
1456
                  /* Wait till we are at 1st instruction in prog.  */
1457
                  if (program_argv != NULL)
1458
                    signal = start_inferior (program_argv, &status);
1459
                  else
1460
                    {
1461
                      status = 'X';
1462
                      signal = TARGET_SIGNAL_KILL;
1463
                    }
1464
                  goto restart;
1465
                }
1466
              else
1467
                {
1468
                  /* It is a request we don't understand.  Respond with an
1469
                     empty packet so that gdb knows that we don't support this
1470
                     request.  */
1471
                  own_buf[0] = '\0';
1472
                  break;
1473
                }
1474
            case 'v':
1475
              /* Extended (long) request.  */
1476
              handle_v_requests (own_buf, &status, &signal,
1477
                                 packet_len, &new_packet_len);
1478
              break;
1479
 
1480
            default:
1481
              /* It is a request we don't understand.  Respond with an
1482
                 empty packet so that gdb knows that we don't support this
1483
                 request.  */
1484
              own_buf[0] = '\0';
1485
              break;
1486
            }
1487
 
1488
          if (new_packet_len != -1)
1489
            putpkt_binary (own_buf, new_packet_len);
1490
          else
1491
            putpkt (own_buf);
1492
 
1493
          response_needed = 0;
1494
 
1495
          if (was_running && (status == 'W' || status == 'X'))
1496
            {
1497
              was_running = 0;
1498
 
1499
              if (status == 'W')
1500
                fprintf (stderr,
1501
                         "\nChild exited with status %d\n", signal);
1502
              if (status == 'X')
1503
                fprintf (stderr, "\nChild terminated with signal = 0x%x (%s)\n",
1504
                         target_signal_to_host (signal),
1505
                         target_signal_to_name (signal));
1506
 
1507
              if (extended_protocol)
1508
                goto restart;
1509
              else
1510
                {
1511
                  fprintf (stderr, "GDBserver exiting\n");
1512
                  exit (0);
1513
                }
1514
            }
1515
 
1516
          if (status != 'W' && status != 'X')
1517
            was_running = 1;
1518
        }
1519
 
1520
      /* If an exit was requested (using the "monitor exit" command),
1521
         terminate now.  The only other way to get here is for
1522
         getpkt to fail; close the connection and reopen it at the
1523
         top of the loop.  */
1524
 
1525
      if (exit_requested)
1526
        {
1527
          remote_close ();
1528
          if (attached && target_running ())
1529
            detach_inferior ();
1530
          else if (target_running ())
1531
            kill_inferior ();
1532
          exit (0);
1533
        }
1534
      else
1535
        {
1536
          fprintf (stderr, "Remote side has terminated connection.  "
1537
                           "GDBserver will reopen the connection.\n");
1538
          remote_close ();
1539
        }
1540
    }
1541
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.