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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [gdb-5.3/] [gdb/] [gdbserver/] [remote-utils.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1181 sfurman
/* Remote utility routines for the remote server for GDB.
2
   Copyright 1986, 1989, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
3
   2002
4
   Free Software Foundation, Inc.
5
 
6
   This file is part of GDB.
7
 
8
   This program is free software; you can redistribute it and/or modify
9
   it under the terms of the GNU General Public License as published by
10
   the Free Software Foundation; either version 2 of the License, or
11
   (at your option) any later version.
12
 
13
   This program is distributed in the hope that it will be useful,
14
   but WITHOUT ANY WARRANTY; without even the implied warranty of
15
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
   GNU General Public License for more details.
17
 
18
   You should have received a copy of the GNU General Public License
19
   along with this program; if not, write to the Free Software
20
   Foundation, Inc., 59 Temple Place - Suite 330,
21
   Boston, MA 02111-1307, USA.  */
22
 
23
#include "server.h"
24
#include "terminal.h"
25
#include <stdio.h>
26
#include <string.h>
27
#include <sys/ioctl.h>
28
#include <sys/file.h>
29
#include <netinet/in.h>
30
#include <sys/socket.h>
31
#include <netdb.h>
32
#include <netinet/tcp.h>
33
#include <sys/ioctl.h>
34
#include <signal.h>
35
#include <fcntl.h>
36
#include <sys/time.h>
37
#include <unistd.h>
38
#include <arpa/inet.h>
39
 
40
int remote_debug = 0;
41
struct ui_file *gdb_stdlog;
42
 
43
static int remote_desc;
44
 
45
/* FIXME headerize? */
46
extern int using_threads;
47
extern int debug_threads;
48
 
49
extern int signal_pid;
50
 
51
/* Open a connection to a remote debugger.
52
   NAME is the filename used for communication.  */
53
 
54
void
55
remote_open (char *name)
56
{
57
  int save_fcntl_flags;
58
 
59
  if (!strchr (name, ':'))
60
    {
61
      remote_desc = open (name, O_RDWR);
62
      if (remote_desc < 0)
63
        perror_with_name ("Could not open remote device");
64
 
65
#ifdef HAVE_TERMIOS
66
      {
67
        struct termios termios;
68
        tcgetattr (remote_desc, &termios);
69
 
70
        termios.c_iflag = 0;
71
        termios.c_oflag = 0;
72
        termios.c_lflag = 0;
73
        termios.c_cflag &= ~(CSIZE | PARENB);
74
        termios.c_cflag |= CLOCAL | CS8;
75
        termios.c_cc[VMIN] = 1;
76
        termios.c_cc[VTIME] = 0;
77
 
78
        tcsetattr (remote_desc, TCSANOW, &termios);
79
      }
80
#endif
81
 
82
#ifdef HAVE_TERMIO
83
      {
84
        struct termio termio;
85
        ioctl (remote_desc, TCGETA, &termio);
86
 
87
        termio.c_iflag = 0;
88
        termio.c_oflag = 0;
89
        termio.c_lflag = 0;
90
        termio.c_cflag &= ~(CSIZE | PARENB);
91
        termio.c_cflag |= CLOCAL | CS8;
92
        termio.c_cc[VMIN] = 1;
93
        termio.c_cc[VTIME] = 0;
94
 
95
        ioctl (remote_desc, TCSETA, &termio);
96
      }
97
#endif
98
 
99
#ifdef HAVE_SGTTY
100
      {
101
        struct sgttyb sg;
102
 
103
        ioctl (remote_desc, TIOCGETP, &sg);
104
        sg.sg_flags = RAW;
105
        ioctl (remote_desc, TIOCSETP, &sg);
106
      }
107
#endif
108
 
109
      fprintf (stderr, "Remote debugging using %s\n", name);
110
    }
111
  else
112
    {
113
      char *port_str;
114
      int port;
115
      struct sockaddr_in sockaddr;
116
      int tmp;
117
      int tmp_desc;
118
 
119
      port_str = strchr (name, ':');
120
 
121
      port = atoi (port_str + 1);
122
 
123
      tmp_desc = socket (PF_INET, SOCK_STREAM, 0);
124
      if (tmp_desc < 0)
125
        perror_with_name ("Can't open socket");
126
 
127
      /* Allow rapid reuse of this port. */
128
      tmp = 1;
129
      setsockopt (tmp_desc, SOL_SOCKET, SO_REUSEADDR, (char *) &tmp,
130
                  sizeof (tmp));
131
 
132
      sockaddr.sin_family = PF_INET;
133
      sockaddr.sin_port = htons (port);
134
      sockaddr.sin_addr.s_addr = INADDR_ANY;
135
 
136
      if (bind (tmp_desc, (struct sockaddr *) &sockaddr, sizeof (sockaddr))
137
          || listen (tmp_desc, 1))
138
        perror_with_name ("Can't bind address");
139
 
140
      tmp = sizeof (sockaddr);
141
      remote_desc = accept (tmp_desc, (struct sockaddr *) &sockaddr, &tmp);
142
      if (remote_desc == -1)
143
        perror_with_name ("Accept failed");
144
 
145
      /* Enable TCP keep alive process. */
146
      tmp = 1;
147
      setsockopt (tmp_desc, SOL_SOCKET, SO_KEEPALIVE, (char *) &tmp, sizeof (tmp));
148
 
149
      /* Tell TCP not to delay small packets.  This greatly speeds up
150
         interactive response. */
151
      tmp = 1;
152
      setsockopt (remote_desc, IPPROTO_TCP, TCP_NODELAY,
153
                  (char *) &tmp, sizeof (tmp));
154
 
155
      close (tmp_desc);         /* No longer need this */
156
 
157
      signal (SIGPIPE, SIG_IGN);        /* If we don't do this, then gdbserver simply
158
                                           exits when the remote side dies.  */
159
 
160
      /* Convert IP address to string.  */
161
      fprintf (stderr, "Remote debugging from host %s\n",
162
         inet_ntoa (sockaddr.sin_addr));
163
    }
164
 
165
#if defined(F_SETFL) && defined (FASYNC)
166
  save_fcntl_flags = fcntl (remote_desc, F_GETFL, 0);
167
  fcntl (remote_desc, F_SETFL, save_fcntl_flags | FASYNC);
168
#if defined (F_SETOWN)
169
  fcntl (remote_desc, F_SETOWN, getpid ());
170
#endif
171
#endif
172
  disable_async_io ();
173
}
174
 
175
void
176
remote_close (void)
177
{
178
  close (remote_desc);
179
}
180
 
181
/* Convert hex digit A to a number.  */
182
 
183
static int
184
fromhex (int a)
185
{
186
  if (a >= '0' && a <= '9')
187
    return a - '0';
188
  else if (a >= 'a' && a <= 'f')
189
    return a - 'a' + 10;
190
  else
191
    error ("Reply contains invalid hex digit");
192
  return 0;
193
}
194
 
195
int
196
unhexify (char *bin, const char *hex, int count)
197
{
198
  int i;
199
 
200
  for (i = 0; i < count; i++)
201
    {
202
      if (hex[0] == 0 || hex[1] == 0)
203
        {
204
          /* Hex string is short, or of uneven length.
205
             Return the count that has been converted so far. */
206
          return i;
207
        }
208
      *bin++ = fromhex (hex[0]) * 16 + fromhex (hex[1]);
209
      hex += 2;
210
    }
211
  return i;
212
}
213
 
214
static void
215
decode_address (CORE_ADDR *addrp, const char *start, int len)
216
{
217
  CORE_ADDR addr;
218
  char ch;
219
  int i;
220
 
221
  addr = 0;
222
  for (i = 0; i < len; i++)
223
    {
224
      ch = start[i];
225
      addr = addr << 4;
226
      addr = addr | (fromhex (ch) & 0x0f);
227
    }
228
  *addrp = addr;
229
}
230
 
231
/* Convert number NIB to a hex digit.  */
232
 
233
static int
234
tohex (int nib)
235
{
236
  if (nib < 10)
237
    return '0' + nib;
238
  else
239
    return 'a' + nib - 10;
240
}
241
 
242
int
243
hexify (char *hex, const char *bin, int count)
244
{
245
  int i;
246
 
247
  /* May use a length, or a nul-terminated string as input. */
248
  if (count == 0)
249
    count = strlen (bin);
250
 
251
  for (i = 0; i < count; i++)
252
    {
253
      *hex++ = tohex ((*bin >> 4) & 0xf);
254
      *hex++ = tohex (*bin++ & 0xf);
255
    }
256
  *hex = 0;
257
  return i;
258
}
259
 
260
/* Send a packet to the remote machine, with error checking.
261
   The data of the packet is in BUF.  Returns >= 0 on success, -1 otherwise. */
262
 
263
int
264
putpkt (char *buf)
265
{
266
  int i;
267
  unsigned char csum = 0;
268
  char *buf2;
269
  char buf3[1];
270
  int cnt = strlen (buf);
271
  char *p;
272
 
273
  buf2 = malloc (PBUFSIZ);
274
 
275
  /* Copy the packet into buffer BUF2, encapsulating it
276
     and giving it a checksum.  */
277
 
278
  p = buf2;
279
  *p++ = '$';
280
 
281
  for (i = 0; i < cnt; i++)
282
    {
283
      csum += buf[i];
284
      *p++ = buf[i];
285
    }
286
  *p++ = '#';
287
  *p++ = tohex ((csum >> 4) & 0xf);
288
  *p++ = tohex (csum & 0xf);
289
 
290
  *p = '\0';
291
 
292
  /* Send it over and over until we get a positive ack.  */
293
 
294
  do
295
    {
296
      int cc;
297
 
298
      if (write (remote_desc, buf2, p - buf2) != p - buf2)
299
        {
300
          perror ("putpkt(write)");
301
          return -1;
302
        }
303
 
304
      if (remote_debug)
305
        {
306
          fprintf (stderr, "putpkt (\"%s\"); [looking for ack]\n", buf2);
307
          fflush (stderr);
308
        }
309
      cc = read (remote_desc, buf3, 1);
310
      if (remote_debug)
311
        {
312
          fprintf (stderr, "[received '%c' (0x%x)]\n", buf3[0], buf3[0]);
313
          fflush (stderr);
314
        }
315
 
316
      if (cc <= 0)
317
        {
318
          if (cc == 0)
319
            fprintf (stderr, "putpkt(read): Got EOF\n");
320
          else
321
            perror ("putpkt(read)");
322
 
323
          free (buf2);
324
          return -1;
325
        }
326
 
327
      /* Check for an input interrupt while we're here.  */
328
      if (buf3[0] == '\003')
329
        kill (signal_pid, SIGINT);
330
    }
331
  while (buf3[0] != '+');
332
 
333
  free (buf2);
334
  return 1;                     /* Success! */
335
}
336
 
337
/* Come here when we get an input interrupt from the remote side.  This
338
   interrupt should only be active while we are waiting for the child to do
339
   something.  About the only thing that should come through is a ^C, which
340
   will cause us to send a SIGINT to the child.  */
341
 
342
static void
343
input_interrupt (int unused)
344
{
345
  fd_set readset;
346
  struct timeval immediate = { 0, 0 };
347
 
348
  /* Protect against spurious interrupts.  This has been observed to
349
     be a problem under NetBSD 1.4 and 1.5.  */
350
 
351
  FD_ZERO (&readset);
352
  FD_SET (remote_desc, &readset);
353
  if (select (remote_desc + 1, &readset, 0, 0, &immediate) > 0)
354
    {
355
      int cc;
356
      char c;
357
 
358
      cc = read (remote_desc, &c, 1);
359
 
360
      if (cc != 1 || c != '\003')
361
        {
362
          fprintf (stderr, "input_interrupt, cc = %d c = %d\n", cc, c);
363
          return;
364
        }
365
 
366
      kill (signal_pid, SIGINT);
367
    }
368
}
369
 
370
void
371
enable_async_io (void)
372
{
373
  signal (SIGIO, input_interrupt);
374
}
375
 
376
void
377
disable_async_io (void)
378
{
379
  signal (SIGIO, SIG_IGN);
380
}
381
 
382
/* Returns next char from remote GDB.  -1 if error.  */
383
 
384
static int
385
readchar (void)
386
{
387
  static char buf[BUFSIZ];
388
  static int bufcnt = 0;
389
  static char *bufp;
390
 
391
  if (bufcnt-- > 0)
392
    return *bufp++ & 0x7f;
393
 
394
  bufcnt = read (remote_desc, buf, sizeof (buf));
395
 
396
  if (bufcnt <= 0)
397
    {
398
      if (bufcnt == 0)
399
        fprintf (stderr, "readchar: Got EOF\n");
400
      else
401
        perror ("readchar");
402
 
403
      return -1;
404
    }
405
 
406
  bufp = buf;
407
  bufcnt--;
408
  return *bufp++ & 0x7f;
409
}
410
 
411
/* Read a packet from the remote machine, with error checking,
412
   and store it in BUF.  Returns length of packet, or negative if error. */
413
 
414
int
415
getpkt (char *buf)
416
{
417
  char *bp;
418
  unsigned char csum, c1, c2;
419
  int c;
420
 
421
  while (1)
422
    {
423
      csum = 0;
424
 
425
      while (1)
426
        {
427
          c = readchar ();
428
          if (c == '$')
429
            break;
430
          if (remote_debug)
431
            {
432
              fprintf (stderr, "[getpkt: discarding char '%c']\n", c);
433
              fflush (stderr);
434
            }
435
 
436
          if (c < 0)
437
            return -1;
438
        }
439
 
440
      bp = buf;
441
      while (1)
442
        {
443
          c = readchar ();
444
          if (c < 0)
445
            return -1;
446
          if (c == '#')
447
            break;
448
          *bp++ = c;
449
          csum += c;
450
        }
451
      *bp = 0;
452
 
453
      c1 = fromhex (readchar ());
454
      c2 = fromhex (readchar ());
455
 
456
      if (csum == (c1 << 4) + c2)
457
        break;
458
 
459
      fprintf (stderr, "Bad checksum, sentsum=0x%x, csum=0x%x, buf=%s\n",
460
               (c1 << 4) + c2, csum, buf);
461
      write (remote_desc, "-", 1);
462
    }
463
 
464
  if (remote_debug)
465
    {
466
      fprintf (stderr, "getpkt (\"%s\");  [sending ack] \n", buf);
467
      fflush (stderr);
468
    }
469
 
470
  write (remote_desc, "+", 1);
471
 
472
  if (remote_debug)
473
    {
474
      fprintf (stderr, "[sent ack]\n");
475
      fflush (stderr);
476
    }
477
 
478
  return bp - buf;
479
}
480
 
481
void
482
write_ok (char *buf)
483
{
484
  buf[0] = 'O';
485
  buf[1] = 'K';
486
  buf[2] = '\0';
487
}
488
 
489
void
490
write_enn (char *buf)
491
{
492
  buf[0] = 'E';
493
  buf[1] = 'N';
494
  buf[2] = 'N';
495
  buf[3] = '\0';
496
}
497
 
498
void
499
convert_int_to_ascii (char *from, char *to, int n)
500
{
501
  int nib;
502
  char ch;
503
  while (n--)
504
    {
505
      ch = *from++;
506
      nib = ((ch & 0xf0) >> 4) & 0x0f;
507
      *to++ = tohex (nib);
508
      nib = ch & 0x0f;
509
      *to++ = tohex (nib);
510
    }
511
  *to++ = 0;
512
}
513
 
514
 
515
void
516
convert_ascii_to_int (char *from, char *to, int n)
517
{
518
  int nib1, nib2;
519
  while (n--)
520
    {
521
      nib1 = fromhex (*from++);
522
      nib2 = fromhex (*from++);
523
      *to++ = (((nib1 & 0x0f) << 4) & 0xf0) | (nib2 & 0x0f);
524
    }
525
}
526
 
527
static char *
528
outreg (int regno, char *buf)
529
{
530
  if ((regno >> 12) != 0)
531
    *buf++ = tohex ((regno >> 12) & 0xf);
532
  if ((regno >> 8) != 0)
533
    *buf++ = tohex ((regno >> 8) & 0xf);
534
  *buf++ = tohex ((regno >> 4) & 0xf);
535
  *buf++ = tohex (regno & 0xf);
536
  *buf++ = ':';
537
  collect_register_as_string (regno, buf);
538
  buf += 2 * register_size (regno);
539
  *buf++ = ';';
540
 
541
  return buf;
542
}
543
 
544
void
545
new_thread_notify (int id)
546
{
547
  char own_buf[256];
548
 
549
  /* The `n' response is not yet part of the remote protocol.  Do nothing.  */
550
  if (1)
551
    return;
552
 
553
  if (server_waiting == 0)
554
    return;
555
 
556
  sprintf (own_buf, "n%x", id);
557
  disable_async_io ();
558
  putpkt (own_buf);
559
  enable_async_io ();
560
}
561
 
562
void
563
dead_thread_notify (int id)
564
{
565
  char own_buf[256];
566
 
567
  /* The `x' response is not yet part of the remote protocol.  Do nothing.  */
568
  if (1)
569
    return;
570
 
571
  sprintf (own_buf, "x%x", id);
572
  disable_async_io ();
573
  putpkt (own_buf);
574
  enable_async_io ();
575
}
576
 
577
void
578
prepare_resume_reply (char *buf, char status, unsigned char signo)
579
{
580
  int nib, sig;
581
 
582
  *buf++ = status;
583
 
584
  sig = (int)target_signal_from_host (signo);
585
 
586
  nib = ((sig & 0xf0) >> 4);
587
  *buf++ = tohex (nib);
588
  nib = sig & 0x0f;
589
  *buf++ = tohex (nib);
590
 
591
  if (status == 'T')
592
    {
593
      const char **regp = gdbserver_expedite_regs;
594
      while (*regp)
595
        {
596
          buf = outreg (find_regno (*regp), buf);
597
          regp ++;
598
        }
599
 
600
      /* Formerly, if the debugger had not used any thread features we would not
601
         burden it with a thread status response.  This was for the benefit of
602
         GDB 4.13 and older.  However, in recent GDB versions the check
603
         (``if (cont_thread != 0)'') does not have the desired effect because of
604
         sillyness in the way that the remote protocol handles specifying a thread.
605
         Since thread support relies on qSymbol support anyway, assume GDB can handle
606
         threads.  */
607
 
608
      if (using_threads)
609
        {
610
          /* FIXME right place to set this? */
611
          thread_from_wait = ((struct inferior_list_entry *)current_inferior)->id;
612
          if (debug_threads)
613
            fprintf (stderr, "Writing resume reply for %d\n\n", thread_from_wait);
614
          if (old_thread_from_wait != thread_from_wait)
615
            {
616
              general_thread = thread_from_wait;
617
              sprintf (buf, "thread:%x;", thread_from_wait);
618
              buf += strlen (buf);
619
              old_thread_from_wait = thread_from_wait;
620
            }
621
        }
622
    }
623
  /* For W and X, we're done.  */
624
  *buf++ = 0;
625
}
626
 
627
void
628
decode_m_packet (char *from, CORE_ADDR *mem_addr_ptr, unsigned int *len_ptr)
629
{
630
  int i = 0, j = 0;
631
  char ch;
632
  *mem_addr_ptr = *len_ptr = 0;
633
 
634
  while ((ch = from[i++]) != ',')
635
    {
636
      *mem_addr_ptr = *mem_addr_ptr << 4;
637
      *mem_addr_ptr |= fromhex (ch) & 0x0f;
638
    }
639
 
640
  for (j = 0; j < 4; j++)
641
    {
642
      if ((ch = from[i++]) == 0)
643
        break;
644
      *len_ptr = *len_ptr << 4;
645
      *len_ptr |= fromhex (ch) & 0x0f;
646
    }
647
}
648
 
649
void
650
decode_M_packet (char *from, CORE_ADDR *mem_addr_ptr, unsigned int *len_ptr,
651
                 char *to)
652
{
653
  int i = 0;
654
  char ch;
655
  *mem_addr_ptr = *len_ptr = 0;
656
 
657
  while ((ch = from[i++]) != ',')
658
    {
659
      *mem_addr_ptr = *mem_addr_ptr << 4;
660
      *mem_addr_ptr |= fromhex (ch) & 0x0f;
661
    }
662
 
663
  while ((ch = from[i++]) != ':')
664
    {
665
      *len_ptr = *len_ptr << 4;
666
      *len_ptr |= fromhex (ch) & 0x0f;
667
    }
668
 
669
  convert_ascii_to_int (&from[i++], to, *len_ptr);
670
}
671
 
672
int
673
look_up_one_symbol (const char *name, CORE_ADDR *addrp)
674
{
675
  char own_buf[266], *p, *q;
676
  int len;
677
 
678
  /* Send the request.  */
679
  strcpy (own_buf, "qSymbol:");
680
  hexify (own_buf + strlen ("qSymbol:"), name, strlen (name));
681
  if (putpkt (own_buf) < 0)
682
    return -1;
683
 
684
  /* FIXME:  Eventually add buffer overflow checking (to getpkt?)  */
685
  len = getpkt (own_buf);
686
  if (len < 0)
687
    return -1;
688
 
689
  if (strncmp (own_buf, "qSymbol:", strlen ("qSymbol:")) != 0)
690
    {
691
      /* Malformed response.  */
692
      if (remote_debug)
693
        {
694
          fprintf (stderr, "Malformed response to qSymbol, ignoring.\n");
695
          fflush (stderr);
696
        }
697
 
698
      return -1;
699
    }
700
 
701
  p = own_buf + strlen ("qSymbol:");
702
  q = p;
703
  while (*q && *q != ':')
704
    q++;
705
 
706
  /* Make sure we found a value for the symbol.  */
707
  if (p == q || *q == '\0')
708
    return 0;
709
 
710
  decode_address (addrp, p, q - p);
711
  return 1;
712
}
713
 

powered by: WebSVN 2.1.0

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