static int nios2_in_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR current_pc, CORE_ADDR start_pc) { enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); /* There has to be a previous instruction in the function. */ if (current_pc > start_pc) { /* Check whether the previous instruction was a stack adjustment. */ unsigned int insn = read_memory_unsigned_integer (current_pc - NIOS2_OPCODE_SIZE, NIOS2_OPCODE_SIZE, byte_order); if ((insn & 0xffc0003c) == 0xdec00004 /* ADDI sp, sp, */ || (insn & 0xffc1ffff) == 0xdec1883a /* ADD sp, sp, */ || (insn & 0xffc0003f) == 0xdec00017) /* LDW sp, constant(sp) */ { /* Then check if it's followed by a return or a tail call. */ insn = read_memory_unsigned_integer (current_pc, NIOS2_OPCODE_SIZE, byte_order); if (insn == 0xf800283a /* RET */ || insn == 0xe800083a /* ERET */ || (insn & 0x07ffffff) == 0x0000683a /* JMP */ || (insn & 0xffc0003f) == 6) /* BR */ return 1; } } return 0; }
static CORE_ADDR amd64_windows_skip_trampoline_code (struct frame_info *frame, CORE_ADDR pc) { CORE_ADDR destination = 0; struct gdbarch *gdbarch = get_frame_arch (frame); enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); /* Check for jmp *<offset>(%rip) (jump near, absolute indirect (/4)). */ if (pc && read_memory_unsigned_integer (pc, 2, byte_order) == 0x25ff) { /* Get opcode offset and see if we can find a reference in our data. */ ULONGEST offset = read_memory_unsigned_integer (pc + 2, 4, byte_order); /* Get address of function pointer at end of pc. */ CORE_ADDR indirect_addr = pc + offset + 6; struct minimal_symbol *indsym = (indirect_addr ? lookup_minimal_symbol_by_pc (indirect_addr).minsym : NULL); const char *symname = indsym ? MSYMBOL_LINKAGE_NAME (indsym) : NULL; if (symname) { if (strncmp (symname, "__imp_", 6) == 0 || strncmp (symname, "_imp_", 5) == 0) destination = read_memory_unsigned_integer (indirect_addr, 8, byte_order); } } return destination; }
static int i386_darwin_sstep_at_sigreturn (x86_thread_state_t *regs) { enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch); static const gdb_byte darwin_syscall[] = { 0xcd, 0x80 }; /* int 0x80 */ gdb_byte buf[sizeof (darwin_syscall)]; /* Check if PC is at a sigreturn system call. */ if (target_read_memory (regs->uts.ts32.__eip, buf, sizeof (buf)) == 0 && memcmp (buf, darwin_syscall, sizeof (darwin_syscall)) == 0 && regs->uts.ts32.__eax == 0xb8 /* SYS_sigreturn */) { ULONGEST uctx_addr; ULONGEST mctx_addr; ULONGEST flags_addr; unsigned int eflags; uctx_addr = read_memory_unsigned_integer (regs->uts.ts32.__esp + 4, 4, byte_order); mctx_addr = read_memory_unsigned_integer (uctx_addr + 28, 4, byte_order); flags_addr = mctx_addr + 12 + 9 * 4; read_memory (flags_addr, (gdb_byte *) &eflags, 4); eflags |= X86_EFLAGS_T; write_memory (flags_addr, (gdb_byte *) &eflags, 4); return 1; } return 0; }
static CORE_ADDR ppc_skip_trampoline_code (struct frame_info *frame, CORE_ADDR pc) { unsigned int insnbuf[POWERPC32_PLT_STUB_LEN]; struct gdbarch *gdbarch = get_frame_arch (frame); struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); CORE_ADDR target = 0; if (ppc_insns_match_pattern (frame, pc, powerpc32_plt_stub, insnbuf)) { /* Insn pattern is lis r11, xxxx lwz r11, xxxx(r11) Branch target is in r11. */ target = (ppc_insn_d_field (insnbuf[0]) << 16) | ppc_insn_d_field (insnbuf[1]); target = read_memory_unsigned_integer (target, 4, byte_order); } if (ppc_insns_match_pattern (frame, pc, powerpc32_plt_stub_so, insnbuf)) { /* Insn pattern is lwz r11, xxxx(r30) Branch target is in r11. */ target = get_frame_register_unsigned (frame, tdep->ppc_gp0_regnum + 30) + ppc_insn_d_field (insnbuf[0]); target = read_memory_unsigned_integer (target, 4, byte_order); } return target; }
static struct trad_frame_cache * aix_sighandle_frame_cache (struct frame_info *this_frame, void **this_cache) { LONGEST backchain; CORE_ADDR base, base_orig, func; struct gdbarch *gdbarch = get_frame_arch (this_frame); struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); struct trad_frame_cache *this_trad_cache; if ((*this_cache) != NULL) return (struct trad_frame_cache *) (*this_cache); this_trad_cache = trad_frame_cache_zalloc (this_frame); (*this_cache) = this_trad_cache; base = get_frame_register_unsigned (this_frame, gdbarch_sp_regnum (gdbarch)); base_orig = base; if (tdep->wordsize == 4) { func = read_memory_unsigned_integer (base_orig + SIG_FRAME_PC_OFFSET + 8, tdep->wordsize, byte_order); safe_read_memory_integer (base_orig + SIG_FRAME_FP_OFFSET + 8, tdep->wordsize, byte_order, &backchain); base = (CORE_ADDR)backchain; } else { func = read_memory_unsigned_integer (base_orig + SIG_FRAME_LR_OFFSET64, tdep->wordsize, byte_order); safe_read_memory_integer (base_orig + SIG_FRAME_FP_OFFSET64, tdep->wordsize, byte_order, &backchain); base = (CORE_ADDR)backchain; } trad_frame_set_reg_value (this_trad_cache, gdbarch_pc_regnum (gdbarch), func); trad_frame_set_reg_value (this_trad_cache, gdbarch_sp_regnum (gdbarch), base); if (tdep->wordsize == 4) trad_frame_set_reg_addr (this_trad_cache, tdep->ppc_lr_regnum, base_orig + 0x38 + 52 + 8); else trad_frame_set_reg_addr (this_trad_cache, tdep->ppc_lr_regnum, base_orig + 0x70 + 320); trad_frame_set_id (this_trad_cache, frame_id_build (base, func)); trad_frame_set_this_base (this_trad_cache, base); return this_trad_cache; }
static int x86_push_ebp_pattern_p (CORE_ADDR memaddr) { gdb_byte op = read_memory_unsigned_integer (memaddr, 1); if (op == 0x55) return 1; if (op == 0x6a) if (read_memory_unsigned_integer (memaddr + 1, 1) == 0x00) return 1; return 0; }
static CORE_ADDR i386lynx_saved_pc_after_call (struct frame_info *frame) { char opcode[7]; static const unsigned char call_inst[] = { 0x9a, 0, 0, 0, 0, 8, 0 }; /* lcall 0x8,0x0 */ read_memory_nobpt (frame->pc - 7, opcode, 7); if (memcmp (opcode, call_inst, 7) == 0) return read_memory_unsigned_integer (read_register (SP_REGNUM) + 4, 4); return read_memory_unsigned_integer (read_register (SP_REGNUM), 4); }
CORE_ADDR i386bsd_sigcontext_addr (struct frame_info *frame) { if (frame->next) /* If this isn't the top frame, the next frame must be for the signal handler itself. A pointer to the sigcontext structure is passed as the third argument to the signal handler. */ return read_memory_unsigned_integer (frame->next->frame + 16, 4); /* This is the top frame. We'll have to find the address of the sigcontext structure by looking at the stack pointer. */ return read_memory_unsigned_integer (read_register (SP_REGNUM) + 8, 4); }
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; }
static int x86_mov_reg_to_local_stack_frame_p (CORE_ADDR memaddr, int *regnum, int *offset) { gdb_byte op; int source_reg_mod = 0; int target_reg_mod = 0; op = read_memory_unsigned_integer (memaddr, 1); if (REX_W_PREFIX_P (op)) { source_reg_mod = REX_W_R (op) << 3; target_reg_mod = REX_W_B (op) << 3; /* The target register should be ebp/rbp which doesn't require an extra bit to specify. */ if (target_reg_mod == 1) return 0; op = read_memory_unsigned_integer (++memaddr, 1); } /* Detect a 'mov %ebx,-0xc(%ebp)' type instruction. aka 'MOV r/m32,r32' in Intel syntax terms. */ if (op == 0x89) { op = read_memory_unsigned_integer (memaddr + 1, 1); /* Mask off the 3-5 bits which indicate the destination register if this is a ModR/M byte. */ int op_sans_dest_reg = op & (~0x38); /* Look for a ModR/M byte with Mod bits 01 and R/M bits 101 ([EBP] disp8), i.e. 01xxx101 I want to see a destination of ebp-disp8 or ebp-disp32. */ if (op_sans_dest_reg != 0x45 && op_sans_dest_reg != 0x85) return 0; int saved_reg = ((op >> 3) & 0x7) | source_reg_mod; int off = 0; if (op_sans_dest_reg == 0x45) off = (int8_t) read_memory_unsigned_integer (memaddr + 2, 1); if (op_sans_dest_reg == 0x85) off = (uint32_t) read_memory_unsigned_integer (memaddr + 2, 4); if (off > 0) return 0; if (regnum != NULL) *regnum = saved_reg; if (offset != NULL) *offset = abs (off); return 1; }
static CORE_ADDR vax_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc) { enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); gdb_byte op = read_memory_unsigned_integer (pc, 1, byte_order); if (op == 0x11) pc += 2; /* skip brb */ if (op == 0x31) pc += 3; /* skip brw */ if (op == 0xC2 && read_memory_unsigned_integer (pc + 2, 1, byte_order) == 0x5E) pc += 3; /* skip subl2 */ if (op == 0x9E && read_memory_unsigned_integer (pc + 1, 1, byte_order) == 0xAE && read_memory_unsigned_integer (pc + 3, 1, byte_order) == 0x5E) pc += 4; /* skip movab */ if (op == 0x9E && read_memory_unsigned_integer (pc + 1, 1, byte_order) == 0xCE && read_memory_unsigned_integer (pc + 4, 1, byte_order) == 0x5E) pc += 5; /* skip movab */ if (op == 0x9E && read_memory_unsigned_integer (pc + 1, 1, byte_order) == 0xEE && read_memory_unsigned_integer (pc + 6, 1, byte_order) == 0x5E) pc += 7; /* skip movab */ return pc; }
static int x86_pop_p (CORE_ADDR memaddr) { gdb_byte op = read_memory_unsigned_integer (memaddr, 1); /* A REX.W prefix opcode indicating that the register being popped is in the second half of the reg set. */ if (op == 0x41) op = read_memory_unsigned_integer (memaddr + 1, 1); /* 58+ rd POP r32 */ if ((op & 0xf8) == 0x58) return 1; return 0; }
static CORE_ADDR ppc64_plt_entry_point (struct gdbarch *gdbarch, CORE_ADDR plt) { enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); /* The first word of the PLT entry is the function entry point. */ return (CORE_ADDR) read_memory_unsigned_integer (plt, 8, byte_order); }
static void ppc_linux_sigtramp_cache (struct frame_info *next_frame, struct trad_frame_cache *this_cache, CORE_ADDR func, LONGEST offset, int bias) { CORE_ADDR base; CORE_ADDR regs; CORE_ADDR gpregs; CORE_ADDR fpregs; int i; struct gdbarch *gdbarch = get_frame_arch (next_frame); struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); base = frame_unwind_register_unsigned (next_frame, gdbarch_sp_regnum (current_gdbarch)); if (bias > 0 && frame_pc_unwind (next_frame) != func) /* See below, some signal trampolines increment the stack as their first instruction, need to compensate for that. */ base -= bias; /* Find the address of the register buffer pointer. */ regs = base + offset; /* Use that to find the address of the corresponding register buffers. */ gpregs = read_memory_unsigned_integer (regs, tdep->wordsize); fpregs = gpregs + 48 * tdep->wordsize; /* General purpose. */ for (i = 0; i < 32; i++) { int regnum = i + tdep->ppc_gp0_regnum; trad_frame_set_reg_addr (this_cache, regnum, gpregs + i * tdep->wordsize); } trad_frame_set_reg_addr (this_cache, gdbarch_pc_regnum (current_gdbarch), gpregs + 32 * tdep->wordsize); trad_frame_set_reg_addr (this_cache, tdep->ppc_ctr_regnum, gpregs + 35 * tdep->wordsize); trad_frame_set_reg_addr (this_cache, tdep->ppc_lr_regnum, gpregs + 36 * tdep->wordsize); trad_frame_set_reg_addr (this_cache, tdep->ppc_xer_regnum, gpregs + 37 * tdep->wordsize); trad_frame_set_reg_addr (this_cache, tdep->ppc_cr_regnum, gpregs + 38 * tdep->wordsize); if (ppc_floating_point_unit_p (gdbarch)) { /* Floating point registers. */ for (i = 0; i < 32; i++) { int regnum = i + gdbarch_fp0_regnum (current_gdbarch); trad_frame_set_reg_addr (this_cache, regnum, fpregs + i * tdep->wordsize); } trad_frame_set_reg_addr (this_cache, tdep->ppc_fpscr_regnum, fpregs + 32 * tdep->wordsize); } trad_frame_set_id (this_cache, frame_id_build (base, func)); }
static CORE_ADDR rs6000_convert_from_func_ptr_addr (struct gdbarch *gdbarch, CORE_ADDR addr, struct target_ops *targ) { struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); struct obj_section *s; s = find_pc_section (addr); /* Normally, functions live inside a section that is executable. So, if ADDR points to a non-executable section, then treat it as a function descriptor and return the target address iff the target address itself points to a section that is executable. */ if (s && (s->the_bfd_section->flags & SEC_CODE) == 0) { CORE_ADDR pc = 0; struct obj_section *pc_section; volatile struct gdb_exception e; TRY_CATCH (e, RETURN_MASK_ERROR) { pc = read_memory_unsigned_integer (addr, tdep->wordsize, byte_order); }
static enum return_value_convention sparc32_return_value (struct gdbarch *gdbarch, struct type *type, struct regcache *regcache, gdb_byte *readbuf, const gdb_byte *writebuf) { /* The psABI says that "...every stack frame reserves the word at %fp+64. If a function returns a structure, union, or quad-precision value, this word should hold the address of the object into which the return value should be copied." This guarantees that we can always find the return value, not just before the function returns. */ if (sparc_structure_or_union_p (type) || (sparc_floating_p (type) && TYPE_LENGTH (type) == 16)) { if (readbuf) { ULONGEST sp; CORE_ADDR addr; regcache_cooked_read_unsigned (regcache, SPARC_SP_REGNUM, &sp); addr = read_memory_unsigned_integer (sp + 64, 4); read_memory (addr, readbuf, TYPE_LENGTH (type)); } return RETURN_VALUE_ABI_PRESERVES_ADDRESS; } if (readbuf) sparc32_extract_return_value (type, regcache, readbuf); if (writebuf) sparc32_store_return_value (type, regcache, writebuf); return RETURN_VALUE_REGISTER_CONVENTION; }
static CORE_ADDR ppc64_desc_entry_point (struct gdbarch *gdbarch, CORE_ADDR desc) { enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); /* The first word of the descriptor is the entry point. */ return (CORE_ADDR) read_memory_unsigned_integer (desc, 8, byte_order); }
static int amd64_darwin_sstep_at_sigreturn (x86_thread_state_t *regs) { enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch); static const gdb_byte darwin_syscall[] = { 0x0f, 0x05 }; /* syscall */ gdb_byte buf[sizeof (darwin_syscall)]; /* Check if PC is at a sigreturn system call. */ if (target_read_memory (regs->uts.ts64.__rip, buf, sizeof (buf)) == 0 && memcmp (buf, darwin_syscall, sizeof (darwin_syscall)) == 0 && (regs->uts.ts64.__rax & 0xffffffff) == 0x20000b8 /* SYS_sigreturn */) { ULONGEST mctx_addr; ULONGEST flags_addr; unsigned int rflags; mctx_addr = read_memory_unsigned_integer (regs->uts.ts64.__rdi + 48, 8, byte_order); flags_addr = mctx_addr + 16 + 17 * 8; /* AMD64 is little endian. */ read_memory (flags_addr, (gdb_byte *) &rflags, 4); rflags |= X86_EFLAGS_T; write_memory (flags_addr, (gdb_byte *) &rflags, 4); return 1; } return 0; }
static CORE_ADDR sparc64_linux_step_trap (struct frame_info *frame, unsigned long insn) { if (insn == 0x91d0206d) { struct gdbarch *gdbarch = get_frame_arch (frame); enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); ULONGEST sp = get_frame_register_unsigned (frame, SPARC_SP_REGNUM); if (sp & 1) sp += BIAS; /* The kernel puts the sigreturn registers on the stack, and this is where the signal unwinding state is take from when returning from a signal. A siginfo_t sits 192 bytes from the base of the stack. This siginfo_t is 128 bytes, and is followed by the sigreturn register save area. The saved PC sits at a 136 byte offset into there. */ return read_memory_unsigned_integer (sp + 192 + 128 + 136, 8, byte_order); } return 0; }
CORE_ADDR arm_wince_skip_main_prologue (struct gdbarch *gdbarch, CORE_ADDR pc) { enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); ULONGEST this_instr; this_instr = read_memory_unsigned_integer (pc, 4, byte_order); /* bl offset <__gccmain> */ if ((this_instr & 0xfff00000) == 0xeb000000) { #define sign_extend(V, N) \ (((long) (V) ^ (1L << ((N) - 1))) - (1L << ((N) - 1))) long offset = sign_extend (this_instr & 0x000fffff, 23) << 2; CORE_ADDR call_dest = (pc + 8 + offset) & 0xffffffffU; struct minimal_symbol *s = lookup_minimal_symbol_by_pc (call_dest); if (s != NULL && SYMBOL_LINKAGE_NAME (s) != NULL && strcmp (SYMBOL_LINKAGE_NAME (s), "__gccmain") == 0) pc += 4; } return pc; }
static CORE_ADDR sparc32_extract_struct_value_address (struct regcache *regcache) { ULONGEST sp; regcache_cooked_read_unsigned (regcache, SPARC_SP_REGNUM, &sp); return read_memory_unsigned_integer (sp + 64, 4); }
static int x86_picbase_setup_pattern_p (CORE_ADDR memaddr, int *regnum) { gdb_byte op; if (length_of_this_instruction (memaddr) != 5 || read_memory_unsigned_integer (memaddr, 1) != 0xe8 || read_memory_unsigned_integer (memaddr + 1, 4) != 0) return 0; op = read_memory_unsigned_integer (memaddr + 5, 1); if ((op & 0xf8) != 0x58) return 0; if (regnum) *regnum = (int) op & 0x7; return 1; }
static void sparc32obsd_supply_uthread (struct regcache *regcache, int regnum, CORE_ADDR addr) { struct gdbarch *gdbarch = get_regcache_arch (regcache); enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); CORE_ADDR fp, fp_addr = addr + SPARC32OBSD_UTHREAD_FP_OFFSET; gdb_byte buf[4]; gdb_assert (regnum >= -1); fp = read_memory_unsigned_integer (fp_addr, 4, byte_order); if (regnum == SPARC_SP_REGNUM || regnum == -1) { store_unsigned_integer (buf, 4, byte_order, fp); regcache_raw_supply (regcache, SPARC_SP_REGNUM, buf); if (regnum == SPARC_SP_REGNUM) return; } if (regnum == SPARC32_PC_REGNUM || regnum == SPARC32_NPC_REGNUM || regnum == -1) { CORE_ADDR i7, i7_addr = addr + SPARC32OBSD_UTHREAD_PC_OFFSET; i7 = read_memory_unsigned_integer (i7_addr, 4, byte_order); if (regnum == SPARC32_PC_REGNUM || regnum == -1) { store_unsigned_integer (buf, 4, byte_order, i7 + 8); regcache_raw_supply (regcache, SPARC32_PC_REGNUM, buf); } if (regnum == SPARC32_NPC_REGNUM || regnum == -1) { store_unsigned_integer (buf, 4, byte_order, i7 + 12); regcache_raw_supply (regcache, SPARC32_NPC_REGNUM, buf); } if (regnum == SPARC32_PC_REGNUM || regnum == SPARC32_NPC_REGNUM) return; } sparc_supply_rwindow (regcache, fp, regnum); }
static void amd64obsd_supply_uthread (struct regcache *regcache, int regnum, CORE_ADDR addr) { struct gdbarch *gdbarch = get_regcache_arch (regcache); enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); CORE_ADDR sp_addr = addr + AMD64OBSD_UTHREAD_RSP_OFFSET; CORE_ADDR sp = 0; gdb_byte buf[8]; int i; gdb_assert (regnum >= -1); if (regnum == -1 || regnum == AMD64_RSP_REGNUM) { int offset; /* Fetch stack pointer from thread structure. */ sp = read_memory_unsigned_integer (sp_addr, 8, byte_order); /* Adjust the stack pointer such that it looks as if we just returned from _thread_machdep_switch. */ offset = amd64obsd_uthread_reg_offset[AMD64_RIP_REGNUM] + 8; store_unsigned_integer (buf, 8, byte_order, sp + offset); regcache_raw_supply (regcache, AMD64_RSP_REGNUM, buf); } for (i = 0; i < ARRAY_SIZE (amd64obsd_uthread_reg_offset); i++) { if (amd64obsd_uthread_reg_offset[i] != -1 && (regnum == -1 || regnum == i)) { /* Fetch stack pointer from thread structure (if we didn't do so already). */ if (sp == 0) sp = read_memory_unsigned_integer (sp_addr, 8, byte_order); /* Read the saved register from the stack frame. */ read_memory (sp + amd64obsd_uthread_reg_offset[i], buf, 8); regcache_raw_supply (regcache, i, buf); } } }
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 (); }
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 xstormy16_analyze_prologue (struct gdbarch *gdbarch, CORE_ADDR start_addr, CORE_ADDR end_addr, struct xstormy16_frame_cache *cache, struct frame_info *this_frame) { enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); CORE_ADDR next_addr; ULONGEST inst, inst2; LONGEST offset; int regnum; /* Initialize framesize with size of PC put on stack by CALLF inst. */ cache->saved_regs[E_PC_REGNUM] = 0; cache->framesize = xstormy16_pc_size; if (start_addr >= end_addr) return end_addr; for (next_addr = start_addr; next_addr < end_addr; next_addr += xstormy16_inst_size) { inst = read_memory_unsigned_integer (next_addr, xstormy16_inst_size, byte_order); inst2 = read_memory_unsigned_integer (next_addr + xstormy16_inst_size, xstormy16_inst_size, byte_order); if (inst >= 0x0082 && inst <= 0x008d) /* push r2 .. push r13 */ { regnum = inst & 0x000f; cache->saved_regs[regnum] = cache->framesize; cache->framesize += xstormy16_reg_size; } /* Optional stack allocation for args and local vars <= 4 byte. */ else if (inst == 0x301f || inst == 0x303f) /* inc r15, #0x1/#0x3 */ { cache->framesize += ((inst & 0x0030) >> 4) + 1; } /* optional stack allocation for args and local vars > 4 && < 16 byte */ else if ((inst & 0xff0f) == 0x510f) /* 51Hf add r15, #0xH */
static void sparc64obsd_supply_uthread (struct regcache *regcache, int regnum, CORE_ADDR addr) { CORE_ADDR fp, fp_addr = addr + SPARC64OBSD_UTHREAD_FP_OFFSET; gdb_byte buf[8]; gdb_assert (regnum >= -1); fp = read_memory_unsigned_integer (fp_addr, 8); if (regnum == SPARC_SP_REGNUM || regnum == -1) { store_unsigned_integer (buf, 8, fp); regcache_raw_supply (regcache, SPARC_SP_REGNUM, buf); if (regnum == SPARC_SP_REGNUM) return; } if (regnum == SPARC64_PC_REGNUM || regnum == SPARC64_NPC_REGNUM || regnum == -1) { CORE_ADDR i7, i7_addr = addr + SPARC64OBSD_UTHREAD_PC_OFFSET; i7 = read_memory_unsigned_integer (i7_addr, 8); if (regnum == SPARC64_PC_REGNUM || regnum == -1) { store_unsigned_integer (buf, 8, i7 + 8); regcache_raw_supply (regcache, SPARC64_PC_REGNUM, buf); } if (regnum == SPARC64_NPC_REGNUM || regnum == -1) { store_unsigned_integer (buf, 8, i7 + 12); regcache_raw_supply (regcache, SPARC64_NPC_REGNUM, buf); } if (regnum == SPARC64_PC_REGNUM || regnum == SPARC64_NPC_REGNUM) return; } sparc_supply_rwindow (regcache, fp, regnum); }
static CORE_ADDR arm_pe_skip_trampoline_code (struct frame_info *frame, CORE_ADDR pc) { struct gdbarch *gdbarch = get_frame_arch (frame); enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); ULONGEST indirect; struct bound_minimal_symbol indsym; const char *symname; CORE_ADDR next_pc; /* The format of an ARM DLL trampoline is: ldr ip, [pc] ldr pc, [ip] .dw __imp_<func> */ if (pc == 0 || read_memory_unsigned_integer (pc + 0, 4, byte_order) != 0xe59fc000 || read_memory_unsigned_integer (pc + 4, 4, byte_order) != 0xe59cf000) return 0; indirect = read_memory_unsigned_integer (pc + 8, 4, byte_order); if (indirect == 0) return 0; indsym = lookup_minimal_symbol_by_pc (indirect); if (indsym.minsym == NULL) return 0; symname = MSYMBOL_LINKAGE_NAME (indsym.minsym); if (symname == NULL || !startswith (symname, "__imp_")) return 0; next_pc = read_memory_unsigned_integer (indirect, 4, byte_order); if (next_pc != 0) return next_pc; /* Check with the default arm gdbarch_skip_trampoline. */ return arm_skip_stub (frame, pc); }
static CORE_ADDR i386bsd_sigcontext_addr (struct frame_info *next_frame) { char buf[4]; CORE_ADDR sp; frame_unwind_register (next_frame, I386_ESP_REGNUM, buf); sp = extract_unsigned_integer (buf, 4); return read_memory_unsigned_integer (sp + 8, 4); }