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