1 /* Target dependent code for the Motorola 68000 series. 2 Copyright (C) 1990, 1992 Free Software Foundation, Inc. 3 4 This file is part of GDB. 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 2 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, write to the Free Software 18 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ 19 20 #include "defs.h" 21 #include "frame.h" 22 #include "gdbcore.h" 23 #include "symtab.h" 24 25 26 /* Push an empty stack frame, to record the current PC, etc. */ 27 28 void 29 m68k_push_dummy_frame () 30 { 31 register CORE_ADDR sp = read_register (SP_REGNUM); 32 register int regnum; 33 char raw_buffer[12]; 34 35 sp = push_word (sp, read_register (PC_REGNUM)); 36 sp = push_word (sp, read_register (FP_REGNUM)); 37 write_register (FP_REGNUM, sp); 38 39 /* Always save the floating-point registers, whether they exist on 40 this target or not. */ 41 for (regnum = FP0_REGNUM + 7; regnum >= FP0_REGNUM; regnum--) 42 { 43 read_register_bytes (REGISTER_BYTE (regnum), raw_buffer, 12); 44 sp = push_bytes (sp, raw_buffer, 12); 45 } 46 47 for (regnum = FP_REGNUM - 1; regnum >= 0; regnum--) 48 { 49 sp = push_word (sp, read_register (regnum)); 50 } 51 sp = push_word (sp, read_register (PS_REGNUM)); 52 write_register (SP_REGNUM, sp); 53 } 54 55 /* Discard from the stack the innermost frame, 56 restoring all saved registers. */ 57 58 void 59 m68k_pop_frame () 60 { 61 register struct frame_info *frame = get_current_frame (); 62 register CORE_ADDR fp; 63 register int regnum; 64 struct frame_saved_regs fsr; 65 struct frame_info *fi; 66 char raw_buffer[12]; 67 68 fp = FRAME_FP (frame); 69 get_frame_saved_regs (frame, &fsr); 70 for (regnum = FP0_REGNUM + 7 ; regnum >= FP0_REGNUM ; regnum--) 71 { 72 if (fsr.regs[regnum]) 73 { 74 read_memory (fsr.regs[regnum], raw_buffer, 12); 75 write_register_bytes (REGISTER_BYTE (regnum), raw_buffer, 12); 76 } 77 } 78 for (regnum = FP_REGNUM - 1 ; regnum >= 0 ; regnum--) 79 { 80 if (fsr.regs[regnum]) 81 { 82 write_register (regnum, read_memory_integer (fsr.regs[regnum], 4)); 83 } 84 } 85 if (fsr.regs[PS_REGNUM]) 86 { 87 write_register (PS_REGNUM, read_memory_integer (fsr.regs[PS_REGNUM], 4)); 88 } 89 write_register (FP_REGNUM, read_memory_integer (fp, 4)); 90 write_register (PC_REGNUM, read_memory_integer (fp + 4, 4)); 91 write_register (SP_REGNUM, fp + 8); 92 flush_cached_frames (); 93 } 94 95 96 /* Given an ip value corresponding to the start of a function, 97 return the ip of the first instruction after the function 98 prologue. This is the generic m68k support. Machines which 99 require something different can override the SKIP_PROLOGUE 100 macro to point elsewhere. 101 102 Some instructions which typically may appear in a function 103 prologue include: 104 105 A link instruction, word form: 106 107 link.w %a6,&0 4e56 XXXX 108 109 A link instruction, long form: 110 111 link.l %fp,&F%1 480e XXXX XXXX 112 113 A movm instruction to preserve integer regs: 114 115 movm.l &M%1,(4,%sp) 48ef XXXX XXXX 116 117 A fmovm instruction to preserve float regs: 118 119 fmovm &FPM%1,(FPO%1,%sp) f237 XXXX XXXX XXXX XXXX 120 121 Some profiling setup code (FIXME, not recognized yet): 122 123 lea.l (.L3,%pc),%a1 43fb XXXX XXXX XXXX 124 bsr _mcount 61ff XXXX XXXX 125 126 */ 127 128 #define P_LINK_L 0x480e 129 #define P_LINK_W 0x4e56 130 #define P_MOV_L 0x207c 131 #define P_JSR 0x4eb9 132 #define P_BSR 0x61ff 133 #define P_LEA_L 0x43fb 134 #define P_MOVM_L 0x48ef 135 #define P_FMOVM 0xf237 136 #define P_TRAP 0x4e40 137 138 CORE_ADDR 139 m68k_skip_prologue (ip) 140 CORE_ADDR ip; 141 { 142 register CORE_ADDR limit; 143 struct symtab_and_line sal; 144 register int op; 145 146 /* Find out if there is a known limit for the extent of the prologue. 147 If so, ensure we don't go past it. If not, assume "infinity". */ 148 149 sal = find_pc_line (ip, 0); 150 limit = (sal.end) ? sal.end : (CORE_ADDR) ~0; 151 152 while (ip < limit) 153 { 154 op = read_memory_integer (ip, 2); 155 op &= 0xFFFF; 156 157 if (op == P_LINK_W) 158 { 159 ip += 4; /* Skip link.w */ 160 } 161 else if (op == 0x4856) 162 ip += 2; /* Skip pea %fp */ 163 else if (op == 0x2c4f) 164 ip += 2; /* Skip move.l %sp, %fp */ 165 else if (op == P_LINK_L) 166 { 167 ip += 6; /* Skip link.l */ 168 } 169 else if (op == P_MOVM_L) 170 { 171 ip += 6; /* Skip movm.l */ 172 } 173 else if (op == P_FMOVM) 174 { 175 ip += 10; /* Skip fmovm */ 176 } 177 else 178 { 179 break; /* Found unknown code, bail out. */ 180 } 181 } 182 return (ip); 183 } 184 185 void 186 m68k_find_saved_regs (frame_info, saved_regs) 187 struct frame_info *frame_info; 188 struct frame_saved_regs *saved_regs; 189 { 190 register int regnum; 191 register int regmask; 192 register CORE_ADDR next_addr; 193 register CORE_ADDR pc; 194 195 /* First possible address for a pc in a call dummy for this frame. */ 196 CORE_ADDR possible_call_dummy_start = 197 (frame_info)->frame - CALL_DUMMY_LENGTH - FP_REGNUM*4 - 4 - 8*12; 198 199 int nextinsn; 200 memset (saved_regs, 0, sizeof (*saved_regs)); 201 if ((frame_info)->pc >= possible_call_dummy_start 202 && (frame_info)->pc <= (frame_info)->frame) 203 { 204 205 /* It is a call dummy. We could just stop now, since we know 206 what the call dummy saves and where. But this code proceeds 207 to parse the "prologue" which is part of the call dummy. 208 This is needlessly complex and confusing. FIXME. */ 209 210 next_addr = (frame_info)->frame; 211 pc = possible_call_dummy_start; 212 } 213 else 214 { 215 pc = get_pc_function_start ((frame_info)->pc); 216 217 if (0x4856 == read_memory_integer (pc, 2) 218 && 0x2c4f == read_memory_integer (pc + 2, 2)) 219 { 220 /* 221 pea %fp 222 move.l %sp, %fp */ 223 224 pc += 4; 225 next_addr = frame_info->frame; 226 } 227 else if (044016 == read_memory_integer (pc, 2)) 228 /* link.l %fp */ 229 /* Find the address above the saved 230 regs using the amount of storage from the link instruction. */ 231 next_addr = (frame_info)->frame + read_memory_integer (pc += 2, 4), pc+=4; 232 else if (047126 == read_memory_integer (pc, 2)) 233 /* link.w %fp */ 234 /* Find the address above the saved 235 regs using the amount of storage from the link instruction. */ 236 next_addr = (frame_info)->frame + read_memory_integer (pc += 2, 2), pc+=2; 237 else goto lose; 238 239 /* If have an addal #-n, sp next, adjust next_addr. */ 240 if ((0177777 & read_memory_integer (pc, 2)) == 0157774) 241 next_addr += read_memory_integer (pc += 2, 4), pc += 4; 242 } 243 regmask = read_memory_integer (pc + 2, 2); 244 245 /* Here can come an fmovem. Check for it. */ 246 nextinsn = 0xffff & read_memory_integer (pc, 2); 247 if (0xf227 == nextinsn 248 && (regmask & 0xff00) == 0xe000) 249 { pc += 4; /* Regmask's low bit is for register fp7, the first pushed */ 250 for (regnum = FP0_REGNUM + 7; regnum >= FP0_REGNUM; regnum--, regmask >>= 1) 251 if (regmask & 1) 252 saved_regs->regs[regnum] = (next_addr -= 12); 253 regmask = read_memory_integer (pc + 2, 2); } 254 255 /* next should be a moveml to (sp) or -(sp) or a movl r,-(sp) */ 256 if (0044327 == read_memory_integer (pc, 2)) 257 { pc += 4; /* Regmask's low bit is for register 0, the first written */ 258 for (regnum = 0; regnum < 16; regnum++, regmask >>= 1) 259 if (regmask & 1) 260 saved_regs->regs[regnum] = (next_addr += 4) - 4; } 261 else if (0044347 == read_memory_integer (pc, 2)) 262 { 263 pc += 4; /* Regmask's low bit is for register 15, the first pushed */ 264 for (regnum = 15; regnum >= 0; regnum--, regmask >>= 1) 265 if (regmask & 1) 266 saved_regs->regs[regnum] = (next_addr -= 4); 267 } 268 else if (0x2f00 == (0xfff0 & read_memory_integer (pc, 2))) 269 { 270 regnum = 0xf & read_memory_integer (pc, 2); pc += 2; 271 saved_regs->regs[regnum] = (next_addr -= 4); 272 /* gcc, at least, may use a pair of movel instructions when saving 273 exactly 2 registers. */ 274 if (0x2f00 == (0xfff0 & read_memory_integer (pc, 2))) 275 { 276 regnum = 0xf & read_memory_integer (pc, 2); 277 pc += 2; 278 saved_regs->regs[regnum] = (next_addr -= 4); 279 } 280 } 281 282 /* fmovemx to index of sp may follow. */ 283 regmask = read_memory_integer (pc + 2, 2); 284 nextinsn = 0xffff & read_memory_integer (pc, 2); 285 if (0xf236 == nextinsn 286 && (regmask & 0xff00) == 0xf000) 287 { pc += 10; /* Regmask's low bit is for register fp0, the first written */ 288 for (regnum = FP0_REGNUM + 7; regnum >= FP0_REGNUM; regnum--, regmask >>= 1) 289 if (regmask & 1) 290 saved_regs->regs[regnum] = (next_addr += 12) - 12; 291 regmask = read_memory_integer (pc + 2, 2); } 292 293 /* clrw -(sp); movw ccr,-(sp) may follow. */ 294 if (0x426742e7 == read_memory_integer (pc, 4)) 295 saved_regs->regs[PS_REGNUM] = (next_addr -= 4); 296 lose: ; 297 saved_regs->regs[SP_REGNUM] = (frame_info)->frame + 8; 298 saved_regs->regs[FP_REGNUM] = (frame_info)->frame; 299 saved_regs->regs[PC_REGNUM] = (frame_info)->frame + 4; 300 #ifdef SIG_SP_FP_OFFSET 301 /* Adjust saved SP_REGNUM for fake _sigtramp frames. */ 302 if (frame_info->signal_handler_caller && frame_info->next) 303 saved_regs->regs[SP_REGNUM] = frame_info->next->frame + SIG_SP_FP_OFFSET; 304 #endif 305 } 306 307 308 #ifdef USE_PROC_FS /* Target dependent support for /proc */ 309 310 #include <sys/procfs.h> 311 312 /* The /proc interface divides the target machine's register set up into 313 two different sets, the general register set (gregset) and the floating 314 point register set (fpregset). For each set, there is an ioctl to get 315 the current register set and another ioctl to set the current values. 316 317 The actual structure passed through the ioctl interface is, of course, 318 naturally machine dependent, and is different for each set of registers. 319 For the m68k for example, the general register set is typically defined 320 by: 321 322 typedef int gregset_t[18]; 323 324 #define R_D0 0 325 ... 326 #define R_PS 17 327 328 and the floating point set by: 329 330 typedef struct fpregset { 331 int f_pcr; 332 int f_psr; 333 int f_fpiaddr; 334 int f_fpregs[8][3]; (8 regs, 96 bits each) 335 } fpregset_t; 336 337 These routines provide the packing and unpacking of gregset_t and 338 fpregset_t formatted data. 339 340 */ 341 342 /* Atari SVR4 has R_SR but not R_PS */ 343 344 #if !defined (R_PS) && defined (R_SR) 345 #define R_PS R_SR 346 #endif 347 348 /* Given a pointer to a general register set in /proc format (gregset_t *), 349 unpack the register contents and supply them as gdb's idea of the current 350 register values. */ 351 352 void 353 supply_gregset (gregsetp) 354 gregset_t *gregsetp; 355 { 356 register int regi; 357 register greg_t *regp = (greg_t *) gregsetp; 358 359 for (regi = 0 ; regi < R_PC ; regi++) 360 { 361 supply_register (regi, (char *) (regp + regi)); 362 } 363 supply_register (PS_REGNUM, (char *) (regp + R_PS)); 364 supply_register (PC_REGNUM, (char *) (regp + R_PC)); 365 } 366 367 void 368 fill_gregset (gregsetp, regno) 369 gregset_t *gregsetp; 370 int regno; 371 { 372 register int regi; 373 register greg_t *regp = (greg_t *) gregsetp; 374 extern char registers[]; 375 376 for (regi = 0 ; regi < R_PC ; regi++) 377 { 378 if ((regno == -1) || (regno == regi)) 379 { 380 *(regp + regi) = *(int *) ®isters[REGISTER_BYTE (regi)]; 381 } 382 } 383 if ((regno == -1) || (regno == PS_REGNUM)) 384 { 385 *(regp + R_PS) = *(int *) ®isters[REGISTER_BYTE (PS_REGNUM)]; 386 } 387 if ((regno == -1) || (regno == PC_REGNUM)) 388 { 389 *(regp + R_PC) = *(int *) ®isters[REGISTER_BYTE (PC_REGNUM)]; 390 } 391 } 392 393 #if defined (FP0_REGNUM) 394 395 /* Given a pointer to a floating point register set in /proc format 396 (fpregset_t *), unpack the register contents and supply them as gdb's 397 idea of the current floating point register values. */ 398 399 void 400 supply_fpregset (fpregsetp) 401 fpregset_t *fpregsetp; 402 { 403 register int regi; 404 char *from; 405 406 for (regi = FP0_REGNUM ; regi < FPC_REGNUM ; regi++) 407 { 408 from = (char *) &(fpregsetp -> f_fpregs[regi-FP0_REGNUM][0]); 409 supply_register (regi, from); 410 } 411 supply_register (FPC_REGNUM, (char *) &(fpregsetp -> f_pcr)); 412 supply_register (FPS_REGNUM, (char *) &(fpregsetp -> f_psr)); 413 supply_register (FPI_REGNUM, (char *) &(fpregsetp -> f_fpiaddr)); 414 } 415 416 /* Given a pointer to a floating point register set in /proc format 417 (fpregset_t *), update the register specified by REGNO from gdb's idea 418 of the current floating point register set. If REGNO is -1, update 419 them all. */ 420 421 void 422 fill_fpregset (fpregsetp, regno) 423 fpregset_t *fpregsetp; 424 int regno; 425 { 426 int regi; 427 char *to; 428 char *from; 429 extern char registers[]; 430 431 for (regi = FP0_REGNUM ; regi < FPC_REGNUM ; regi++) 432 { 433 if ((regno == -1) || (regno == regi)) 434 { 435 from = (char *) ®isters[REGISTER_BYTE (regi)]; 436 to = (char *) &(fpregsetp -> f_fpregs[regi-FP0_REGNUM][0]); 437 memcpy (to, from, REGISTER_RAW_SIZE (regi)); 438 } 439 } 440 if ((regno == -1) || (regno == FPC_REGNUM)) 441 { 442 fpregsetp -> f_pcr = *(int *) ®isters[REGISTER_BYTE (FPC_REGNUM)]; 443 } 444 if ((regno == -1) || (regno == FPS_REGNUM)) 445 { 446 fpregsetp -> f_psr = *(int *) ®isters[REGISTER_BYTE (FPS_REGNUM)]; 447 } 448 if ((regno == -1) || (regno == FPI_REGNUM)) 449 { 450 fpregsetp -> f_fpiaddr = *(int *) ®isters[REGISTER_BYTE (FPI_REGNUM)]; 451 } 452 } 453 454 #endif /* defined (FP0_REGNUM) */ 455 456 #endif /* USE_PROC_FS */ 457 458 #ifdef GET_LONGJMP_TARGET 459 /* Figure out where the longjmp will land. Slurp the args out of the stack. 460 We expect the first arg to be a pointer to the jmp_buf structure from which 461 we extract the pc (JB_PC) that we will land at. The pc is copied into PC. 462 This routine returns true on success. */ 463 464 int 465 get_longjmp_target(pc) 466 CORE_ADDR *pc; 467 { 468 char buf[TARGET_PTR_BIT / TARGET_CHAR_BIT]; 469 CORE_ADDR sp, jb_addr; 470 471 sp = read_register(SP_REGNUM); 472 473 if (target_read_memory (sp + SP_ARG0, /* Offset of first arg on stack */ 474 buf, 475 TARGET_PTR_BIT / TARGET_CHAR_BIT)) 476 return 0; 477 478 jb_addr = extract_address (buf, TARGET_PTR_BIT / TARGET_CHAR_BIT); 479 480 if (target_read_memory (jb_addr + JB_PC * JB_ELEMENT_SIZE, buf, 481 TARGET_PTR_BIT / TARGET_CHAR_BIT)) 482 return 0; 483 484 *pc = extract_address (buf, TARGET_PTR_BIT / TARGET_CHAR_BIT); 485 486 return 1; 487 } 488 #endif /* GET_LONGJMP_TARGET */ 489 490 /* Immediately after a function call, return the saved pc before the frame 491 is setup. For sun3's, we check for the common case of being inside of a 492 system call, and if so, we know that Sun pushes the call # on the stack 493 prior to doing the trap. */ 494 495 CORE_ADDR 496 m68k_saved_pc_after_call(frame) 497 struct frame_info *frame; 498 { 499 #ifdef SYSCALL_TRAP 500 int op; 501 502 op = read_memory_integer (frame->pc - SYSCALL_TRAP_OFFSET, 2); 503 504 if (op == SYSCALL_TRAP) 505 return read_memory_integer (read_register (SP_REGNUM) + 4, 4); 506 else 507 #endif /* SYSCALL_TRAP */ 508 return read_memory_integer (read_register (SP_REGNUM), 4); 509 } 510 511 /* This used to be needed by tm-sun3.h but is probably not 512 used by any targets anymore. Keep it for now anyway. 513 This works like blockframe.c:sigtramp_saved_pc() */ 514 515 #ifdef SIG_PC_FP_OFFSET 516 CORE_ADDR 517 m68k_sigtramp_saved_pc (frame) 518 struct frame_info *frame; 519 { 520 CORE_ADDR nextfp, pc; 521 522 if (frame->signal_handler_caller == 0) 523 abort(); 524 525 nextfp = (frame)->next ? 526 (frame)->next->frame : 527 read_register (SP_REGNUM) - 8; 528 nextfp += SIG_PC_FP_OFFSET; 529 530 pc = read_memory_integer (nextfp, 4); 531 532 return pc; 533 } 534 #endif /* SIG_PC_FP_OFFSET */ 535 536 /* For Open- and NetBSD, sigtramp is 32 bytes before STACK_END_ADDR, 537 but we don't know where that is until run-time! */ 538 539 #if defined(TM_NBSD_H) || defined(TM_OBSD_H) 540 int 541 nbsd_in_sigtramp (pc) 542 CORE_ADDR pc; 543 { 544 static CORE_ADDR stack_end_addr; 545 struct minimal_symbol *msymbol; 546 CORE_ADDR pssaddr; 547 int rv; 548 549 if (stack_end_addr == 0) { 550 msymbol = lookup_minimal_symbol("__ps_strings", NULL, NULL); 551 if (msymbol == NULL) 552 pssaddr = 0x40a0; /* XXX return 0? */ 553 else 554 pssaddr = SYMBOL_VALUE_ADDRESS(msymbol); 555 stack_end_addr = read_memory_integer (pssaddr, 4); 556 stack_end_addr = (stack_end_addr + 0xFF) & ~0xFF; 557 } 558 rv = ((pc >= (stack_end_addr - 32)) && 559 (pc < stack_end_addr)); 560 return rv; 561 } 562 #endif /* TM_NBSD_H || TM_OBSD_H */ 563 564 void 565 _initialize_m68k_tdep () 566 { 567 tm_print_insn = print_insn_m68k; 568 } 569