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