Import gdb-7.10.1
[dragonfly.git] / contrib / gdb-7 / gdb / stubs / ia64vms-stub.c
1 /* GDB stub for Itanium OpenVMS
2    Copyright (C) 2012-2015 Free Software Foundation, Inc.
3
4    Contributed by Tristan Gingold, AdaCore.
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 3 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, see <http://www.gnu.org/licenses/>.  */
18
19 /* On VMS, the debugger (in our case the stub) is loaded in the process and
20    executed (via SYS$IMGSTA) before the main entry point of the executable.
21    In UNIX parlance, this is like using LD_PRELOAD and debug via installing
22    SIGTRAP, SIGSEGV... handlers.
23
24    This is currently a partial implementation.  In particular, modifying
25    registers is currently not implemented, as well as inferior procedure
26    calls.
27
28    This is written in very low-level C, in order not to use the C runtime,
29    because it may have weird consequences on the program being debugged.
30 */
31
32 #if __INITIAL_POINTER_SIZE != 64
33 #error "Must be compiled with 64 bit pointers"
34 #endif
35
36 #define __NEW_STARLET 1
37 #include <descrip.h>
38 #include <iledef.h>
39 #include <efndef.h>
40 #include <in.h>
41 #include <inet.h>
42 #include <iodef.h>
43 #include <ssdef.h>
44 #include <starlet.h>
45 #include <stsdef.h>
46 #include <tcpip$inetdef.h>
47
48 #include <lib$routines.h>
49 #include <ots$routines.h>
50 #include <str$routines.h>
51 #include <libdef.h>
52 #include <clidef.h>
53 #include <iosbdef.h>
54 #include <dvidef.h>
55 #include <lnmdef.h>
56 #include <builtins.h>
57 #include <prtdef.h>
58 #include <psldef.h>
59 #include <ssdef.h>
60 #include <chfdef.h>
61
62 #include <lib_c/imcbdef.h>
63 #include <lib_c/ldrimgdef.h>
64 #include <lib_c/intstkdef.h>
65 #include <lib_c/psrdef.h>
66 #include <lib_c/ifddef.h>
67 #include <lib_c/eihddef.h>
68
69 #include <stdarg.h>
70 #include <pthread_debug.h>
71
72 #define VMS_PAGE_SIZE 0x2000
73 #define VMS_PAGE_MASK (VMS_PAGE_SIZE - 1)
74
75 /* Declared in lib$ots.  */
76 extern void ots$fill (void *addr, size_t len, unsigned char b);
77 extern void ots$move (void *dst, size_t len, const void *src);
78 extern int ots$strcmp_eql (const void *str1, size_t str1len,
79                            const void *str2, size_t str2len);
80
81 /* Stub port number.  */
82 static unsigned int serv_port = 1234;
83
84 /* DBGEXT structure.  Not declared in any header.  */
85 struct dbgext_control_block
86 {
87   unsigned short dbgext$w_function_code;
88 #define DBGEXT$K_NEXT_TASK            3
89 #define DBGEXT$K_STOP_ALL_OTHER_TASKS 31
90 #define DBGEXT$K_GET_REGS 33
91   unsigned short dbgext$w_facility_id;
92 #define CMA$_FACILITY 64
93   unsigned int dbgext$l_status;
94   unsigned int dbgext$l_flags;
95   unsigned int dbgext$l_print_routine;
96   unsigned int dbgext$l_evnt_code;
97   unsigned int dbgext$l_evnt_name;
98   unsigned int dbgext$l_evnt_entry;
99   unsigned int dbgext$l_task_value;
100   unsigned int dbgext$l_task_number;
101   unsigned int dbgext$l_ada_flags;
102   unsigned int dbgext$l_stop_value;
103 #define dbgext$l_priority   dbgext$l_stop_value;
104 #define dbgext$l_symb_addr  dbgext$l_stop_value;
105 #define dbgext$l_time_slice dbgext$l_stop_value;
106   unsigned int dbgext$l_active_registers;
107 };
108
109 #pragma pointer_size save
110 #pragma pointer_size 32
111
112 /* Pthread handler.  */
113 static int (*dbgext_func) (struct dbgext_control_block *blk);
114
115 #pragma pointer_size restore
116
117 /* Set to 1 if thread-aware.  */
118 static int has_threads;
119
120 /* Current thread.  */
121 static pthread_t selected_thread;
122 static pthreadDebugId_t selected_id;
123
124 /* Internal debugging flags.  */
125 struct debug_flag
126 {
127   /* Name of the flag (as a string descriptor).  */
128   const struct dsc$descriptor_s name;
129   /* Value.  */
130   int val;
131 };
132
133 /* Macro to define a debugging flag.  */
134 #define DEBUG_FLAG_ENTRY(str) \
135   { { sizeof (str) - 1, DSC$K_DTYPE_T, DSC$K_CLASS_S, str }, 0}
136
137 static struct debug_flag debug_flags[] =
138 {
139   /* Disp packets exchanged with gdb.  */
140   DEBUG_FLAG_ENTRY("packets"),
141 #define trace_pkt (debug_flags[0].val)
142   /* Display entry point informations.  */
143   DEBUG_FLAG_ENTRY("entry"),
144 #define trace_entry (debug_flags[1].val)
145   /* Be verbose about exceptions.  */
146   DEBUG_FLAG_ENTRY("excp"),
147 #define trace_excp (debug_flags[2].val)
148   /* Be verbose about unwinding.  */
149   DEBUG_FLAG_ENTRY("unwind"),
150 #define trace_unwind (debug_flags[3].val)
151   /* Display image at startup.  */
152   DEBUG_FLAG_ENTRY("images"),
153 #define trace_images (debug_flags[4].val)
154   /* Display pthread_debug info.  */
155   DEBUG_FLAG_ENTRY("pthreaddbg")
156 #define trace_pthreaddbg (debug_flags[5].val)
157 };
158
159 #define NBR_DEBUG_FLAGS (sizeof (debug_flags) / sizeof (debug_flags[0]))
160
161 /* Connect inet device I/O channel.  */
162 static unsigned short conn_channel;
163
164 /* Widely used hex digit to ascii.  */
165 static const char hex[] = "0123456789abcdef";
166
167 /* Socket characteristics.  Apparently, there are no declaration for it in
168    standard headers.  */
169 struct sockchar
170 {
171   unsigned short prot;
172   unsigned char type;
173   unsigned char af;
174 };
175
176 /* Chain of images loaded.  */
177 extern IMCB* ctl$gl_imglstptr;
178
179 /* IA64 integer register representation.  */
180 union ia64_ireg
181 {
182   unsigned __int64 v;
183   unsigned char b[8];
184 };
185
186 /* IA64 register numbers, as defined by ia64-tdep.h.  */
187 #define IA64_GR0_REGNUM         0
188 #define IA64_GR32_REGNUM        (IA64_GR0_REGNUM + 32)
189
190 /* Floating point registers; 128 82-bit wide registers.  */
191 #define IA64_FR0_REGNUM         128
192
193 /* Predicate registers; There are 64 of these one bit registers.  It'd
194    be more convenient (implementation-wise) to use a single 64 bit
195    word with all of these register in them.  Note that there's also a
196    IA64_PR_REGNUM below which contains all the bits and is used for
197    communicating the actual values to the target.  */
198 #define IA64_PR0_REGNUM         256
199
200 /* Branch registers: 8 64-bit registers for holding branch targets.  */
201 #define IA64_BR0_REGNUM         320
202
203 /* Virtual frame pointer; this matches IA64_FRAME_POINTER_REGNUM in
204    gcc/config/ia64/ia64.h.  */
205 #define IA64_VFP_REGNUM         328
206
207 /* Virtual return address pointer; this matches
208    IA64_RETURN_ADDRESS_POINTER_REGNUM in gcc/config/ia64/ia64.h.  */
209 #define IA64_VRAP_REGNUM        329
210
211 /* Predicate registers: There are 64 of these 1-bit registers.  We
212    define a single register which is used to communicate these values
213    to/from the target.  We will somehow contrive to make it appear
214    that IA64_PR0_REGNUM thru IA64_PR63_REGNUM hold the actual values.  */
215 #define IA64_PR_REGNUM          330
216
217 /* Instruction pointer: 64 bits wide.  */
218 #define IA64_IP_REGNUM          331
219
220 /* Process Status Register.  */
221 #define IA64_PSR_REGNUM         332
222
223 /* Current Frame Marker (raw form may be the cr.ifs).  */
224 #define IA64_CFM_REGNUM         333
225
226 /* Application registers; 128 64-bit wide registers possible, but some
227    of them are reserved.  */
228 #define IA64_AR0_REGNUM         334
229 #define IA64_KR0_REGNUM         (IA64_AR0_REGNUM + 0)
230 #define IA64_KR7_REGNUM         (IA64_KR0_REGNUM + 7)
231
232 #define IA64_RSC_REGNUM         (IA64_AR0_REGNUM + 16)
233 #define IA64_BSP_REGNUM         (IA64_AR0_REGNUM + 17)
234 #define IA64_BSPSTORE_REGNUM    (IA64_AR0_REGNUM + 18)
235 #define IA64_RNAT_REGNUM        (IA64_AR0_REGNUM + 19)
236 #define IA64_FCR_REGNUM         (IA64_AR0_REGNUM + 21)
237 #define IA64_EFLAG_REGNUM       (IA64_AR0_REGNUM + 24)
238 #define IA64_CSD_REGNUM         (IA64_AR0_REGNUM + 25)
239 #define IA64_SSD_REGNUM         (IA64_AR0_REGNUM + 26)
240 #define IA64_CFLG_REGNUM        (IA64_AR0_REGNUM + 27)
241 #define IA64_FSR_REGNUM         (IA64_AR0_REGNUM + 28)
242 #define IA64_FIR_REGNUM         (IA64_AR0_REGNUM + 29)
243 #define IA64_FDR_REGNUM         (IA64_AR0_REGNUM + 30)
244 #define IA64_CCV_REGNUM         (IA64_AR0_REGNUM + 32)
245 #define IA64_UNAT_REGNUM        (IA64_AR0_REGNUM + 36)
246 #define IA64_FPSR_REGNUM        (IA64_AR0_REGNUM + 40)
247 #define IA64_ITC_REGNUM         (IA64_AR0_REGNUM + 44)
248 #define IA64_PFS_REGNUM         (IA64_AR0_REGNUM + 64)
249 #define IA64_LC_REGNUM          (IA64_AR0_REGNUM + 65)
250 #define IA64_EC_REGNUM          (IA64_AR0_REGNUM + 66)
251
252 /* NAT (Not A Thing) Bits for the general registers; there are 128 of
253    these.  */
254 #define IA64_NAT0_REGNUM        462
255
256 /* Process registers when a condition is caught.  */
257 struct ia64_all_regs
258 {
259   union ia64_ireg gr[32];
260   union ia64_ireg br[8];
261   union ia64_ireg ip;
262   union ia64_ireg psr;
263   union ia64_ireg bsp;
264   union ia64_ireg cfm;
265   union ia64_ireg pfs;
266   union ia64_ireg pr;
267 };
268
269 static struct ia64_all_regs excp_regs;
270 static struct ia64_all_regs sel_regs;
271 static pthread_t sel_regs_pthread;
272
273 /* IO channel for the terminal.  */
274 static unsigned short term_chan;
275
276 /* Output buffer and length.  */
277 static char term_buf[128];
278 static int term_buf_len;
279
280 /* Buffer for communication with gdb.  */
281 static unsigned char gdb_buf[sizeof (struct ia64_all_regs) * 2 + 64];
282 static unsigned int gdb_blen;
283
284 /* Previous primary handler.  */
285 static void *prevhnd;
286
287 /* Entry point address and bundle.  */
288 static unsigned __int64 entry_pc;
289 static unsigned char entry_saved[16];
290
291 /* Write on the terminal.  */
292
293 static void
294 term_raw_write (const char *str, unsigned int len)
295 {
296   unsigned short status;
297   struct _iosb iosb;
298
299   status = sys$qiow (EFN$C_ENF,           /* Event flag.  */
300                      term_chan,           /* I/O channel.  */
301                      IO$_WRITEVBLK,       /* I/O function code.  */
302                      &iosb,               /* I/O status block.  */
303                      0,                   /* Ast service routine.  */
304                      0,                   /* Ast parameter.  */
305                      (char *)str,         /* P1 - buffer address.  */
306                      len,                 /* P2 - buffer length.  */
307                      0, 0, 0, 0);
308
309   if (status & STS$M_SUCCESS)
310     status = iosb.iosb$w_status;
311   if (!(status & STS$M_SUCCESS))
312     LIB$SIGNAL (status);
313 }
314
315 /* Flush ther term buffer.  */
316
317 static void
318 term_flush (void)
319 {
320   if (term_buf_len != 0)
321     {
322       term_raw_write (term_buf, term_buf_len);
323       term_buf_len = 0;
324     }
325 }
326
327 /* Write a single character, without translation.  */
328
329 static void
330 term_raw_putchar (char c)
331 {
332   if (term_buf_len == sizeof (term_buf))
333     term_flush ();
334   term_buf[term_buf_len++] = c;
335 }
336
337 /* Write character C.  Translate '\n' to '\n\r'.  */
338
339 static void
340 term_putc (char c)
341 {
342   if (c < 32)
343     switch (c)
344       {
345       case '\r':
346       case '\n':
347         break;
348       default:
349         c = '.';
350         break;
351       }
352   term_raw_putchar (c);
353   if (c == '\n')
354     {
355       term_raw_putchar ('\r');
356       term_flush ();
357     }
358 }
359
360 /* Write a C string.  */
361
362 static void
363 term_puts (const char *str)
364 {
365   while (*str)
366     term_putc (*str++);
367 }
368
369 /* Write LEN bytes from STR.  */
370
371 static void
372 term_write (const char *str, unsigned int len)
373 {
374   for (; len > 0; len--)
375     term_putc (*str++);
376 }
377
378 /* Write using FAO formatting.  */
379
380 static void
381 term_fao (const char *str, unsigned int str_len, ...)
382 {
383   int cnt;
384   va_list vargs;
385   int i;
386   __int64 *args;
387   int status;
388   struct dsc$descriptor_s dstr =
389     { str_len, DSC$K_DTYPE_T, DSC$K_CLASS_S, (__char_ptr32)str };
390   char buf[128];
391   $DESCRIPTOR (buf_desc, buf);
392
393   va_start (vargs, str_len);
394   va_count (cnt);
395   args = (__int64 *) __ALLOCA (cnt * sizeof (__int64));
396   cnt -= 2;
397   for (i = 0; i < cnt; i++)
398     args[i] = va_arg (vargs, __int64);
399
400   status = sys$faol_64 (&dstr, &buf_desc.dsc$w_length, &buf_desc, args);
401   if (status & 1)
402     {
403       /* FAO !/ already insert a line feed.  */
404       for (i = 0; i < buf_desc.dsc$w_length; i++)
405         {
406           term_raw_putchar (buf[i]);
407           if (buf[i] == '\n')
408             term_flush ();
409         }
410     }
411       
412   va_end (vargs);
413 }
414
415 #define TERM_FAO(STR, ...) term_fao (STR, sizeof (STR) - 1, __VA_ARGS__)
416
417 /* New line.  */
418
419 static void
420 term_putnl (void)
421 {
422   term_putc ('\n');
423 }
424
425 /* Initialize terminal.  */
426
427 static void
428 term_init (void)
429 {
430   unsigned int status,i;
431   unsigned short len;
432   char resstring[LNM$C_NAMLENGTH];
433   static const $DESCRIPTOR (tabdesc, "LNM$FILE_DEV");
434   static const $DESCRIPTOR (logdesc, "SYS$OUTPUT");
435   $DESCRIPTOR (term_desc, resstring);
436   ILE3 item_lst[2];
437
438   item_lst[0].ile3$w_length = LNM$C_NAMLENGTH;
439   item_lst[0].ile3$w_code = LNM$_STRING;
440   item_lst[0].ile3$ps_bufaddr = resstring;
441   item_lst[0].ile3$ps_retlen_addr = &len;
442   item_lst[1].ile3$w_length = 0;
443   item_lst[1].ile3$w_code = 0;
444
445   /* Translate the logical name.  */
446   status = SYS$TRNLNM (0,                 /* Attr of the logical name.  */
447                        (void *) &tabdesc, /* Logical name table.  */
448                        (void *) &logdesc, /* Logical name.  */
449                        0,          /* Access mode.  */
450                        item_lst);  /* Item list.  */
451   if (!(status & STS$M_SUCCESS))
452     LIB$SIGNAL (status);
453
454   term_desc.dsc$w_length = len;
455
456   /* Examine 4-byte header.  Skip escape sequence.  */
457   if (resstring[0] == 0x1B)
458     {
459       term_desc.dsc$w_length -= 4;
460       term_desc.dsc$a_pointer += 4;
461     }
462
463   /* Assign a channel.  */
464   status = sys$assign (&term_desc,   /* Device name.  */
465                        &term_chan,   /* I/O channel.  */
466                        0,            /* Access mode.  */
467                        0);
468   if (!(status & STS$M_SUCCESS))
469     LIB$SIGNAL (status);
470 }
471
472 /* Convert from native endianness to network endianness (and vice-versa).  */
473
474 static unsigned int
475 wordswap (unsigned int v)
476 {
477   return ((v & 0xff) << 8) | ((v >> 8) & 0xff);
478 }
479
480 /* Initialize the socket connection, and wait for a client.  */
481
482 static void
483 sock_init (void)
484 {
485   struct _iosb iosb;
486   unsigned int status;
487
488   /* Listen channel and characteristics.  */
489   unsigned short listen_channel;
490   struct sockchar listen_sockchar;
491
492   /* Client address.  */
493   unsigned short cli_addrlen;
494   struct sockaddr_in cli_addr;
495   ILE3 cli_itemlst;
496
497   /* Our address.  */
498   struct sockaddr_in serv_addr;
499   ILE2 serv_itemlst;
500
501   /* Reuseaddr option value (on).  */
502   int optval = 1;
503   ILE2 sockopt_itemlst;
504   ILE2 reuseaddr_itemlst;
505
506   /* TCP/IP network pseudodevice.  */
507   static const $DESCRIPTOR (inet_device, "TCPIP$DEVICE:");
508
509   /* Initialize socket characteristics.  */
510   listen_sockchar.prot = TCPIP$C_TCP;
511   listen_sockchar.type = TCPIP$C_STREAM;
512   listen_sockchar.af   = TCPIP$C_AF_INET;
513
514   /* Assign I/O channels to network device.  */
515   status = sys$assign ((void *) &inet_device, &listen_channel, 0, 0);
516   if (status & STS$M_SUCCESS)
517     status = sys$assign ((void *) &inet_device, &conn_channel, 0, 0);
518   if (!(status & STS$M_SUCCESS))
519     {
520       term_puts ("Failed to assign I/O channel(s)\n");
521       LIB$SIGNAL (status);
522     }
523
524   /* Create a listen socket.  */
525   status = sys$qiow (EFN$C_ENF,           /* Event flag.  */
526                      listen_channel,      /* I/O channel.  */
527                      IO$_SETMODE,         /* I/O function code.  */
528                      &iosb,               /* I/O status block.  */
529                      0,                   /* Ast service routine.  */
530                      0,                   /* Ast parameter.  */
531                      &listen_sockchar,    /* P1 - socket characteristics.  */
532                      0, 0, 0, 0, 0);
533   if (status & STS$M_SUCCESS)
534     status = iosb.iosb$w_status;
535   if (!(status & STS$M_SUCCESS))
536     {
537       term_puts ("Failed to create socket\n");
538       LIB$SIGNAL (status);
539     }
540
541   /* Set reuse address option.  */
542   /* Initialize reuseaddr's item-list element.  */
543   reuseaddr_itemlst.ile2$w_length   = sizeof (optval);
544   reuseaddr_itemlst.ile2$w_code     = TCPIP$C_REUSEADDR;
545   reuseaddr_itemlst.ile2$ps_bufaddr = &optval;
546
547   /* Initialize setsockopt's item-list descriptor.  */
548   sockopt_itemlst.ile2$w_length   = sizeof (reuseaddr_itemlst);
549   sockopt_itemlst.ile2$w_code     = TCPIP$C_SOCKOPT;
550   sockopt_itemlst.ile2$ps_bufaddr = &reuseaddr_itemlst;
551
552   status = sys$qiow (EFN$C_ENF,       /* Event flag.  */
553                      listen_channel,  /* I/O channel.  */
554                      IO$_SETMODE,     /* I/O function code.  */
555                      &iosb,           /* I/O status block.  */
556                      0,               /* Ast service routine.  */
557                      0,               /* Ast parameter.  */
558                      0,               /* P1.  */
559                      0,               /* P2.  */
560                      0,               /* P3.  */
561                      0,               /* P4.  */
562                      (__int64) &sockopt_itemlst, /* P5 - socket options.  */
563                      0);
564   if (status & STS$M_SUCCESS)
565     status = iosb.iosb$w_status;
566   if (!(status & STS$M_SUCCESS))
567     {
568       term_puts ("Failed to set socket option\n");
569       LIB$SIGNAL (status);
570     }
571
572   /* Bind server's ip address and port number to listen socket.  */
573   /* Initialize server's socket address structure.  */
574   ots$fill (&serv_addr, sizeof (serv_addr), 0);
575   serv_addr.sin_family = TCPIP$C_AF_INET;
576   serv_addr.sin_port = wordswap (serv_port);
577   serv_addr.sin_addr.s_addr = TCPIP$C_INADDR_ANY;
578
579   /* Initialize server's item-list descriptor.  */
580   serv_itemlst.ile2$w_length   = sizeof (serv_addr);
581   serv_itemlst.ile2$w_code     = TCPIP$C_SOCK_NAME;
582   serv_itemlst.ile2$ps_bufaddr = &serv_addr;
583
584   status = sys$qiow (EFN$C_ENF,           /* Event flag.  */
585                      listen_channel,      /* I/O channel.  */
586                      IO$_SETMODE,         /* I/O function code.  */
587                      &iosb,               /* I/O status block.  */
588                      0,                   /* Ast service routine.  */
589                      0,                   /* Ast parameter.  */
590                      0,                   /* P1.  */
591                      0,                   /* P2.  */
592                      (__int64) &serv_itemlst, /* P3 - local socket name.  */
593                      0, 0, 0);
594   if (status & STS$M_SUCCESS)
595     status = iosb.iosb$w_status;
596   if (!(status & STS$M_SUCCESS))
597     {
598       term_puts ("Failed to bind socket\n");
599       LIB$SIGNAL (status);
600     }
601
602   /* Set socket as a listen socket.  */
603   status = sys$qiow (EFN$C_ENF,           /* Event flag.  */
604                      listen_channel,      /* I/O channel.  */
605                      IO$_SETMODE,         /* I/O function code.  */
606                      &iosb,               /* I/O status block.  */
607                      0,                   /* Ast service routine.  */
608                      0,                   /* Ast parameter.  */
609                      0,                   /* P1.  */
610                      0,                   /* P2.  */
611                      0,                   /* P3.  */
612                      1,                   /* P4 - connection backlog.  */
613                      0, 0);
614   if (status & STS$M_SUCCESS)
615     status = iosb.iosb$w_status;
616   if (!(status & STS$M_SUCCESS))
617     {
618       term_puts ("Failed to set socket passive\n");
619       LIB$SIGNAL (status);
620     }
621
622   /* Accept connection from a client.  */
623   TERM_FAO ("Waiting for a client connection on port: !ZW!/",
624             wordswap (serv_addr.sin_port));
625
626   status = sys$qiow (EFN$C_ENF,              /* Event flag.  */
627                      listen_channel,         /* I/O channel.  */
628                      IO$_ACCESS|IO$M_ACCEPT, /* I/O function code.  */
629                      &iosb,                  /* I/O status block.  */
630                      0,                      /* Ast service routine.  */
631                      0,                      /* Ast parameter.  */
632                      0,                      /* P1.  */
633                      0,                      /* P2.  */
634                      0,                      /* P3.  */
635                      (__int64) &conn_channel, /* P4 - I/O channel for conn.  */
636                      0, 0);
637
638   if (status & STS$M_SUCCESS)
639     status = iosb.iosb$w_status;
640   if (!(status & STS$M_SUCCESS))
641     {
642       term_puts ("Failed to accept client connection\n");
643       LIB$SIGNAL (status);
644     }
645
646   /* Log client connection request.  */
647   cli_itemlst.ile3$w_length = sizeof (cli_addr);
648   cli_itemlst.ile3$w_code = TCPIP$C_SOCK_NAME;
649   cli_itemlst.ile3$ps_bufaddr = &cli_addr;
650   cli_itemlst.ile3$ps_retlen_addr = &cli_addrlen;
651   ots$fill (&cli_addr, sizeof(cli_addr), 0);
652   status = sys$qiow (EFN$C_ENF,           /* Event flag.  */
653                      conn_channel,        /* I/O channel.  */
654                      IO$_SENSEMODE,       /* I/O function code.  */
655                      &iosb,               /* I/O status block.  */
656                      0,                   /* Ast service routine.  */
657                      0,                   /* Ast parameter.  */
658                      0,                   /* P1.  */
659                      0,                   /* P2.  */
660                      0,                   /* P3.  */
661                      (__int64) &cli_itemlst,  /* P4 - peer socket name.  */
662                      0, 0);
663   if (status & STS$M_SUCCESS)
664     status = iosb.iosb$w_status;
665   if (!(status & STS$M_SUCCESS))
666     {
667       term_puts ("Failed to get client name\n");
668       LIB$SIGNAL (status);
669     }
670
671   TERM_FAO ("Accepted connection from host: !UB.!UB,!UB.!UB, port: !UW!/",
672             (cli_addr.sin_addr.s_addr >> 0) & 0xff,
673             (cli_addr.sin_addr.s_addr >> 8) & 0xff,
674             (cli_addr.sin_addr.s_addr >> 16) & 0xff,
675             (cli_addr.sin_addr.s_addr >> 24) & 0xff,
676             wordswap (cli_addr.sin_port));
677 }
678
679 /* Close the socket.  */
680
681 static void
682 sock_close (void)
683 {
684   struct _iosb iosb;
685   unsigned int status;
686
687   /* Close socket.  */
688   status = sys$qiow (EFN$C_ENF,           /* Event flag.  */
689                      conn_channel,        /* I/O channel.  */
690                      IO$_DEACCESS,        /* I/O function code.  */
691                      &iosb,               /* I/O status block.  */
692                      0,                   /* Ast service routine.  */
693                      0,                   /* Ast parameter.  */
694                      0, 0, 0, 0, 0, 0);
695
696   if (status & STS$M_SUCCESS)
697     status = iosb.iosb$w_status;
698   if (!(status & STS$M_SUCCESS))
699     {
700       term_puts ("Failed to close socket\n");
701       LIB$SIGNAL (status);
702     }
703
704   /* Deassign I/O channel to network device.  */
705   status = sys$dassgn (conn_channel);
706
707   if (!(status & STS$M_SUCCESS))
708     {
709       term_puts ("Failed to deassign I/O channel\n");
710       LIB$SIGNAL (status);
711     }
712 }
713
714 /* Mark a page as R/W.  Return old rights.  */
715
716 static unsigned int
717 page_set_rw (unsigned __int64 startva, unsigned __int64 len,
718              unsigned int *oldprot)
719 {
720   unsigned int status;
721   unsigned __int64 retva;
722   unsigned __int64 retlen;
723
724   status = SYS$SETPRT_64 ((void *)startva, len, PSL$C_USER, PRT$C_UW,
725                           (void *)&retva, &retlen, oldprot);
726   return status;
727 }
728
729 /* Restore page rights.  */
730
731 static void
732 page_restore_rw (unsigned __int64 startva, unsigned __int64 len,
733                 unsigned int prot)
734 {
735   unsigned int status;
736   unsigned __int64 retva;
737   unsigned __int64 retlen;
738   unsigned int oldprot;
739
740   status = SYS$SETPRT_64 ((void *)startva, len, PSL$C_USER, prot,
741                           (void *)&retva, &retlen, &oldprot);
742   if (!(status & STS$M_SUCCESS))
743     LIB$SIGNAL (status);
744 }
745
746 /* Get the TEB (thread environment block).  */
747
748 static pthread_t
749 get_teb (void)
750 {
751   return (pthread_t)__getReg (_IA64_REG_TP);
752 }
753
754 /* Enable thread scheduling if VAL is true.  */
755
756 static unsigned int
757 set_thread_scheduling (int val)
758 {
759   struct dbgext_control_block blk;
760   unsigned int status;
761
762   if (!dbgext_func)
763     return 0;
764
765   blk.dbgext$w_function_code = DBGEXT$K_STOP_ALL_OTHER_TASKS;
766   blk.dbgext$w_facility_id = CMA$_FACILITY;
767   blk.dbgext$l_stop_value = val;
768
769   status = dbgext_func (&blk);
770   if (!(status & STS$M_SUCCESS))
771     {
772       TERM_FAO ("set_thread_scheduling error, val=!SL, status=!XL!/",
773                 val, blk.dbgext$l_status);
774       lib$signal (status);
775     }
776
777   return blk.dbgext$l_stop_value;
778 }
779
780 /* Get next thead (after THR).  Start with 0.  */
781
782 static unsigned int
783 thread_next (unsigned int thr)
784 {
785   struct dbgext_control_block blk;
786   unsigned int status;
787
788   if (!dbgext_func)
789     return 0;
790
791   blk.dbgext$w_function_code = DBGEXT$K_NEXT_TASK;
792   blk.dbgext$w_facility_id = CMA$_FACILITY;
793   blk.dbgext$l_ada_flags = 0;
794   blk.dbgext$l_task_value = thr;
795
796   status = dbgext_func (&blk);
797   if (!(status & STS$M_SUCCESS))
798     lib$signal (status);
799
800   return blk.dbgext$l_task_value;
801 }
802
803 /* Pthread Debug callbacks.  */
804
805 static int
806 read_callback (pthreadDebugClient_t context,
807                pthreadDebugTargetAddr_t addr,
808                pthreadDebugAddr_t buf,
809                size_t size)
810 {
811   if (trace_pthreaddbg)
812     TERM_FAO ("read_callback (!XH, !XH, !SL)!/", addr, buf, size);
813   ots$move (buf, size, addr);
814   return 0;
815 }
816
817 static int
818 write_callback (pthreadDebugClient_t context,
819                 pthreadDebugTargetAddr_t addr,
820                 pthreadDebugLongConstAddr_t buf,
821                 size_t size)
822 {
823   if (trace_pthreaddbg)
824     TERM_FAO ("write_callback (!XH, !XH, !SL)!/", addr, buf, size);
825   ots$move (addr, size, buf);
826   return 0;
827 }
828
829 static int
830 suspend_callback (pthreadDebugClient_t context)
831 {
832   /* Always suspended.  */
833   return 0;
834 }
835
836 static int
837 resume_callback (pthreadDebugClient_t context)
838 {
839   /* So no need to resume.  */
840   return 0;
841 }
842
843 static int
844 kthdinfo_callback (pthreadDebugClient_t context,
845                    pthreadDebugKId_t kid,
846                    pthreadDebugKThreadInfo_p thread_info)
847 {
848   if (trace_pthreaddbg)
849     term_puts ("kthinfo_callback");
850   return ENOSYS;
851 }
852
853 static int
854 hold_callback (pthreadDebugClient_t context,
855                pthreadDebugKId_t kid)
856 {
857   if (trace_pthreaddbg)
858     term_puts ("hold_callback");
859   return ENOSYS;
860 }
861
862 static int
863 unhold_callback (pthreadDebugClient_t context,
864                  pthreadDebugKId_t kid)
865 {
866   if (trace_pthreaddbg)
867     term_puts ("unhold_callback");
868   return ENOSYS;
869 }
870
871 static int
872 getfreg_callback (pthreadDebugClient_t context,
873                   pthreadDebugFregs_t *reg,
874                   pthreadDebugKId_t kid)
875 {
876   if (trace_pthreaddbg)
877     term_puts ("getfreg_callback");
878   return ENOSYS;
879 }
880
881 static int
882 setfreg_callback (pthreadDebugClient_t context,
883                   const pthreadDebugFregs_t *reg,
884                   pthreadDebugKId_t kid)
885 {
886   if (trace_pthreaddbg)
887     term_puts ("setfreg_callback");
888   return ENOSYS;
889 }
890
891 static int
892 getreg_callback (pthreadDebugClient_t context,
893                  pthreadDebugRegs_t *reg,
894                  pthreadDebugKId_t kid)
895 {
896   if (trace_pthreaddbg)
897     term_puts ("getreg_callback");
898   return ENOSYS;
899 }
900
901 static int
902 setreg_callback (pthreadDebugClient_t context,
903                  const pthreadDebugRegs_t *reg,
904                  pthreadDebugKId_t kid)
905 {
906   if (trace_pthreaddbg)
907     term_puts ("setreg_callback");
908   return ENOSYS;
909 }
910
911 static int
912 output_callback (pthreadDebugClient_t context, 
913                  pthreadDebugConstString_t line)
914 {
915   term_puts (line);
916   term_putnl ();
917   return 0;
918 }
919
920 static int
921 error_callback (pthreadDebugClient_t context, 
922                  pthreadDebugConstString_t line)
923 {
924   term_puts (line);
925   term_putnl ();
926   return 0;
927 }
928
929 static pthreadDebugAddr_t
930 malloc_callback (pthreadDebugClient_t caller_context, size_t size)
931 {
932   unsigned int status;
933   unsigned int res;
934   int len;
935
936   len = size + 16;
937   status = lib$get_vm (&len, &res, 0);
938   if (!(status & STS$M_SUCCESS))
939     LIB$SIGNAL (status);
940   if (trace_pthreaddbg)
941     TERM_FAO ("malloc_callback (!UL) -> !XA!/", size, res);
942   *(unsigned int *)res = len;
943   return (char *)res + 16;
944 }
945
946 static void
947 free_callback (pthreadDebugClient_t caller_context, pthreadDebugAddr_t address)
948 {
949   unsigned int status;
950   unsigned int res;
951   int len;
952
953   res = (unsigned int)address - 16;
954   len = *(unsigned int *)res;
955   if (trace_pthreaddbg)
956     TERM_FAO ("free_callback (!XA)!/", address);
957   status = lib$free_vm (&len, &res, 0);
958   if (!(status & STS$M_SUCCESS))
959     LIB$SIGNAL (status);
960 }
961
962 static int
963 speckthd_callback (pthreadDebugClient_t caller_context,
964                    pthreadDebugSpecialType_t type,
965                    pthreadDebugKId_t *kernel_tid)
966 {
967   return ENOTSUP;
968 }
969
970 static pthreadDebugCallbacks_t pthread_debug_callbacks = {
971   PTHREAD_DEBUG_VERSION,
972   read_callback,
973   write_callback,
974   suspend_callback,
975   resume_callback,
976   kthdinfo_callback,
977   hold_callback,
978   unhold_callback,
979   getfreg_callback,
980   setfreg_callback,
981   getreg_callback,
982   setreg_callback,
983   output_callback,
984   error_callback,
985   malloc_callback,
986   free_callback,
987   speckthd_callback
988 };
989
990 /* Name of the pthread shared library.  */
991 static const $DESCRIPTOR (pthread_rtl_desc, "PTHREAD$RTL");
992
993 /* List of symbols to extract from pthread debug library.  */
994 struct pthread_debug_entry
995 {
996   const unsigned int namelen;
997   const __char_ptr32 name;
998   __void_ptr32 func;
999 };
1000
1001 #define DEBUG_ENTRY(str) { sizeof(str) - 1, str, 0 }
1002
1003 static struct pthread_debug_entry pthread_debug_entries[] = {
1004   DEBUG_ENTRY("pthreadDebugContextInit"),
1005   DEBUG_ENTRY("pthreadDebugThdSeqInit"),
1006   DEBUG_ENTRY("pthreadDebugThdSeqNext"),
1007   DEBUG_ENTRY("pthreadDebugThdSeqDestroy"),
1008   DEBUG_ENTRY("pthreadDebugThdGetInfo"),
1009   DEBUG_ENTRY("pthreadDebugThdGetInfoAddr"),
1010   DEBUG_ENTRY("pthreadDebugThdGetReg"),
1011   DEBUG_ENTRY("pthreadDebugCmd")
1012 };
1013
1014 /* Pthread debug context.  */
1015 static pthreadDebugContext_t debug_context;
1016
1017 /* Wrapper around pthread debug entry points.  */
1018
1019 static int
1020 pthread_debug_thd_seq_init (pthreadDebugId_t *id)
1021 {
1022   return ((int (*)())pthread_debug_entries[1].func)
1023     (debug_context, id);
1024 }
1025
1026 static int
1027 pthread_debug_thd_seq_next (pthreadDebugId_t *id)
1028 {
1029   return ((int (*)())pthread_debug_entries[2].func)
1030     (debug_context, id);
1031 }
1032
1033 static int
1034 pthread_debug_thd_seq_destroy (void)
1035 {
1036   return ((int (*)())pthread_debug_entries[3].func)
1037     (debug_context);
1038 }
1039
1040 static int
1041 pthread_debug_thd_get_info (pthreadDebugId_t id,
1042                             pthreadDebugThreadInfo_t *info)
1043 {
1044   return ((int (*)())pthread_debug_entries[4].func)
1045     (debug_context, id, info);
1046 }
1047
1048 static int
1049 pthread_debug_thd_get_info_addr (pthread_t thr,
1050                                  pthreadDebugThreadInfo_t *info)
1051 {
1052   return ((int (*)())pthread_debug_entries[5].func)
1053     (debug_context, thr, info);
1054 }
1055
1056 static int
1057 pthread_debug_thd_get_reg (pthreadDebugId_t thr,
1058                            pthreadDebugRegs_t *regs)
1059 {
1060   return ((int (*)())pthread_debug_entries[6].func)
1061     (debug_context, thr, regs);
1062 }
1063
1064 static int
1065 stub_pthread_debug_cmd (const char *cmd)
1066 {
1067   return ((int (*)())pthread_debug_entries[7].func)
1068     (debug_context, cmd);
1069 }
1070
1071 /* Show all the threads.  */
1072
1073 static void
1074 threads_show (void)
1075 {
1076   pthreadDebugId_t id;
1077   pthreadDebugThreadInfo_t info;
1078   int res;
1079
1080   res = pthread_debug_thd_seq_init (&id);
1081   if (res != 0)
1082     {
1083       TERM_FAO ("seq init failed, res=!SL!/", res);
1084       return;
1085     }
1086   while (1)
1087     {
1088       if (pthread_debug_thd_get_info (id, &info) != 0)
1089         {
1090           TERM_FAO ("thd_get_info !SL failed!/", id);
1091           break;
1092         }
1093       if (pthread_debug_thd_seq_next (&id) != 0)
1094         break;
1095     }
1096   pthread_debug_thd_seq_destroy ();
1097 }
1098
1099 /* Initialize pthread support.  */
1100
1101 static void
1102 threads_init (void)
1103 {
1104   static const $DESCRIPTOR (dbgext_desc, "PTHREAD$DBGEXT");
1105   static const $DESCRIPTOR (pthread_debug_desc, "PTHREAD$DBGSHR");
1106   static const $DESCRIPTOR (dbgsymtable_desc, "PTHREAD_DBG_SYMTABLE");
1107   int pthread_dbgext;
1108   int status;
1109   void *dbg_symtable;
1110   int i;
1111   void *caller_context = 0;
1112
1113   status = lib$find_image_symbol
1114     ((void *) &pthread_rtl_desc, (void *) &dbgext_desc,
1115      (int *) &dbgext_func);
1116   if (!(status & STS$M_SUCCESS))
1117     LIB$SIGNAL (status);
1118   
1119   status = lib$find_image_symbol
1120     ((void *) &pthread_rtl_desc, (void *) &dbgsymtable_desc,
1121      (int *) &dbg_symtable);
1122   if (!(status & STS$M_SUCCESS))
1123     LIB$SIGNAL (status);
1124
1125   /* Find entry points in pthread_debug.  */
1126   for (i = 0;
1127        i < sizeof (pthread_debug_entries) / sizeof (pthread_debug_entries[0]);
1128        i++)
1129     {
1130       struct dsc$descriptor_s sym =
1131         { pthread_debug_entries[i].namelen,
1132           DSC$K_DTYPE_T, DSC$K_CLASS_S,
1133           pthread_debug_entries[i].name };
1134       status = lib$find_image_symbol
1135         ((void *) &pthread_debug_desc, (void *) &sym,
1136          (int *) &pthread_debug_entries[i].func);
1137       if (!(status & STS$M_SUCCESS))
1138         lib$signal (status);
1139     }
1140
1141   if (trace_pthreaddbg)
1142     TERM_FAO ("debug symtable: !XH!/", dbg_symtable);
1143   status = ((int (*)()) pthread_debug_entries[0].func)
1144     (&caller_context, &pthread_debug_callbacks, dbg_symtable, &debug_context);
1145   if (status != 0)
1146     TERM_FAO ("cannot initialize pthread_debug: !UL!/", status);
1147   TERM_FAO ("pthread debug done!/", 0);
1148 }
1149
1150 /* Convert an hexadecimal character to a nibble.  Return -1 in case of
1151    error.  */
1152
1153 static int
1154 hex2nibble (unsigned char h)
1155 {
1156   if (h >= '0' && h <= '9')
1157     return h - '0';
1158   if (h >= 'A' && h <= 'F')
1159     return h - 'A' + 10;
1160   if (h >= 'a' && h <= 'f')
1161     return h - 'a' + 10;
1162   return -1;
1163 }
1164
1165 /* Convert an hexadecimal 2 character string to a byte.  Return -1 in case
1166    of error.  */
1167
1168 static int
1169 hex2byte (const unsigned char *p)
1170 {
1171   int h, l;
1172
1173   h = hex2nibble (p[0]);
1174   l = hex2nibble (p[1]);
1175   if (h == -1 || l == -1)
1176     return -1;
1177   return (h << 4) | l;
1178 }
1179
1180 /* Convert a byte V to a 2 character strings P.  */
1181
1182 static void
1183 byte2hex (unsigned char *p, unsigned char v)
1184 {
1185   p[0] = hex[v >> 4];
1186   p[1] = hex[v & 0xf];
1187 }
1188
1189 /* Convert a quadword V to a 16 character strings P.  */
1190
1191 static void
1192 quad2hex (unsigned char *p, unsigned __int64 v)
1193 {
1194   int i;
1195   for (i = 0; i < 16; i++)
1196     {
1197       p[i] = hex[v >> 60];
1198       v <<= 4;
1199     }
1200 }
1201
1202 static void
1203 long2pkt (unsigned int v)
1204 {
1205   int i;
1206
1207   for (i = 0; i < 8; i++)
1208     {
1209       gdb_buf[gdb_blen + i] = hex[(v >> 28) & 0x0f];
1210       v <<= 4;
1211     }
1212   gdb_blen += 8;
1213 }
1214
1215 /* Generate an error packet.  */
1216
1217 static void
1218 packet_error (unsigned int err)
1219 {
1220   gdb_buf[1] = 'E';
1221   byte2hex (gdb_buf + 2, err);
1222   gdb_blen = 4;
1223 }
1224
1225 /* Generate an OK packet.  */
1226
1227 static void
1228 packet_ok (void)
1229 {
1230   gdb_buf[1] = 'O';
1231   gdb_buf[2] = 'K';
1232   gdb_blen = 3;
1233 }
1234
1235 /* Append a register to the packet.  */
1236
1237 static void
1238 ireg2pkt (const unsigned char *p)
1239 {
1240   int i;
1241
1242   for (i = 0; i < 8; i++)
1243     {
1244       byte2hex (gdb_buf + gdb_blen, p[i]);
1245       gdb_blen += 2;
1246     }
1247 }
1248
1249 /* Append a C string (ASCIZ) to the packet.  */
1250
1251 static void
1252 str2pkt (const char *str)
1253 {
1254   while (*str)
1255     gdb_buf[gdb_blen++] = *str++;
1256 }
1257
1258 /* Extract a number fro the packet.  */
1259
1260 static unsigned __int64
1261 pkt2val (const unsigned char *pkt, unsigned int *pos)
1262 {
1263   unsigned __int64 res = 0;
1264   unsigned int i;
1265
1266   while (1)
1267     {
1268       int r = hex2nibble (pkt[*pos]);
1269
1270       if (r < 0)
1271         return res;
1272       res = (res << 4) | r;
1273       (*pos)++;
1274     }
1275 }
1276
1277 /* Append LEN bytes from B to the current gdb packet (encode in binary).  */
1278
1279 static void
1280 mem2bin (const unsigned char *b, unsigned int len)
1281 {
1282   unsigned int i;
1283   for (i = 0; i < len; i++)
1284     switch (b[i])
1285       {
1286       case '#':
1287       case '$':
1288       case '}':
1289       case '*':
1290       case 0:
1291         gdb_buf[gdb_blen++] = '}';
1292         gdb_buf[gdb_blen++] = b[i] ^ 0x20;
1293         break;
1294       default:
1295         gdb_buf[gdb_blen++] = b[i];
1296         break;
1297       }
1298 }
1299
1300 /* Append LEN bytes from B to the current gdb packet (encode in hex).  */
1301
1302 static void
1303 mem2hex (const unsigned char *b, unsigned int len)
1304 {
1305   unsigned int i;
1306   for (i = 0; i < len; i++)
1307     {
1308       byte2hex (gdb_buf + gdb_blen, b[i]);
1309       gdb_blen += 2;
1310     }
1311 }
1312
1313 /* Handle the 'q' packet.  */
1314
1315 static void
1316 handle_q_packet (const unsigned char *pkt, unsigned int pktlen)
1317 {
1318   /* For qfThreadInfo and qsThreadInfo.  */
1319   static unsigned int first_thread;
1320   static unsigned int last_thread;
1321
1322   static const char xfer_uib[] = "qXfer:uib:read:";
1323 #define XFER_UIB_LEN (sizeof (xfer_uib) - 1)
1324   static const char qfthreadinfo[] = "qfThreadInfo";
1325 #define QFTHREADINFO_LEN (sizeof (qfthreadinfo) - 1)
1326   static const char qsthreadinfo[] = "qsThreadInfo";
1327 #define QSTHREADINFO_LEN (sizeof (qsthreadinfo) - 1)
1328   static const char qthreadextrainfo[] = "qThreadExtraInfo,";
1329 #define QTHREADEXTRAINFO_LEN (sizeof (qthreadextrainfo) - 1)
1330   static const char qsupported[] = "qSupported:";
1331 #define QSUPPORTED_LEN (sizeof (qsupported) - 1)
1332
1333   if (pktlen == 2 && pkt[1] == 'C')
1334     {
1335       /* Current thread.  */
1336       gdb_buf[0] = '$';
1337       gdb_buf[1] = 'Q';
1338       gdb_buf[2] = 'C';
1339       gdb_blen = 3;
1340       if (has_threads)
1341         long2pkt ((unsigned long) get_teb ());
1342       return;
1343     }
1344   else if (pktlen > XFER_UIB_LEN
1345       && ots$strcmp_eql (pkt, XFER_UIB_LEN, xfer_uib, XFER_UIB_LEN))
1346     {
1347       /* Get unwind information block.  */
1348       unsigned __int64 pc;
1349       unsigned int pos = XFER_UIB_LEN;
1350       unsigned int off;
1351       unsigned int len;
1352       union
1353       {
1354         unsigned char bytes[32];
1355         struct
1356         {
1357           unsigned __int64 code_start_va;
1358           unsigned __int64 code_end_va;
1359           unsigned __int64 uib_start_va;
1360           unsigned __int64 gp_value;
1361         } data;
1362       } uei;
1363       int res;
1364       int i;
1365
1366       packet_error (0);
1367
1368       pc = pkt2val (pkt, &pos);
1369       if (pkt[pos] != ':')
1370         return;
1371       pos++;
1372       off = pkt2val (pkt, &pos);
1373       if (pkt[pos] != ',' || off != 0)
1374         return;
1375       pos++;
1376       len = pkt2val (pkt, &pos);
1377       if (pkt[pos] != '#' || len != 0x20)
1378         return;
1379
1380       res = SYS$GET_UNWIND_ENTRY_INFO (pc, &uei.data, 0);
1381       if (res == SS$_NODATA || res != SS$_NORMAL)
1382         ots$fill (uei.bytes, sizeof (uei.bytes), 0);
1383
1384       if (trace_unwind)
1385         {
1386           TERM_FAO ("Unwind request for !XH, status=!XL, uib=!XQ, GP=!XQ!/",
1387                     pc, res, uei.data.uib_start_va, uei.data.gp_value);
1388         }
1389
1390       gdb_buf[0] = '$';
1391       gdb_buf[1] = 'l';
1392       gdb_blen = 2;
1393       mem2bin (uei.bytes, sizeof (uei.bytes));
1394     }
1395   else if (pktlen == QFTHREADINFO_LEN
1396            && ots$strcmp_eql (pkt, QFTHREADINFO_LEN,
1397                               qfthreadinfo, QFTHREADINFO_LEN))
1398     {
1399       /* Get first thread(s).  */
1400       gdb_buf[0] = '$';
1401       gdb_buf[1] = 'm';
1402       gdb_blen = 2;
1403
1404       if (!has_threads)
1405         {
1406           gdb_buf[1] = 'l';
1407           return;
1408         }
1409       first_thread = thread_next (0);
1410       last_thread = first_thread;
1411       long2pkt (first_thread);
1412     }
1413   else if (pktlen == QSTHREADINFO_LEN
1414            && ots$strcmp_eql (pkt, QSTHREADINFO_LEN,
1415                               qsthreadinfo, QSTHREADINFO_LEN))
1416     {
1417       /* Get subsequent threads.  */
1418       gdb_buf[0] = '$';
1419       gdb_buf[1] = 'm';
1420       gdb_blen = 2;
1421       while (dbgext_func)
1422         {
1423           unsigned int res;
1424           res = thread_next (last_thread);
1425           if (res == first_thread)
1426             break;
1427           if (gdb_blen > 2)
1428             gdb_buf[gdb_blen++] = ',';
1429           long2pkt (res);
1430           last_thread = res;
1431           if (gdb_blen > sizeof (gdb_buf) - 16)
1432             break;
1433         }
1434
1435       if (gdb_blen == 2)
1436         gdb_buf[1] = 'l';
1437     }
1438   else if (pktlen > QTHREADEXTRAINFO_LEN
1439            && ots$strcmp_eql (pkt, QTHREADEXTRAINFO_LEN,
1440                               qthreadextrainfo, QTHREADEXTRAINFO_LEN))
1441     {
1442       /* Get extra info about a thread.  */
1443       pthread_t thr;
1444       unsigned int pos = QTHREADEXTRAINFO_LEN;
1445       pthreadDebugThreadInfo_t info;
1446       int res;
1447
1448       packet_error (0);
1449       if (!has_threads)
1450         return;
1451
1452       thr = (pthread_t) pkt2val (pkt, &pos);
1453       if (pkt[pos] != '#')
1454         return;
1455       res = pthread_debug_thd_get_info_addr (thr, &info);
1456       if (res != 0)
1457         {
1458           TERM_FAO ("qThreadExtraInfo (!XH) failed: !SL!/", thr, res);
1459           return;
1460         }
1461       gdb_buf[0] = '$';
1462       gdb_blen = 1;
1463       mem2hex ((const unsigned char *)"VMS-thread", 11);
1464     }
1465   else if (pktlen > QSUPPORTED_LEN
1466            && ots$strcmp_eql (pkt, QSUPPORTED_LEN,
1467                               qsupported, QSUPPORTED_LEN))
1468     {
1469       /* Get supported features.  */
1470       pthread_t thr;
1471       unsigned int pos = QSUPPORTED_LEN;
1472       pthreadDebugThreadInfo_t info;
1473       int res;
1474       
1475       /* Ignore gdb features.  */
1476       gdb_buf[0] = '$';
1477       gdb_blen = 1;
1478
1479       str2pkt ("qXfer:uib:read+");
1480       return;
1481     }
1482   else
1483     {
1484       if (trace_pkt)
1485         {
1486           term_puts ("unknown <: ");
1487           term_write ((char *)pkt, pktlen);
1488           term_putnl ();
1489         }
1490       return;
1491     }
1492 }
1493
1494 /* Handle the 'v' packet.  */
1495
1496 static int
1497 handle_v_packet (const unsigned char *pkt, unsigned int pktlen)
1498 {
1499   static const char vcontq[] = "vCont?";
1500 #define VCONTQ_LEN (sizeof (vcontq) - 1)
1501
1502   if (pktlen == VCONTQ_LEN
1503       && ots$strcmp_eql (pkt, VCONTQ_LEN, vcontq, VCONTQ_LEN))
1504     {
1505       gdb_buf[0] = '$';
1506       gdb_blen = 1;
1507
1508       str2pkt ("vCont;c;s");
1509       return 0;
1510     }
1511   else
1512     {
1513       if (trace_pkt)
1514         {
1515           term_puts ("unknown <: ");
1516           term_write ((char *)pkt, pktlen);
1517           term_putnl ();
1518         }
1519       return 0;
1520     }
1521 }
1522
1523 /* Get regs for the selected thread.  */
1524
1525 static struct ia64_all_regs *
1526 get_selected_regs (void)
1527 {
1528   pthreadDebugRegs_t regs;
1529   int res;
1530
1531   if (selected_thread == 0 || selected_thread == get_teb ())
1532     return &excp_regs;
1533
1534   if (selected_thread == sel_regs_pthread)
1535     return &sel_regs;
1536
1537   /* Read registers.  */
1538   res = pthread_debug_thd_get_reg (selected_id, &regs);
1539   if (res != 0)
1540     {
1541       /* FIXME: return NULL ?  */
1542       return &excp_regs;
1543     }
1544   sel_regs_pthread = selected_thread;
1545   sel_regs.gr[1].v = regs.gp;
1546   sel_regs.gr[4].v = regs.r4;
1547   sel_regs.gr[5].v = regs.r5;
1548   sel_regs.gr[6].v = regs.r6;
1549   sel_regs.gr[7].v = regs.r7;
1550   sel_regs.gr[12].v = regs.sp;
1551   sel_regs.br[0].v = regs.rp;
1552   sel_regs.br[1].v = regs.b1;
1553   sel_regs.br[2].v = regs.b2;
1554   sel_regs.br[3].v = regs.b3;
1555   sel_regs.br[4].v = regs.b4;
1556   sel_regs.br[5].v = regs.b5;
1557   sel_regs.ip.v = regs.ip;
1558   sel_regs.bsp.v = regs.bspstore; /* FIXME: it is correct ?  */
1559   sel_regs.pfs.v = regs.pfs;
1560   sel_regs.pr.v = regs.pr;
1561   return &sel_regs;
1562 }
1563
1564 /* Create a status packet.  */
1565
1566 static void
1567 packet_status (void)
1568 {
1569   gdb_blen = 0;
1570   if (has_threads)
1571     {
1572       str2pkt ("$T05thread:");
1573       long2pkt ((unsigned long) get_teb ());
1574       gdb_buf[gdb_blen++] = ';';
1575     }
1576   else
1577     str2pkt ("$S05");
1578 }
1579
1580 /* Return 1 to continue.  */
1581
1582 static int
1583 handle_packet (unsigned char *pkt, unsigned int len)
1584 {
1585   unsigned int pos;
1586
1587   /* By default, reply unsupported.  */
1588   gdb_buf[0] = '$';
1589   gdb_blen = 1;
1590
1591   pos = 1;
1592   switch (pkt[0])
1593     {
1594     case '?':
1595       if (len == 1)
1596         {
1597           packet_status ();
1598           return 0;
1599         }
1600       break;
1601     case 'c':
1602       if (len == 1)
1603         {
1604           /* Clear psr.ss.  */
1605           excp_regs.psr.v &= ~(unsigned __int64)PSR$M_SS;
1606           return 1;
1607         }
1608       else
1609         packet_error (0);
1610       break;
1611     case 'g':
1612       if (len == 1)
1613         {
1614           unsigned int i;
1615           struct ia64_all_regs *regs = get_selected_regs ();
1616           unsigned char *p = regs->gr[0].b;
1617
1618           for (i = 0; i < 8 * 32; i++)
1619             byte2hex (gdb_buf + 1 + 2 * i, p[i]);
1620           gdb_blen += 2 * 8 * 32;
1621           return 0;
1622         }
1623       break;
1624     case 'H':
1625       if (pkt[1] == 'g')
1626         {
1627           int res;
1628           unsigned __int64 val;
1629           pthreadDebugThreadInfo_t info;
1630           
1631           pos++;
1632           val = pkt2val (pkt, &pos);
1633           if (pos != len)
1634             {
1635               packet_error (0);
1636               return 0;
1637             }
1638           if (val == 0)
1639             {
1640               /* Default one.  */
1641               selected_thread = get_teb ();
1642               selected_id = 0;
1643             }
1644           else if (!has_threads)
1645             {
1646               packet_error (0);
1647               return 0;
1648             }
1649           else
1650             {
1651               res = pthread_debug_thd_get_info_addr ((pthread_t) val, &info);
1652               if (res != 0)
1653                 {
1654                   TERM_FAO ("qThreadExtraInfo (!XH) failed: !SL!/", val, res);
1655                   packet_error (0);
1656                   return 0;
1657                 }
1658               selected_thread = info.teb;
1659               selected_id = info.sequence;
1660             }
1661           packet_ok ();
1662           break;
1663         }
1664       else if (pkt[1] == 'c'
1665                && ((pkt[2] == '-' && pkt[3] == '1' && len == 4)
1666                    || (pkt[2] == '0' && len == 3)))
1667         {
1668           /* Silently accept 'Hc0' and 'Hc-1'.  */
1669           packet_ok ();
1670           break;
1671         }
1672       else
1673         {
1674           packet_error (0);
1675           return 0;
1676         }
1677     case 'k':
1678       SYS$EXIT (SS$_NORMAL);
1679       break;
1680     case 'm':
1681       {
1682         unsigned __int64 addr;
1683         unsigned __int64 paddr;
1684         unsigned int l;
1685         unsigned int i;
1686
1687         addr = pkt2val (pkt, &pos);
1688         if (pkt[pos] != ',')
1689           {
1690             packet_error (0);
1691             return 0;
1692           }
1693         pos++;
1694         l = pkt2val (pkt, &pos);
1695         if (pkt[pos] != '#')
1696           {
1697             packet_error (0);
1698             return 0;
1699           }
1700
1701         /* Check access.  */
1702         i = l + (addr & VMS_PAGE_MASK);
1703         paddr = addr & ~VMS_PAGE_MASK;
1704         while (1)
1705           {
1706             if (__prober (paddr, 0) != 1)
1707               {
1708                 packet_error (2);
1709                 return 0;
1710               }
1711             if (i < VMS_PAGE_SIZE)
1712               break;
1713             i -= VMS_PAGE_SIZE;
1714             paddr += VMS_PAGE_SIZE;
1715           }
1716
1717         /* Transfer.  */
1718         for (i = 0; i < l; i++)
1719           byte2hex (gdb_buf + 1 + 2 * i, ((unsigned char *)addr)[i]);
1720         gdb_blen += 2 * l;
1721       }
1722       break;
1723     case 'M':
1724       {
1725         unsigned __int64 addr;
1726         unsigned __int64 paddr;
1727         unsigned int l;
1728         unsigned int i;
1729         unsigned int oldprot;
1730
1731         addr = pkt2val (pkt, &pos);
1732         if (pkt[pos] != ',')
1733           {
1734             packet_error (0);
1735             return 0;
1736           }
1737         pos++;
1738         l = pkt2val (pkt, &pos);
1739         if (pkt[pos] != ':')
1740           {
1741             packet_error (0);
1742             return 0;
1743           }
1744         pos++;
1745         page_set_rw (addr, l, &oldprot);
1746
1747         /* Check access.  */
1748         i = l + (addr & VMS_PAGE_MASK);
1749         paddr = addr & ~VMS_PAGE_MASK;
1750         while (1)
1751           {
1752             if (__probew (paddr, 0) != 1)
1753               {
1754                 page_restore_rw (addr, l, oldprot);
1755                 return 0;
1756               }
1757             if (i < VMS_PAGE_SIZE)
1758               break;
1759             i -= VMS_PAGE_SIZE;
1760             paddr += VMS_PAGE_SIZE;
1761           }
1762
1763         /* Write.  */
1764         for (i = 0; i < l; i++)
1765           {
1766             int v = hex2byte (pkt + pos);
1767             pos += 2;
1768             ((unsigned char *)addr)[i] = v;
1769           }
1770
1771         /* Sync caches.  */
1772         for (i = 0; i < l; i += 15)
1773           __fc (addr + i);
1774         __fc (addr + l);
1775
1776         page_restore_rw (addr, l, oldprot);
1777         packet_ok ();
1778       }
1779       break;
1780     case 'p':
1781       {
1782         unsigned int num = 0;
1783         unsigned int i;
1784         struct ia64_all_regs *regs = get_selected_regs ();
1785
1786         num = pkt2val (pkt, &pos);
1787         if (pos != len)
1788           {
1789             packet_error (0);
1790             return 0;
1791           }
1792
1793         switch (num)
1794           {
1795           case IA64_IP_REGNUM:
1796             ireg2pkt (regs->ip.b);
1797             break;
1798           case IA64_BR0_REGNUM:
1799             ireg2pkt (regs->br[0].b);
1800             break;
1801           case IA64_PSR_REGNUM:
1802             ireg2pkt (regs->psr.b);
1803             break;
1804           case IA64_BSP_REGNUM:
1805             ireg2pkt (regs->bsp.b);
1806             break;
1807           case IA64_CFM_REGNUM:
1808             ireg2pkt (regs->cfm.b);
1809             break;
1810           case IA64_PFS_REGNUM:
1811             ireg2pkt (regs->pfs.b);
1812             break;
1813           case IA64_PR_REGNUM:
1814             ireg2pkt (regs->pr.b);
1815             break;
1816           default:
1817             TERM_FAO ("gdbserv: unhandled reg !UW!/", num);
1818             packet_error (0);
1819             return 0;
1820           }
1821       }
1822       break;
1823     case 'q':
1824       handle_q_packet (pkt, len);
1825       break;
1826     case 's':
1827       if (len == 1)
1828         {
1829           /* Set psr.ss.  */
1830           excp_regs.psr.v |= (unsigned __int64)PSR$M_SS;
1831           return 1;
1832         }
1833       else
1834         packet_error (0);
1835       break;
1836     case 'T':
1837       /* Thread status.  */
1838       if (!has_threads)
1839         {
1840           packet_ok ();
1841           break;
1842         }
1843       else
1844         {
1845           int res;
1846           unsigned __int64 val;
1847           unsigned int fthr, thr;
1848           
1849           val = pkt2val (pkt, &pos);
1850           /* Default is error (but only after parsing is complete).  */
1851           packet_error (0);
1852           if (pos != len)
1853             break;
1854
1855           /* Follow the list.  This makes a O(n2) algorithm, but we don't really
1856              have the choice.  Note that pthread_debug_thd_get_info_addr
1857              doesn't look reliable.  */
1858           fthr = thread_next (0);
1859           thr = fthr;
1860           do
1861             {
1862               if (val == thr)
1863                 {
1864                   packet_ok ();
1865                   break;
1866                 }
1867               thr = thread_next (thr);
1868             }
1869           while (thr != fthr);
1870         }
1871       break;
1872     case 'v':
1873       return handle_v_packet (pkt, len);
1874       break;
1875     case 'V':
1876       if (len > 3 && pkt[1] == 'M' && pkt[2] == 'S' && pkt[3] == ' ')
1877         {
1878           /* Temporary extension.  */
1879           if (has_threads)
1880             {
1881               pkt[len] = 0;
1882               stub_pthread_debug_cmd ((char *)pkt + 4);
1883               packet_ok ();
1884             }
1885           else
1886             packet_error (0);
1887         }
1888       break;
1889     default:
1890       if (trace_pkt)
1891         {
1892           term_puts ("unknown <: ");
1893           term_write ((char *)pkt, len);
1894           term_putnl ();
1895         }
1896       break;
1897     }
1898   return 0;
1899 }
1900
1901 /* Raw write to gdb.  */
1902
1903 static void
1904 sock_write (const unsigned char *buf, int len)
1905 {
1906   struct _iosb iosb;
1907   unsigned int status;
1908
1909   /* Write data to connection.  */
1910   status = sys$qiow (EFN$C_ENF,           /* Event flag.  */
1911                      conn_channel,        /* I/O channel.  */
1912                      IO$_WRITEVBLK,       /* I/O function code.  */
1913                      &iosb,               /* I/O status block.  */
1914                      0,                   /* Ast service routine.  */
1915                      0,                   /* Ast parameter.  */
1916                      (char *)buf,         /* P1 - buffer address.  */
1917                      len,                 /* P2 - buffer length.  */
1918                      0, 0, 0, 0);
1919   if (status & STS$M_SUCCESS)
1920     status = iosb.iosb$w_status;
1921   if (!(status & STS$M_SUCCESS))
1922     {
1923       term_puts ("Failed to write data to gdb\n");
1924       LIB$SIGNAL (status);
1925     }
1926 }
1927
1928 /* Compute the cheksum and send the packet.  */
1929
1930 static void
1931 send_pkt (void)
1932 {
1933   unsigned char chksum = 0;
1934   unsigned int i;
1935
1936   for (i = 1; i < gdb_blen; i++)
1937     chksum += gdb_buf[i];
1938
1939   gdb_buf[gdb_blen] = '#';
1940   byte2hex (gdb_buf + gdb_blen + 1, chksum);
1941
1942   sock_write (gdb_buf, gdb_blen + 3);
1943
1944   if (trace_pkt > 1)
1945     {
1946       term_puts (">: ");
1947       term_write ((char *)gdb_buf, gdb_blen + 3);
1948       term_putnl ();
1949     }
1950 }
1951
1952 /* Read and handle one command.  Return 1 is execution must resume.  */
1953
1954 static int
1955 one_command (void)
1956 {
1957   struct _iosb iosb;
1958   unsigned int status;
1959   unsigned int off;
1960   unsigned int dollar_off = 0;
1961   unsigned int sharp_off = 0;
1962   unsigned int cmd_off;
1963   unsigned int cmd_len;
1964
1965   /* Wait for a packet.  */
1966   while (1)
1967     {
1968       off = 0;
1969       while (1)
1970         {
1971           /* Read data from connection.  */
1972           status = sys$qiow (EFN$C_ENF,           /* Event flag.  */
1973                              conn_channel,        /* I/O channel.  */
1974                              IO$_READVBLK,        /* I/O function code.  */
1975                              &iosb,               /* I/O status block.  */
1976                              0,                   /* Ast service routine.  */
1977                              0,                   /* Ast parameter.  */
1978                              gdb_buf + off,       /* P1 - buffer address.  */
1979                              sizeof (gdb_buf) - off, /* P2 - buffer leng.  */
1980                              0, 0, 0, 0);
1981           if (status & STS$M_SUCCESS)
1982             status = iosb.iosb$w_status;
1983           if (!(status & STS$M_SUCCESS))
1984             {
1985               term_puts ("Failed to read data from connection\n" );
1986               LIB$SIGNAL (status);
1987             }
1988
1989 #ifdef RAW_DUMP
1990           term_puts ("{: ");
1991           term_write ((char *)gdb_buf + off, iosb.iosb$w_bcnt);
1992           term_putnl ();
1993 #endif
1994
1995           gdb_blen = off + iosb.iosb$w_bcnt;
1996
1997           if (off == 0)
1998             {
1999               /* Search for '$'.  */
2000               for (dollar_off = 0; dollar_off < gdb_blen; dollar_off++)
2001                 if (gdb_buf[dollar_off] == '$')
2002                   break;
2003               if (dollar_off >= gdb_blen)
2004                 {
2005                   /* Not found, discard the data.  */
2006                   off = 0;
2007                   continue;
2008                 }
2009               /* Search for '#'.  */
2010               for (sharp_off = dollar_off + 1;
2011                    sharp_off < gdb_blen;
2012                    sharp_off++)
2013                 if (gdb_buf[sharp_off] == '#')
2014                   break;
2015             }
2016           else if (sharp_off >= off)
2017             {
2018               /* Search for '#'.  */
2019               for (; sharp_off < gdb_blen; sharp_off++)
2020                 if (gdb_buf[sharp_off] == '#')
2021                   break;
2022             }
2023
2024           /* Got packet with checksum.  */
2025           if (sharp_off + 2 <= gdb_blen)
2026             break;
2027
2028           off = gdb_blen;
2029           if (gdb_blen == sizeof (gdb_buf))
2030             {
2031               /* Packet too large, discard.  */
2032               off = 0;
2033             }
2034         }
2035
2036       /* Validate and acknowledge a packet.  */
2037       {
2038         unsigned char chksum = 0;
2039         unsigned int i;
2040         int v;
2041
2042         for (i = dollar_off + 1; i < sharp_off; i++)
2043           chksum += gdb_buf[i];
2044         v = hex2byte (gdb_buf + sharp_off + 1);
2045         if (v != chksum)
2046           {
2047             term_puts ("Discard bad checksum packet\n");
2048             continue;
2049           }
2050         else
2051           {
2052             sock_write ((const unsigned char *)"+", 1);
2053             break;
2054           }
2055       }
2056     }
2057
2058   if (trace_pkt > 1)
2059     {
2060       term_puts ("<: ");
2061       term_write ((char *)gdb_buf + dollar_off, sharp_off - dollar_off + 1);
2062       term_putnl ();
2063     }
2064
2065   cmd_off = dollar_off + 1;
2066   cmd_len = sharp_off - dollar_off - 1;
2067
2068   if (handle_packet (gdb_buf + dollar_off + 1, sharp_off - dollar_off - 1) == 1)
2069     return 1;
2070
2071   send_pkt ();
2072   return 0;
2073 }
2074
2075 /* Display the condition given by SIG64.  */
2076
2077 static void
2078 display_excp (struct chf64$signal_array *sig64, struct chf$mech_array *mech)
2079 {
2080   unsigned int status;
2081   char msg[160];
2082   unsigned short msglen;
2083   $DESCRIPTOR (msg_desc, msg);
2084   unsigned char outadr[4];
2085
2086   status = SYS$GETMSG (sig64->chf64$q_sig_name, &msglen, &msg_desc, 0, outadr);
2087   if (status & STS$M_SUCCESS)
2088     {
2089       char msg2[160];
2090       unsigned short msg2len;
2091       struct dsc$descriptor_s msg2_desc =
2092         { sizeof (msg2), DSC$K_DTYPE_T, DSC$K_CLASS_S, msg2};
2093       msg_desc.dsc$w_length = msglen;
2094       status = SYS$FAOL_64 (&msg_desc, &msg2len, &msg2_desc,
2095                             &sig64->chf64$q_sig_arg1);
2096       if (status & STS$M_SUCCESS)
2097         term_write (msg2, msg2len);
2098     }
2099   else
2100     term_puts ("no message");
2101   term_putnl ();
2102
2103   if (trace_excp > 1)
2104     {
2105       TERM_FAO (" Frame: !XH, Depth: !4SL, Esf: !XH!/",
2106                 mech->chf$q_mch_frame, mech->chf$q_mch_depth,
2107                 mech->chf$q_mch_esf_addr);
2108     }
2109 }
2110
2111 /* Get all registers from current thread.  */
2112
2113 static void
2114 read_all_registers (struct chf$mech_array *mech)
2115 {
2116   struct _intstk *intstk =
2117     (struct _intstk *)mech->chf$q_mch_esf_addr;
2118   struct chf64$signal_array *sig64 =
2119     (struct chf64$signal_array *)mech->chf$ph_mch_sig64_addr;
2120   unsigned int cnt = sig64->chf64$w_sig_arg_count;
2121   unsigned __int64 pc = (&sig64->chf64$q_sig_name)[cnt - 2];
2122
2123   excp_regs.ip.v = pc;
2124   excp_regs.psr.v = intstk->intstk$q_ipsr;
2125   /* GDB and linux expects bsp to point after the current register frame.
2126      Adjust.  */
2127   {
2128     unsigned __int64 bsp = intstk->intstk$q_bsp;
2129     unsigned int sof = intstk->intstk$q_ifs & 0x7f;
2130     unsigned int delta = ((bsp >> 3) & 0x3f) + sof;
2131     excp_regs.bsp.v = bsp + ((sof + delta / 0x3f) << 3);
2132   }
2133   excp_regs.cfm.v = intstk->intstk$q_ifs & 0x3fffffffff;
2134   excp_regs.pfs.v = intstk->intstk$q_pfs;
2135   excp_regs.pr.v = intstk->intstk$q_preds;
2136   excp_regs.gr[0].v = 0;
2137   excp_regs.gr[1].v = intstk->intstk$q_gp;
2138   excp_regs.gr[2].v = intstk->intstk$q_r2;
2139   excp_regs.gr[3].v = intstk->intstk$q_r3;
2140   excp_regs.gr[4].v = intstk->intstk$q_r4;
2141   excp_regs.gr[5].v = intstk->intstk$q_r5;
2142   excp_regs.gr[6].v = intstk->intstk$q_r6;
2143   excp_regs.gr[7].v = intstk->intstk$q_r7;
2144   excp_regs.gr[8].v = intstk->intstk$q_r8;
2145   excp_regs.gr[9].v = intstk->intstk$q_r9;
2146   excp_regs.gr[10].v = intstk->intstk$q_r10;
2147   excp_regs.gr[11].v = intstk->intstk$q_r11;
2148   excp_regs.gr[12].v = (unsigned __int64)intstk + intstk->intstk$l_stkalign;
2149   excp_regs.gr[13].v = intstk->intstk$q_r13;
2150   excp_regs.gr[14].v = intstk->intstk$q_r14;
2151   excp_regs.gr[15].v = intstk->intstk$q_r15;
2152   excp_regs.gr[16].v = intstk->intstk$q_r16;
2153   excp_regs.gr[17].v = intstk->intstk$q_r17;
2154   excp_regs.gr[18].v = intstk->intstk$q_r18;
2155   excp_regs.gr[19].v = intstk->intstk$q_r19;
2156   excp_regs.gr[20].v = intstk->intstk$q_r20;
2157   excp_regs.gr[21].v = intstk->intstk$q_r21;
2158   excp_regs.gr[22].v = intstk->intstk$q_r22;
2159   excp_regs.gr[23].v = intstk->intstk$q_r23;
2160   excp_regs.gr[24].v = intstk->intstk$q_r24;
2161   excp_regs.gr[25].v = intstk->intstk$q_r25;
2162   excp_regs.gr[26].v = intstk->intstk$q_r26;
2163   excp_regs.gr[27].v = intstk->intstk$q_r27;
2164   excp_regs.gr[28].v = intstk->intstk$q_r28;
2165   excp_regs.gr[29].v = intstk->intstk$q_r29;
2166   excp_regs.gr[30].v = intstk->intstk$q_r30;
2167   excp_regs.gr[31].v = intstk->intstk$q_r31;
2168   excp_regs.br[0].v = intstk->intstk$q_b0;
2169   excp_regs.br[1].v = intstk->intstk$q_b1;
2170   excp_regs.br[2].v = intstk->intstk$q_b2;
2171   excp_regs.br[3].v = intstk->intstk$q_b3;
2172   excp_regs.br[4].v = intstk->intstk$q_b4;
2173   excp_regs.br[5].v = intstk->intstk$q_b5;
2174   excp_regs.br[6].v = intstk->intstk$q_b6;
2175   excp_regs.br[7].v = intstk->intstk$q_b7;
2176 }
2177
2178 /* Write all registers to current thread.  FIXME: not yet complete.  */
2179
2180 static void
2181 write_all_registers (struct chf$mech_array *mech)
2182 {
2183   struct _intstk *intstk =
2184     (struct _intstk *)mech->chf$q_mch_esf_addr;
2185
2186   intstk->intstk$q_ipsr = excp_regs.psr.v;
2187 }
2188
2189 /* Do debugging.  Report status to gdb and execute commands.  */
2190
2191 static void
2192 do_debug (struct chf$mech_array *mech)
2193 {
2194   struct _intstk *intstk =
2195     (struct _intstk *)mech->chf$q_mch_esf_addr;
2196   unsigned int old_ast;
2197   unsigned int old_sch;
2198   unsigned int status;
2199
2200   /* Disable ast.  */
2201   status = sys$setast (0);
2202   switch (status)
2203     {
2204     case SS$_WASCLR:
2205       old_ast = 0;
2206       break;
2207     case SS$_WASSET:
2208       old_ast = 1;
2209       break;
2210     default:
2211       /* Should never happen!  */
2212       lib$signal (status);
2213     }
2214
2215   /* Disable thread scheduling.  */
2216   if (has_threads)
2217     old_sch = set_thread_scheduling (0);
2218
2219   read_all_registers (mech);
2220
2221   /* Send stop reply packet.  */
2222   packet_status ();
2223   send_pkt ();
2224
2225   while (one_command () == 0)
2226     ;
2227
2228   write_all_registers (mech);
2229
2230   /* Re-enable scheduling.  */
2231   if (has_threads)
2232     set_thread_scheduling (old_sch);
2233
2234   /* Re-enable AST.  */
2235   status = sys$setast (old_ast);
2236   if (!(status & STS$M_SUCCESS))
2237     LIB$SIGNAL (status);
2238 }
2239
2240 /* The condition handler.  That's the core of the stub.  */
2241
2242 static int
2243 excp_handler (struct chf$signal_array *sig,
2244               struct chf$mech_array *mech)
2245 {
2246   struct chf64$signal_array *sig64 =
2247     (struct chf64$signal_array *)mech->chf$ph_mch_sig64_addr;
2248   unsigned int code = sig->chf$l_sig_name & STS$M_COND_ID;
2249   unsigned int cnt = sig64->chf64$w_sig_arg_count;
2250   unsigned __int64 pc;
2251   unsigned int ret;
2252   /* Self protection.  FIXME: Should be per thread ?  */
2253   static int in_handler = 0;
2254
2255   /* Completly ignore some conditions (signaled indirectly by this stub).  */
2256   switch (code)
2257     {
2258     case LIB$_KEYNOTFOU & STS$M_COND_ID:
2259       return SS$_RESIGNAL_64;
2260     default:
2261       break;
2262     }
2263
2264   /* Protect against recursion.  */
2265   in_handler++;
2266   if (in_handler > 1)
2267     {
2268       if (in_handler == 2)
2269         TERM_FAO ("gdbstub: exception in handler (pc=!XH)!!!/",
2270                   (&sig64->chf64$q_sig_name)[cnt - 2]);
2271       sys$exit (sig->chf$l_sig_name);
2272     }
2273
2274   pc = (&sig64->chf64$q_sig_name)[cnt - 2];
2275   if (trace_excp)
2276     TERM_FAO ("excp_handler: code: !XL, pc=!XH!/", code, pc);
2277
2278   /* If break on the entry point, restore the bundle.  */
2279   if (code == (SS$_BREAK & STS$M_COND_ID)
2280       && pc == entry_pc
2281       && entry_pc != 0)
2282     {
2283       static unsigned int entry_prot;
2284
2285       if (trace_entry)
2286         term_puts ("initial entry breakpoint\n");
2287       page_set_rw (entry_pc, 16, &entry_prot);
2288
2289       ots$move ((void *)entry_pc, 16, entry_saved);
2290       __fc (entry_pc);
2291       page_restore_rw (entry_pc, 16, entry_prot);
2292     }
2293
2294   switch (code)
2295     {
2296     case SS$_ACCVIO & STS$M_COND_ID:
2297       if (trace_excp <= 1)
2298         display_excp (sig64, mech);
2299       /* Fall through.  */
2300     case SS$_BREAK  & STS$M_COND_ID:
2301     case SS$_OPCDEC & STS$M_COND_ID:
2302     case SS$_TBIT   & STS$M_COND_ID:
2303     case SS$_DEBUG  & STS$M_COND_ID:
2304       if (trace_excp > 1)
2305         {
2306           int i;
2307           struct _intstk *intstk =
2308             (struct _intstk *)mech->chf$q_mch_esf_addr;
2309
2310           display_excp (sig64, mech);
2311
2312           TERM_FAO (" intstk: !XH!/", intstk);
2313           for (i = 0; i < cnt + 1; i++)
2314             TERM_FAO ("   !XH!/", ((unsigned __int64 *)sig64)[i]);
2315         }
2316       do_debug (mech);
2317       ret = SS$_CONTINUE_64;
2318       break;
2319
2320     default:
2321       display_excp (sig64, mech);
2322       ret = SS$_RESIGNAL_64;
2323       break;
2324     }
2325
2326   in_handler--;
2327   /* Discard selected thread registers.  */
2328   sel_regs_pthread = 0;
2329   return ret;
2330 }
2331
2332 /* Setup internal trace flags according to GDBSTUB$TRACE logical.  */
2333
2334 static void
2335 trace_init (void)
2336 {
2337   unsigned int status, i, start;
2338   unsigned short len;
2339   char resstring[LNM$C_NAMLENGTH];
2340   static const $DESCRIPTOR (tabdesc, "LNM$DCL_LOGICAL");
2341   static const $DESCRIPTOR (logdesc, "GDBSTUB$TRACE");
2342   $DESCRIPTOR (sub_desc, resstring);
2343   ILE3 item_lst[2];
2344
2345   item_lst[0].ile3$w_length = LNM$C_NAMLENGTH;
2346   item_lst[0].ile3$w_code = LNM$_STRING;
2347   item_lst[0].ile3$ps_bufaddr = resstring;
2348   item_lst[0].ile3$ps_retlen_addr = &len;
2349   item_lst[1].ile3$w_length = 0;
2350   item_lst[1].ile3$w_code = 0;
2351
2352   /* Translate the logical name.  */
2353   status = SYS$TRNLNM (0,               /* Attributes of the logical name.  */
2354                        (void *)&tabdesc,       /* Logical name table.  */
2355                        (void *)&logdesc,       /* Logical name.  */
2356                        0,                      /* Access mode.  */
2357                        &item_lst);             /* Item list.  */
2358   if (status == SS$_NOLOGNAM)
2359     return;
2360   if (!(status & STS$M_SUCCESS))
2361     LIB$SIGNAL (status);
2362
2363   start = 0;
2364   for (i = 0; i <= len; i++)
2365     {
2366       if ((i == len || resstring[i] == ',' || resstring[i] == ';')
2367           && i != start)
2368         {
2369           int j;
2370
2371           sub_desc.dsc$a_pointer = resstring + start;
2372           sub_desc.dsc$w_length = i - start;
2373
2374           for (j = 0; j < NBR_DEBUG_FLAGS; j++)
2375             if (str$case_blind_compare (&sub_desc, 
2376                                         (void *)&debug_flags[j].name) == 0)
2377               {
2378                 debug_flags[j].val++;
2379                 break;
2380               }
2381           if (j == NBR_DEBUG_FLAGS)
2382             TERM_FAO ("GDBSTUB$TRACE: unknown directive !AS!/", &sub_desc);
2383
2384           start = i + 1;
2385         }
2386     }
2387
2388   TERM_FAO ("GDBSTUB$TRACE=!AD ->", len, resstring);
2389   for (i = 0; i < NBR_DEBUG_FLAGS; i++)
2390     if (debug_flags[i].val > 0)
2391       TERM_FAO (" !AS=!ZL", &debug_flags[i].name, debug_flags[i].val);
2392   term_putnl ();
2393 }
2394
2395
2396 /* Entry point.  */
2397
2398 static int
2399 stub_start (unsigned __int64 *progxfer, void *cli_util,
2400             EIHD *imghdr, IFD *imgfile,
2401             unsigned int linkflag, unsigned int cliflag)
2402 {
2403   static int initialized;
2404   int i;
2405   int cnt;
2406   int is_attached;
2407   IMCB *imcb;
2408   if (initialized)
2409     term_puts ("gdbstub: re-entry\n");
2410   else
2411     initialized = 1;
2412
2413   /* When attached (through SS$_DEBUG condition), the number of arguments
2414      is 4 and PROGXFER is the PC at interruption.  */
2415   va_count (cnt);
2416   is_attached = cnt == 4;
2417
2418   term_init ();
2419
2420   /* Hello banner.  */
2421   term_puts ("Hello from gdb stub\n");
2422
2423   trace_init ();
2424
2425   if (trace_entry && !is_attached)
2426     {
2427       TERM_FAO ("xfer: !XH, imghdr: !XH, ifd: !XH!/",
2428                 progxfer, imghdr, imgfile);
2429       for (i = -2; i < 8; i++)
2430         TERM_FAO ("  at !2SW: !XH!/", i, progxfer[i]);
2431     }
2432
2433   /* Search for entry point.  */
2434   if (!is_attached)
2435     {
2436       entry_pc = 0;
2437       for (i = 0; progxfer[i]; i++)
2438         entry_pc = progxfer[i];
2439
2440       if (trace_entry)
2441         {
2442           if (entry_pc == 0)
2443             {
2444               term_puts ("No entry point\n");
2445               return 0;
2446             }
2447           else
2448             TERM_FAO ("Entry: !XH!/",entry_pc);
2449         }
2450     }
2451   else
2452     entry_pc = progxfer[0];
2453
2454   has_threads = 0;
2455   for (imcb = ctl$gl_imglstptr->imcb$l_flink;
2456        imcb != ctl$gl_imglstptr;
2457        imcb = imcb->imcb$l_flink)
2458     {
2459       if (ots$strcmp_eql (pthread_rtl_desc.dsc$a_pointer,
2460                           pthread_rtl_desc.dsc$w_length,
2461                           imcb->imcb$t_log_image_name + 1,
2462                           imcb->imcb$t_log_image_name[0]))
2463         has_threads = 1;
2464                           
2465       if (trace_images)
2466         {
2467           unsigned int j;
2468           LDRIMG *ldrimg = imcb->imcb$l_ldrimg;
2469           LDRISD *ldrisd;
2470
2471           TERM_FAO ("!XA-!XA ",
2472                     imcb->imcb$l_starting_address,
2473                     imcb->imcb$l_end_address);
2474
2475           switch (imcb->imcb$b_act_code)
2476             {
2477             case IMCB$K_MAIN_PROGRAM:
2478               term_puts ("prog");
2479               break;
2480             case IMCB$K_MERGED_IMAGE:
2481               term_puts ("mrge");
2482               break;
2483             case IMCB$K_GLOBAL_IMAGE_SECTION:
2484               term_puts ("glob");
2485               break;
2486             default:
2487               term_puts ("????");
2488             }
2489           TERM_FAO (" !AD !40AC!/",
2490                     1, "KESU" + (imcb->imcb$b_access_mode & 3),
2491                     imcb->imcb$t_log_image_name);
2492
2493           if ((long) ldrimg < 0 || trace_images < 2)
2494             continue;
2495           ldrisd = ldrimg->ldrimg$l_segments;
2496           for (j = 0; j < ldrimg->ldrimg$l_segcount; j++)
2497             {
2498               unsigned int flags = ldrisd[j].ldrisd$i_flags;
2499               term_puts ("   ");
2500               term_putc (flags & 0x04 ? 'R' : '-');
2501               term_putc (flags & 0x02 ? 'W' : '-');
2502               term_putc (flags & 0x01 ? 'X' : '-');
2503               term_puts (flags & 0x01000000 ? " Prot" : "     ");
2504               term_puts (flags & 0x04000000 ? " Shrt" : "     ");
2505               term_puts (flags & 0x08000000 ? " Shrd" : "     ");
2506               TERM_FAO (" !XA-!XA!/",
2507                         ldrisd[j].ldrisd$p_base,
2508                         (unsigned __int64) ldrisd[j].ldrisd$p_base 
2509                         + ldrisd[j].ldrisd$i_len - 1);
2510             }
2511           ldrisd = ldrimg->ldrimg$l_dyn_seg;
2512           if (ldrisd)
2513             TERM_FAO ("   dynamic            !XA-!XA!/",
2514                       ldrisd->ldrisd$p_base,
2515                       (unsigned __int64) ldrisd->ldrisd$p_base 
2516                       + ldrisd->ldrisd$i_len - 1);
2517         }
2518     }
2519
2520   if (has_threads)
2521     threads_init ();
2522
2523   /* Wait for connection.  */
2524   sock_init ();
2525
2526   /* Set primary exception vector.  */
2527   {
2528     unsigned int status;
2529     status = sys$setexv (0, excp_handler, PSL$C_USER, (__void_ptr32) &prevhnd);
2530     if (!(status & STS$M_SUCCESS))
2531       LIB$SIGNAL (status);
2532   }
2533
2534   if (is_attached)
2535     {
2536       return excp_handler ((struct chf$signal_array *) progxfer[2],
2537                            (struct chf$mech_array *) progxfer[3]);
2538     }
2539
2540   /* Change first instruction to set a breakpoint.  */
2541   {
2542     /*
2543       01 08 00 40 00 00         [MII]       break.m 0x80001
2544       00 00 00 02 00 00                     nop.i 0x0
2545       00 00 04 00                           nop.i 0x0;;
2546     */
2547     static const unsigned char initbp[16] =
2548       { 0x01, 0x08, 0x00, 0x40, 0x00, 0x00,
2549         0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
2550         0x00, 0x00, 0x04, 0x00 };
2551     unsigned int entry_prot;
2552     unsigned int status;
2553     
2554     status = page_set_rw (entry_pc, 16, &entry_prot);
2555
2556     if (!(status & STS$M_SUCCESS))
2557       {
2558         if ((status & STS$M_COND_ID) == (SS$_NOT_PROCESS_VA & STS$M_COND_ID))
2559           {
2560             /* Cannot write here.  This can happen when pthreads are
2561                used.  */
2562             entry_pc = 0;
2563             term_puts ("gdbstub: cannot set breakpoint on entry\n");
2564           }
2565         else
2566           LIB$SIGNAL (status);
2567       }
2568     
2569     if (entry_pc != 0)
2570       {
2571         ots$move (entry_saved, 16, (void *)entry_pc);
2572         ots$move ((void *)entry_pc, 16, (void *)initbp);
2573         __fc (entry_pc);
2574         page_restore_rw (entry_pc, 16, entry_prot);
2575       }
2576   }
2577
2578   /* If it wasn't possible to set a breakpoint on the entry point,
2579      accept gdb commands now.  Note that registers are not updated.  */
2580   if (entry_pc == 0)
2581     {
2582       while (one_command () == 0)
2583         ;
2584     }
2585
2586   /* We will see!  */
2587   return SS$_CONTINUE;
2588 }
2589
2590 /* Declare the entry point of this relocatable module.  */
2591
2592 struct xfer_vector
2593 {
2594   __int64 impure_start;
2595   __int64 impure_end;
2596   int (*entry) ();
2597 };
2598
2599 #pragma __extern_model save
2600 #pragma __extern_model strict_refdef "XFER_PSECT"
2601 struct xfer_vector xfer_vector = {0, 0, stub_start};
2602 #pragma __extern_model restore