📄 am29k-tdep.c
字号:
p += 4; } /* We've found the start of the function. * Try looking for a tag word that indicates whether there is a * memory frame pointer and what the memory stack allocation is. * If one doesn't exist, try using a more exhaustive search of * the prologue. For now we don't care about the argcount or * whether or not the routine is transparent. */ if (examine_tag(p-4,&trans,NULL,&msize,&mfp_used)) /* Found a good tag */ examine_prologue (p, &rsize, 0, 0); else /* No tag try prologue */ examine_prologue (p, &rsize, &msize, &mfp_used); fci->rsize = rsize; fci->msize = msize; fci->flags = 0; if (mfp_used) fci->flags |= MFP_USED; if (trans) fci->flags |= TRANSPARENT; if (innermost_frame) { fci->saved_msp = read_register (MSP_REGNUM) + msize; } else { if (mfp_used) fci->saved_msp = read_register_stack_integer (fci->frame + rsize - 4, 4); else fci->saved_msp = fci->next->saved_msp + msize; }}voidinit_extra_frame_info (fci) struct frame_info *fci;{ if (fci->next == 0) /* Assume innermost frame. May produce strange results for "info frame" but there isn't any way to tell the difference. */ init_frame_info (1, fci); else { /* We're in get_prev_frame_info. Take care of everything in init_frame_pc. */ ; }}voidinit_frame_pc (fromleaf, fci) int fromleaf; struct frame_info *fci;{ fci->pc = (fromleaf ? SAVED_PC_AFTER_CALL (fci->next) : fci->next ? FRAME_SAVED_PC (fci->next) : read_pc ()); init_frame_info (fromleaf, fci);}/* Local variables (i.e. LOC_LOCAL) are on the memory stack, with their offsets being relative to the memory stack pointer (high C) or saved_msp (gcc). */CORE_ADDRframe_locals_address (fi) struct frame_info *fi;{ if (fi->flags & MFP_USED) return fi->saved_msp; else return fi->saved_msp - fi->msize;}/* Routines for reading the register stack. The caller gets to treat the register stack as a uniform stack in memory, from address $gr1 straight through $rfb and beyond. *//* Analogous to read_memory except the length is understood to be 4. Also, myaddr can be NULL (meaning don't bother to read), and if actual_mem_addr is non-NULL, store there the address that it was fetched from (or if from a register the offset within registers). Set *LVAL to lval_memory or lval_register, depending on where it came from. */voidread_register_stack (memaddr, myaddr, actual_mem_addr, lval) CORE_ADDR memaddr; char *myaddr; CORE_ADDR *actual_mem_addr; enum lval_type *lval;{ long rfb = read_register (RFB_REGNUM); long rsp = read_register (RSP_REGNUM); /* If we don't do this 'info register' stops in the middle. */ if (memaddr >= rstack_high_address) { int val = -1; /* a bogus value */ /* It's in a local register, but off the end of the stack. */ int regnum = (memaddr - rsp) / 4 + LR0_REGNUM; if (myaddr != NULL) *(int*)myaddr = val; /* Provide bogusness */ supply_register(regnum,&val); /* More bogusness */ if (lval != NULL) *lval = lval_register; if (actual_mem_addr != NULL) *actual_mem_addr = REGISTER_BYTE (regnum); } else if (memaddr < rfb) { /* It's in a register. */ int regnum = (memaddr - rsp) / 4 + LR0_REGNUM; if (regnum < LR0_REGNUM || regnum > LR0_REGNUM + 127) error ("Attempt to read register stack out of range."); if (myaddr != NULL) read_register_gen (regnum, myaddr); if (lval != NULL) *lval = lval_register; if (actual_mem_addr != NULL) *actual_mem_addr = REGISTER_BYTE (regnum); } else { /* It's in the memory portion of the register stack. */ if (myaddr != NULL) read_memory (memaddr, myaddr, 4); if (lval != NULL) *lval = lval_memory; if (actual_mem_addr != NULL) *actual_mem_addr = memaddr; }}/* Analogous to read_memory_integer except the length is understood to be 4. */longread_register_stack_integer (memaddr, len) CORE_ADDR memaddr; int len;{ long buf; read_register_stack (memaddr, &buf, NULL, NULL); SWAP_TARGET_AND_HOST (&buf, 4); return buf;}/* Copy 4 bytes from GDB memory at MYADDR into inferior memory at MEMADDR and put the actual address written into in *ACTUAL_MEM_ADDR. */static voidwrite_register_stack (memaddr, myaddr, actual_mem_addr) CORE_ADDR memaddr; char *myaddr; CORE_ADDR *actual_mem_addr;{ long rfb = read_register (RFB_REGNUM); long rsp = read_register (RSP_REGNUM); /* If we don't do this 'info register' stops in the middle. */ if (memaddr >= rstack_high_address) { /* It's in a register, but off the end of the stack. */ if (actual_mem_addr != NULL) *actual_mem_addr = NULL; } else if (memaddr < rfb) { /* It's in a register. */ int regnum = (memaddr - rsp) / 4 + LR0_REGNUM; if (regnum < LR0_REGNUM || regnum > LR0_REGNUM + 127) error ("Attempt to read register stack out of range."); if (myaddr != NULL) write_register (regnum, *(long *)myaddr); if (actual_mem_addr != NULL) *actual_mem_addr = NULL; } else { /* It's in the memory portion of the register stack. */ if (myaddr != NULL) write_memory (memaddr, myaddr, 4); if (actual_mem_addr != NULL) *actual_mem_addr = memaddr; }}/* Find register number REGNUM relative to FRAME and put its (raw) contents in *RAW_BUFFER. Set *OPTIMIZED if the variable was optimized out (and thus can't be fetched). If the variable was fetched from memory, set *ADDRP to where it was fetched from, otherwise it was fetched from a register. The argument RAW_BUFFER must point to aligned memory. */voidget_saved_register (raw_buffer, optimized, addrp, frame, regnum, lvalp) char *raw_buffer; int *optimized; CORE_ADDR *addrp; FRAME frame; int regnum; enum lval_type *lvalp;{ struct frame_info *fi; CORE_ADDR addr; enum lval_type lval; if (frame == 0) return; fi = get_frame_info (frame); /* Once something has a register number, it doesn't get optimized out. */ if (optimized != NULL) *optimized = 0; if (regnum == RSP_REGNUM) { if (raw_buffer != NULL) *(CORE_ADDR *)raw_buffer = fi->frame; if (lvalp != NULL) *lvalp = not_lval; return; } else if (regnum == PC_REGNUM) { if (raw_buffer != NULL) *(CORE_ADDR *)raw_buffer = fi->pc; /* Not sure we have to do this. */ if (lvalp != NULL) *lvalp = not_lval; return; } else if (regnum == MSP_REGNUM) { if (raw_buffer != NULL) { if (fi->next != NULL) *(CORE_ADDR *)raw_buffer = fi->next->saved_msp; else *(CORE_ADDR *)raw_buffer = read_register (MSP_REGNUM); } /* The value may have been computed, not fetched. */ if (lvalp != NULL) *lvalp = not_lval; return; } else if (regnum < LR0_REGNUM || regnum >= LR0_REGNUM + 128) { /* These registers are not saved over procedure calls, so just print out the current values. */ if (raw_buffer != NULL) *(CORE_ADDR *)raw_buffer = read_register (regnum); if (lvalp != NULL) *lvalp = lval_register; if (addrp != NULL) *addrp = REGISTER_BYTE (regnum); return; } addr = fi->frame + (regnum - LR0_REGNUM) * 4; if (raw_buffer != NULL) read_register_stack (addr, raw_buffer, &addr, &lval); if (lvalp != NULL) *lvalp = lval; if (addrp != NULL) *addrp = addr;}/* Discard from the stack the innermost frame, restoring all saved registers. */voidpop_frame (){ FRAME frame = get_current_frame (); struct frame_info *fi = get_frame_info (frame); CORE_ADDR rfb = read_register (RFB_REGNUM); CORE_ADDR gr1 = fi->frame + fi->rsize; CORE_ADDR lr1; int i; /* If popping a dummy frame, need to restore registers. */ if (PC_IN_CALL_DUMMY (read_register (PC_REGNUM), read_register (SP_REGNUM), FRAME_FP (fi))) { int lrnum = LR0_REGNUM + DUMMY_ARG/4; for (i = 0; i < DUMMY_SAVE_SR128; ++i) write_register (SR_REGNUM (i + 128),read_register (lrnum++)); for (i = 0; i < DUMMY_SAVE_SR160; ++i) write_register (SR_REGNUM(i+160), read_register (lrnum++)); for (i = 0; i < DUMMY_SAVE_GREGS; ++i) write_register (RETURN_REGNUM + i, read_register (lrnum++)); /* Restore the PCs. */ write_register(PC_REGNUM, read_register (lrnum++)); write_register(NPC_REGNUM, read_register (lrnum)); } /* Restore the memory stack pointer. */ write_register (MSP_REGNUM, fi->saved_msp); /* Restore the register stack pointer. */ write_register (GR1_REGNUM, gr1); /* Check whether we need to fill registers. */ lr1 = read_register (LR0_REGNUM + 1); if (lr1 > rfb) { /* Fill. */ int num_bytes = lr1 - rfb; int i; long word; write_register (RAB_REGNUM, read_register (RAB_REGNUM) + num_bytes); write_register (RFB_REGNUM, lr1); for (i = 0; i < num_bytes; i += 4) { /* Note: word is in host byte order. */ word = read_memory_integer (rfb + i, 4); write_register (LR0_REGNUM + ((rfb - gr1) % 0x80) + i / 4, word); } } flush_cached_frames (); set_current_frame (create_new_frame (0, read_pc())); }/* Push an empty stack frame, to record the current PC, etc. */void push_dummy_frame (){ long w; CORE_ADDR rab, gr1; CORE_ADDR msp = read_register (MSP_REGNUM); int lrnum, i, saved_lr0; /* Allocate the new frame. */ gr1 = read_register (GR1_REGNUM) - DUMMY_FRAME_RSIZE; write_register (GR1_REGNUM, gr1); rab = read_register (RAB_REGNUM); if (gr1 < rab) { /* We need to spill registers. */ int num_bytes = rab - gr1; CORE_ADDR rfb = read_register (RFB_REGNUM); int i; long word; write_register (RFB_REGNUM, rfb - num_bytes); write_register (RAB_REGNUM, gr1); for (i = 0; i < num_bytes; i += 4) { /* Note: word is in target byte order. */ read_register_gen (LR0_REGNUM + i / 4, &word); write_memory (rfb - num_bytes + i, &word, 4); } } /* There are no arguments in to the dummy frame, so we don't need more than rsize plus the return address and lr1. */ write_register (LR0_REGNUM + 1, gr1 + DUMMY_FRAME_RSIZE + 2 * 4); /* Set the memory frame pointer. */ write_register (LR0_REGNUM + DUMMY_FRAME_RSIZE / 4 - 1, msp); /* Allocate arg_slop. */ write_register (MSP_REGNUM, msp - 16 * 4); /* Save registers. */ lrnum = LR0_REGNUM + DUMMY_ARG/4; for (i = 0; i < DUMMY_SAVE_SR128; ++i) write_register (lrnum++, read_register (SR_REGNUM (i + 128))); for (i = 0; i < DUMMY_SAVE_SR160; ++i) write_register (lrnum++, read_register (SR_REGNUM (i + 160))); for (i = 0; i < DUMMY_SAVE_GREGS; ++i) write_register (lrnum++, read_register (RETURN_REGNUM + i)); /* Save the PCs. */ write_register (lrnum++, read_register (PC_REGNUM)); write_register (lrnum, read_register (NPC_REGNUM));}reginv_com (args, fromtty) char *args; int fromtty;{ registers_changed(); if (fromtty) printf_filtered("Gdb's register cache invalidated.\n");}/* We use this mostly for debugging gdb */void_initialize_29k(){ extern CORE_ADDR text_end; add_com ("reginv ", class_obscure, reginv_com, "Invalidate gdb's internal register cache."); /* FIXME, there should be a way to make a CORE_ADDR variable settable. */ add_show_from_set (add_set_cmd ("rstack_high_address", class_support, var_uinteger, (char *)&rstack_high_address, "Set top address in memory of the register stack.\n\Attempts to access registers saved above this address will be ignored\n\or will produce the value -1.", &setlist), &showlist); /* FIXME, there should be a way to make a CORE_ADDR variable settable. */ add_show_from_set (add_set_cmd ("call_scratch_address", class_support, var_uinteger, (char *)&text_end,"Set address in memory where small amounts of RAM can be used when\n\making function calls into the inferior.", &setlist), &showlist);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -