1/* Native-dependent code for LynxOS. 2 3 Copyright 1993, 1994, 1995, 1996, 1999, 2000, 2001, 2003 Free 4 Software Foundation, Inc. 5 6 This file is part of GDB. 7 8 This program is free software; you can redistribute it and/or modify 9 it under the terms of the GNU General Public License as published by 10 the Free Software Foundation; either version 2 of the License, or 11 (at your option) any later version. 12 13 This program is distributed in the hope that it will be useful, 14 but WITHOUT ANY WARRANTY; without even the implied warranty of 15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 GNU General Public License for more details. 17 18 You should have received a copy of the GNU General Public License 19 along with this program; if not, write to the Free Software 20 Foundation, Inc., 59 Temple Place - Suite 330, 21 Boston, MA 02111-1307, USA. */ 22 23#include "defs.h" 24#include "frame.h" 25#include "inferior.h" 26#include "target.h" 27#include "gdbcore.h" 28#include "regcache.h" 29 30#include <sys/ptrace.h> 31#Include "gdb_wait.h" 32#include <sys/fpp.h> 33 34static unsigned long registers_addr (int pid); 35static void fetch_core_registers (char *, unsigned, int, CORE_ADDR); 36 37#define X(ENTRY)(offsetof(struct econtext, ENTRY)) 38 39#ifdef I386 40/* Mappings from tm-i386v.h */ 41 42static int regmap[] = 43{ 44 X (eax), 45 X (ecx), 46 X (edx), 47 X (ebx), 48 X (esp), /* sp */ 49 X (ebp), /* fp */ 50 X (esi), 51 X (edi), 52 X (eip), /* pc */ 53 X (flags), /* ps */ 54 X (cs), 55 X (ss), 56 X (ds), 57 X (es), 58 X (ecode), /* Lynx doesn't give us either fs or gs, so */ 59 X (fault), /* we just substitute these two in the hopes 60 that they are useful. */ 61}; 62#endif /* I386 */ 63 64#ifdef M68K 65/* Mappings from tm-m68k.h */ 66 67static int regmap[] = 68{ 69 X (regs[0]), /* d0 */ 70 X (regs[1]), /* d1 */ 71 X (regs[2]), /* d2 */ 72 X (regs[3]), /* d3 */ 73 X (regs[4]), /* d4 */ 74 X (regs[5]), /* d5 */ 75 X (regs[6]), /* d6 */ 76 X (regs[7]), /* d7 */ 77 X (regs[8]), /* a0 */ 78 X (regs[9]), /* a1 */ 79 X (regs[10]), /* a2 */ 80 X (regs[11]), /* a3 */ 81 X (regs[12]), /* a4 */ 82 X (regs[13]), /* a5 */ 83 X (regs[14]), /* fp */ 84 offsetof (st_t, usp) - offsetof (st_t, ec), /* sp */ 85 X (status), /* ps */ 86 X (pc), 87 88 X (fregs[0 * 3]), /* fp0 */ 89 X (fregs[1 * 3]), /* fp1 */ 90 X (fregs[2 * 3]), /* fp2 */ 91 X (fregs[3 * 3]), /* fp3 */ 92 X (fregs[4 * 3]), /* fp4 */ 93 X (fregs[5 * 3]), /* fp5 */ 94 X (fregs[6 * 3]), /* fp6 */ 95 X (fregs[7 * 3]), /* fp7 */ 96 97 X (fcregs[0]), /* fpcontrol */ 98 X (fcregs[1]), /* fpstatus */ 99 X (fcregs[2]), /* fpiaddr */ 100 X (ssw), /* fpcode */ 101 X (fault), /* fpflags */ 102}; 103#endif /* M68K */ 104 105#ifdef SPARC 106/* Mappings from tm-sparc.h */ 107 108#define FX(ENTRY)(offsetof(struct fcontext, ENTRY)) 109 110static int regmap[] = 111{ 112 -1, /* g0 */ 113 X (g1), 114 X (g2), 115 X (g3), 116 X (g4), 117 -1, /* g5->g7 aren't saved by Lynx */ 118 -1, 119 -1, 120 121 X (o[0]), 122 X (o[1]), 123 X (o[2]), 124 X (o[3]), 125 X (o[4]), 126 X (o[5]), 127 X (o[6]), /* sp */ 128 X (o[7]), /* ra */ 129 130 -1, -1, -1, -1, -1, -1, -1, -1, /* l0 -> l7 */ 131 132 -1, -1, -1, -1, -1, -1, -1, -1, /* i0 -> i7 */ 133 134 FX (f.fregs[0]), /* f0 */ 135 FX (f.fregs[1]), 136 FX (f.fregs[2]), 137 FX (f.fregs[3]), 138 FX (f.fregs[4]), 139 FX (f.fregs[5]), 140 FX (f.fregs[6]), 141 FX (f.fregs[7]), 142 FX (f.fregs[8]), 143 FX (f.fregs[9]), 144 FX (f.fregs[10]), 145 FX (f.fregs[11]), 146 FX (f.fregs[12]), 147 FX (f.fregs[13]), 148 FX (f.fregs[14]), 149 FX (f.fregs[15]), 150 FX (f.fregs[16]), 151 FX (f.fregs[17]), 152 FX (f.fregs[18]), 153 FX (f.fregs[19]), 154 FX (f.fregs[20]), 155 FX (f.fregs[21]), 156 FX (f.fregs[22]), 157 FX (f.fregs[23]), 158 FX (f.fregs[24]), 159 FX (f.fregs[25]), 160 FX (f.fregs[26]), 161 FX (f.fregs[27]), 162 FX (f.fregs[28]), 163 FX (f.fregs[29]), 164 FX (f.fregs[30]), 165 FX (f.fregs[31]), 166 167 X (y), 168 X (psr), 169 X (wim), 170 X (tbr), 171 X (pc), 172 X (npc), 173 FX (fsr), /* fpsr */ 174 -1, /* cpsr */ 175}; 176#endif /* SPARC */ 177 178#ifdef rs6000 179 180static int regmap[] = 181{ 182 X (iregs[0]), /* r0 */ 183 X (iregs[1]), 184 X (iregs[2]), 185 X (iregs[3]), 186 X (iregs[4]), 187 X (iregs[5]), 188 X (iregs[6]), 189 X (iregs[7]), 190 X (iregs[8]), 191 X (iregs[9]), 192 X (iregs[10]), 193 X (iregs[11]), 194 X (iregs[12]), 195 X (iregs[13]), 196 X (iregs[14]), 197 X (iregs[15]), 198 X (iregs[16]), 199 X (iregs[17]), 200 X (iregs[18]), 201 X (iregs[19]), 202 X (iregs[20]), 203 X (iregs[21]), 204 X (iregs[22]), 205 X (iregs[23]), 206 X (iregs[24]), 207 X (iregs[25]), 208 X (iregs[26]), 209 X (iregs[27]), 210 X (iregs[28]), 211 X (iregs[29]), 212 X (iregs[30]), 213 X (iregs[31]), 214 215 X (fregs[0]), /* f0 */ 216 X (fregs[1]), 217 X (fregs[2]), 218 X (fregs[3]), 219 X (fregs[4]), 220 X (fregs[5]), 221 X (fregs[6]), 222 X (fregs[7]), 223 X (fregs[8]), 224 X (fregs[9]), 225 X (fregs[10]), 226 X (fregs[11]), 227 X (fregs[12]), 228 X (fregs[13]), 229 X (fregs[14]), 230 X (fregs[15]), 231 X (fregs[16]), 232 X (fregs[17]), 233 X (fregs[18]), 234 X (fregs[19]), 235 X (fregs[20]), 236 X (fregs[21]), 237 X (fregs[22]), 238 X (fregs[23]), 239 X (fregs[24]), 240 X (fregs[25]), 241 X (fregs[26]), 242 X (fregs[27]), 243 X (fregs[28]), 244 X (fregs[29]), 245 X (fregs[30]), 246 X (fregs[31]), 247 248 X (srr0), /* IAR (PC) */ 249 X (srr1), /* MSR (PS) */ 250 X (cr), /* CR */ 251 X (lr), /* LR */ 252 X (ctr), /* CTR */ 253 X (xer), /* XER */ 254 X (mq) /* MQ */ 255}; 256 257#endif /* rs6000 */ 258 259#if defined (I386) || defined (M68K) || defined (rs6000) 260 261/* Return the offset relative to the start of the per-thread data to the 262 saved context block. */ 263 264static unsigned long 265registers_addr (int pid) 266{ 267 CORE_ADDR stblock; 268 int ecpoff = offsetof (st_t, ecp); 269 CORE_ADDR ecp; 270 271 errno = 0; 272 stblock = (CORE_ADDR) ptrace (PTRACE_THREADUSER, pid, (PTRACE_ARG3_TYPE) 0, 273 0); 274 if (errno) 275 perror_with_name ("ptrace(PTRACE_THREADUSER)"); 276 277 ecp = (CORE_ADDR) ptrace (PTRACE_PEEKTHREAD, pid, (PTRACE_ARG3_TYPE) ecpoff, 278 0); 279 if (errno) 280 perror_with_name ("ptrace(PTRACE_PEEKTHREAD)"); 281 282 return ecp - stblock; 283} 284 285/* Fetch one or more registers from the inferior. REGNO == -1 to get 286 them all. We actually fetch more than requested, when convenient, 287 marking them as valid so we won't fetch them again. */ 288 289void 290fetch_inferior_registers (int regno) 291{ 292 int reglo, reghi; 293 int i; 294 unsigned long ecp; 295 296 if (regno == -1) 297 { 298 reglo = 0; 299 reghi = NUM_REGS - 1; 300 } 301 else 302 reglo = reghi = regno; 303 304 ecp = registers_addr (PIDGET (inferior_ptid)); 305 306 { 307 char buf[MAX_REGISTER_SIZE]; 308 for (regno = reglo; regno <= reghi; regno++) 309 { 310 int ptrace_fun = PTRACE_PEEKTHREAD; 311 312#ifdef M68K 313 ptrace_fun = regno == SP_REGNUM ? PTRACE_PEEKUSP : PTRACE_PEEKTHREAD; 314#endif 315 316 for (i = 0; i < DEPRECATED_REGISTER_RAW_SIZE (regno); i += sizeof (int)) 317 { 318 unsigned int reg; 319 320 errno = 0; 321 reg = ptrace (ptrace_fun, PIDGET (inferior_ptid), 322 (PTRACE_ARG3_TYPE) (ecp + regmap[regno] + i), 0); 323 if (errno) 324 perror_with_name ("ptrace(PTRACE_PEEKUSP)"); 325 326 *(int *) &buf[i] = reg; 327 } 328 supply_register (regno, buf); 329 } 330 } 331} 332 333/* Store our register values back into the inferior. 334 If REGNO is -1, do this for all registers. 335 Otherwise, REGNO specifies which register (so we can save time). */ 336 337void 338store_inferior_registers (int regno) 339{ 340 int reglo, reghi; 341 int i; 342 unsigned long ecp; 343 344 if (regno == -1) 345 { 346 reglo = 0; 347 reghi = NUM_REGS - 1; 348 } 349 else 350 reglo = reghi = regno; 351 352 ecp = registers_addr (PIDGET (inferior_ptid)); 353 354 for (regno = reglo; regno <= reghi; regno++) 355 { 356 int ptrace_fun = PTRACE_POKEUSER; 357 358 if (CANNOT_STORE_REGISTER (regno)) 359 continue; 360 361#ifdef M68K 362 ptrace_fun = regno == SP_REGNUM ? PTRACE_POKEUSP : PTRACE_POKEUSER; 363#endif 364 365 for (i = 0; i < DEPRECATED_REGISTER_RAW_SIZE (regno); i += sizeof (int)) 366 { 367 unsigned int reg; 368 369 reg = *(unsigned int *) &deprecated_registers[DEPRECATED_REGISTER_BYTE (regno) + i]; 370 371 errno = 0; 372 ptrace (ptrace_fun, PIDGET (inferior_ptid), 373 (PTRACE_ARG3_TYPE) (ecp + regmap[regno] + i), reg); 374 if (errno) 375 perror_with_name ("ptrace(PTRACE_POKEUSP)"); 376 } 377 } 378} 379#endif /* defined (I386) || defined (M68K) || defined (rs6000) */ 380 381/* Wait for child to do something. Return pid of child, or -1 in case 382 of error; store status through argument pointer OURSTATUS. */ 383 384ptid_t 385child_wait (ptid_t ptid, struct target_waitstatus *ourstatus) 386{ 387 int save_errno; 388 int thread; 389 union wait status; 390 int pid; 391 392 while (1) 393 { 394 int sig; 395 396 set_sigint_trap (); /* Causes SIGINT to be passed on to the 397 attached process. */ 398 pid = wait (&status); 399 400 save_errno = errno; 401 402 clear_sigint_trap (); 403 404 if (pid == -1) 405 { 406 if (save_errno == EINTR) 407 continue; 408 fprintf_unfiltered (gdb_stderr, "Child process unexpectedly missing: %s.\n", 409 safe_strerror (save_errno)); 410 /* Claim it exited with unknown signal. */ 411 ourstatus->kind = TARGET_WAITKIND_SIGNALLED; 412 ourstatus->value.sig = TARGET_SIGNAL_UNKNOWN; 413 return -1; 414 } 415 416 if (pid != PIDGET (inferior_ptid)) /* Some other process?!? */ 417 continue; 418 419 thread = status.w_tid; /* Get thread id from status */ 420 421 /* Initial thread value can only be acquired via wait, so we have to 422 resort to this hack. */ 423 424 if (TIDGET (inferior_ptid) == 0 && thread != 0) 425 { 426 inferior_ptid = MERGEPID (PIDGET (inferior_ptid), thread); 427 add_thread (inferior_ptid); 428 } 429 430 ptid = BUILDPID (pid, thread); 431 432 /* We've become a single threaded process again. */ 433 if (thread == 0) 434 inferior_ptid = ptid; 435 436 /* Check for thread creation. */ 437 if (WIFSTOPPED (status) 438 && WSTOPSIG (status) == SIGTRAP 439 && !in_thread_list (ptid)) 440 { 441 int realsig; 442 443 realsig = ptrace (PTRACE_GETTRACESIG, PIDGET (ptid), 444 (PTRACE_ARG3_TYPE) 0, 0); 445 446 if (realsig == SIGNEWTHREAD) 447 { 448 /* It's a new thread notification. We don't want to much with 449 realsig -- the code in wait_for_inferior expects SIGTRAP. */ 450 ourstatus->kind = TARGET_WAITKIND_SPURIOUS; 451 ourstatus->value.sig = TARGET_SIGNAL_0; 452 return ptid; 453 } 454 else 455 error ("Signal for unknown thread was not SIGNEWTHREAD"); 456 } 457 458 /* Check for thread termination. */ 459 else if (WIFSTOPPED (status) 460 && WSTOPSIG (status) == SIGTRAP 461 && in_thread_list (ptid)) 462 { 463 int realsig; 464 465 realsig = ptrace (PTRACE_GETTRACESIG, PIDGET (ptid), 466 (PTRACE_ARG3_TYPE) 0, 0); 467 468 if (realsig == SIGTHREADEXIT) 469 { 470 ptrace (PTRACE_CONT, PIDGET (ptid), (PTRACE_ARG3_TYPE) 0, 0); 471 continue; 472 } 473 } 474 475#ifdef SPARC 476 /* SPARC Lynx uses an byte reversed wait status; we must use the 477 host macros to access it. These lines just a copy of 478 store_waitstatus. We can't use CHILD_SPECIAL_WAITSTATUS 479 because target.c can't include the Lynx <sys/wait.h>. */ 480 if (WIFEXITED (status)) 481 { 482 ourstatus->kind = TARGET_WAITKIND_EXITED; 483 ourstatus->value.integer = WEXITSTATUS (status); 484 } 485 else if (!WIFSTOPPED (status)) 486 { 487 ourstatus->kind = TARGET_WAITKIND_SIGNALLED; 488 ourstatus->value.sig = 489 target_signal_from_host (WTERMSIG (status)); 490 } 491 else 492 { 493 ourstatus->kind = TARGET_WAITKIND_STOPPED; 494 ourstatus->value.sig = 495 target_signal_from_host (WSTOPSIG (status)); 496 } 497#else 498 store_waitstatus (ourstatus, status.w_status); 499#endif 500 501 return ptid; 502 } 503} 504 505/* Return nonzero if the given thread is still alive. */ 506int 507child_thread_alive (ptid_t ptid) 508{ 509 int pid = PIDGET (ptid); 510 511 /* Arggh. Apparently pthread_kill only works for threads within 512 the process that calls pthread_kill. 513 514 We want to avoid the lynx signal extensions as they simply don't 515 map well to the generic gdb interface we want to keep. 516 517 All we want to do is determine if a particular thread is alive; 518 it appears as if we can just make a harmless thread specific 519 ptrace call to do that. */ 520 return (ptrace (PTRACE_THREADUSER, pid, 0, 0) != -1); 521} 522 523/* Resume execution of the inferior process. 524 If STEP is nonzero, single-step it. 525 If SIGNAL is nonzero, give it that signal. */ 526 527void 528child_resume (ptid_t ptid, int step, enum target_signal signal) 529{ 530 int func; 531 int pid = PIDGET (ptid); 532 533 errno = 0; 534 535 /* If pid == -1, then we want to step/continue all threads, else 536 we only want to step/continue a single thread. */ 537 if (pid == -1) 538 { 539 pid = PIDGET (inferior_ptid); 540 func = step ? PTRACE_SINGLESTEP : PTRACE_CONT; 541 } 542 else 543 func = step ? PTRACE_SINGLESTEP_ONE : PTRACE_CONT_ONE; 544 545 546 /* An address of (PTRACE_ARG3_TYPE)1 tells ptrace to continue from where 547 it was. (If GDB wanted it to start some other way, we have already 548 written a new PC value to the child.) 549 550 If this system does not support PT_STEP, a higher level function will 551 have called single_step() to transmute the step request into a 552 continue request (by setting breakpoints on all possible successor 553 instructions), so we don't have to worry about that here. */ 554 555 ptrace (func, pid, (PTRACE_ARG3_TYPE) 1, target_signal_to_host (signal)); 556 557 if (errno) 558 perror_with_name ("ptrace"); 559} 560 561/* Convert a Lynx process ID to a string. Returns the string in a static 562 buffer. */ 563 564char * 565child_pid_to_str (ptid_t ptid) 566{ 567 static char buf[40]; 568 569 sprintf (buf, "process %d thread %d", PIDGET (ptid), TIDGET (ptid)); 570 571 return buf; 572} 573 574/* Extract the register values out of the core file and store 575 them where `read_register' will find them. 576 577 CORE_REG_SECT points to the register values themselves, read into memory. 578 CORE_REG_SIZE is the size of that area. 579 WHICH says which set of registers we are handling (0 = int, 2 = float 580 on machines where they are discontiguous). 581 REG_ADDR is the offset from u.u_ar0 to the register values relative to 582 core_reg_sect. This is used with old-fashioned core files to 583 locate the registers in a large upage-plus-stack ".reg" section. 584 Original upage address X is at location core_reg_sect+x+reg_addr. 585 */ 586 587static void 588fetch_core_registers (char *core_reg_sect, unsigned core_reg_size, int which, 589 CORE_ADDR reg_addr) 590{ 591 struct st_entry s; 592 unsigned int regno; 593 594 for (regno = 0; regno < NUM_REGS; regno++) 595 if (regmap[regno] != -1) 596 supply_register (regno, core_reg_sect + offsetof (st_t, ec) 597 + regmap[regno]); 598 599#ifdef SPARC 600/* Fetching this register causes all of the I & L regs to be read from the 601 stack and validated. */ 602 603 fetch_inferior_registers (I0_REGNUM); 604#endif 605} 606 607 608/* Register that we are able to handle lynx core file formats. 609 FIXME: is this really bfd_target_unknown_flavour? */ 610 611static struct core_fns lynx_core_fns = 612{ 613 bfd_target_unknown_flavour, /* core_flavour */ 614 default_check_format, /* check_format */ 615 default_core_sniffer, /* core_sniffer */ 616 fetch_core_registers, /* core_read_registers */ 617 NULL /* next */ 618}; 619 620void 621_initialize_core_lynx (void) 622{ 623 add_core_fns (&lynx_core_fns); 624} 625