Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(75)

Side by Side Diff: gdb/stubs/ia64vms-stub.c

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

Powered by Google App Engine
This is Rietveld 408576698