static CORE_ADDR frv_frame_saved_pc (struct frame_info *frame) { frv_frame_init_saved_regs (frame); /* Perhaps the prologue analyzer recorded where it was stored. (As of 14 Oct 2001, it never does.) */ if (frame->saved_regs && frame->saved_regs[pc_regnum] != 0) return read_memory_integer (frame->saved_regs[pc_regnum], 4); /* If the prologue analyzer tells us the link register was saved on the stack, get it from there. */ if (frame->extra_info->lr_saved_on_stack) return read_memory_integer (frame->frame + 8, 4); /* Otherwise, it's still in LR. However, if FRAME isn't the youngest frame, this is kind of suspicious --- if this frame called somebody else, then its LR has certainly been overwritten. */ if (! frame->next) return read_register (lr_regnum); /* By default, assume it's saved in the standard place, relative to the frame pointer. */ return read_memory_integer (frame->frame + 8, 4); }
CORE_ADDR sigtramp_saved_pc (struct frame_info *frame) { CORE_ADDR sigcontext_addr; char *buf; int ptrbytes = TARGET_PTR_BIT / TARGET_CHAR_BIT; int sigcontext_offs = (2 * TARGET_INT_BIT) / TARGET_CHAR_BIT; buf = alloca (ptrbytes); /* Get sigcontext address, it is the third parameter on the stack. */ if (frame->next) sigcontext_addr = read_memory_integer (FRAME_ARGS_ADDRESS (frame->next) + FRAME_ARGS_SKIP + sigcontext_offs, ptrbytes); else sigcontext_addr = read_memory_integer (read_register (SP_REGNUM) + sigcontext_offs, ptrbytes); /* Don't cause a memory_error when accessing sigcontext in case the stack layout has changed or the stack is corrupt. */ target_read_memory (sigcontext_addr + SIGCONTEXT_PC_OFFSET, buf, ptrbytes); return extract_unsigned_integer (buf, ptrbytes); }
int f77_get_dynamic_lowerbound (struct type *type, int *lower_bound) { CORE_ADDR current_frame_addr; CORE_ADDR ptr_to_lower_bound; switch (TYPE_ARRAY_LOWER_BOUND_TYPE (type)) { case BOUND_BY_VALUE_ON_STACK: current_frame_addr = get_frame_base (deprecated_selected_frame); if (current_frame_addr > 0) { *lower_bound = read_memory_integer (current_frame_addr + TYPE_ARRAY_LOWER_BOUND_VALUE (type), 4); } else { *lower_bound = DEFAULT_LOWER_BOUND; return BOUND_FETCH_ERROR; } break; case BOUND_SIMPLE: *lower_bound = TYPE_ARRAY_LOWER_BOUND_VALUE (type); break; case BOUND_CANNOT_BE_DETERMINED: error ("Lower bound may not be '*' in F77"); break; case BOUND_BY_REF_ON_STACK: current_frame_addr = get_frame_base (deprecated_selected_frame); if (current_frame_addr > 0) { ptr_to_lower_bound = read_memory_typed_address (current_frame_addr + TYPE_ARRAY_LOWER_BOUND_VALUE (type), builtin_type_void_data_ptr); *lower_bound = read_memory_integer (ptr_to_lower_bound, 4); } else { *lower_bound = DEFAULT_LOWER_BOUND; return BOUND_FETCH_ERROR; } break; case BOUND_BY_REF_IN_REG: case BOUND_BY_VALUE_IN_REG: default: error ("??? unhandled dynamic array bound type ???"); break; } return BOUND_FETCH_OK; }
static int i386obsd_supply_pcb (struct regcache *regcache, struct pcb *pcb) { struct gdbarch *gdbarch = regcache->arch (); enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); struct switchframe sf; /* The following is true for OpenBSD 3.6: The pcb contains %esp and %ebp at the point of the context switch in cpu_switch(). At that point we have a stack frame as described by `struct switchframe', which for OpenBSD 3.6 has the following layout: interrupt level %edi %esi %ebx %eip we reconstruct the register state as it would look when we just returned from cpu_switch(). */ /* The stack pointer shouldn't be zero. */ if (pcb->pcb_esp == 0) return 0; /* Read the stack frame, and check its validity. We do this by checking if the saved interrupt priority level in the stack frame looks reasonable.. */ #ifdef PCB_SAVECTX if ((pcb->pcb_flags & PCB_SAVECTX) == 0) { /* Yes, we have a frame that matches cpu_switch(). */ read_memory (pcb->pcb_esp, (gdb_byte *) &sf, sizeof sf); pcb->pcb_esp += sizeof (struct switchframe); regcache->raw_supply (I386_EDI_REGNUM, &sf.sf_edi); regcache->raw_supply (I386_ESI_REGNUM, &sf.sf_esi); regcache->raw_supply (I386_EBX_REGNUM, &sf.sf_ebx); regcache->raw_supply (I386_EIP_REGNUM, &sf.sf_eip); } else #endif { /* No, the pcb must have been last updated by savectx(). */ pcb->pcb_esp = pcb->pcb_ebp; pcb->pcb_ebp = read_memory_integer(pcb->pcb_esp, 4, byte_order); sf.sf_eip = read_memory_integer(pcb->pcb_esp + 4, 4, byte_order); regcache->raw_supply (I386_EIP_REGNUM, &sf.sf_eip); } regcache->raw_supply (I386_EBP_REGNUM, &pcb->pcb_ebp); regcache->raw_supply (I386_ESP_REGNUM, &pcb->pcb_esp); return 1; }
static CORE_ADDR alpha_osf1_sigcontext_addr (struct frame_info *frame) { struct frame_info *next_frame = get_next_frame (frame); if (next_frame != NULL) return (read_memory_integer (get_frame_base (next_frame), 8)); else return (read_memory_integer (get_frame_base (frame), 8)); }
static void kgdb_thr_add_procs(CORE_ADDR paddr, CORE_ADDR (*cpu_pcb_addr) (u_int)) { struct gdbarch *gdbarch = target_gdbarch (); struct type *ptr_type = builtin_type (gdbarch)->builtin_data_ptr; enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); struct kthr *kt; CORE_ADDR pcb, pnext, tdaddr, tdnext; ULONGEST oncpu; LONGEST pid, tid; while (paddr != 0) { TRY { tdaddr = read_memory_typed_address (paddr + proc_off_p_threads, ptr_type); pid = read_memory_integer (paddr + proc_off_p_pid, 4, byte_order); pnext = read_memory_typed_address (paddr + proc_off_p_list, ptr_type); } CATCH(e, RETURN_MASK_ERROR) { break; } END_CATCH while (tdaddr != 0) { TRY { tid = read_memory_integer (tdaddr + thread_off_td_tid, 4, byte_order); oncpu = read_memory_unsigned_integer (tdaddr + thread_off_td_oncpu, thread_oncpu_size, byte_order); pcb = read_memory_typed_address (tdaddr + thread_off_td_pcb, ptr_type); tdnext = read_memory_typed_address (tdaddr + thread_off_td_plist, ptr_type); } CATCH(e, RETURN_MASK_ERROR) { break; } END_CATCH kt = malloc(sizeof(*kt)); kt->next = first; kt->kaddr = tdaddr; if (tid == dumptid) kt->pcb = dumppcb; else if (cpu_stopped(oncpu)) kt->pcb = cpu_pcb_addr(oncpu); else kt->pcb = pcb; kt->tid = tid; kt->pid = pid; kt->paddr = paddr; kt->cpu = oncpu; first = kt; tdaddr = tdnext; } paddr = pnext; } }
static CORE_ADDR m68k_frame_saved_pc (struct frame_info *frame) { if (frame->signal_handler_caller) { if (frame->next) return read_memory_integer (frame->next->frame + SIG_PC_FP_OFFSET, 4); else return read_memory_integer (read_register (SP_REGNUM) + SIG_PC_FP_OFFSET - 8, 4); } else return read_memory_integer (frame->frame + 4, 4); }
static CORE_ADDR mn10300_frame_saved_pc (struct frame_info *fi) { int adjust = saved_regs_size (fi); return (read_memory_integer (fi->frame + adjust, REGISTER_SIZE)); }
int isi_frame_num_args (struct frame_info *fi) { int val; CORE_ADDR pc = FRAME_SAVED_PC (fi); int insn = 0177777 & read_memory_integer (pc, 2); val = 0; if (insn == 0047757 || insn == 0157374) /* lea W(sp),sp or addaw #W,sp */ val = read_memory_integer (pc + 2, 2); else if ((insn & 0170777) == 0050217 /* addql #N, sp */ || (insn & 0170777) == 0050117) /* addqw */ { val = (insn >> 9) & 7; if (val == 0) val = 8; }
static CORE_ADDR alpha_osf1_sigcontext_addr (struct frame_info *next_frame) { const struct frame_id next_id = get_frame_id (next_frame); return (read_memory_integer (next_id.stack_addr, 8)); }
void frame_find_saved_regs (struct frame_info *frame_info, struct frame_saved_regs *frame_saved_regs) { register int regnum; register int regmask; register CORE_ADDR next_addr; register CORE_ADDR pc; unsigned char thebyte; memset (frame_saved_regs, '\0', sizeof *frame_saved_regs); if ((frame_info)->pc >= (frame_info)->frame - CALL_DUMMY_LENGTH - FP_REGNUM * 4 - 4 && (frame_info)->pc <= (frame_info)->frame) { next_addr = (frame_info)->frame; pc = (frame_info)->frame - CALL_DUMMY_LENGTH - FP_REGNUM * 4 - 4; } else { pc = get_pc_function_start ((frame_info)->pc); /* Verify we have a link a6 instruction next; if not we lose. If we win, find the address above the saved regs using the amount of storage from the link instruction. */ thebyte = read_memory_integer (pc, 1); if (0x1f == thebyte) next_addr = (frame_info)->frame + read_memory_integer (pc += 1, 2), pc += 2; else if (0x17 == thebyte) next_addr = (frame_info)->frame + read_memory_integer (pc += 1, 1), pc += 1; else goto lose; #if 0 /* FIXME steve */ /* If have an add:g.waddal #-n, sp next, adjust next_addr. */ if ((0x0c0177777 & read_memory_integer (pc, 2)) == 0157774) next_addr += read_memory_integer (pc += 2, 4), pc += 4; #endif } thebyte = read_memory_integer (pc, 1); if (thebyte == 0x12) { /* Got stm */ pc++; regmask = read_memory_integer (pc, 1); pc++; for (regnum = 0; regnum < 8; regnum++, regmask >>= 1) { if (regmask & 1) { (frame_saved_regs)->regs[regnum] = (next_addr += 2) - 2; } } thebyte = read_memory_integer (pc, 1); }
static CORE_ADDR d10v_skip_prologue (CORE_ADDR pc) { unsigned long op; unsigned short op1, op2; CORE_ADDR func_addr, func_end; struct symtab_and_line sal; /* If we have line debugging information, then the end of the prologue should be the first assembly instruction of the first source line. */ if (find_pc_partial_function (pc, NULL, &func_addr, &func_end)) { sal = find_pc_line (func_addr, 0); if (sal.end && sal.end < func_end) return sal.end; } if (target_read_memory (pc, (char *) &op, 4)) return pc; /* Can't access it -- assume no prologue. */ while (1) { op = (unsigned long) read_memory_integer (pc, 4); if ((op & 0xC0000000) == 0xC0000000) { /* long instruction */ if (((op & 0x3FFF0000) != 0x01FF0000) && /* add3 sp,sp,n */ ((op & 0x3F0F0000) != 0x340F0000) && /* st rn, @(offset,sp) */ ((op & 0x3F1F0000) != 0x350F0000)) /* st2w rn, @(offset,sp) */ break; } else { /* short instructions */ if ((op & 0xC0000000) == 0x80000000) { op2 = (op & 0x3FFF8000) >> 15; op1 = op & 0x7FFF; } else { op1 = (op & 0x3FFF8000) >> 15; op2 = op & 0x7FFF; } if (check_prologue (op1)) { if (!check_prologue (op2)) { /* If the previous opcode was really part of the prologue and not just a NOP, then we want to break after both instructions. */ if (op1 != 0x5E00) pc += 4; break; } } else break; }
CORE_ADDR h8500_frame_chain (struct frame_info *thisframe) { if (!inside_entry_file (thisframe->pc)) return (read_memory_integer (FRAME_FP (thisframe), PTR_SIZE)); else return 0; }
static void i386_linux_resume (ptid_t ptid, int step, enum target_signal signal) { int pid = PIDGET (ptid); int request = PTRACE_CONT; if (pid == -1) /* Resume all threads. */ /* I think this only gets used in the non-threaded case, where "resume all threads" and "resume inferior_ptid" are the same. */ pid = PIDGET (inferior_ptid); if (step) { CORE_ADDR pc = read_pc_pid (pid_to_ptid (pid)); gdb_byte buf[LINUX_SYSCALL_LEN]; request = PTRACE_SINGLESTEP; /* Returning from a signal trampoline is done by calling a special system call (sigreturn or rt_sigreturn, see i386-linux-tdep.c for more information). This system call restores the registers that were saved when the signal was raised, including %eflags. That means that single-stepping won't work. Instead, we'll have to modify the signal context that's about to be restored, and set the trace flag there. */ /* First check if PC is at a system call. */ if (deprecated_read_memory_nobpt (pc, buf, LINUX_SYSCALL_LEN) == 0 && memcmp (buf, linux_syscall, LINUX_SYSCALL_LEN) == 0) { int syscall = read_register_pid (LINUX_SYSCALL_REGNUM, pid_to_ptid (pid)); /* Then check the system call number. */ if (syscall == SYS_sigreturn || syscall == SYS_rt_sigreturn) { CORE_ADDR sp = read_register (I386_ESP_REGNUM); CORE_ADDR addr = sp; unsigned long int eflags; if (syscall == SYS_rt_sigreturn) addr = read_memory_integer (sp + 8, 4) + 20; /* Set the trace flag in the context that's about to be restored. */ addr += LINUX_SIGCONTEXT_EFLAGS_OFFSET; read_memory (addr, (gdb_byte *) &eflags, 4); eflags |= 0x0100; write_memory (addr, (gdb_byte *) &eflags, 4); } } } if (ptrace (request, pid, 0, target_signal_to_host (signal)) == -1) perror_with_name (("ptrace")); }
static CORE_ADDR i386_linux_sigcontext_addr (struct frame_info *frame) { CORE_ADDR pc; pc = i386_linux_sigtramp_start (frame->pc); if (pc) { CORE_ADDR sp; if (frame->next) /* If this isn't the top frame, the next frame must be for the signal handler itself. The sigcontext structure lives on the stack, right after the signum argument. */ return frame->next->frame + 12; /* This is the top frame. We'll have to find the address of the sigcontext structure by looking at the stack pointer. Keep in mind that the first instruction of the sigtramp code is "pop %eax". If the PC is at this instruction, adjust the returned value accordingly. */ sp = read_register (SP_REGNUM); if (pc == frame->pc) return sp + 4; return sp; } pc = i386_linux_rt_sigtramp_start (frame->pc); if (pc) { if (frame->next) /* If this isn't the top frame, the next frame must be for the signal handler itself. The sigcontext structure is part of the user context. A pointer to the user context is passed as the third argument to the signal handler. */ return read_memory_integer (frame->next->frame + 16, 4) + 20; /* This is the top frame. Again, use the stack pointer to find the address of the sigcontext structure. */ return read_memory_integer (read_register (SP_REGNUM) + 8, 4) + 20; } error ("Couldn't recognize signal trampoline."); return 0; }
static int hppa_hpux_in_solib_return_trampoline (struct gdbarch *gdbarch, CORE_ADDR pc, const char *name) { enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); struct unwind_table_entry *u; /* Get the unwind descriptor corresponding to PC, return zero if no unwind was found. */ u = find_unwind_entry (pc); if (!u) return 0; /* If this isn't a linker stub or it's just a long branch stub, then return zero. */ if (u->stub_unwind.stub_type == 0 || u->stub_unwind.stub_type == LONG_BRANCH) return 0; /* The call and return path execute the same instructions within an IMPORT stub! So an IMPORT stub is both a call and return trampoline. */ if (u->stub_unwind.stub_type == IMPORT) return 1; /* Parameter relocation stubs always have a call path and may have a return path. */ if (u->stub_unwind.stub_type == PARAMETER_RELOCATION || u->stub_unwind.stub_type == EXPORT) { CORE_ADDR addr; /* Search forward from the current PC until we hit a branch or the end of the stub. */ for (addr = pc; addr <= u->region_end; addr += 4) { unsigned long insn; insn = read_memory_integer (addr, 4, byte_order); /* Does it look like a bl? If so then it's the call path, if we find a bv or be first, then we're on the return path. */ if ((insn & 0xfc00e000) == 0xe8000000) return 0; else if ((insn & 0xfc00e001) == 0xe800c000 || (insn & 0xfc000000) == 0xe0000000) return 1; } /* Should never happen. */ warning (_("Unable to find branch in parameter relocation stub.")); return 0; } /* Unknown stub type. For now, just return zero. */ return 0; }
static CORE_ADDR lm32_analyze_prologue (struct gdbarch *gdbarch, CORE_ADDR pc, CORE_ADDR limit, struct lm32_frame_cache *info) { enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); unsigned long instruction; /* Keep reading though instructions, until we come across an instruction that isn't likely to be part of the prologue. */ info->size = 0; for (; pc < limit; pc += 4) { /* Read an instruction. */ instruction = read_memory_integer (pc, 4, byte_order); if ((LM32_OPCODE (instruction) == OP_SW) && (LM32_REG0 (instruction) == SIM_LM32_SP_REGNUM)) { /* Any stack displaced store is likely part of the prologue. Record that the register is being saved, and the offset into the stack. */ info->saved_regs[LM32_REG1 (instruction)].addr = LM32_IMM16 (instruction); } else if ((LM32_OPCODE (instruction) == OP_ADDI) && (LM32_REG1 (instruction) == SIM_LM32_SP_REGNUM)) { /* An add to the SP is likely to be part of the prologue. Adjust stack size by whatever the instruction adds to the sp. */ info->size -= LM32_IMM16 (instruction); } else if ( /* add fp,fp,sp */ ((LM32_OPCODE (instruction) == OP_ADD) && (LM32_REG2 (instruction) == SIM_LM32_FP_REGNUM) && (LM32_REG0 (instruction) == SIM_LM32_FP_REGNUM) && (LM32_REG1 (instruction) == SIM_LM32_SP_REGNUM)) /* mv fp,imm */ || ((LM32_OPCODE (instruction) == OP_ADDI) && (LM32_REG1 (instruction) == SIM_LM32_FP_REGNUM) && (LM32_REG0 (instruction) == SIM_LM32_R0_REGNUM))) { /* Likely to be in the prologue for functions that require a frame pointer. */ } else { /* Any other instruction is likely not to be part of the prologue. */ break; } } return pc; }
static CORE_ADDR m68k_frame_chain (struct frame_info *thisframe) { if (thisframe->signal_handler_caller) return thisframe->frame; else if (!inside_entry_file ((thisframe)->pc)) return read_memory_integer ((thisframe)->frame, 4); else return 0; }
void single_step () { branch_type br, isannulled(); CORE_ADDR pc; long pc_instruction; if (!one_stepped) { /* Always set breakpoint for NPC. */ next_pc = read_register (NPC_REGNUM); npc4 = next_pc + 4; /* branch not taken */ target_insert_breakpoint (next_pc, break_mem[0]); /* printf ("set break at %x\n",next_pc); */ pc = read_register (PC_REGNUM); pc_instruction = read_memory_integer (pc, sizeof(pc_instruction)); br = isannulled (pc_instruction, pc, &target); brknpc4 = brktrg = 0; if (br == bicca) { /* Conditional annulled branch will either end up at npc (if taken) or at npc+4 (if not taken). Trap npc+4. */ brknpc4 = 1; target_insert_breakpoint (npc4, break_mem[1]); } else if (br == baa && target != next_pc) { /* Unconditional annulled branch will always end up at the target. */ brktrg = 1; target_insert_breakpoint (target, break_mem[2]); } /* We are ready to let it go */ one_stepped = 1; return; } else { /* Remove breakpoints */ target_remove_breakpoint (next_pc, break_mem[0]); if (brknpc4) target_remove_breakpoint (npc4, break_mem[1]); if (brktrg) target_remove_breakpoint (target, break_mem[2]); one_stepped = 0; } }
int arm_linux_in_sigtramp (CORE_ADDR pc, char *func_name) { unsigned long inst; inst = read_memory_integer (pc, 4); return (inst == ARM_LINUX_SIGRETURN_INSTR || inst == ARM_LINUX_RT_SIGRETURN_INSTR); }
CORE_ADDR h8500_skip_prologue (CORE_ADDR start_pc) { short int w; w = read_memory_integer (start_pc, 1); if (w == LINK_8) { start_pc += 2; w = read_memory_integer (start_pc, 1); } if (w == LINK_16) { start_pc += 3; w = read_memory_integer (start_pc, 2); } return start_pc; }
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 CORE_ADDR frv_frame_chain (struct frame_info *frame) { CORE_ADDR saved_fp_addr; if (frame->saved_regs && frame->saved_regs[fp_regnum] != 0) saved_fp_addr = frame->saved_regs[fp_regnum]; else /* Just assume it was saved in the usual place. */ saved_fp_addr = frame->frame; return read_memory_integer (saved_fp_addr, 4); }
static CORE_ADDR alpha_osf1_sigcontext_addr (struct frame_info *this_frame) { struct gdbarch *gdbarch = get_frame_arch (this_frame); enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); struct frame_info *next_frame = get_next_frame (this_frame); struct frame_id next_id = null_frame_id; if (next_frame != NULL) next_id = get_frame_id (next_frame); return (read_memory_integer (next_id.stack_addr, 8, byte_order)); }
static CORE_ADDR mn10300_frame_chain (struct frame_info *fi) { struct frame_info *dummy; /* Walk through the prologue to determine the stack size, location of saved registers, end of the prologue, etc. */ if (fi->extra_info->status == 0) mn10300_analyze_prologue (fi, (CORE_ADDR) 0); /* Quit now if mn10300_analyze_prologue set NO_MORE_FRAMES. */ if (fi->extra_info->status & NO_MORE_FRAMES) return 0; /* Now that we've analyzed our prologue, determine the frame pointer for our caller. If our caller has a frame pointer, then we need to find the entry value of $a3 to our function. If fsr.regs[A3_REGNUM] is nonzero, then it's at the memory location pointed to by fsr.regs[A3_REGNUM]. Else it's still in $a3. If our caller does not have a frame pointer, then his frame base is fi->frame + -caller's stack size. */ /* The easiest way to get that info is to analyze our caller's frame. So we set up a dummy frame and call mn10300_analyze_prologue to find stuff for us. */ dummy = analyze_dummy_frame (FRAME_SAVED_PC (fi), fi->frame); if (dummy->extra_info->status & MY_FRAME_IN_FP) { /* Our caller has a frame pointer. So find the frame in $a3 or in the stack. */ if (fi->saved_regs[A3_REGNUM]) return (read_memory_integer (fi->saved_regs[A3_REGNUM], REGISTER_SIZE)); else return read_register (A3_REGNUM); } else { int adjust = saved_regs_size (fi); /* Our caller does not have a frame pointer. So his frame starts at the base of our frame (fi->frame) + register save space + <his size>. */ return fi->frame + adjust + -dummy->extra_info->stack_size; } }
static CORE_ADDR moxie_analyze_prologue (CORE_ADDR start_addr, CORE_ADDR end_addr, struct moxie_frame_cache *cache, struct frame_info *this_frame) { CORE_ADDR next_addr; ULONGEST inst, inst2; LONGEST offset; int regnum; /* Record where the jsra instruction saves the PC and FP. */ cache->saved_regs[MOXIE_PC_REGNUM] = -4; cache->saved_regs[MOXIE_FP_REGNUM] = 0; cache->framesize = 0; if (start_addr >= end_addr) return end_addr; for (next_addr = start_addr; next_addr < end_addr; ) { inst = read_memory_unsigned_integer (next_addr, 2); /* Match "push $rN" where N is between 2 and 13 inclusive. */ if (inst >= 0x0614 && inst <= 0x061f) { regnum = inst & 0x000f; cache->framesize += 4; cache->saved_regs[regnum] = cache->framesize; next_addr += 2; } /* Optional stack allocation for args and local vars <= 4 byte. */ else if (inst == 0x01f0) /* ldi.l $r12, X */ { offset = read_memory_integer (next_addr + 2, 4); inst2 = read_memory_unsigned_integer (next_addr + 6, 2); if (inst2 == 0x051f) /* add.l $sp, $r12 */ { cache->framesize += offset; } return (next_addr + 8); } else /* This is not a prologue instruction. */ break; } return next_addr; }
CORE_ADDR arm_linux_sigcontext_register_address (CORE_ADDR sp, CORE_ADDR pc, int regno) { unsigned long inst; CORE_ADDR reg_addr = 0; inst = read_memory_integer (pc, 4); if (inst == ARM_LINUX_SIGRETURN_INSTR || inst == ARM_LINUX_RT_SIGRETURN_INSTR) { CORE_ADDR sigcontext_addr; /* The sigcontext structure is at different places for the two signal return instructions. For ARM_LINUX_SIGRETURN_INSTR, it starts at the SP value. For ARM_LINUX_RT_SIGRETURN_INSTR, it is at SP+8. For the latter instruction, it may also be the case that the address of this structure may be determined by reading the 4 bytes at SP, but I'm not convinced this is reliable. In any event, these magic constants (0 and 8) may be determined by examining struct sigframe and struct rt_sigframe in arch/arm/kernel/signal.c in the Linux kernel sources. */ if (inst == ARM_LINUX_RT_SIGRETURN_INSTR) sigcontext_addr = sp + 8; else /* inst == ARM_LINUX_SIGRETURN_INSTR */ sigcontext_addr = sp + 0; /* The layout of the sigcontext structure for ARM GNU/Linux is in include/asm-arm/sigcontext.h in the Linux kernel sources. There are three 4-byte fields which precede the saved r0 field. (This accounts for the 12 in the code below.) The sixteen registers (4 bytes per field) follow in order. The PSR value follows the sixteen registers which accounts for the constant 19 below. */ if (0 <= regno && regno <= ARM_PC_REGNUM) reg_addr = sigcontext_addr + 12 + (4 * regno); else if (regno == ARM_PS_REGNUM) reg_addr = sigcontext_addr + 19 * 4; } return reg_addr; }
extern CORE_ADDR altos_skip_prologue (CORE_ADDR pc) { register int op = read_memory_integer (pc, 2); if (op == P_LINKW_FP) pc += 4; /* Skip link #word */ else if (op == P_LINKL_FP) pc += 6; /* Skip link #long */ /* Not sure why branches are here. */ /* From tm-altos.h */ else if (op == 0060000) pc += 4; /* Skip bra #word */ else if (op == 00600377) pc += 6; /* skip bra #long */ else if ((op & 0177400) == 0060000) pc += 2; /* skip bra #char */ return pc; }
struct kthr * kgdb_thr_init(CORE_ADDR (*cpu_pcb_addr) (u_int)) { struct gdbarch *gdbarch = target_gdbarch (); struct type *ptr_type = builtin_type (gdbarch)->builtin_data_ptr; enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); struct kthr *kt; CORE_ADDR addr, paddr; while (first != NULL) { kt = first; first = kt->next; free(kt); } addr = kgdb_lookup("allproc"); if (addr == 0) return (NULL); TRY { paddr = read_memory_typed_address (addr, ptr_type); } CATCH(e, RETURN_MASK_ERROR) { return (NULL); } END_CATCH dumppcb = kgdb_lookup("dumppcb"); if (dumppcb == 0) return (NULL); #if 1 TRY { dumptid = parse_and_eval_long("dumptid"); } CATCH(e, RETURN_MASK_ERROR) { dumptid = -1; } END_CATCH #else addr = kgdb_lookup("dumptid"); if (addr != 0) { TRY { dumptid = read_memory_integer (addr, 4, byte_order); } CATCH(e, RETURN_MASK_ERROR) { dumptid = -1; } END_CATCH } else
static int do_captured_read_memory_integer (void *data) { struct captured_read_memory_integer_arguments *args; CORE_ADDR memaddr; int len; args = (struct captured_read_memory_integer_arguments*)data; memaddr = args->memaddr; len = args->len; /* APPLE LOCAL begin unsigned */ if (args->signedp) args->result.sresult = read_memory_integer(memaddr, len); else args->result.uresult = read_memory_unsigned_integer(memaddr, len); /* APPLE LOCAL end unsigned */ return 1; }