CORE_ADDR microblaze_frame_saved_pc (struct frame_info * fi) { if (PC_IN_CALL_DUMMY (fi->pc, fi->frame, fi->frame)) return generic_read_register_dummy (fi->pc, fi->frame, PC_REGNUM); else return microblaze_find_callers_reg (fi, PR_REGNUM); /* return microblaze_find_callers_reg (fi, PC_REGNUM); */ }
int generic_file_frame_chain_valid (CORE_ADDR fp, struct frame_info *fi) { if (PC_IN_CALL_DUMMY (FRAME_SAVED_PC (fi), fp, fp)) return 1; /* don't prune CALL_DUMMY frames */ else /* fall back to default algorithm (see frame.h) */ return (fp != 0 && (INNER_THAN (fi->frame, fp) || fi->frame == fp) && !inside_entry_file (FRAME_SAVED_PC (fi))); }
void generic_pop_current_frame (void (*popper) (struct frame_info * frame)) { struct frame_info *frame = get_current_frame (); if (PC_IN_CALL_DUMMY (frame->pc, frame->frame, frame->frame)) generic_pop_dummy_frame (); else (*popper) (frame); }
void microblaze_pop_frame (struct frame_info *fi) { int rn; CORE_ADDR func_addr, func_end, addr; enum microblaze_instr op; int insn, rd, ra, rb, imm; int status; char *name; int offset = 0; /* offset that the return instruction specifies */ /* Find the start and end of this function. */ /* siva/9/19/05: pop frame was not computing this offset. copied code from microblaze_fix_call_dummy to find the return insn & the offset */ status = find_pc_partial_function (fi->pc, &name, &func_addr, &func_end); for (addr = func_addr; addr < func_end; addr += INST_WORD_SIZE) { /* Start decoding the function looking for rtsd */ insn = get_insn (addr); op = microblaze_decode_insn (insn, &rd, &ra, &rb, &imm); /* Check for return. */ if (IS_RETURN(op)) { offset = imm; break; } } if (PC_IN_CALL_DUMMY (fi->pc, fi->frame, fi->frame)) generic_pop_dummy_frame (); else { /* Write out the PC we saved. */ write_register (PC_REGNUM, FRAME_SAVED_PC (fi) + offset); /* Restore any saved registers. */ for (rn = 0; rn < NUM_REGS; rn++) { if (fi->saved_regs[rn] != 0) { ULONGEST value; value = read_memory_unsigned_integer (fi->saved_regs[rn], REGISTER_SIZE); write_register (rn, value); } } /* Actually cut back the stack. */ write_register (SP_REGNUM, FRAME_FP (fi)); } /* Finally, throw away any cached frame information. */ flush_cached_frames (); }
CORE_ADDR microblaze_find_callers_reg (struct frame_info *fi, int regnum) { LONGEST ret; for (; fi != NULL; fi = fi->next) { if (PC_IN_CALL_DUMMY (fi->pc, fi->frame, fi->frame)) return generic_read_register_dummy (fi->pc, fi->frame, regnum); else if (fi->saved_regs[regnum] != 0) return microblaze_read_memory_integer (fi->saved_regs[regnum]); } return read_register (regnum); }
int inside_entry_file (CORE_ADDR addr) { if (addr == 0) return 1; if (symfile_objfile == 0) return 0; if (CALL_DUMMY_LOCATION == AT_ENTRY_POINT) { /* Do not stop backtracing if the pc is in the call dummy at the entry point. */ /* FIXME: Won't always work with zeros for the last two arguments */ if (PC_IN_CALL_DUMMY (addr, 0, 0)) return 0; } return (addr >= symfile_objfile->ei.entry_file_lowpc && addr < symfile_objfile->ei.entry_file_highpc); }
void microblaze_init_extra_frame_info (struct frame_info *fi) { if (fi->next) fi->pc = FRAME_SAVED_PC (fi->next); frame_saved_regs_zalloc (fi); fi->extra_info = (struct frame_extra_info *) frame_obstack_alloc (sizeof (struct frame_extra_info)); fi->extra_info->status = 0; fi->extra_info->framesize = 0; if (PC_IN_CALL_DUMMY (fi->pc, fi->frame, fi->frame)) { /* We need to setup fi->frame here because run_stack_dummy gets it wrong by assuming it's always FP. */ fi->frame = generic_read_register_dummy (fi->pc, fi->frame, SP_REGNUM); } else microblaze_analyze_prologue (fi, 0); }
void generic_get_saved_register (char *raw_buffer, int *optimized, CORE_ADDR *addrp, struct frame_info *frame, int regnum, enum lval_type *lval) { if (!target_has_registers) error ("No registers."); /* Normal systems don't optimize out things with register numbers. */ if (optimized != NULL) *optimized = 0; if (addrp) /* default assumption: not found in memory */ *addrp = 0; /* Note: since the current frame's registers could only have been saved by frames INTERIOR TO the current frame, we skip examining the current frame itself: otherwise, we would be getting the previous frame's registers which were saved by the current frame. */ while (frame && ((frame = frame->next) != NULL)) { if (PC_IN_CALL_DUMMY (frame->pc, frame->frame, frame->frame)) { if (lval) /* found it in a CALL_DUMMY frame */ *lval = not_lval; if (raw_buffer) memcpy (raw_buffer, generic_find_dummy_frame (frame->pc, frame->frame) + REGISTER_BYTE (regnum), REGISTER_RAW_SIZE (regnum)); return; } FRAME_INIT_SAVED_REGS (frame); if (frame->saved_regs != NULL && frame->saved_regs[regnum] != 0) { if (lval) /* found it saved on the stack */ *lval = lval_memory; if (regnum == SP_REGNUM) { if (raw_buffer) /* SP register treated specially */ store_address (raw_buffer, REGISTER_RAW_SIZE (regnum), frame->saved_regs[regnum]); } else { if (addrp) /* any other register */ *addrp = frame->saved_regs[regnum]; if (raw_buffer) read_memory (frame->saved_regs[regnum], raw_buffer, REGISTER_RAW_SIZE (regnum)); } return; } } /* If we get thru the loop to this point, it means the register was not saved in any frame. Return the actual live-register value. */ if (lval) /* found it in a live register */ *lval = lval_register; if (addrp) *addrp = REGISTER_BYTE (regnum); if (raw_buffer) read_register_gen (regnum, raw_buffer); }