gdb/stubs/ia64vms-stub.c - gdb

Global variables defined

Data types defined

Functions defined

Macros defined

Source code

  1. /* GDB stub for Itanium OpenVMS
  2.    Copyright (C) 2012-2015 Free Software Foundation, Inc.

  3.    Contributed by Tristan Gingold, AdaCore.

  4.    This program is free software; you can redistribute it and/or modify
  5.    it under the terms of the GNU General Public License as published by
  6.    the Free Software Foundation; either version 3 of the License, or
  7.    (at your option) any later version.

  8.    This program is distributed in the hope that it will be useful,
  9.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  10.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  11.    GNU General Public License for more details.

  12.    You should have received a copy of the GNU General Public License
  13.    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */

  14. /* On VMS, the debugger (in our case the stub) is loaded in the process and
  15.    executed (via SYS$IMGSTA) before the main entry point of the executable.
  16.    In UNIX parlance, this is like using LD_PRELOAD and debug via installing
  17.    SIGTRAP, SIGSEGV... handlers.

  18.    This is currently a partial implementation.  In particular, modifying
  19.    registers is currently not implemented, as well as inferior procedure
  20.    calls.

  21.    This is written in very low-level C, in order not to use the C runtime,
  22.    because it may have weird consequences on the program being debugged.
  23. */

  24. #if __INITIAL_POINTER_SIZE != 64
  25. #error "Must be compiled with 64 bit pointers"
  26. #endif

  27. #define __NEW_STARLET 1
  28. #include <descrip.h>
  29. #include <iledef.h>
  30. #include <efndef.h>
  31. #include <in.h>
  32. #include <inet.h>
  33. #include <iodef.h>
  34. #include <ssdef.h>
  35. #include <starlet.h>
  36. #include <stsdef.h>
  37. #include <tcpip$inetdef.h>

  38. #include <lib$routines.h>
  39. #include <ots$routines.h>
  40. #include <str$routines.h>
  41. #include <libdef.h>
  42. #include <clidef.h>
  43. #include <iosbdef.h>
  44. #include <dvidef.h>
  45. #include <lnmdef.h>
  46. #include <builtins.h>
  47. #include <prtdef.h>
  48. #include <psldef.h>
  49. #include <ssdef.h>
  50. #include <chfdef.h>

  51. #include <lib_c/imcbdef.h>
  52. #include <lib_c/ldrimgdef.h>
  53. #include <lib_c/intstkdef.h>
  54. #include <lib_c/psrdef.h>
  55. #include <lib_c/ifddef.h>
  56. #include <lib_c/eihddef.h>

  57. #include <stdarg.h>
  58. #include <pthread_debug.h>

  59. #define VMS_PAGE_SIZE 0x2000
  60. #define VMS_PAGE_MASK (VMS_PAGE_SIZE - 1)

  61. /* Declared in lib$ots.  */
  62. extern void ots$fill (void *addr, size_t len, unsigned char b);
  63. extern void ots$move (void *dst, size_t len, const void *src);
  64. extern int ots$strcmp_eql (const void *str1, size_t str1len,
  65.                            const void *str2, size_t str2len);

  66. /* Stub port number.  */
  67. static unsigned int serv_port = 1234;

  68. /* DBGEXT structure.  Not declared in any header.  */
  69. struct dbgext_control_block
  70. {
  71.   unsigned short dbgext$w_function_code;
  72. #define DBGEXT$K_NEXT_TASK              3
  73. #define DBGEXT$K_STOP_ALL_OTHER_TASKS 31
  74. #define DBGEXT$K_GET_REGS 33
  75.   unsigned short dbgext$w_facility_id;
  76. #define CMA$_FACILITY 64
  77.   unsigned int dbgext$l_status;
  78.   unsigned int dbgext$l_flags;
  79.   unsigned int dbgext$l_print_routine;
  80.   unsigned int dbgext$l_evnt_code;
  81.   unsigned int dbgext$l_evnt_name;
  82.   unsigned int dbgext$l_evnt_entry;
  83.   unsigned int dbgext$l_task_value;
  84.   unsigned int dbgext$l_task_number;
  85.   unsigned int dbgext$l_ada_flags;
  86.   unsigned int dbgext$l_stop_value;
  87. #define dbgext$l_priority   dbgext$l_stop_value;
  88. #define dbgext$l_symb_addr  dbgext$l_stop_value;
  89. #define dbgext$l_time_slice dbgext$l_stop_value;
  90.   unsigned int dbgext$l_active_registers;
  91. };

  92. #pragma pointer_size save
  93. #pragma pointer_size 32

  94. /* Pthread handler.  */
  95. static int (*dbgext_func) (struct dbgext_control_block *blk);

  96. #pragma pointer_size restore

  97. /* Set to 1 if thread-aware.  */
  98. static int has_threads;

  99. /* Current thread.  */
  100. static pthread_t selected_thread;
  101. static pthreadDebugId_t selected_id;

  102. /* Internal debugging flags.  */
  103. struct debug_flag
  104. {
  105.   /* Name of the flag (as a string descriptor).  */
  106.   const struct dsc$descriptor_s name;
  107.   /* Value.  */
  108.   int val;
  109. };

  110. /* Macro to define a debugging flag.  */
  111. #define DEBUG_FLAG_ENTRY(str) \
  112.   { { sizeof (str) - 1, DSC$K_DTYPE_T, DSC$K_CLASS_S, str }, 0}

  113. static struct debug_flag debug_flags[] =
  114. {
  115.   /* Disp packets exchanged with gdb.  */
  116.   DEBUG_FLAG_ENTRY("packets"),
  117. #define trace_pkt (debug_flags[0].val)
  118.   /* Display entry point informations.  */
  119.   DEBUG_FLAG_ENTRY("entry"),
  120. #define trace_entry (debug_flags[1].val)
  121.   /* Be verbose about exceptions.  */
  122.   DEBUG_FLAG_ENTRY("excp"),
  123. #define trace_excp (debug_flags[2].val)
  124.   /* Be verbose about unwinding.  */
  125.   DEBUG_FLAG_ENTRY("unwind"),
  126. #define trace_unwind (debug_flags[3].val)
  127.   /* Display image at startup.  */
  128.   DEBUG_FLAG_ENTRY("images"),
  129. #define trace_images (debug_flags[4].val)
  130.   /* Display pthread_debug info.  */
  131.   DEBUG_FLAG_ENTRY("pthreaddbg")
  132. #define trace_pthreaddbg (debug_flags[5].val)
  133. };

  134. #define NBR_DEBUG_FLAGS (sizeof (debug_flags) / sizeof (debug_flags[0]))

  135. /* Connect inet device I/O channel.  */
  136. static unsigned short conn_channel;

  137. /* Widely used hex digit to ascii.  */
  138. static const char hex[] = "0123456789abcdef";

  139. /* Socket characteristics.  Apparently, there are no declaration for it in
  140.    standard headers.  */
  141. struct sockchar
  142. {
  143.   unsigned short prot;
  144.   unsigned char type;
  145.   unsigned char af;
  146. };

  147. /* Chain of images loaded.  */
  148. extern IMCB* ctl$gl_imglstptr;

  149. /* IA64 integer register representation.  */
  150. union ia64_ireg
  151. {
  152.   unsigned __int64 v;
  153.   unsigned char b[8];
  154. };

  155. /* IA64 register numbers, as defined by ia64-tdep.h.  */
  156. #define IA64_GR0_REGNUM                0
  157. #define IA64_GR32_REGNUM        (IA64_GR0_REGNUM + 32)

  158. /* Floating point registers; 128 82-bit wide registers.  */
  159. #define IA64_FR0_REGNUM                128

  160. /* Predicate registers; There are 64 of these one bit registers.  It'd
  161.    be more convenient (implementation-wise) to use a single 64 bit
  162.    word with all of these register in them.  Note that there's also a
  163.    IA64_PR_REGNUM below which contains all the bits and is used for
  164.    communicating the actual values to the target.  */
  165. #define IA64_PR0_REGNUM                256

  166. /* Branch registers: 8 64-bit registers for holding branch targets.  */
  167. #define IA64_BR0_REGNUM                320

  168. /* Virtual frame pointer; this matches IA64_FRAME_POINTER_REGNUM in
  169.    gcc/config/ia64/ia64.h.  */
  170. #define IA64_VFP_REGNUM                328

  171. /* Virtual return address pointer; this matches
  172.    IA64_RETURN_ADDRESS_POINTER_REGNUM in gcc/config/ia64/ia64.h.  */
  173. #define IA64_VRAP_REGNUM        329

  174. /* Predicate registers: There are 64 of these 1-bit registers.  We
  175.    define a single register which is used to communicate these values
  176.    to/from the target.  We will somehow contrive to make it appear
  177.    that IA64_PR0_REGNUM thru IA64_PR63_REGNUM hold the actual values.  */
  178. #define IA64_PR_REGNUM                330

  179. /* Instruction pointer: 64 bits wide.  */
  180. #define IA64_IP_REGNUM                331

  181. /* Process Status Register.  */
  182. #define IA64_PSR_REGNUM                332

  183. /* Current Frame Marker (raw form may be the cr.ifs).  */
  184. #define IA64_CFM_REGNUM                333

  185. /* Application registers; 128 64-bit wide registers possible, but some
  186.    of them are reserved.  */
  187. #define IA64_AR0_REGNUM                334
  188. #define IA64_KR0_REGNUM                (IA64_AR0_REGNUM + 0)
  189. #define IA64_KR7_REGNUM                (IA64_KR0_REGNUM + 7)

  190. #define IA64_RSC_REGNUM                (IA64_AR0_REGNUM + 16)
  191. #define IA64_BSP_REGNUM                (IA64_AR0_REGNUM + 17)
  192. #define IA64_BSPSTORE_REGNUM        (IA64_AR0_REGNUM + 18)
  193. #define IA64_RNAT_REGNUM        (IA64_AR0_REGNUM + 19)
  194. #define IA64_FCR_REGNUM                (IA64_AR0_REGNUM + 21)
  195. #define IA64_EFLAG_REGNUM        (IA64_AR0_REGNUM + 24)
  196. #define IA64_CSD_REGNUM                (IA64_AR0_REGNUM + 25)
  197. #define IA64_SSD_REGNUM                (IA64_AR0_REGNUM + 26)
  198. #define IA64_CFLG_REGNUM        (IA64_AR0_REGNUM + 27)
  199. #define IA64_FSR_REGNUM                (IA64_AR0_REGNUM + 28)
  200. #define IA64_FIR_REGNUM                (IA64_AR0_REGNUM + 29)
  201. #define IA64_FDR_REGNUM                (IA64_AR0_REGNUM + 30)
  202. #define IA64_CCV_REGNUM                (IA64_AR0_REGNUM + 32)
  203. #define IA64_UNAT_REGNUM        (IA64_AR0_REGNUM + 36)
  204. #define IA64_FPSR_REGNUM        (IA64_AR0_REGNUM + 40)
  205. #define IA64_ITC_REGNUM                (IA64_AR0_REGNUM + 44)
  206. #define IA64_PFS_REGNUM                (IA64_AR0_REGNUM + 64)
  207. #define IA64_LC_REGNUM                (IA64_AR0_REGNUM + 65)
  208. #define IA64_EC_REGNUM                (IA64_AR0_REGNUM + 66)

  209. /* NAT (Not A Thing) Bits for the general registers; there are 128 of
  210.    these.  */
  211. #define IA64_NAT0_REGNUM        462

  212. /* Process registers when a condition is caught.  */
  213. struct ia64_all_regs
  214. {
  215.   union ia64_ireg gr[32];
  216.   union ia64_ireg br[8];
  217.   union ia64_ireg ip;
  218.   union ia64_ireg psr;
  219.   union ia64_ireg bsp;
  220.   union ia64_ireg cfm;
  221.   union ia64_ireg pfs;
  222.   union ia64_ireg pr;
  223. };

  224. static struct ia64_all_regs excp_regs;
  225. static struct ia64_all_regs sel_regs;
  226. static pthread_t sel_regs_pthread;

  227. /* IO channel for the terminal.  */
  228. static unsigned short term_chan;

  229. /* Output buffer and length.  */
  230. static char term_buf[128];
  231. static int term_buf_len;

  232. /* Buffer for communication with gdb.  */
  233. static unsigned char gdb_buf[sizeof (struct ia64_all_regs) * 2 + 64];
  234. static unsigned int gdb_blen;

  235. /* Previous primary handler.  */
  236. static void *prevhnd;

  237. /* Entry point address and bundle.  */
  238. static unsigned __int64 entry_pc;
  239. static unsigned char entry_saved[16];

  240. /* Write on the terminal.  */

  241. static void
  242. term_raw_write (const char *str, unsigned int len)
  243. {
  244.   unsigned short status;
  245.   struct _iosb iosb;

  246.   status = sys$qiow (EFN$C_ENF,           /* Event flag.  */
  247.                      term_chan,           /* I/O channel.  */
  248.                      IO$_WRITEVBLK,       /* I/O function code.  */
  249.                      &iosb,               /* I/O status block.  */
  250.                      0,                   /* Ast service routine.  */
  251.                      0,                   /* Ast parameter.  */
  252.                      (char *)str,         /* P1 - buffer address.  */
  253.                      len,                 /* P2 - buffer length.  */
  254.                      0, 0, 0, 0);

  255.   if (status & STS$M_SUCCESS)
  256.     status = iosb.iosb$w_status;
  257.   if (!(status & STS$M_SUCCESS))
  258.     LIB$SIGNAL (status);
  259. }

  260. /* Flush ther term buffer.  */

  261. static void
  262. term_flush (void)
  263. {
  264.   if (term_buf_len != 0)
  265.     {
  266.       term_raw_write (term_buf, term_buf_len);
  267.       term_buf_len = 0;
  268.     }
  269. }

  270. /* Write a single character, without translation.  */

  271. static void
  272. term_raw_putchar (char c)
  273. {
  274.   if (term_buf_len == sizeof (term_buf))
  275.     term_flush ();
  276.   term_buf[term_buf_len++] = c;
  277. }

  278. /* Write character C.  Translate '\n' to '\n\r'.  */

  279. static void
  280. term_putc (char c)
  281. {
  282.   if (c < 32)
  283.     switch (c)
  284.       {
  285.       case '\r':
  286.       case '\n':
  287.         break;
  288.       default:
  289.         c = '.';
  290.         break;
  291.       }
  292.   term_raw_putchar (c);
  293.   if (c == '\n')
  294.     {
  295.       term_raw_putchar ('\r');
  296.       term_flush ();
  297.     }
  298. }

  299. /* Write a C string.  */

  300. static void
  301. term_puts (const char *str)
  302. {
  303.   while (*str)
  304.     term_putc (*str++);
  305. }

  306. /* Write LEN bytes from STR.  */

  307. static void
  308. term_write (const char *str, unsigned int len)
  309. {
  310.   for (; len > 0; len--)
  311.     term_putc (*str++);
  312. }

  313. /* Write using FAO formatting.  */

  314. static void
  315. term_fao (const char *str, unsigned int str_len, ...)
  316. {
  317.   int cnt;
  318.   va_list vargs;
  319.   int i;
  320.   __int64 *args;
  321.   int status;
  322.   struct dsc$descriptor_s dstr =
  323.     { str_len, DSC$K_DTYPE_T, DSC$K_CLASS_S, (__char_ptr32)str };
  324.   char buf[128];
  325.   $DESCRIPTOR (buf_desc, buf);

  326.   va_start (vargs, str_len);
  327.   va_count (cnt);
  328.   args = (__int64 *) __ALLOCA (cnt * sizeof (__int64));
  329.   cnt -= 2;
  330.   for (i = 0; i < cnt; i++)
  331.     args[i] = va_arg (vargs, __int64);

  332.   status = sys$faol_64 (&dstr, &buf_desc.dsc$w_length, &buf_desc, args);
  333.   if (status & 1)
  334.     {
  335.       /* FAO !/ already insert a line feed.  */
  336.       for (i = 0; i < buf_desc.dsc$w_length; i++)
  337.         {
  338.           term_raw_putchar (buf[i]);
  339.           if (buf[i] == '\n')
  340.             term_flush ();
  341.         }
  342.     }

  343.   va_end (vargs);
  344. }

  345. #define TERM_FAO(STR, ...) term_fao (STR, sizeof (STR) - 1, __VA_ARGS__)

  346. /* New line.  */

  347. static void
  348. term_putnl (void)
  349. {
  350.   term_putc ('\n');
  351. }

  352. /* Initialize terminal.  */

  353. static void
  354. term_init (void)
  355. {
  356.   unsigned int status,i;
  357.   unsigned short len;
  358.   char resstring[LNM$C_NAMLENGTH];
  359.   static const $DESCRIPTOR (tabdesc, "LNM$FILE_DEV");
  360.   static const $DESCRIPTOR (logdesc, "SYS$OUTPUT");
  361.   $DESCRIPTOR (term_desc, resstring);
  362.   ILE3 item_lst[2];

  363.   item_lst[0].ile3$w_length = LNM$C_NAMLENGTH;
  364.   item_lst[0].ile3$w_code = LNM$_STRING;
  365.   item_lst[0].ile3$ps_bufaddr = resstring;
  366.   item_lst[0].ile3$ps_retlen_addr = &len;
  367.   item_lst[1].ile3$w_length = 0;
  368.   item_lst[1].ile3$w_code = 0;

  369.   /* Translate the logical name.  */
  370.   status = SYS$TRNLNM (0,                    /* Attr of the logical name.  */
  371.                        (void *) &tabdesc, /* Logical name table.  */
  372.                        (void *) &logdesc, /* Logical name.  */
  373.                        0,          /* Access mode.  */
  374.                        item_lst);  /* Item list.  */
  375.   if (!(status & STS$M_SUCCESS))
  376.     LIB$SIGNAL (status);

  377.   term_desc.dsc$w_length = len;

  378.   /* Examine 4-byte header.  Skip escape sequence.  */
  379.   if (resstring[0] == 0x1B)
  380.     {
  381.       term_desc.dsc$w_length -= 4;
  382.       term_desc.dsc$a_pointer += 4;
  383.     }

  384.   /* Assign a channel.  */
  385.   status = sys$assign (&term_desc,   /* Device name.  */
  386.                        &term_chan,   /* I/O channel.  */
  387.                        0,            /* Access mode.  */
  388.                        0);
  389.   if (!(status & STS$M_SUCCESS))
  390.     LIB$SIGNAL (status);
  391. }

  392. /* Convert from native endianness to network endianness (and vice-versa).  */

  393. static unsigned int
  394. wordswap (unsigned int v)
  395. {
  396.   return ((v & 0xff) << 8) | ((v >> 8) & 0xff);
  397. }

  398. /* Initialize the socket connection, and wait for a client.  */

  399. static void
  400. sock_init (void)
  401. {
  402.   struct _iosb iosb;
  403.   unsigned int status;

  404.   /* Listen channel and characteristics.  */
  405.   unsigned short listen_channel;
  406.   struct sockchar listen_sockchar;

  407.   /* Client address.  */
  408.   unsigned short cli_addrlen;
  409.   struct sockaddr_in cli_addr;
  410.   ILE3 cli_itemlst;

  411.   /* Our address.  */
  412.   struct sockaddr_in serv_addr;
  413.   ILE2 serv_itemlst;

  414.   /* Reuseaddr option value (on).  */
  415.   int optval = 1;
  416.   ILE2 sockopt_itemlst;
  417.   ILE2 reuseaddr_itemlst;

  418.   /* TCP/IP network pseudodevice.  */
  419.   static const $DESCRIPTOR (inet_device, "TCPIP$DEVICE:");

  420.   /* Initialize socket characteristics.  */
  421.   listen_sockchar.prot = TCPIP$C_TCP;
  422.   listen_sockchar.type = TCPIP$C_STREAM;
  423.   listen_sockchar.af   = TCPIP$C_AF_INET;

  424.   /* Assign I/O channels to network device.  */
  425.   status = sys$assign ((void *) &inet_device, &listen_channel, 0, 0);
  426.   if (status & STS$M_SUCCESS)
  427.     status = sys$assign ((void *) &inet_device, &conn_channel, 0, 0);
  428.   if (!(status & STS$M_SUCCESS))
  429.     {
  430.       term_puts ("Failed to assign I/O channel(s)\n");
  431.       LIB$SIGNAL (status);
  432.     }

  433.   /* Create a listen socket.  */
  434.   status = sys$qiow (EFN$C_ENF,           /* Event flag.  */
  435.                      listen_channel,      /* I/O channel.  */
  436.                      IO$_SETMODE,         /* I/O function code.  */
  437.                      &iosb,               /* I/O status block.  */
  438.                      0,                   /* Ast service routine.  */
  439.                      0,                   /* Ast parameter.  */
  440.                      &listen_sockchar,    /* P1 - socket characteristics.  */
  441.                      0, 0, 0, 0, 0);
  442.   if (status & STS$M_SUCCESS)
  443.     status = iosb.iosb$w_status;
  444.   if (!(status & STS$M_SUCCESS))
  445.     {
  446.       term_puts ("Failed to create socket\n");
  447.       LIB$SIGNAL (status);
  448.     }

  449.   /* Set reuse address option.  */
  450.   /* Initialize reuseaddr's item-list element.  */
  451.   reuseaddr_itemlst.ile2$w_length   = sizeof (optval);
  452.   reuseaddr_itemlst.ile2$w_code     = TCPIP$C_REUSEADDR;
  453.   reuseaddr_itemlst.ile2$ps_bufaddr = &optval;

  454.   /* Initialize setsockopt's item-list descriptor.  */
  455.   sockopt_itemlst.ile2$w_length   = sizeof (reuseaddr_itemlst);
  456.   sockopt_itemlst.ile2$w_code     = TCPIP$C_SOCKOPT;
  457.   sockopt_itemlst.ile2$ps_bufaddr = &reuseaddr_itemlst;

  458.   status = sys$qiow (EFN$C_ENF,       /* Event flag.  */
  459.                      listen_channel,  /* I/O channel.  */
  460.                      IO$_SETMODE,     /* I/O function code.  */
  461.                      &iosb,           /* I/O status block.  */
  462.                      0,               /* Ast service routine.  */
  463.                      0,               /* Ast parameter.  */
  464.                      0,               /* P1.  */
  465.                      0,               /* P2.  */
  466.                      0,               /* P3.  */
  467.                      0,               /* P4.  */
  468.                      (__int64) &sockopt_itemlst, /* P5 - socket options.  */
  469.                      0);
  470.   if (status & STS$M_SUCCESS)
  471.     status = iosb.iosb$w_status;
  472.   if (!(status & STS$M_SUCCESS))
  473.     {
  474.       term_puts ("Failed to set socket option\n");
  475.       LIB$SIGNAL (status);
  476.     }

  477.   /* Bind server's ip address and port number to listen socket.  */
  478.   /* Initialize server's socket address structure.  */
  479.   ots$fill (&serv_addr, sizeof (serv_addr), 0);
  480.   serv_addr.sin_family = TCPIP$C_AF_INET;
  481.   serv_addr.sin_port = wordswap (serv_port);
  482.   serv_addr.sin_addr.s_addr = TCPIP$C_INADDR_ANY;

  483.   /* Initialize server's item-list descriptor.  */
  484.   serv_itemlst.ile2$w_length   = sizeof (serv_addr);
  485.   serv_itemlst.ile2$w_code     = TCPIP$C_SOCK_NAME;
  486.   serv_itemlst.ile2$ps_bufaddr = &serv_addr;

  487.   status = sys$qiow (EFN$C_ENF,           /* Event flag.  */
  488.                      listen_channel,      /* I/O channel.  */
  489.                      IO$_SETMODE,         /* I/O function code.  */
  490.                      &iosb,               /* I/O status block.  */
  491.                      0,                   /* Ast service routine.  */
  492.                      0,                   /* Ast parameter.  */
  493.                      0,                   /* P1.  */
  494.                      0,                   /* P2.  */
  495.                      (__int64) &serv_itemlst, /* P3 - local socket name.  */
  496.                      0, 0, 0);
  497.   if (status & STS$M_SUCCESS)
  498.     status = iosb.iosb$w_status;
  499.   if (!(status & STS$M_SUCCESS))
  500.     {
  501.       term_puts ("Failed to bind socket\n");
  502.       LIB$SIGNAL (status);
  503.     }

  504.   /* Set socket as a listen socket.  */
  505.   status = sys$qiow (EFN$C_ENF,           /* Event flag.  */
  506.                      listen_channel,      /* I/O channel.  */
  507.                      IO$_SETMODE,         /* I/O function code.  */
  508.                      &iosb,               /* I/O status block.  */
  509.                      0,                   /* Ast service routine.  */
  510.                      0,                   /* Ast parameter.  */
  511.                      0,                   /* P1.  */
  512.                      0,                   /* P2.  */
  513.                      0,                   /* P3.  */
  514.                      1,                   /* P4 - connection backlog.  */
  515.                      0, 0);
  516.   if (status & STS$M_SUCCESS)
  517.     status = iosb.iosb$w_status;
  518.   if (!(status & STS$M_SUCCESS))
  519.     {
  520.       term_puts ("Failed to set socket passive\n");
  521.       LIB$SIGNAL (status);
  522.     }

  523.   /* Accept connection from a client.  */
  524.   TERM_FAO ("Waiting for a client connection on port: !ZW!/",
  525.             wordswap (serv_addr.sin_port));

  526.   status = sys$qiow (EFN$C_ENF,              /* Event flag.  */
  527.                      listen_channel,         /* I/O channel.  */
  528.                      IO$_ACCESS|IO$M_ACCEPT, /* I/O function code.  */
  529.                      &iosb,                  /* I/O status block.  */
  530.                      0,                      /* Ast service routine.  */
  531.                      0,                      /* Ast parameter.  */
  532.                      0,                      /* P1.  */
  533.                      0,                      /* P2.  */
  534.                      0,                      /* P3.  */
  535.                      (__int64) &conn_channel, /* P4 - I/O channel for conn.  */
  536.                      0, 0);

  537.   if (status & STS$M_SUCCESS)
  538.     status = iosb.iosb$w_status;
  539.   if (!(status & STS$M_SUCCESS))
  540.     {
  541.       term_puts ("Failed to accept client connection\n");
  542.       LIB$SIGNAL (status);
  543.     }

  544.   /* Log client connection request.  */
  545.   cli_itemlst.ile3$w_length = sizeof (cli_addr);
  546.   cli_itemlst.ile3$w_code = TCPIP$C_SOCK_NAME;
  547.   cli_itemlst.ile3$ps_bufaddr = &cli_addr;
  548.   cli_itemlst.ile3$ps_retlen_addr = &cli_addrlen;
  549.   ots$fill (&cli_addr, sizeof(cli_addr), 0);
  550.   status = sys$qiow (EFN$C_ENF,           /* Event flag.  */
  551.                      conn_channel,        /* I/O channel.  */
  552.                      IO$_SENSEMODE,       /* I/O function code.  */
  553.                      &iosb,               /* I/O status block.  */
  554.                      0,                   /* Ast service routine.  */
  555.                      0,                   /* Ast parameter.  */
  556.                      0,                   /* P1.  */
  557.                      0,                   /* P2.  */
  558.                      0,                   /* P3.  */
  559.                      (__int64) &cli_itemlst,  /* P4 - peer socket name.  */
  560.                      0, 0);
  561.   if (status & STS$M_SUCCESS)
  562.     status = iosb.iosb$w_status;
  563.   if (!(status & STS$M_SUCCESS))
  564.     {
  565.       term_puts ("Failed to get client name\n");
  566.       LIB$SIGNAL (status);
  567.     }

  568.   TERM_FAO ("Accepted connection from host: !UB.!UB,!UB.!UB, port: !UW!/",
  569.             (cli_addr.sin_addr.s_addr >> 0) & 0xff,
  570.             (cli_addr.sin_addr.s_addr >> 8) & 0xff,
  571.             (cli_addr.sin_addr.s_addr >> 16) & 0xff,
  572.             (cli_addr.sin_addr.s_addr >> 24) & 0xff,
  573.             wordswap (cli_addr.sin_port));
  574. }

  575. /* Close the socket.  */

  576. static void
  577. sock_close (void)
  578. {
  579.   struct _iosb iosb;
  580.   unsigned int status;

  581.   /* Close socket.  */
  582.   status = sys$qiow (EFN$C_ENF,           /* Event flag.  */
  583.                      conn_channel,        /* I/O channel.  */
  584.                      IO$_DEACCESS,        /* I/O function code.  */
  585.                      &iosb,               /* I/O status block.  */
  586.                      0,                   /* Ast service routine.  */
  587.                      0,                   /* Ast parameter.  */
  588.                      0, 0, 0, 0, 0, 0);

  589.   if (status & STS$M_SUCCESS)
  590.     status = iosb.iosb$w_status;
  591.   if (!(status & STS$M_SUCCESS))
  592.     {
  593.       term_puts ("Failed to close socket\n");
  594.       LIB$SIGNAL (status);
  595.     }

  596.   /* Deassign I/O channel to network device.  */
  597.   status = sys$dassgn (conn_channel);

  598.   if (!(status & STS$M_SUCCESS))
  599.     {
  600.       term_puts ("Failed to deassign I/O channel\n");
  601.       LIB$SIGNAL (status);
  602.     }
  603. }

  604. /* Mark a page as R/W.  Return old rights.  */

  605. static unsigned int
  606. page_set_rw (unsigned __int64 startva, unsigned __int64 len,
  607.              unsigned int *oldprot)
  608. {
  609.   unsigned int status;
  610.   unsigned __int64 retva;
  611.   unsigned __int64 retlen;

  612.   status = SYS$SETPRT_64 ((void *)startva, len, PSL$C_USER, PRT$C_UW,
  613.                           (void *)&retva, &retlen, oldprot);
  614.   return status;
  615. }

  616. /* Restore page rights.  */

  617. static void
  618. page_restore_rw (unsigned __int64 startva, unsigned __int64 len,
  619.                 unsigned int prot)
  620. {
  621.   unsigned int status;
  622.   unsigned __int64 retva;
  623.   unsigned __int64 retlen;
  624.   unsigned int oldprot;

  625.   status = SYS$SETPRT_64 ((void *)startva, len, PSL$C_USER, prot,
  626.                           (void *)&retva, &retlen, &oldprot);
  627.   if (!(status & STS$M_SUCCESS))
  628.     LIB$SIGNAL (status);
  629. }

  630. /* Get the TEB (thread environment block).  */

  631. static pthread_t
  632. get_teb (void)
  633. {
  634.   return (pthread_t)__getReg (_IA64_REG_TP);
  635. }

  636. /* Enable thread scheduling if VAL is true.  */

  637. static unsigned int
  638. set_thread_scheduling (int val)
  639. {
  640.   struct dbgext_control_block blk;
  641.   unsigned int status;

  642.   if (!dbgext_func)
  643.     return 0;

  644.   blk.dbgext$w_function_code = DBGEXT$K_STOP_ALL_OTHER_TASKS;
  645.   blk.dbgext$w_facility_id = CMA$_FACILITY;
  646.   blk.dbgext$l_stop_value = val;

  647.   status = dbgext_func (&blk);
  648.   if (!(status & STS$M_SUCCESS))
  649.     {
  650.       TERM_FAO ("set_thread_scheduling error, val=!SL, status=!XL!/",
  651.                 val, blk.dbgext$l_status);
  652.       lib$signal (status);
  653.     }

  654.   return blk.dbgext$l_stop_value;
  655. }

  656. /* Get next thead (after THR).  Start with 0.  */

  657. static unsigned int
  658. thread_next (unsigned int thr)
  659. {
  660.   struct dbgext_control_block blk;
  661.   unsigned int status;

  662.   if (!dbgext_func)
  663.     return 0;

  664.   blk.dbgext$w_function_code = DBGEXT$K_NEXT_TASK;
  665.   blk.dbgext$w_facility_id = CMA$_FACILITY;
  666.   blk.dbgext$l_ada_flags = 0;
  667.   blk.dbgext$l_task_value = thr;

  668.   status = dbgext_func (&blk);
  669.   if (!(status & STS$M_SUCCESS))
  670.     lib$signal (status);

  671.   return blk.dbgext$l_task_value;
  672. }

  673. /* Pthread Debug callbacks.  */

  674. static int
  675. read_callback (pthreadDebugClient_t context,
  676.                pthreadDebugTargetAddr_t addr,
  677.                pthreadDebugAddr_t buf,
  678.                size_t size)
  679. {
  680.   if (trace_pthreaddbg)
  681.     TERM_FAO ("read_callback (!XH, !XH, !SL)!/", addr, buf, size);
  682.   ots$move (buf, size, addr);
  683.   return 0;
  684. }

  685. static int
  686. write_callback (pthreadDebugClient_t context,
  687.                 pthreadDebugTargetAddr_t addr,
  688.                 pthreadDebugLongConstAddr_t buf,
  689.                 size_t size)
  690. {
  691.   if (trace_pthreaddbg)
  692.     TERM_FAO ("write_callback (!XH, !XH, !SL)!/", addr, buf, size);
  693.   ots$move (addr, size, buf);
  694.   return 0;
  695. }

  696. static int
  697. suspend_callback (pthreadDebugClient_t context)
  698. {
  699.   /* Always suspended.  */
  700.   return 0;
  701. }

  702. static int
  703. resume_callback (pthreadDebugClient_t context)
  704. {
  705.   /* So no need to resume.  */
  706.   return 0;
  707. }

  708. static int
  709. kthdinfo_callback (pthreadDebugClient_t context,
  710.                    pthreadDebugKId_t kid,
  711.                    pthreadDebugKThreadInfo_p thread_info)
  712. {
  713.   if (trace_pthreaddbg)
  714.     term_puts ("kthinfo_callback");
  715.   return ENOSYS;
  716. }

  717. static int
  718. hold_callback (pthreadDebugClient_t context,
  719.                pthreadDebugKId_t kid)
  720. {
  721.   if (trace_pthreaddbg)
  722.     term_puts ("hold_callback");
  723.   return ENOSYS;
  724. }

  725. static int
  726. unhold_callback (pthreadDebugClient_t context,
  727.                  pthreadDebugKId_t kid)
  728. {
  729.   if (trace_pthreaddbg)
  730.     term_puts ("unhold_callback");
  731.   return ENOSYS;
  732. }

  733. static int
  734. getfreg_callback (pthreadDebugClient_t context,
  735.                   pthreadDebugFregs_t *reg,
  736.                   pthreadDebugKId_t kid)
  737. {
  738.   if (trace_pthreaddbg)
  739.     term_puts ("getfreg_callback");
  740.   return ENOSYS;
  741. }

  742. static int
  743. setfreg_callback (pthreadDebugClient_t context,
  744.                   const pthreadDebugFregs_t *reg,
  745.                   pthreadDebugKId_t kid)
  746. {
  747.   if (trace_pthreaddbg)
  748.     term_puts ("setfreg_callback");
  749.   return ENOSYS;
  750. }

  751. static int
  752. getreg_callback (pthreadDebugClient_t context,
  753.                  pthreadDebugRegs_t *reg,
  754.                  pthreadDebugKId_t kid)
  755. {
  756.   if (trace_pthreaddbg)
  757.     term_puts ("getreg_callback");
  758.   return ENOSYS;
  759. }

  760. static int
  761. setreg_callback (pthreadDebugClient_t context,
  762.                  const pthreadDebugRegs_t *reg,
  763.                  pthreadDebugKId_t kid)
  764. {
  765.   if (trace_pthreaddbg)
  766.     term_puts ("setreg_callback");
  767.   return ENOSYS;
  768. }

  769. static int
  770. output_callback (pthreadDebugClient_t context,
  771.                  pthreadDebugConstString_t line)
  772. {
  773.   term_puts (line);
  774.   term_putnl ();
  775.   return 0;
  776. }

  777. static int
  778. error_callback (pthreadDebugClient_t context,
  779.                  pthreadDebugConstString_t line)
  780. {
  781.   term_puts (line);
  782.   term_putnl ();
  783.   return 0;
  784. }

  785. static pthreadDebugAddr_t
  786. malloc_callback (pthreadDebugClient_t caller_context, size_t size)
  787. {
  788.   unsigned int status;
  789.   unsigned int res;
  790.   int len;

  791.   len = size + 16;
  792.   status = lib$get_vm (&len, &res, 0);
  793.   if (!(status & STS$M_SUCCESS))
  794.     LIB$SIGNAL (status);
  795.   if (trace_pthreaddbg)
  796.     TERM_FAO ("malloc_callback (!UL) -> !XA!/", size, res);
  797.   *(unsigned int *)res = len;
  798.   return (char *)res + 16;
  799. }

  800. static void
  801. free_callback (pthreadDebugClient_t caller_context, pthreadDebugAddr_t address)
  802. {
  803.   unsigned int status;
  804.   unsigned int res;
  805.   int len;

  806.   res = (unsigned int)address - 16;
  807.   len = *(unsigned int *)res;
  808.   if (trace_pthreaddbg)
  809.     TERM_FAO ("free_callback (!XA)!/", address);
  810.   status = lib$free_vm (&len, &res, 0);
  811.   if (!(status & STS$M_SUCCESS))
  812.     LIB$SIGNAL (status);
  813. }

  814. static int
  815. speckthd_callback (pthreadDebugClient_t caller_context,
  816.                    pthreadDebugSpecialType_t type,
  817.                    pthreadDebugKId_t *kernel_tid)
  818. {
  819.   return ENOTSUP;
  820. }

  821. static pthreadDebugCallbacks_t pthread_debug_callbacks = {
  822.   PTHREAD_DEBUG_VERSION,
  823.   read_callback,
  824.   write_callback,
  825.   suspend_callback,
  826.   resume_callback,
  827.   kthdinfo_callback,
  828.   hold_callback,
  829.   unhold_callback,
  830.   getfreg_callback,
  831.   setfreg_callback,
  832.   getreg_callback,
  833.   setreg_callback,
  834.   output_callback,
  835.   error_callback,
  836.   malloc_callback,
  837.   free_callback,
  838.   speckthd_callback
  839. };

  840. /* Name of the pthread shared library.  */
  841. static const $DESCRIPTOR (pthread_rtl_desc, "PTHREAD$RTL");

  842. /* List of symbols to extract from pthread debug library.  */
  843. struct pthread_debug_entry
  844. {
  845.   const unsigned int namelen;
  846.   const __char_ptr32 name;
  847.   __void_ptr32 func;
  848. };

  849. #define DEBUG_ENTRY(str) { sizeof(str) - 1, str, 0 }

  850. static struct pthread_debug_entry pthread_debug_entries[] = {
  851.   DEBUG_ENTRY("pthreadDebugContextInit"),
  852.   DEBUG_ENTRY("pthreadDebugThdSeqInit"),
  853.   DEBUG_ENTRY("pthreadDebugThdSeqNext"),
  854.   DEBUG_ENTRY("pthreadDebugThdSeqDestroy"),
  855.   DEBUG_ENTRY("pthreadDebugThdGetInfo"),
  856.   DEBUG_ENTRY("pthreadDebugThdGetInfoAddr"),
  857.   DEBUG_ENTRY("pthreadDebugThdGetReg"),
  858.   DEBUG_ENTRY("pthreadDebugCmd")
  859. };

  860. /* Pthread debug context.  */
  861. static pthreadDebugContext_t debug_context;

  862. /* Wrapper around pthread debug entry points.  */

  863. static int
  864. pthread_debug_thd_seq_init (pthreadDebugId_t *id)
  865. {
  866.   return ((int (*)())pthread_debug_entries[1].func)
  867.     (debug_context, id);
  868. }

  869. static int
  870. pthread_debug_thd_seq_next (pthreadDebugId_t *id)
  871. {
  872.   return ((int (*)())pthread_debug_entries[2].func)
  873.     (debug_context, id);
  874. }

  875. static int
  876. pthread_debug_thd_seq_destroy (void)
  877. {
  878.   return ((int (*)())pthread_debug_entries[3].func)
  879.     (debug_context);
  880. }

  881. static int
  882. pthread_debug_thd_get_info (pthreadDebugId_t id,
  883.                             pthreadDebugThreadInfo_t *info)
  884. {
  885.   return ((int (*)())pthread_debug_entries[4].func)
  886.     (debug_context, id, info);
  887. }

  888. static int
  889. pthread_debug_thd_get_info_addr (pthread_t thr,
  890.                                  pthreadDebugThreadInfo_t *info)
  891. {
  892.   return ((int (*)())pthread_debug_entries[5].func)
  893.     (debug_context, thr, info);
  894. }

  895. static int
  896. pthread_debug_thd_get_reg (pthreadDebugId_t thr,
  897.                            pthreadDebugRegs_t *regs)
  898. {
  899.   return ((int (*)())pthread_debug_entries[6].func)
  900.     (debug_context, thr, regs);
  901. }

  902. static int
  903. stub_pthread_debug_cmd (const char *cmd)
  904. {
  905.   return ((int (*)())pthread_debug_entries[7].func)
  906.     (debug_context, cmd);
  907. }

  908. /* Show all the threads.  */

  909. static void
  910. threads_show (void)
  911. {
  912.   pthreadDebugId_t id;
  913.   pthreadDebugThreadInfo_t info;
  914.   int res;

  915.   res = pthread_debug_thd_seq_init (&id);
  916.   if (res != 0)
  917.     {
  918.       TERM_FAO ("seq init failed, res=!SL!/", res);
  919.       return;
  920.     }
  921.   while (1)
  922.     {
  923.       if (pthread_debug_thd_get_info (id, &info) != 0)
  924.         {
  925.           TERM_FAO ("thd_get_info !SL failed!/", id);
  926.           break;
  927.         }
  928.       if (pthread_debug_thd_seq_next (&id) != 0)
  929.         break;
  930.     }
  931.   pthread_debug_thd_seq_destroy ();
  932. }

  933. /* Initialize pthread support.  */

  934. static void
  935. threads_init (void)
  936. {
  937.   static const $DESCRIPTOR (dbgext_desc, "PTHREAD$DBGEXT");
  938.   static const $DESCRIPTOR (pthread_debug_desc, "PTHREAD$DBGSHR");
  939.   static const $DESCRIPTOR (dbgsymtable_desc, "PTHREAD_DBG_SYMTABLE");
  940.   int pthread_dbgext;
  941.   int status;
  942.   void *dbg_symtable;
  943.   int i;
  944.   void *caller_context = 0;

  945.   status = lib$find_image_symbol
  946.     ((void *) &pthread_rtl_desc, (void *) &dbgext_desc,
  947.      (int *) &dbgext_func);
  948.   if (!(status & STS$M_SUCCESS))
  949.     LIB$SIGNAL (status);

  950.   status = lib$find_image_symbol
  951.     ((void *) &pthread_rtl_desc, (void *) &dbgsymtable_desc,
  952.      (int *) &dbg_symtable);
  953.   if (!(status & STS$M_SUCCESS))
  954.     LIB$SIGNAL (status);

  955.   /* Find entry points in pthread_debug.  */
  956.   for (i = 0;
  957.        i < sizeof (pthread_debug_entries) / sizeof (pthread_debug_entries[0]);
  958.        i++)
  959.     {
  960.       struct dsc$descriptor_s sym =
  961.         { pthread_debug_entries[i].namelen,
  962.           DSC$K_DTYPE_T, DSC$K_CLASS_S,
  963.           pthread_debug_entries[i].name };
  964.       status = lib$find_image_symbol
  965.         ((void *) &pthread_debug_desc, (void *) &sym,
  966.          (int *) &pthread_debug_entries[i].func);
  967.       if (!(status & STS$M_SUCCESS))
  968.         lib$signal (status);
  969.     }

  970.   if (trace_pthreaddbg)
  971.     TERM_FAO ("debug symtable: !XH!/", dbg_symtable);
  972.   status = ((int (*)()) pthread_debug_entries[0].func)
  973.     (&caller_context, &pthread_debug_callbacks, dbg_symtable, &debug_context);
  974.   if (status != 0)
  975.     TERM_FAO ("cannot initialize pthread_debug: !UL!/", status);
  976.   TERM_FAO ("pthread debug done!/", 0);
  977. }

  978. /* Convert an hexadecimal character to a nibble.  Return -1 in case of
  979.    error.  */

  980. static int
  981. hex2nibble (unsigned char h)
  982. {
  983.   if (h >= '0' && h <= '9')
  984.     return h - '0';
  985.   if (h >= 'A' && h <= 'F')
  986.     return h - 'A' + 10;
  987.   if (h >= 'a' && h <= 'f')
  988.     return h - 'a' + 10;
  989.   return -1;
  990. }

  991. /* Convert an hexadecimal 2 character string to a byte.  Return -1 in case
  992.    of error.  */

  993. static int
  994. hex2byte (const unsigned char *p)
  995. {
  996.   int h, l;

  997.   h = hex2nibble (p[0]);
  998.   l = hex2nibble (p[1]);
  999.   if (h == -1 || l == -1)
  1000.     return -1;
  1001.   return (h << 4) | l;
  1002. }

  1003. /* Convert a byte V to a 2 character strings P.  */

  1004. static void
  1005. byte2hex (unsigned char *p, unsigned char v)
  1006. {
  1007.   p[0] = hex[v >> 4];
  1008.   p[1] = hex[v & 0xf];
  1009. }

  1010. /* Convert a quadword V to a 16 character strings P.  */

  1011. static void
  1012. quad2hex (unsigned char *p, unsigned __int64 v)
  1013. {
  1014.   int i;
  1015.   for (i = 0; i < 16; i++)
  1016.     {
  1017.       p[i] = hex[v >> 60];
  1018.       v <<= 4;
  1019.     }
  1020. }

  1021. static void
  1022. long2pkt (unsigned int v)
  1023. {
  1024.   int i;

  1025.   for (i = 0; i < 8; i++)
  1026.     {
  1027.       gdb_buf[gdb_blen + i] = hex[(v >> 28) & 0x0f];
  1028.       v <<= 4;
  1029.     }
  1030.   gdb_blen += 8;
  1031. }

  1032. /* Generate an error packet.  */

  1033. static void
  1034. packet_error (unsigned int err)
  1035. {
  1036.   gdb_buf[1] = 'E';
  1037.   byte2hex (gdb_buf + 2, err);
  1038.   gdb_blen = 4;
  1039. }

  1040. /* Generate an OK packet.  */

  1041. static void
  1042. packet_ok (void)
  1043. {
  1044.   gdb_buf[1] = 'O';
  1045.   gdb_buf[2] = 'K';
  1046.   gdb_blen = 3;
  1047. }

  1048. /* Append a register to the packet.  */

  1049. static void
  1050. ireg2pkt (const unsigned char *p)
  1051. {
  1052.   int i;

  1053.   for (i = 0; i < 8; i++)
  1054.     {
  1055.       byte2hex (gdb_buf + gdb_blen, p[i]);
  1056.       gdb_blen += 2;
  1057.     }
  1058. }

  1059. /* Append a C string (ASCIZ) to the packet.  */

  1060. static void
  1061. str2pkt (const char *str)
  1062. {
  1063.   while (*str)
  1064.     gdb_buf[gdb_blen++] = *str++;
  1065. }

  1066. /* Extract a number fro the packet.  */

  1067. static unsigned __int64
  1068. pkt2val (const unsigned char *pkt, unsigned int *pos)
  1069. {
  1070.   unsigned __int64 res = 0;
  1071.   unsigned int i;

  1072.   while (1)
  1073.     {
  1074.       int r = hex2nibble (pkt[*pos]);

  1075.       if (r < 0)
  1076.         return res;
  1077.       res = (res << 4) | r;
  1078.       (*pos)++;
  1079.     }
  1080. }

  1081. /* Append LEN bytes from B to the current gdb packet (encode in binary).  */

  1082. static void
  1083. mem2bin (const unsigned char *b, unsigned int len)
  1084. {
  1085.   unsigned int i;
  1086.   for (i = 0; i < len; i++)
  1087.     switch (b[i])
  1088.       {
  1089.       case '#':
  1090.       case '$':
  1091.       case '}':
  1092.       case '*':
  1093.       case 0:
  1094.         gdb_buf[gdb_blen++] = '}';
  1095.         gdb_buf[gdb_blen++] = b[i] ^ 0x20;
  1096.         break;
  1097.       default:
  1098.         gdb_buf[gdb_blen++] = b[i];
  1099.         break;
  1100.       }
  1101. }

  1102. /* Append LEN bytes from B to the current gdb packet (encode in hex).  */

  1103. static void
  1104. mem2hex (const unsigned char *b, unsigned int len)
  1105. {
  1106.   unsigned int i;
  1107.   for (i = 0; i < len; i++)
  1108.     {
  1109.       byte2hex (gdb_buf + gdb_blen, b[i]);
  1110.       gdb_blen += 2;
  1111.     }
  1112. }

  1113. /* Handle the 'q' packet.  */

  1114. static void
  1115. handle_q_packet (const unsigned char *pkt, unsigned int pktlen)
  1116. {
  1117.   /* For qfThreadInfo and qsThreadInfo.  */
  1118.   static unsigned int first_thread;
  1119.   static unsigned int last_thread;

  1120.   static const char xfer_uib[] = "qXfer:uib:read:";
  1121. #define XFER_UIB_LEN (sizeof (xfer_uib) - 1)
  1122.   static const char qfthreadinfo[] = "qfThreadInfo";
  1123. #define QFTHREADINFO_LEN (sizeof (qfthreadinfo) - 1)
  1124.   static const char qsthreadinfo[] = "qsThreadInfo";
  1125. #define QSTHREADINFO_LEN (sizeof (qsthreadinfo) - 1)
  1126.   static const char qthreadextrainfo[] = "qThreadExtraInfo,";
  1127. #define QTHREADEXTRAINFO_LEN (sizeof (qthreadextrainfo) - 1)
  1128.   static const char qsupported[] = "qSupported:";
  1129. #define QSUPPORTED_LEN (sizeof (qsupported) - 1)

  1130.   if (pktlen == 2 && pkt[1] == 'C')
  1131.     {
  1132.       /* Current thread.  */
  1133.       gdb_buf[0] = '$';
  1134.       gdb_buf[1] = 'Q';
  1135.       gdb_buf[2] = 'C';
  1136.       gdb_blen = 3;
  1137.       if (has_threads)
  1138.         long2pkt ((unsigned long) get_teb ());
  1139.       return;
  1140.     }
  1141.   else if (pktlen > XFER_UIB_LEN
  1142.       && ots$strcmp_eql (pkt, XFER_UIB_LEN, xfer_uib, XFER_UIB_LEN))
  1143.     {
  1144.       /* Get unwind information block.  */
  1145.       unsigned __int64 pc;
  1146.       unsigned int pos = XFER_UIB_LEN;
  1147.       unsigned int off;
  1148.       unsigned int len;
  1149.       union
  1150.       {
  1151.         unsigned char bytes[32];
  1152.         struct
  1153.         {
  1154.           unsigned __int64 code_start_va;
  1155.           unsigned __int64 code_end_va;
  1156.           unsigned __int64 uib_start_va;
  1157.           unsigned __int64 gp_value;
  1158.         } data;
  1159.       } uei;
  1160.       int res;
  1161.       int i;

  1162.       packet_error (0);

  1163.       pc = pkt2val (pkt, &pos);
  1164.       if (pkt[pos] != ':')
  1165.         return;
  1166.       pos++;
  1167.       off = pkt2val (pkt, &pos);
  1168.       if (pkt[pos] != ',' || off != 0)
  1169.         return;
  1170.       pos++;
  1171.       len = pkt2val (pkt, &pos);
  1172.       if (pkt[pos] != '#' || len != 0x20)
  1173.         return;

  1174.       res = SYS$GET_UNWIND_ENTRY_INFO (pc, &uei.data, 0);
  1175.       if (res == SS$_NODATA || res != SS$_NORMAL)
  1176.         ots$fill (uei.bytes, sizeof (uei.bytes), 0);

  1177.       if (trace_unwind)
  1178.         {
  1179.           TERM_FAO ("Unwind request for !XH, status=!XL, uib=!XQ, GP=!XQ!/",
  1180.                     pc, res, uei.data.uib_start_va, uei.data.gp_value);
  1181.         }

  1182.       gdb_buf[0] = '$';
  1183.       gdb_buf[1] = 'l';
  1184.       gdb_blen = 2;
  1185.       mem2bin (uei.bytes, sizeof (uei.bytes));
  1186.     }
  1187.   else if (pktlen == QFTHREADINFO_LEN
  1188.            && ots$strcmp_eql (pkt, QFTHREADINFO_LEN,
  1189.                               qfthreadinfo, QFTHREADINFO_LEN))
  1190.     {
  1191.       /* Get first thread(s).  */
  1192.       gdb_buf[0] = '$';
  1193.       gdb_buf[1] = 'm';
  1194.       gdb_blen = 2;

  1195.       if (!has_threads)
  1196.         {
  1197.           gdb_buf[1] = 'l';
  1198.           return;
  1199.         }
  1200.       first_thread = thread_next (0);
  1201.       last_thread = first_thread;
  1202.       long2pkt (first_thread);
  1203.     }
  1204.   else if (pktlen == QSTHREADINFO_LEN
  1205.            && ots$strcmp_eql (pkt, QSTHREADINFO_LEN,
  1206.                               qsthreadinfo, QSTHREADINFO_LEN))
  1207.     {
  1208.       /* Get subsequent threads.  */
  1209.       gdb_buf[0] = '$';
  1210.       gdb_buf[1] = 'm';
  1211.       gdb_blen = 2;
  1212.       while (dbgext_func)
  1213.         {
  1214.           unsigned int res;
  1215.           res = thread_next (last_thread);
  1216.           if (res == first_thread)
  1217.             break;
  1218.           if (gdb_blen > 2)
  1219.             gdb_buf[gdb_blen++] = ',';
  1220.           long2pkt (res);
  1221.           last_thread = res;
  1222.           if (gdb_blen > sizeof (gdb_buf) - 16)
  1223.             break;
  1224.         }

  1225.       if (gdb_blen == 2)
  1226.         gdb_buf[1] = 'l';
  1227.     }
  1228.   else if (pktlen > QTHREADEXTRAINFO_LEN
  1229.            && ots$strcmp_eql (pkt, QTHREADEXTRAINFO_LEN,
  1230.                               qthreadextrainfo, QTHREADEXTRAINFO_LEN))
  1231.     {
  1232.       /* Get extra info about a thread.  */
  1233.       pthread_t thr;
  1234.       unsigned int pos = QTHREADEXTRAINFO_LEN;
  1235.       pthreadDebugThreadInfo_t info;
  1236.       int res;

  1237.       packet_error (0);
  1238.       if (!has_threads)
  1239.         return;

  1240.       thr = (pthread_t) pkt2val (pkt, &pos);
  1241.       if (pkt[pos] != '#')
  1242.         return;
  1243.       res = pthread_debug_thd_get_info_addr (thr, &info);
  1244.       if (res != 0)
  1245.         {
  1246.           TERM_FAO ("qThreadExtraInfo (!XH) failed: !SL!/", thr, res);
  1247.           return;
  1248.         }
  1249.       gdb_buf[0] = '$';
  1250.       gdb_blen = 1;
  1251.       mem2hex ((const unsigned char *)"VMS-thread", 11);
  1252.     }
  1253.   else if (pktlen > QSUPPORTED_LEN
  1254.            && ots$strcmp_eql (pkt, QSUPPORTED_LEN,
  1255.                               qsupported, QSUPPORTED_LEN))
  1256.     {
  1257.       /* Get supported features.  */
  1258.       pthread_t thr;
  1259.       unsigned int pos = QSUPPORTED_LEN;
  1260.       pthreadDebugThreadInfo_t info;
  1261.       int res;

  1262.       /* Ignore gdb features.  */
  1263.       gdb_buf[0] = '$';
  1264.       gdb_blen = 1;

  1265.       str2pkt ("qXfer:uib:read+");
  1266.       return;
  1267.     }
  1268.   else
  1269.     {
  1270.       if (trace_pkt)
  1271.         {
  1272.           term_puts ("unknown <: ");
  1273.           term_write ((char *)pkt, pktlen);
  1274.           term_putnl ();
  1275.         }
  1276.       return;
  1277.     }
  1278. }

  1279. /* Handle the 'v' packet.  */

  1280. static int
  1281. handle_v_packet (const unsigned char *pkt, unsigned int pktlen)
  1282. {
  1283.   static const char vcontq[] = "vCont?";
  1284. #define VCONTQ_LEN (sizeof (vcontq) - 1)

  1285.   if (pktlen == VCONTQ_LEN
  1286.       && ots$strcmp_eql (pkt, VCONTQ_LEN, vcontq, VCONTQ_LEN))
  1287.     {
  1288.       gdb_buf[0] = '$';
  1289.       gdb_blen = 1;

  1290.       str2pkt ("vCont;c;s");
  1291.       return 0;
  1292.     }
  1293.   else
  1294.     {
  1295.       if (trace_pkt)
  1296.         {
  1297.           term_puts ("unknown <: ");
  1298.           term_write ((char *)pkt, pktlen);
  1299.           term_putnl ();
  1300.         }
  1301.       return 0;
  1302.     }
  1303. }

  1304. /* Get regs for the selected thread.  */

  1305. static struct ia64_all_regs *
  1306. get_selected_regs (void)
  1307. {
  1308.   pthreadDebugRegs_t regs;
  1309.   int res;

  1310.   if (selected_thread == 0 || selected_thread == get_teb ())
  1311.     return &excp_regs;

  1312.   if (selected_thread == sel_regs_pthread)
  1313.     return &sel_regs;

  1314.   /* Read registers.  */
  1315.   res = pthread_debug_thd_get_reg (selected_id, &regs);
  1316.   if (res != 0)
  1317.     {
  1318.       /* FIXME: return NULL ?  */
  1319.       return &excp_regs;
  1320.     }
  1321.   sel_regs_pthread = selected_thread;
  1322.   sel_regs.gr[1].v = regs.gp;
  1323.   sel_regs.gr[4].v = regs.r4;
  1324.   sel_regs.gr[5].v = regs.r5;
  1325.   sel_regs.gr[6].v = regs.r6;
  1326.   sel_regs.gr[7].v = regs.r7;
  1327.   sel_regs.gr[12].v = regs.sp;
  1328.   sel_regs.br[0].v = regs.rp;
  1329.   sel_regs.br[1].v = regs.b1;
  1330.   sel_regs.br[2].v = regs.b2;
  1331.   sel_regs.br[3].v = regs.b3;
  1332.   sel_regs.br[4].v = regs.b4;
  1333.   sel_regs.br[5].v = regs.b5;
  1334.   sel_regs.ip.v = regs.ip;
  1335.   sel_regs.bsp.v = regs.bspstore; /* FIXME: it is correct ?  */
  1336.   sel_regs.pfs.v = regs.pfs;
  1337.   sel_regs.pr.v = regs.pr;
  1338.   return &sel_regs;
  1339. }

  1340. /* Create a status packet.  */

  1341. static void
  1342. packet_status (void)
  1343. {
  1344.   gdb_blen = 0;
  1345.   if (has_threads)
  1346.     {
  1347.       str2pkt ("$T05thread:");
  1348.       long2pkt ((unsigned long) get_teb ());
  1349.       gdb_buf[gdb_blen++] = ';';
  1350.     }
  1351.   else
  1352.     str2pkt ("$S05");
  1353. }

  1354. /* Return 1 to continue.  */

  1355. static int
  1356. handle_packet (unsigned char *pkt, unsigned int len)
  1357. {
  1358.   unsigned int pos;

  1359.   /* By default, reply unsupported.  */
  1360.   gdb_buf[0] = '$';
  1361.   gdb_blen = 1;

  1362.   pos = 1;
  1363.   switch (pkt[0])
  1364.     {
  1365.     case '?':
  1366.       if (len == 1)
  1367.         {
  1368.           packet_status ();
  1369.           return 0;
  1370.         }
  1371.       break;
  1372.     case 'c':
  1373.       if (len == 1)
  1374.         {
  1375.           /* Clear psr.ss.  */
  1376.           excp_regs.psr.v &= ~(unsigned __int64)PSR$M_SS;
  1377.           return 1;
  1378.         }
  1379.       else
  1380.         packet_error (0);
  1381.       break;
  1382.     case 'g':
  1383.       if (len == 1)
  1384.         {
  1385.           unsigned int i;
  1386.           struct ia64_all_regs *regs = get_selected_regs ();
  1387.           unsigned char *p = regs->gr[0].b;

  1388.           for (i = 0; i < 8 * 32; i++)
  1389.             byte2hex (gdb_buf + 1 + 2 * i, p[i]);
  1390.           gdb_blen += 2 * 8 * 32;
  1391.           return 0;
  1392.         }
  1393.       break;
  1394.     case 'H':
  1395.       if (pkt[1] == 'g')
  1396.         {
  1397.           int res;
  1398.           unsigned __int64 val;
  1399.           pthreadDebugThreadInfo_t info;

  1400.           pos++;
  1401.           val = pkt2val (pkt, &pos);
  1402.           if (pos != len)
  1403.             {
  1404.               packet_error (0);
  1405.               return 0;
  1406.             }
  1407.           if (val == 0)
  1408.             {
  1409.               /* Default one.  */
  1410.               selected_thread = get_teb ();
  1411.               selected_id = 0;
  1412.             }
  1413.           else if (!has_threads)
  1414.             {
  1415.               packet_error (0);
  1416.               return 0;
  1417.             }
  1418.           else
  1419.             {
  1420.               res = pthread_debug_thd_get_info_addr ((pthread_t) val, &info);
  1421.               if (res != 0)
  1422.                 {
  1423.                   TERM_FAO ("qThreadExtraInfo (!XH) failed: !SL!/", val, res);
  1424.                   packet_error (0);
  1425.                   return 0;
  1426.                 }
  1427.               selected_thread = info.teb;
  1428.               selected_id = info.sequence;
  1429.             }
  1430.           packet_ok ();
  1431.           break;
  1432.         }
  1433.       else if (pkt[1] == 'c'
  1434.                && ((pkt[2] == '-' && pkt[3] == '1' && len == 4)
  1435.                    || (pkt[2] == '0' && len == 3)))
  1436.         {
  1437.           /* Silently accept 'Hc0' and 'Hc-1'.  */
  1438.           packet_ok ();
  1439.           break;
  1440.         }
  1441.       else
  1442.         {
  1443.           packet_error (0);
  1444.           return 0;
  1445.         }
  1446.     case 'k':
  1447.       SYS$EXIT (SS$_NORMAL);
  1448.       break;
  1449.     case 'm':
  1450.       {
  1451.         unsigned __int64 addr;
  1452.         unsigned __int64 paddr;
  1453.         unsigned int l;
  1454.         unsigned int i;

  1455.         addr = pkt2val (pkt, &pos);
  1456.         if (pkt[pos] != ',')
  1457.           {
  1458.             packet_error (0);
  1459.             return 0;
  1460.           }
  1461.         pos++;
  1462.         l = pkt2val (pkt, &pos);
  1463.         if (pkt[pos] != '#')
  1464.           {
  1465.             packet_error (0);
  1466.             return 0;
  1467.           }

  1468.         /* Check access.  */
  1469.         i = l + (addr & VMS_PAGE_MASK);
  1470.         paddr = addr & ~VMS_PAGE_MASK;
  1471.         while (1)
  1472.           {
  1473.             if (__prober (paddr, 0) != 1)
  1474.               {
  1475.                 packet_error (2);
  1476.                 return 0;
  1477.               }
  1478.             if (i < VMS_PAGE_SIZE)
  1479.               break;
  1480.             i -= VMS_PAGE_SIZE;
  1481.             paddr += VMS_PAGE_SIZE;
  1482.           }

  1483.         /* Transfer.  */
  1484.         for (i = 0; i < l; i++)
  1485.           byte2hex (gdb_buf + 1 + 2 * i, ((unsigned char *)addr)[i]);
  1486.         gdb_blen += 2 * l;
  1487.       }
  1488.       break;
  1489.     case 'M':
  1490.       {
  1491.         unsigned __int64 addr;
  1492.         unsigned __int64 paddr;
  1493.         unsigned int l;
  1494.         unsigned int i;
  1495.         unsigned int oldprot;

  1496.         addr = pkt2val (pkt, &pos);
  1497.         if (pkt[pos] != ',')
  1498.           {
  1499.             packet_error (0);
  1500.             return 0;
  1501.           }
  1502.         pos++;
  1503.         l = pkt2val (pkt, &pos);
  1504.         if (pkt[pos] != ':')
  1505.           {
  1506.             packet_error (0);
  1507.             return 0;
  1508.           }
  1509.         pos++;
  1510.         page_set_rw (addr, l, &oldprot);

  1511.         /* Check access.  */
  1512.         i = l + (addr & VMS_PAGE_MASK);
  1513.         paddr = addr & ~VMS_PAGE_MASK;
  1514.         while (1)
  1515.           {
  1516.             if (__probew (paddr, 0) != 1)
  1517.               {
  1518.                 page_restore_rw (addr, l, oldprot);
  1519.                 return 0;
  1520.               }
  1521.             if (i < VMS_PAGE_SIZE)
  1522.               break;
  1523.             i -= VMS_PAGE_SIZE;
  1524.             paddr += VMS_PAGE_SIZE;
  1525.           }

  1526.         /* Write.  */
  1527.         for (i = 0; i < l; i++)
  1528.           {
  1529.             int v = hex2byte (pkt + pos);
  1530.             pos += 2;
  1531.             ((unsigned char *)addr)[i] = v;
  1532.           }

  1533.         /* Sync caches.  */
  1534.         for (i = 0; i < l; i += 15)
  1535.           __fc (addr + i);
  1536.         __fc (addr + l);

  1537.         page_restore_rw (addr, l, oldprot);
  1538.         packet_ok ();
  1539.       }
  1540.       break;
  1541.     case 'p':
  1542.       {
  1543.         unsigned int num = 0;
  1544.         unsigned int i;
  1545.         struct ia64_all_regs *regs = get_selected_regs ();

  1546.         num = pkt2val (pkt, &pos);
  1547.         if (pos != len)
  1548.           {
  1549.             packet_error (0);
  1550.             return 0;
  1551.           }

  1552.         switch (num)
  1553.           {
  1554.           case IA64_IP_REGNUM:
  1555.             ireg2pkt (regs->ip.b);
  1556.             break;
  1557.           case IA64_BR0_REGNUM:
  1558.             ireg2pkt (regs->br[0].b);
  1559.             break;
  1560.           case IA64_PSR_REGNUM:
  1561.             ireg2pkt (regs->psr.b);
  1562.             break;
  1563.           case IA64_BSP_REGNUM:
  1564.             ireg2pkt (regs->bsp.b);
  1565.             break;
  1566.           case IA64_CFM_REGNUM:
  1567.             ireg2pkt (regs->cfm.b);
  1568.             break;
  1569.           case IA64_PFS_REGNUM:
  1570.             ireg2pkt (regs->pfs.b);
  1571.             break;
  1572.           case IA64_PR_REGNUM:
  1573.             ireg2pkt (regs->pr.b);
  1574.             break;
  1575.           default:
  1576.             TERM_FAO ("gdbserv: unhandled reg !UW!/", num);
  1577.             packet_error (0);
  1578.             return 0;
  1579.           }
  1580.       }
  1581.       break;
  1582.     case 'q':
  1583.       handle_q_packet (pkt, len);
  1584.       break;
  1585.     case 's':
  1586.       if (len == 1)
  1587.         {
  1588.           /* Set psr.ss.  */
  1589.           excp_regs.psr.v |= (unsigned __int64)PSR$M_SS;
  1590.           return 1;
  1591.         }
  1592.       else
  1593.         packet_error (0);
  1594.       break;
  1595.     case 'T':
  1596.       /* Thread status.  */
  1597.       if (!has_threads)
  1598.         {
  1599.           packet_ok ();
  1600.           break;
  1601.         }
  1602.       else
  1603.         {
  1604.           int res;
  1605.           unsigned __int64 val;
  1606.           unsigned int fthr, thr;

  1607.           val = pkt2val (pkt, &pos);
  1608.           /* Default is error (but only after parsing is complete).  */
  1609.           packet_error (0);
  1610.           if (pos != len)
  1611.             break;

  1612.           /* Follow the list.  This makes a O(n2) algorithm, but we don't really
  1613.              have the choice.  Note that pthread_debug_thd_get_info_addr
  1614.              doesn't look reliable.  */
  1615.           fthr = thread_next (0);
  1616.           thr = fthr;
  1617.           do
  1618.             {
  1619.               if (val == thr)
  1620.                 {
  1621.                   packet_ok ();
  1622.                   break;
  1623.                 }
  1624.               thr = thread_next (thr);
  1625.             }
  1626.           while (thr != fthr);
  1627.         }
  1628.       break;
  1629.     case 'v':
  1630.       return handle_v_packet (pkt, len);
  1631.       break;
  1632.     case 'V':
  1633.       if (len > 3 && pkt[1] == 'M' && pkt[2] == 'S' && pkt[3] == ' ')
  1634.         {
  1635.           /* Temporary extension.  */
  1636.           if (has_threads)
  1637.             {
  1638.               pkt[len] = 0;
  1639.               stub_pthread_debug_cmd ((char *)pkt + 4);
  1640.               packet_ok ();
  1641.             }
  1642.           else
  1643.             packet_error (0);
  1644.         }
  1645.       break;
  1646.     default:
  1647.       if (trace_pkt)
  1648.         {
  1649.           term_puts ("unknown <: ");
  1650.           term_write ((char *)pkt, len);
  1651.           term_putnl ();
  1652.         }
  1653.       break;
  1654.     }
  1655.   return 0;
  1656. }

  1657. /* Raw write to gdb.  */

  1658. static void
  1659. sock_write (const unsigned char *buf, int len)
  1660. {
  1661.   struct _iosb iosb;
  1662.   unsigned int status;

  1663.   /* Write data to connection.  */
  1664.   status = sys$qiow (EFN$C_ENF,           /* Event flag.  */
  1665.                      conn_channel,        /* I/O channel.  */
  1666.                      IO$_WRITEVBLK,       /* I/O function code.  */
  1667.                      &iosb,               /* I/O status block.  */
  1668.                      0,                   /* Ast service routine.  */
  1669.                      0,                   /* Ast parameter.  */
  1670.                      (char *)buf,         /* P1 - buffer address.  */
  1671.                      len,                 /* P2 - buffer length.  */
  1672.                      0, 0, 0, 0);
  1673.   if (status & STS$M_SUCCESS)
  1674.     status = iosb.iosb$w_status;
  1675.   if (!(status & STS$M_SUCCESS))
  1676.     {
  1677.       term_puts ("Failed to write data to gdb\n");
  1678.       LIB$SIGNAL (status);
  1679.     }
  1680. }

  1681. /* Compute the cheksum and send the packet.  */

  1682. static void
  1683. send_pkt (void)
  1684. {
  1685.   unsigned char chksum = 0;
  1686.   unsigned int i;

  1687.   for (i = 1; i < gdb_blen; i++)
  1688.     chksum += gdb_buf[i];

  1689.   gdb_buf[gdb_blen] = '#';
  1690.   byte2hex (gdb_buf + gdb_blen + 1, chksum);

  1691.   sock_write (gdb_buf, gdb_blen + 3);

  1692.   if (trace_pkt > 1)
  1693.     {
  1694.       term_puts (">: ");
  1695.       term_write ((char *)gdb_buf, gdb_blen + 3);
  1696.       term_putnl ();
  1697.     }
  1698. }

  1699. /* Read and handle one command.  Return 1 is execution must resume.  */

  1700. static int
  1701. one_command (void)
  1702. {
  1703.   struct _iosb iosb;
  1704.   unsigned int status;
  1705.   unsigned int off;
  1706.   unsigned int dollar_off = 0;
  1707.   unsigned int sharp_off = 0;
  1708.   unsigned int cmd_off;
  1709.   unsigned int cmd_len;

  1710.   /* Wait for a packet.  */
  1711.   while (1)
  1712.     {
  1713.       off = 0;
  1714.       while (1)
  1715.         {
  1716.           /* Read data from connection.  */
  1717.           status = sys$qiow (EFN$C_ENF,           /* Event flag.  */
  1718.                              conn_channel,        /* I/O channel.  */
  1719.                              IO$_READVBLK,        /* I/O function code.  */
  1720.                              &iosb,               /* I/O status block.  */
  1721.                              0,                   /* Ast service routine.  */
  1722.                              0,                   /* Ast parameter.  */
  1723.                              gdb_buf + off,       /* P1 - buffer address.  */
  1724.                              sizeof (gdb_buf) - off, /* P2 - buffer leng.  */
  1725.                              0, 0, 0, 0);
  1726.           if (status & STS$M_SUCCESS)
  1727.             status = iosb.iosb$w_status;
  1728.           if (!(status & STS$M_SUCCESS))
  1729.             {
  1730.               term_puts ("Failed to read data from connection\n" );
  1731.               LIB$SIGNAL (status);
  1732.             }

  1733. #ifdef RAW_DUMP
  1734.           term_puts ("{: ");
  1735.           term_write ((char *)gdb_buf + off, iosb.iosb$w_bcnt);
  1736.           term_putnl ();
  1737. #endif

  1738.           gdb_blen = off + iosb.iosb$w_bcnt;

  1739.           if (off == 0)
  1740.             {
  1741.               /* Search for '$'.  */
  1742.               for (dollar_off = 0; dollar_off < gdb_blen; dollar_off++)
  1743.                 if (gdb_buf[dollar_off] == '$')
  1744.                   break;
  1745.               if (dollar_off >= gdb_blen)
  1746.                 {
  1747.                   /* Not found, discard the data.  */
  1748.                   off = 0;
  1749.                   continue;
  1750.                 }
  1751.               /* Search for '#'.  */
  1752.               for (sharp_off = dollar_off + 1;
  1753.                    sharp_off < gdb_blen;
  1754.                    sharp_off++)
  1755.                 if (gdb_buf[sharp_off] == '#')
  1756.                   break;
  1757.             }
  1758.           else if (sharp_off >= off)
  1759.             {
  1760.               /* Search for '#'.  */
  1761.               for (; sharp_off < gdb_blen; sharp_off++)
  1762.                 if (gdb_buf[sharp_off] == '#')
  1763.                   break;
  1764.             }

  1765.           /* Got packet with checksum.  */
  1766.           if (sharp_off + 2 <= gdb_blen)
  1767.             break;

  1768.           off = gdb_blen;
  1769.           if (gdb_blen == sizeof (gdb_buf))
  1770.             {
  1771.               /* Packet too large, discard.  */
  1772.               off = 0;
  1773.             }
  1774.         }

  1775.       /* Validate and acknowledge a packet.  */
  1776.       {
  1777.         unsigned char chksum = 0;
  1778.         unsigned int i;
  1779.         int v;

  1780.         for (i = dollar_off + 1; i < sharp_off; i++)
  1781.           chksum += gdb_buf[i];
  1782.         v = hex2byte (gdb_buf + sharp_off + 1);
  1783.         if (v != chksum)
  1784.           {
  1785.             term_puts ("Discard bad checksum packet\n");
  1786.             continue;
  1787.           }
  1788.         else
  1789.           {
  1790.             sock_write ((const unsigned char *)"+", 1);
  1791.             break;
  1792.           }
  1793.       }
  1794.     }

  1795.   if (trace_pkt > 1)
  1796.     {
  1797.       term_puts ("<: ");
  1798.       term_write ((char *)gdb_buf + dollar_off, sharp_off - dollar_off + 1);
  1799.       term_putnl ();
  1800.     }

  1801.   cmd_off = dollar_off + 1;
  1802.   cmd_len = sharp_off - dollar_off - 1;

  1803.   if (handle_packet (gdb_buf + dollar_off + 1, sharp_off - dollar_off - 1) == 1)
  1804.     return 1;

  1805.   send_pkt ();
  1806.   return 0;
  1807. }

  1808. /* Display the condition given by SIG64.  */

  1809. static void
  1810. display_excp (struct chf64$signal_array *sig64, struct chf$mech_array *mech)
  1811. {
  1812.   unsigned int status;
  1813.   char msg[160];
  1814.   unsigned short msglen;
  1815.   $DESCRIPTOR (msg_desc, msg);
  1816.   unsigned char outadr[4];

  1817.   status = SYS$GETMSG (sig64->chf64$q_sig_name, &msglen, &msg_desc, 0, outadr);
  1818.   if (status & STS$M_SUCCESS)
  1819.     {
  1820.       char msg2[160];
  1821.       unsigned short msg2len;
  1822.       struct dsc$descriptor_s msg2_desc =
  1823.         { sizeof (msg2), DSC$K_DTYPE_T, DSC$K_CLASS_S, msg2};
  1824.       msg_desc.dsc$w_length = msglen;
  1825.       status = SYS$FAOL_64 (&msg_desc, &msg2len, &msg2_desc,
  1826.                             &sig64->chf64$q_sig_arg1);
  1827.       if (status & STS$M_SUCCESS)
  1828.         term_write (msg2, msg2len);
  1829.     }
  1830.   else
  1831.     term_puts ("no message");
  1832.   term_putnl ();

  1833.   if (trace_excp > 1)
  1834.     {
  1835.       TERM_FAO (" Frame: !XH, Depth: !4SL, Esf: !XH!/",
  1836.                 mech->chf$q_mch_frame, mech->chf$q_mch_depth,
  1837.                 mech->chf$q_mch_esf_addr);
  1838.     }
  1839. }

  1840. /* Get all registers from current thread.  */

  1841. static void
  1842. read_all_registers (struct chf$mech_array *mech)
  1843. {
  1844.   struct _intstk *intstk =
  1845.     (struct _intstk *)mech->chf$q_mch_esf_addr;
  1846.   struct chf64$signal_array *sig64 =
  1847.     (struct chf64$signal_array *)mech->chf$ph_mch_sig64_addr;
  1848.   unsigned int cnt = sig64->chf64$w_sig_arg_count;
  1849.   unsigned __int64 pc = (&sig64->chf64$q_sig_name)[cnt - 2];

  1850.   excp_regs.ip.v = pc;
  1851.   excp_regs.psr.v = intstk->intstk$q_ipsr;
  1852.   /* GDB and linux expects bsp to point after the current register frame.
  1853.      Adjust.  */
  1854.   {
  1855.     unsigned __int64 bsp = intstk->intstk$q_bsp;
  1856.     unsigned int sof = intstk->intstk$q_ifs & 0x7f;
  1857.     unsigned int delta = ((bsp >> 3) & 0x3f) + sof;
  1858.     excp_regs.bsp.v = bsp + ((sof + delta / 0x3f) << 3);
  1859.   }
  1860.   excp_regs.cfm.v = intstk->intstk$q_ifs & 0x3fffffffff;
  1861.   excp_regs.pfs.v = intstk->intstk$q_pfs;
  1862.   excp_regs.pr.v = intstk->intstk$q_preds;
  1863.   excp_regs.gr[0].v = 0;
  1864.   excp_regs.gr[1].v = intstk->intstk$q_gp;
  1865.   excp_regs.gr[2].v = intstk->intstk$q_r2;
  1866.   excp_regs.gr[3].v = intstk->intstk$q_r3;
  1867.   excp_regs.gr[4].v = intstk->intstk$q_r4;
  1868.   excp_regs.gr[5].v = intstk->intstk$q_r5;
  1869.   excp_regs.gr[6].v = intstk->intstk$q_r6;
  1870.   excp_regs.gr[7].v = intstk->intstk$q_r7;
  1871.   excp_regs.gr[8].v = intstk->intstk$q_r8;
  1872.   excp_regs.gr[9].v = intstk->intstk$q_r9;
  1873.   excp_regs.gr[10].v = intstk->intstk$q_r10;
  1874.   excp_regs.gr[11].v = intstk->intstk$q_r11;
  1875.   excp_regs.gr[12].v = (unsigned __int64)intstk + intstk->intstk$l_stkalign;
  1876.   excp_regs.gr[13].v = intstk->intstk$q_r13;
  1877.   excp_regs.gr[14].v = intstk->intstk$q_r14;
  1878.   excp_regs.gr[15].v = intstk->intstk$q_r15;
  1879.   excp_regs.gr[16].v = intstk->intstk$q_r16;
  1880.   excp_regs.gr[17].v = intstk->intstk$q_r17;
  1881.   excp_regs.gr[18].v = intstk->intstk$q_r18;
  1882.   excp_regs.gr[19].v = intstk->intstk$q_r19;
  1883.   excp_regs.gr[20].v = intstk->intstk$q_r20;
  1884.   excp_regs.gr[21].v = intstk->intstk$q_r21;
  1885.   excp_regs.gr[22].v = intstk->intstk$q_r22;
  1886.   excp_regs.gr[23].v = intstk->intstk$q_r23;
  1887.   excp_regs.gr[24].v = intstk->intstk$q_r24;
  1888.   excp_regs.gr[25].v = intstk->intstk$q_r25;
  1889.   excp_regs.gr[26].v = intstk->intstk$q_r26;
  1890.   excp_regs.gr[27].v = intstk->intstk$q_r27;
  1891.   excp_regs.gr[28].v = intstk->intstk$q_r28;
  1892.   excp_regs.gr[29].v = intstk->intstk$q_r29;
  1893.   excp_regs.gr[30].v = intstk->intstk$q_r30;
  1894.   excp_regs.gr[31].v = intstk->intstk$q_r31;
  1895.   excp_regs.br[0].v = intstk->intstk$q_b0;
  1896.   excp_regs.br[1].v = intstk->intstk$q_b1;
  1897.   excp_regs.br[2].v = intstk->intstk$q_b2;
  1898.   excp_regs.br[3].v = intstk->intstk$q_b3;
  1899.   excp_regs.br[4].v = intstk->intstk$q_b4;
  1900.   excp_regs.br[5].v = intstk->intstk$q_b5;
  1901.   excp_regs.br[6].v = intstk->intstk$q_b6;
  1902.   excp_regs.br[7].v = intstk->intstk$q_b7;
  1903. }

  1904. /* Write all registers to current threadFIXME: not yet complete.  */

  1905. static void
  1906. write_all_registers (struct chf$mech_array *mech)
  1907. {
  1908.   struct _intstk *intstk =
  1909.     (struct _intstk *)mech->chf$q_mch_esf_addr;

  1910.   intstk->intstk$q_ipsr = excp_regs.psr.v;
  1911. }

  1912. /* Do debugging.  Report status to gdb and execute commands.  */

  1913. static void
  1914. do_debug (struct chf$mech_array *mech)
  1915. {
  1916.   struct _intstk *intstk =
  1917.     (struct _intstk *)mech->chf$q_mch_esf_addr;
  1918.   unsigned int old_ast;
  1919.   unsigned int old_sch;
  1920.   unsigned int status;

  1921.   /* Disable ast.  */
  1922.   status = sys$setast (0);
  1923.   switch (status)
  1924.     {
  1925.     case SS$_WASCLR:
  1926.       old_ast = 0;
  1927.       break;
  1928.     case SS$_WASSET:
  1929.       old_ast = 1;
  1930.       break;
  1931.     default:
  1932.       /* Should never happen!  */
  1933.       lib$signal (status);
  1934.     }

  1935.   /* Disable thread scheduling.  */
  1936.   if (has_threads)
  1937.     old_sch = set_thread_scheduling (0);

  1938.   read_all_registers (mech);

  1939.   /* Send stop reply packet.  */
  1940.   packet_status ();
  1941.   send_pkt ();

  1942.   while (one_command () == 0)
  1943.     ;

  1944.   write_all_registers (mech);

  1945.   /* Re-enable scheduling.  */
  1946.   if (has_threads)
  1947.     set_thread_scheduling (old_sch);

  1948.   /* Re-enable AST.  */
  1949.   status = sys$setast (old_ast);
  1950.   if (!(status & STS$M_SUCCESS))
  1951.     LIB$SIGNAL (status);
  1952. }

  1953. /* The condition handler.  That's the core of the stub.  */

  1954. static int
  1955. excp_handler (struct chf$signal_array *sig,
  1956.               struct chf$mech_array *mech)
  1957. {
  1958.   struct chf64$signal_array *sig64 =
  1959.     (struct chf64$signal_array *)mech->chf$ph_mch_sig64_addr;
  1960.   unsigned int code = sig->chf$l_sig_name & STS$M_COND_ID;
  1961.   unsigned int cnt = sig64->chf64$w_sig_arg_count;
  1962.   unsigned __int64 pc;
  1963.   unsigned int ret;
  1964.   /* Self protection.  FIXME: Should be per thread ?  */
  1965.   static int in_handler = 0;

  1966.   /* Completly ignore some conditions (signaled indirectly by this stub).  */
  1967.   switch (code)
  1968.     {
  1969.     case LIB$_KEYNOTFOU & STS$M_COND_ID:
  1970.       return SS$_RESIGNAL_64;
  1971.     default:
  1972.       break;
  1973.     }

  1974.   /* Protect against recursion.  */
  1975.   in_handler++;
  1976.   if (in_handler > 1)
  1977.     {
  1978.       if (in_handler == 2)
  1979.         TERM_FAO ("gdbstub: exception in handler (pc=!XH)!!!/",
  1980.                   (&sig64->chf64$q_sig_name)[cnt - 2]);
  1981.       sys$exit (sig->chf$l_sig_name);
  1982.     }

  1983.   pc = (&sig64->chf64$q_sig_name)[cnt - 2];
  1984.   if (trace_excp)
  1985.     TERM_FAO ("excp_handler: code: !XL, pc=!XH!/", code, pc);

  1986.   /* If break on the entry point, restore the bundle.  */
  1987.   if (code == (SS$_BREAK & STS$M_COND_ID)
  1988.       && pc == entry_pc
  1989.       && entry_pc != 0)
  1990.     {
  1991.       static unsigned int entry_prot;

  1992.       if (trace_entry)
  1993.         term_puts ("initial entry breakpoint\n");
  1994.       page_set_rw (entry_pc, 16, &entry_prot);

  1995.       ots$move ((void *)entry_pc, 16, entry_saved);
  1996.       __fc (entry_pc);
  1997.       page_restore_rw (entry_pc, 16, entry_prot);
  1998.     }

  1999.   switch (code)
  2000.     {
  2001.     case SS$_ACCVIO & STS$M_COND_ID:
  2002.       if (trace_excp <= 1)
  2003.         display_excp (sig64, mech);
  2004.       /* Fall through.  */
  2005.     case SS$_BREAK  & STS$M_COND_ID:
  2006.     case SS$_OPCDEC & STS$M_COND_ID:
  2007.     case SS$_TBIT   & STS$M_COND_ID:
  2008.     case SS$_DEBUG  & STS$M_COND_ID:
  2009.       if (trace_excp > 1)
  2010.         {
  2011.           int i;
  2012.           struct _intstk *intstk =
  2013.             (struct _intstk *)mech->chf$q_mch_esf_addr;

  2014.           display_excp (sig64, mech);

  2015.           TERM_FAO (" intstk: !XH!/", intstk);
  2016.           for (i = 0; i < cnt + 1; i++)
  2017.             TERM_FAO ("   !XH!/", ((unsigned __int64 *)sig64)[i]);
  2018.         }
  2019.       do_debug (mech);
  2020.       ret = SS$_CONTINUE_64;
  2021.       break;

  2022.     default:
  2023.       display_excp (sig64, mech);
  2024.       ret = SS$_RESIGNAL_64;
  2025.       break;
  2026.     }

  2027.   in_handler--;
  2028.   /* Discard selected thread registers.  */
  2029.   sel_regs_pthread = 0;
  2030.   return ret;
  2031. }

  2032. /* Setup internal trace flags according to GDBSTUB$TRACE logical.  */

  2033. static void
  2034. trace_init (void)
  2035. {
  2036.   unsigned int status, i, start;
  2037.   unsigned short len;
  2038.   char resstring[LNM$C_NAMLENGTH];
  2039.   static const $DESCRIPTOR (tabdesc, "LNM$DCL_LOGICAL");
  2040.   static const $DESCRIPTOR (logdesc, "GDBSTUB$TRACE");
  2041.   $DESCRIPTOR (sub_desc, resstring);
  2042.   ILE3 item_lst[2];

  2043.   item_lst[0].ile3$w_length = LNM$C_NAMLENGTH;
  2044.   item_lst[0].ile3$w_code = LNM$_STRING;
  2045.   item_lst[0].ile3$ps_bufaddr = resstring;
  2046.   item_lst[0].ile3$ps_retlen_addr = &len;
  2047.   item_lst[1].ile3$w_length = 0;
  2048.   item_lst[1].ile3$w_code = 0;

  2049.   /* Translate the logical name.  */
  2050.   status = SYS$TRNLNM (0,                   /* Attributes of the logical name.  */
  2051.                        (void *)&tabdesc,       /* Logical name table.  */
  2052.                        (void *)&logdesc,       /* Logical name.  */
  2053.                        0,                             /* Access mode.  */
  2054.                        &item_lst);             /* Item list.  */
  2055.   if (status == SS$_NOLOGNAM)
  2056.     return;
  2057.   if (!(status & STS$M_SUCCESS))
  2058.     LIB$SIGNAL (status);

  2059.   start = 0;
  2060.   for (i = 0; i <= len; i++)
  2061.     {
  2062.       if ((i == len || resstring[i] == ',' || resstring[i] == ';')
  2063.           && i != start)
  2064.         {
  2065.           int j;

  2066.           sub_desc.dsc$a_pointer = resstring + start;
  2067.           sub_desc.dsc$w_length = i - start;

  2068.           for (j = 0; j < NBR_DEBUG_FLAGS; j++)
  2069.             if (str$case_blind_compare (&sub_desc,
  2070.                                         (void *)&debug_flags[j].name) == 0)
  2071.               {
  2072.                 debug_flags[j].val++;
  2073.                 break;
  2074.               }
  2075.           if (j == NBR_DEBUG_FLAGS)
  2076.             TERM_FAO ("GDBSTUB$TRACE: unknown directive !AS!/", &sub_desc);

  2077.           start = i + 1;
  2078.         }
  2079.     }

  2080.   TERM_FAO ("GDBSTUB$TRACE=!AD ->", len, resstring);
  2081.   for (i = 0; i < NBR_DEBUG_FLAGS; i++)
  2082.     if (debug_flags[i].val > 0)
  2083.       TERM_FAO (" !AS=!ZL", &debug_flags[i].name, debug_flags[i].val);
  2084.   term_putnl ();
  2085. }


  2086. /* Entry point.  */

  2087. static int
  2088. stub_start (unsigned __int64 *progxfer, void *cli_util,
  2089.             EIHD *imghdr, IFD *imgfile,
  2090.             unsigned int linkflag, unsigned int cliflag)
  2091. {
  2092.   static int initialized;
  2093.   int i;
  2094.   int cnt;
  2095.   int is_attached;
  2096.   IMCB *imcb;
  2097.   if (initialized)
  2098.     term_puts ("gdbstub: re-entry\n");
  2099.   else
  2100.     initialized = 1;

  2101.   /* When attached (through SS$_DEBUG condition), the number of arguments
  2102.      is 4 and PROGXFER is the PC at interruption.  */
  2103.   va_count (cnt);
  2104.   is_attached = cnt == 4;

  2105.   term_init ();

  2106.   /* Hello banner.  */
  2107.   term_puts ("Hello from gdb stub\n");

  2108.   trace_init ();

  2109.   if (trace_entry && !is_attached)
  2110.     {
  2111.       TERM_FAO ("xfer: !XH, imghdr: !XH, ifd: !XH!/",
  2112.                 progxfer, imghdr, imgfile);
  2113.       for (i = -2; i < 8; i++)
  2114.         TERM_FAO ("  at !2SW: !XH!/", i, progxfer[i]);
  2115.     }

  2116.   /* Search for entry point.  */
  2117.   if (!is_attached)
  2118.     {
  2119.       entry_pc = 0;
  2120.       for (i = 0; progxfer[i]; i++)
  2121.         entry_pc = progxfer[i];

  2122.       if (trace_entry)
  2123.         {
  2124.           if (entry_pc == 0)
  2125.             {
  2126.               term_puts ("No entry point\n");
  2127.               return 0;
  2128.             }
  2129.           else
  2130.             TERM_FAO ("Entry: !XH!/",entry_pc);
  2131.         }
  2132.     }
  2133.   else
  2134.     entry_pc = progxfer[0];

  2135.   has_threads = 0;
  2136.   for (imcb = ctl$gl_imglstptr->imcb$l_flink;
  2137.        imcb != ctl$gl_imglstptr;
  2138.        imcb = imcb->imcb$l_flink)
  2139.     {
  2140.       if (ots$strcmp_eql (pthread_rtl_desc.dsc$a_pointer,
  2141.                           pthread_rtl_desc.dsc$w_length,
  2142.                           imcb->imcb$t_log_image_name + 1,
  2143.                           imcb->imcb$t_log_image_name[0]))
  2144.         has_threads = 1;

  2145.       if (trace_images)
  2146.         {
  2147.           unsigned int j;
  2148.           LDRIMG *ldrimg = imcb->imcb$l_ldrimg;
  2149.           LDRISD *ldrisd;

  2150.           TERM_FAO ("!XA-!XA ",
  2151.                     imcb->imcb$l_starting_address,
  2152.                     imcb->imcb$l_end_address);

  2153.           switch (imcb->imcb$b_act_code)
  2154.             {
  2155.             case IMCB$K_MAIN_PROGRAM:
  2156.               term_puts ("prog");
  2157.               break;
  2158.             case IMCB$K_MERGED_IMAGE:
  2159.               term_puts ("mrge");
  2160.               break;
  2161.             case IMCB$K_GLOBAL_IMAGE_SECTION:
  2162.               term_puts ("glob");
  2163.               break;
  2164.             default:
  2165.               term_puts ("????");
  2166.             }
  2167.           TERM_FAO (" !AD !40AC!/",
  2168.                     1, "KESU" + (imcb->imcb$b_access_mode & 3),
  2169.                     imcb->imcb$t_log_image_name);

  2170.           if ((long) ldrimg < 0 || trace_images < 2)
  2171.             continue;
  2172.           ldrisd = ldrimg->ldrimg$l_segments;
  2173.           for (j = 0; j < ldrimg->ldrimg$l_segcount; j++)
  2174.             {
  2175.               unsigned int flags = ldrisd[j].ldrisd$i_flags;
  2176.               term_puts ("   ");
  2177.               term_putc (flags & 0x04 ? 'R' : '-');
  2178.               term_putc (flags & 0x02 ? 'W' : '-');
  2179.               term_putc (flags & 0x01 ? 'X' : '-');
  2180.               term_puts (flags & 0x01000000 ? " Prot" : "     ");
  2181.               term_puts (flags & 0x04000000 ? " Shrt" : "     ");
  2182.               term_puts (flags & 0x08000000 ? " Shrd" : "     ");
  2183.               TERM_FAO (" !XA-!XA!/",
  2184.                         ldrisd[j].ldrisd$p_base,
  2185.                         (unsigned __int64) ldrisd[j].ldrisd$p_base
  2186.                         + ldrisd[j].ldrisd$i_len - 1);
  2187.             }
  2188.           ldrisd = ldrimg->ldrimg$l_dyn_seg;
  2189.           if (ldrisd)
  2190.             TERM_FAO ("   dynamic            !XA-!XA!/",
  2191.                       ldrisd->ldrisd$p_base,
  2192.                       (unsigned __int64) ldrisd->ldrisd$p_base
  2193.                       + ldrisd->ldrisd$i_len - 1);
  2194.         }
  2195.     }

  2196.   if (has_threads)
  2197.     threads_init ();

  2198.   /* Wait for connection.  */
  2199.   sock_init ();

  2200.   /* Set primary exception vector.  */
  2201.   {
  2202.     unsigned int status;
  2203.     status = sys$setexv (0, excp_handler, PSL$C_USER, (__void_ptr32) &prevhnd);
  2204.     if (!(status & STS$M_SUCCESS))
  2205.       LIB$SIGNAL (status);
  2206.   }

  2207.   if (is_attached)
  2208.     {
  2209.       return excp_handler ((struct chf$signal_array *) progxfer[2],
  2210.                            (struct chf$mech_array *) progxfer[3]);
  2211.     }

  2212.   /* Change first instruction to set a breakpoint.  */
  2213.   {
  2214.     /*
  2215.       01 08 00 40 00 00         [MII]       break.m 0x80001
  2216.       00 00 00 02 00 00                     nop.i 0x0
  2217.       00 00 04 00                           nop.i 0x0;;
  2218.     */
  2219.     static const unsigned char initbp[16] =
  2220.       { 0x01, 0x08, 0x00, 0x40, 0x00, 0x00,
  2221.         0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
  2222.         0x00, 0x00, 0x04, 0x00 };
  2223.     unsigned int entry_prot;
  2224.     unsigned int status;

  2225.     status = page_set_rw (entry_pc, 16, &entry_prot);

  2226.     if (!(status & STS$M_SUCCESS))
  2227.       {
  2228.         if ((status & STS$M_COND_ID) == (SS$_NOT_PROCESS_VA & STS$M_COND_ID))
  2229.           {
  2230.             /* Cannot write here.  This can happen when pthreads are
  2231.                used.  */
  2232.             entry_pc = 0;
  2233.             term_puts ("gdbstub: cannot set breakpoint on entry\n");
  2234.           }
  2235.         else
  2236.           LIB$SIGNAL (status);
  2237.       }

  2238.     if (entry_pc != 0)
  2239.       {
  2240.         ots$move (entry_saved, 16, (void *)entry_pc);
  2241.         ots$move ((void *)entry_pc, 16, (void *)initbp);
  2242.         __fc (entry_pc);
  2243.         page_restore_rw (entry_pc, 16, entry_prot);
  2244.       }
  2245.   }

  2246.   /* If it wasn't possible to set a breakpoint on the entry point,
  2247.      accept gdb commands now.  Note that registers are not updated.  */
  2248.   if (entry_pc == 0)
  2249.     {
  2250.       while (one_command () == 0)
  2251.         ;
  2252.     }

  2253.   /* We will see!  */
  2254.   return SS$_CONTINUE;
  2255. }

  2256. /* Declare the entry point of this relocatable module.  */

  2257. struct xfer_vector
  2258. {
  2259.   __int64 impure_start;
  2260.   __int64 impure_end;
  2261.   int (*entry) ();
  2262. };

  2263. #pragma __extern_model save
  2264. #pragma __extern_model strict_refdef "XFER_PSECT"
  2265. struct xfer_vector xfer_vector = {0, 0, stub_start};
  2266. #pragma __extern_model restore