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