void generic_push_dummy_frame (void) { struct dummy_frame *dummy_frame; CORE_ADDR fp = (get_current_frame ())->frame; /* check to see if there are stale dummy frames, perhaps left over from when a longjump took us out of a function that was called by the debugger */ dummy_frame = dummy_frame_stack; while (dummy_frame) if (INNER_THAN (dummy_frame->fp, fp)) /* stale -- destroy! */ { dummy_frame_stack = dummy_frame->next; xfree (dummy_frame->registers); xfree (dummy_frame); dummy_frame = dummy_frame_stack; } else dummy_frame = dummy_frame->next; dummy_frame = xmalloc (sizeof (struct dummy_frame)); dummy_frame->registers = xmalloc (REGISTER_BYTES); dummy_frame->pc = read_pc (); dummy_frame->sp = read_sp (); dummy_frame->top = dummy_frame->sp; dummy_frame->fp = fp; read_register_bytes (0, dummy_frame->registers, REGISTER_BYTES); dummy_frame->next = dummy_frame_stack; dummy_frame_stack = dummy_frame; }
/* Functions to read and write the frame pointer */ CORE_ADDR microblaze_target_read_fp() { CORE_ADDR pc; long reg, offset; pc = read_pc(); microblaze_virtual_frame_pointer( pc, ®, &offset); return read_register(reg) + offset; }
void init_frame_pc_default (int fromleaf, struct frame_info *prev) { if (fromleaf) prev->pc = SAVED_PC_AFTER_CALL (prev->next); else if (prev->next != NULL) prev->pc = FRAME_SAVED_PC (prev->next); else prev->pc = read_pc (); }
/* return [AD][0-7][d][WL] : SZ='W'/'L' XI = hexa value for reg ($D0) */ static s32 indAnXi() { s32 v; read_pc(); v = (d.w&0x8000)? ('A'<<24) : ('D'<<24); v |= ('0'+((d.w>>12)&7)) << 16; v |= (u8)d.w<<8; v |= ((d.w&(1<<11))? 'L' : 'W'); return v; }
struct frame_info * get_current_frame (void) { if (current_frame == NULL) { if (target_has_stack) current_frame = create_new_frame (read_fp (), read_pc ()); else error ("No stack."); } return current_frame; }
/* Generic prepare_to_proceed(). This one should be suitable for most targets that support threads. */ int generic_prepare_to_proceed (int select_it) { ptid_t wait_ptid; struct target_waitstatus wait_status; /* Get the last target status returned by target_wait(). */ get_last_target_status (&wait_ptid, &wait_status); /* Make sure we were stopped either at a breakpoint, or because of a Ctrl-C. */ if (wait_status.kind != TARGET_WAITKIND_STOPPED || (wait_status.value.sig != TARGET_SIGNAL_TRAP && wait_status.value.sig != TARGET_SIGNAL_INT)) { return 0; } if (!ptid_equal (wait_ptid, minus_one_ptid) && !ptid_equal (inferior_ptid, wait_ptid)) { /* Switched over from WAIT_PID. */ CORE_ADDR wait_pc = read_pc_pid (wait_ptid); if (wait_pc != read_pc ()) { if (select_it) { /* Switch back to WAIT_PID thread. */ inferior_ptid = wait_ptid; /* FIXME: This stuff came from switch_to_thread() in thread.c (which should probably be a public function). */ flush_cached_frames (); registers_changed (); stop_pc = wait_pc; select_frame (get_current_frame ()); } /* We return 1 to indicate that there is a breakpoint here, so we need to step over it before continuing to avoid hitting it straight away. */ if (breakpoint_here_p (wait_pc)) { return 1; } } } return 0; }
static void metrowerks_step (CORE_ADDR range_start, CORE_ADDR range_stop, int step_into) { struct frame_info *frame = NULL; CORE_ADDR pc = 0; /* When single stepping in assembly, the plugin passes (start + 1) as the stop address. Round the stop address up to the next valid instruction */ if ((range_stop & ~0x3) != range_stop) range_stop = ((range_stop + 4) & ~0x3); pc = read_pc(); if (range_start >= range_stop) error ("invalid step range (the stop address must be greater than the start address)"); if (pc < range_start) error ("invalid step range ($pc is 0x%lx, less than the stop address of 0x%lx)", (unsigned long) pc, (unsigned long) range_start); if (pc == range_stop) error ("invalid step range ($pc is 0x%lx, equal to the stop address of 0x%lx)", (unsigned long) pc, (unsigned long) range_stop); if (pc > range_stop) error ("invalid step range ($pc is 0x%lx, greater than the stop address of 0x%lx)", (unsigned long) pc, (unsigned long) range_stop); clear_proceed_status (); frame = get_current_frame (); if (frame == NULL) error ("No current frame"); step_frame_address = FRAME_FP (frame); step_sp = read_sp (); step_range_start = range_start; step_range_end = range_stop; step_over_calls = step_into ? STEP_OVER_NONE : STEP_OVER_ALL; step_multi = 0; metrowerks_stepping = 1; proceed ((CORE_ADDR) -1, TARGET_SIGNAL_DEFAULT, 1); make_exec_cleanup (metrowerks_stepping_cleanup, NULL); }
void m68k_pop_frame () { register FRAME frame = get_current_frame (); register CORE_ADDR fp; register int regnum; struct frame_saved_regs fsr; struct frame_info *fi; char raw_buffer[12]; fi = get_frame_info (frame); fp = fi -> frame; get_frame_saved_regs (fi, &fsr); #if defined (HAVE_68881) for (regnum = FP0_REGNUM + 7 ; regnum >= FP0_REGNUM ; regnum--) { if (fsr.regs[regnum]) { read_memory (fsr.regs[regnum], raw_buffer, 12); write_register_bytes (REGISTER_BYTE (regnum), raw_buffer, 12); } } #endif for (regnum = FP_REGNUM - 1 ; regnum >= 0 ; regnum--) { if (fsr.regs[regnum]) { write_register (regnum, read_memory_integer (fsr.regs[regnum], 4)); } } if (fsr.regs[PS_REGNUM]) { write_register (PS_REGNUM, read_memory_integer (fsr.regs[PS_REGNUM], 4)); } write_register (FP_REGNUM, read_memory_integer (fp, 4)); write_register (PC_REGNUM, read_memory_integer (fp + 4, 4)); write_register (SP_REGNUM, fp + 8); flush_cached_frames (); set_current_frame (create_new_frame (read_register (FP_REGNUM), read_pc ())); }
static void exec_one_dummy_insn (struct gdbarch *gdbarch) { #define DUMMY_INSN_ADDR gdbarch_tdep (gdbarch)->text_segment_base+0x200 int ret, status, pid; CORE_ADDR prev_pc; void *bp; /* We plant one dummy breakpoint into DUMMY_INSN_ADDR address. We assume that this address will never be executed again by the real code. */ bp = deprecated_insert_raw_breakpoint (DUMMY_INSN_ADDR); /* You might think this could be done with a single ptrace call, and you'd be correct for just about every platform I've ever worked on. However, rs6000-ibm-aix4.1.3 seems to have screwed this up -- the inferior never hits the breakpoint (it's also worth noting powerpc-ibm-aix4.1.3 works correctly). */ prev_pc = read_pc (); write_pc (DUMMY_INSN_ADDR); if (ARCH64 ()) ret = rs6000_ptrace64 (PT_CONTINUE, PIDGET (inferior_ptid), 1, 0, NULL); else ret = rs6000_ptrace32 (PT_CONTINUE, PIDGET (inferior_ptid), (int *)1, 0, NULL); if (ret != 0) perror ("pt_continue"); do { pid = wait (&status); } while (pid != PIDGET (inferior_ptid)); write_pc (prev_pc); deprecated_remove_raw_breakpoint (bp); }
struct macro_scope * default_macro_scope (void) { struct symtab_and_line sal; struct macro_source_file *main; struct macro_scope *ms; /* If there's a selected frame, use its PC. */ if (deprecated_selected_frame) sal = find_pc_line (get_frame_pc (deprecated_selected_frame), 0); /* If the target has any registers at all, then use its PC. Why we would have registers but no stack, I'm not sure. */ else if (target_has_registers) sal = find_pc_line (read_pc (), 0); /* If all else fails, fall back to the current listing position. */ else { /* Don't call select_source_symtab here. That can raise an error if symbols aren't loaded, but GDB calls the expression evaluator in all sorts of contexts. For example, commands like `set width' call the expression evaluator to evaluate their numeric arguments. If the current language is C, then that may call this function to choose a scope for macro expansion. If you don't have any symbol files loaded, then get_current_or_default would raise an error. But `set width' shouldn't raise an error just because it can't decide which scope to macro-expand its argument in. */ struct symtab_and_line cursal = get_current_source_symtab_and_line (); sal.symtab = cursal.symtab; sal.line = cursal.line; } return sal_macro_scope (sal); }
static void exec_one_dummy_insn (void) { #define DUMMY_INSN_ADDR (TEXT_SEGMENT_BASE)+0x200 char shadow_contents[BREAKPOINT_MAX]; /* Stash old bkpt addr contents */ int ret, status, pid; CORE_ADDR prev_pc; /* We plant one dummy breakpoint into DUMMY_INSN_ADDR address. We assume that this address will never be executed again by the real code. */ target_insert_breakpoint (DUMMY_INSN_ADDR, shadow_contents); /* You might think this could be done with a single ptrace call, and you'd be correct for just about every platform I've ever worked on. However, rs6000-ibm-aix4.1.3 seems to have screwed this up -- the inferior never hits the breakpoint (it's also worth noting powerpc-ibm-aix4.1.3 works correctly). */ prev_pc = read_pc (); write_pc (DUMMY_INSN_ADDR); if (ARCH64 ()) ret = rs6000_ptrace64 (PT_CONTINUE, PIDGET (inferior_ptid), 1, 0, NULL); else ret = rs6000_ptrace32 (PT_CONTINUE, PIDGET (inferior_ptid), (int *)1, 0, NULL); if (ret != 0) perror ("pt_continue"); do { pid = wait (&status); } while (pid != PIDGET (inferior_ptid)); write_pc (prev_pc); target_remove_breakpoint (DUMMY_INSN_ADDR, shadow_contents); }
static s32 immW(void) { read_pc(); return d.w; }
static s32 relPC(void) { read_pc(); return (d.pc + d.w - 2) & d.memmsk; }
static s32 adrW(void) { read_pc(); return d.w; }
void read_climate_and_pc () { char fn [77], fnp [77], lfs [7]; int i, j, jj = 0, lf; if (global_monitor) monitor_leaf(1, "read_climate_and_pc"); read_esd(); open_files(1); printf(" Reading: Climate and Plant Community description. \n\n"); for (i = 0; i < n_lats; i++) { for (j = 0; j < n_lons; j++) { if (earth[i][j] == '1') { read_climate(); read_pc(); set_constants(jj); int2str(eco[jj].iflpn, (jj + 1), 6, 0); ++jj; } else skip_data(1); } skip_data(0); } close_files(0); printf(" Reading: LF FCs. \n"); strcpy(fnp, global_directory); strcat(fnp, "/lf_"); for (lf = 1; lf <= num_lf; lf++) { printf(" LF = %3d \n", lf); strcpy(fn, fnp); if (lf < 10) strcat(fn, "00"); else if (lf < 100) strcat(fn, "0"); int_to_ascii(lf, lfs); strcat(fn, lfs); read_lf(lf, fn); } printf("\n"); if (global_monitor) monitor_leaf(0, "read_climate_and_pc"); }
static s32 immB(void) { return (s32)(s8)read_pc(); }
struct block * get_current_block (void) { return block_for_pc (read_pc ()); }
static int enable_break (void) { int success = 0; struct minimal_symbol *msymbol; char **bkpt_namep; asection *interp_sect; /* First, remove all the solib event breakpoints. Their addresses may have changed since the last time we ran the program. */ remove_solib_event_breakpoints (); interp_text_sect_low = interp_text_sect_high = 0; interp_plt_sect_low = interp_plt_sect_high = 0; /* Find the .interp section; if not found, warn the user and drop into the old breakpoint at symbol code. */ interp_sect = bfd_get_section_by_name (exec_bfd, ".interp"); if (interp_sect) { unsigned int interp_sect_size; char *buf; CORE_ADDR load_addr; bfd *tmp_bfd; CORE_ADDR sym_addr = 0; /* Read the contents of the .interp section into a local buffer; the contents specify the dynamic linker this program uses. */ interp_sect_size = bfd_section_size (exec_bfd, interp_sect); buf = alloca (interp_sect_size); bfd_get_section_contents (exec_bfd, interp_sect, buf, 0, interp_sect_size); /* Now we need to figure out where the dynamic linker was loaded so that we can load its symbols and place a breakpoint in the dynamic linker itself. This address is stored on the stack. However, I've been unable to find any magic formula to find it for Solaris (appears to be trivial on GNU/Linux). Therefore, we have to try an alternate mechanism to find the dynamic linker's base address. */ tmp_bfd = bfd_openr (buf, gnutarget); if (tmp_bfd == NULL) goto bkpt_at_symbol; /* Make sure the dynamic linker's really a useful object. */ if (!bfd_check_format (tmp_bfd, bfd_object)) { warning (_("Unable to grok dynamic linker %s as an object file"), buf); bfd_close (tmp_bfd); goto bkpt_at_symbol; } /* We find the dynamic linker's base address by examining the current pc (which point at the entry point for the dynamic linker) and subtracting the offset of the entry point. */ load_addr = read_pc () - tmp_bfd->start_address; /* Record the relocated start and end address of the dynamic linker text and plt section for aix5_in_dynsym_resolve_code. */ interp_sect = bfd_get_section_by_name (tmp_bfd, ".text"); if (interp_sect) { interp_text_sect_low = bfd_section_vma (tmp_bfd, interp_sect) + load_addr; interp_text_sect_high = interp_text_sect_low + bfd_section_size (tmp_bfd, interp_sect); } interp_sect = bfd_get_section_by_name (tmp_bfd, ".plt"); if (interp_sect) { interp_plt_sect_low = bfd_section_vma (tmp_bfd, interp_sect) + load_addr; interp_plt_sect_high = interp_plt_sect_low + bfd_section_size (tmp_bfd, interp_sect); } /* Now try to set a breakpoint in the dynamic linker. */ for (bkpt_namep = solib_break_names; *bkpt_namep != NULL; bkpt_namep++) { sym_addr = bfd_lookup_symbol (tmp_bfd, *bkpt_namep); if (sym_addr != 0) break; } /* We're done with the temporary bfd. */ bfd_close (tmp_bfd); if (sym_addr != 0) { create_solib_event_breakpoint (load_addr + sym_addr); return 1; } /* For whatever reason we couldn't set a breakpoint in the dynamic linker. Warn and drop into the old code. */ bkpt_at_symbol: warning (_("Unable to find dynamic linker breakpoint function.\nGDB will be unable to debug shared library initializers\nand track explicitly loaded dynamic code.")); } /* Nothing good happened. */ success = 0; return (success); }
static s32 immL(void) { return (read_pc()<<16) | (read_pc()&0xffff ); }