diff options
Diffstat (limited to 'gdb')
-rw-r--r-- | gdb/ChangeLog | 22 | ||||
-rw-r--r-- | gdb/arm-linux-tdep.c | 109 | ||||
-rw-r--r-- | gdb/arm-tdep.c | 132 | ||||
-rw-r--r-- | gdb/arm-tdep.h | 9 | ||||
-rw-r--r-- | gdb/regcache.c | 15 | ||||
-rw-r--r-- | gdb/regcache.h | 4 |
6 files changed, 212 insertions, 79 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 507a1cc..a590a0d 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,5 +1,27 @@ 2015-12-18 Antoine Tremblay <antoine.tremblay@ericsson.com> + * arm-linux-tdep.c (arm_linux_sigreturn_next_pc_offset): New function. + (arm_linux_sigreturn_next_pc): Likewise. + (arm_linux_syscall_next_pc): Use regcache instead of frame. + (arm_linux_software_single_step): Likewise. + * arm-tdep.c (arm_is_thumb): New function. + (shifted_reg_va): Use regcache instead of frame. + (thumb_get_next_pc_raw): Likewise. + (arm_get_next_pc_raw): Likewise. + (arm_get_next_pc): Likewise. + (thumb_deal_with_atomic_sequence_raw): Likewise. + (arm_deal_with_atomic_sequence_raw): Likewise. + (arm_deal_with_atomic_sequence): Likewise. + (arm_software_single_step): Likewise. + * arm-tdep.h (struct gdbarch_tdep): Use regcache for syscall_next_pc. + (arm_get_next_pc): Use regcache. + (arm_deal_with_atomic_sequence): Likewise. + (arm_is_thumb): New declaration. + * regcache.c (regcache_raw_get_unsigned): New function. + * regcache.h (regcache_raw_get_unsigned): New function declaration. + +2015-12-18 Antoine Tremblay <antoine.tremblay@ericsson.com> + * arch/arm.c (bitcount): Move from arm-tdep.c. (condition_true): Likewise. * arch/arm.h (Instruction Definitions): Move form arm-tdep.h. diff --git a/gdb/arm-linux-tdep.c b/gdb/arm-linux-tdep.c index 73e1271..e06cf77 100644 --- a/gdb/arm-linux-tdep.c +++ b/gdb/arm-linux-tdep.c @@ -257,6 +257,11 @@ static const gdb_byte arm_linux_thumb2_le_breakpoint[] = { 0xf0, 0xf7, 0x00, 0xa #define ARM_LDR_PC_SP_12 0xe49df00c #define ARM_LDR_PC_SP_4 0xe49df004 +/* Syscall number for sigreturn. */ +#define ARM_SIGRETURN 119 +/* Syscall number for rt_sigreturn. */ +#define ARM_RT_SIGRETURN 173 + static void arm_linux_sigtramp_cache (struct frame_info *this_frame, struct trad_frame_cache *this_cache, @@ -805,6 +810,70 @@ arm_linux_sigreturn_return_addr (struct frame_info *frame, return 0; } +/* Calculate the offset from stack pointer of the pc register on the stack + in the case of a sigreturn or sigreturn_rt syscall. */ +static int +arm_linux_sigreturn_next_pc_offset (unsigned long sp, + unsigned long sp_data, + unsigned long svc_number, + int is_sigreturn) +{ + /* Offset of R0 register. */ + int r0_offset = 0; + /* Offset of PC register. */ + int pc_offset = 0; + + if (is_sigreturn) + { + if (sp_data == ARM_NEW_SIGFRAME_MAGIC) + r0_offset = ARM_UCONTEXT_SIGCONTEXT + ARM_SIGCONTEXT_R0; + else + r0_offset = ARM_SIGCONTEXT_R0; + } + else + { + if (sp_data == sp + ARM_OLD_RT_SIGFRAME_SIGINFO) + r0_offset = ARM_OLD_RT_SIGFRAME_UCONTEXT; + else + r0_offset = ARM_NEW_RT_SIGFRAME_UCONTEXT; + + r0_offset += ARM_UCONTEXT_SIGCONTEXT + ARM_SIGCONTEXT_R0; + } + + pc_offset = r0_offset + INT_REGISTER_SIZE * ARM_PC_REGNUM; + + return pc_offset; +} + +/* Find the value of the next PC after a sigreturn or rt_sigreturn syscall + based on current processor state. */ +static CORE_ADDR +arm_linux_sigreturn_next_pc (struct regcache *regcache, + unsigned long svc_number) +{ + ULONGEST sp; + unsigned long sp_data; + CORE_ADDR next_pc = 0; + struct gdbarch *gdbarch = get_regcache_arch (regcache); + enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); + int pc_offset = 0; + int is_sigreturn = 0; + + gdb_assert (svc_number == ARM_SIGRETURN + || svc_number == ARM_RT_SIGRETURN); + + is_sigreturn = (svc_number == ARM_SIGRETURN); + regcache_cooked_read_unsigned (regcache, ARM_SP_REGNUM, &sp); + sp_data = read_memory_unsigned_integer (sp, 4, byte_order); + + pc_offset = arm_linux_sigreturn_next_pc_offset (sp, sp_data, svc_number, + is_sigreturn); + + next_pc = read_memory_unsigned_integer (sp + pc_offset, 4, byte_order); + + return next_pc; +} + /* At a ptrace syscall-stop, return the syscall number. This either comes from the SWI instruction (OABI) or from r7 (EABI). @@ -858,25 +927,26 @@ arm_linux_get_syscall_number (struct gdbarch *gdbarch, return svc_number; } -/* When FRAME is at a syscall instruction, return the PC of the next - instruction to be executed. */ +/* When the processor is at a syscall instruction, return the PC of the + next instruction to be executed. */ static CORE_ADDR -arm_linux_syscall_next_pc (struct frame_info *frame) +arm_linux_syscall_next_pc (struct regcache *regcache) { - CORE_ADDR pc = get_frame_pc (frame); - CORE_ADDR return_addr = 0; - int is_thumb = arm_frame_is_thumb (frame); + CORE_ADDR pc = regcache_read_pc (regcache); + CORE_ADDR next_pc = 0; + int is_thumb = arm_is_thumb (regcache); ULONGEST svc_number = 0; + struct gdbarch *gdbarch = get_regcache_arch (regcache); if (is_thumb) { - svc_number = get_frame_register_unsigned (frame, 7); - return_addr = pc + 2; + svc_number = regcache_raw_get_unsigned (regcache, 7); + next_pc = pc + 2; } else { - struct gdbarch *gdbarch = get_frame_arch (frame); + struct gdbarch *gdbarch = get_regcache_arch (regcache); enum bfd_endian byte_order_for_code = gdbarch_byte_order_for_code (gdbarch); unsigned long this_instr = @@ -889,19 +959,20 @@ arm_linux_syscall_next_pc (struct frame_info *frame) } else /* EABI. */ { - svc_number = get_frame_register_unsigned (frame, 7); + svc_number = regcache_raw_get_unsigned (regcache, 7); } - return_addr = pc + 4; + next_pc = pc + 4; } - arm_linux_sigreturn_return_addr (frame, svc_number, &return_addr, &is_thumb); + if (svc_number == ARM_SIGRETURN || svc_number == ARM_RT_SIGRETURN) + next_pc = arm_linux_sigreturn_next_pc (regcache, svc_number); /* Addresses for calling Thumb functions have the bit 0 set. */ if (is_thumb) - return_addr |= 1; + next_pc = MAKE_THUMB_ADDR (next_pc); - return return_addr; + return next_pc; } @@ -910,11 +981,13 @@ arm_linux_syscall_next_pc (struct frame_info *frame) static int arm_linux_software_single_step (struct frame_info *frame) { - struct gdbarch *gdbarch = get_frame_arch (frame); - struct address_space *aspace = get_frame_address_space (frame); + struct regcache *regcache = get_current_regcache (); + struct gdbarch *gdbarch = get_regcache_arch (regcache); + struct address_space *aspace = get_regcache_aspace (regcache); + CORE_ADDR next_pc; - if (arm_deal_with_atomic_sequence (frame)) + if (arm_deal_with_atomic_sequence (regcache)) return 1; /* If the target does have hardware single step, GDB doesn't have @@ -922,7 +995,7 @@ arm_linux_software_single_step (struct frame_info *frame) if (target_can_do_single_step () == 1) return 0; - next_pc = arm_get_next_pc (frame, get_frame_pc (frame)); + next_pc = arm_get_next_pc (regcache, regcache_read_pc (regcache)); /* The Linux kernel offers some user-mode helpers in a high page. We can not read this page (as of 2.6.23), and even if we could then we couldn't diff --git a/gdb/arm-tdep.c b/gdb/arm-tdep.c index 848af97..ebe4c40 100644 --- a/gdb/arm-tdep.c +++ b/gdb/arm-tdep.c @@ -281,6 +281,19 @@ arm_psr_thumb_bit (struct gdbarch *gdbarch) return CPSR_T; } +/* Determine if the processor is currently executing in Thumb mode. */ + +int +arm_is_thumb (struct regcache *regcache) +{ + ULONGEST cpsr; + ULONGEST t_bit = arm_psr_thumb_bit (get_regcache_arch (regcache)); + + cpsr = regcache_raw_get_unsigned (regcache, ARM_PS_REGNUM); + + return (cpsr & t_bit) != 0; +} + /* Determine if FRAME is executing in Thumb mode. */ int @@ -4302,7 +4315,7 @@ convert_to_extended (const struct floatformat *fmt, void *dbl, const void *ptr, } static unsigned long -shifted_reg_val (struct frame_info *frame, unsigned long inst, int carry, +shifted_reg_val (struct regcache *regcache, unsigned long inst, int carry, unsigned long pc_val, unsigned long status_reg) { unsigned long res, shift; @@ -4313,14 +4326,14 @@ shifted_reg_val (struct frame_info *frame, unsigned long inst, int carry, { int rs = bits (inst, 8, 11); shift = (rs == 15 ? pc_val + 8 - : get_frame_register_unsigned (frame, rs)) & 0xFF; + : regcache_raw_get_unsigned (regcache, rs)) & 0xFF; } else shift = bits (inst, 7, 11); res = (rm == ARM_PC_REGNUM ? (pc_val + (bit (inst, 4) ? 12 : 8)) - : get_frame_register_unsigned (frame, rm)); + : regcache_raw_get_unsigned (regcache, rm)); switch (shifttype) { @@ -4372,10 +4385,10 @@ thumb_advance_itstate (unsigned int itstate) another breakpoint by our caller. */ static CORE_ADDR -thumb_get_next_pc_raw (struct frame_info *frame, CORE_ADDR pc) +thumb_get_next_pc_raw (struct regcache *regcache, CORE_ADDR pc) { - struct gdbarch *gdbarch = get_frame_arch (frame); - struct address_space *aspace = get_frame_address_space (frame); + struct gdbarch *gdbarch = get_regcache_arch (regcache); + struct address_space *aspace = get_regcache_aspace (regcache); enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); enum bfd_endian byte_order_for_code = gdbarch_byte_order_for_code (gdbarch); unsigned long pc_val = ((unsigned long) pc) + 4; /* PC after prefetch */ @@ -4397,7 +4410,7 @@ thumb_get_next_pc_raw (struct frame_info *frame, CORE_ADDR pc) base condition. One of the low four bits will be set if an IT block is active. These bits read as zero on earlier processors. */ - status = get_frame_register_unsigned (frame, ARM_PS_REGNUM); + status = regcache_raw_get_unsigned (regcache, ARM_PS_REGNUM); itstate = ((status >> 8) & 0xfc) | ((status >> 25) & 0x3); /* If-Then handling. On GNU/Linux, where this routine is used, we @@ -4512,7 +4525,7 @@ thumb_get_next_pc_raw (struct frame_info *frame, CORE_ADDR pc) /* Fetch the saved PC from the stack. It's stored above all of the other registers. */ offset = bitcount (bits (inst1, 0, 7)) * INT_REGISTER_SIZE; - sp = get_frame_register_unsigned (frame, ARM_SP_REGNUM); + sp = regcache_raw_get_unsigned (regcache, ARM_SP_REGNUM); nextpc = read_memory_unsigned_integer (sp + offset, 4, byte_order); } else if ((inst1 & 0xf000) == 0xd000) /* conditional branch */ @@ -4524,7 +4537,7 @@ thumb_get_next_pc_raw (struct frame_info *frame, CORE_ADDR pc) tdep = gdbarch_tdep (gdbarch); if (tdep->syscall_next_pc != NULL) - nextpc = tdep->syscall_next_pc (frame); + nextpc = tdep->syscall_next_pc (regcache); } else if (cond != 0x0f && condition_true (cond, status)) @@ -4568,7 +4581,7 @@ thumb_get_next_pc_raw (struct frame_info *frame, CORE_ADDR pc) else if (inst1 == 0xf3de && (inst2 & 0xff00) == 0x3f00) { /* SUBS PC, LR, #imm8. */ - nextpc = get_frame_register_unsigned (frame, ARM_LR_REGNUM); + nextpc = regcache_raw_get_unsigned (regcache, ARM_LR_REGNUM); nextpc -= inst2 & 0x00ff; } else if ((inst2 & 0xd000) == 0x8000 && (inst1 & 0x0380) != 0x0380) @@ -4626,14 +4639,15 @@ thumb_get_next_pc_raw (struct frame_info *frame, CORE_ADDR pc) if (load_pc) { - CORE_ADDR addr = get_frame_register_unsigned (frame, rn); - nextpc = get_frame_memory_unsigned (frame, addr + offset, 4); + CORE_ADDR addr = regcache_raw_get_unsigned (regcache, rn); + nextpc = read_memory_unsigned_integer (addr + offset, 4, + byte_order); } } else if ((inst1 & 0xffef) == 0xea4f && (inst2 & 0xfff0) == 0x0f00) { /* MOV PC or MOVS PC. */ - nextpc = get_frame_register_unsigned (frame, bits (inst2, 0, 3)); + nextpc = regcache_raw_get_unsigned (regcache, bits (inst2, 0, 3)); nextpc = MAKE_THUMB_ADDR (nextpc); } else if ((inst1 & 0xff70) == 0xf850 && (inst2 & 0xf000) == 0xf000) @@ -4643,7 +4657,7 @@ thumb_get_next_pc_raw (struct frame_info *frame, CORE_ADDR pc) int rn, load_pc = 1; rn = bits (inst1, 0, 3); - base = get_frame_register_unsigned (frame, rn); + base = regcache_raw_get_unsigned (regcache, rn); if (rn == ARM_PC_REGNUM) { base = (base + 4) & ~(CORE_ADDR) 0x3; @@ -4667,14 +4681,14 @@ thumb_get_next_pc_raw (struct frame_info *frame, CORE_ADDR pc) else if ((inst2 & 0x0fc0) == 0x0000) { int shift = bits (inst2, 4, 5), rm = bits (inst2, 0, 3); - base += get_frame_register_unsigned (frame, rm) << shift; + base += regcache_raw_get_unsigned (regcache, rm) << shift; } else /* Reserved. */ load_pc = 0; if (load_pc) - nextpc = get_frame_memory_unsigned (frame, base, 4); + nextpc = read_memory_unsigned_integer (base, 4, byte_order); } else if ((inst1 & 0xfff0) == 0xe8d0 && (inst2 & 0xfff0) == 0xf000) { @@ -4685,10 +4699,11 @@ thumb_get_next_pc_raw (struct frame_info *frame, CORE_ADDR pc) if (tbl_reg == 0x0f) table = pc + 4; /* Regcache copy of PC isn't right yet. */ else - table = get_frame_register_unsigned (frame, tbl_reg); + table = regcache_raw_get_unsigned (regcache, tbl_reg); - offset = get_frame_register_unsigned (frame, bits (inst2, 0, 3)); - length = 2 * get_frame_memory_unsigned (frame, table + offset, 1); + offset = regcache_raw_get_unsigned (regcache, bits (inst2, 0, 3)); + length = 2 * read_memory_unsigned_integer (table + offset, 1, + byte_order); nextpc = pc_val + length; } else if ((inst1 & 0xfff0) == 0xe8d0 && (inst2 & 0xfff0) == 0xf010) @@ -4700,10 +4715,11 @@ thumb_get_next_pc_raw (struct frame_info *frame, CORE_ADDR pc) if (tbl_reg == 0x0f) table = pc + 4; /* Regcache copy of PC isn't right yet. */ else - table = get_frame_register_unsigned (frame, tbl_reg); + table = regcache_raw_get_unsigned (regcache, tbl_reg); - offset = 2 * get_frame_register_unsigned (frame, bits (inst2, 0, 3)); - length = 2 * get_frame_memory_unsigned (frame, table + offset, 2); + offset = 2 * regcache_raw_get_unsigned (regcache, bits (inst2, 0, 3)); + length = 2 * read_memory_unsigned_integer (table + offset, 2, + byte_order); nextpc = pc_val + length; } } @@ -4712,14 +4728,14 @@ thumb_get_next_pc_raw (struct frame_info *frame, CORE_ADDR pc) if (bits (inst1, 3, 6) == 0x0f) nextpc = UNMAKE_THUMB_ADDR (pc_val); else - nextpc = get_frame_register_unsigned (frame, bits (inst1, 3, 6)); + nextpc = regcache_raw_get_unsigned (regcache, bits (inst1, 3, 6)); } else if ((inst1 & 0xff87) == 0x4687) /* mov pc, REG */ { if (bits (inst1, 3, 6) == 0x0f) nextpc = pc_val; else - nextpc = get_frame_register_unsigned (frame, bits (inst1, 3, 6)); + nextpc = regcache_raw_get_unsigned (regcache, bits (inst1, 3, 6)); nextpc = MAKE_THUMB_ADDR (nextpc); } @@ -4727,7 +4743,7 @@ thumb_get_next_pc_raw (struct frame_info *frame, CORE_ADDR pc) { /* CBNZ or CBZ. */ int imm = (bit (inst1, 9) << 6) + (bits (inst1, 3, 7) << 1); - ULONGEST reg = get_frame_register_unsigned (frame, bits (inst1, 0, 2)); + ULONGEST reg = regcache_raw_get_unsigned (regcache, bits (inst1, 0, 2)); if (bit (inst1, 11) && reg != 0) nextpc = pc_val + imm; @@ -4746,9 +4762,9 @@ thumb_get_next_pc_raw (struct frame_info *frame, CORE_ADDR pc) address. */ static CORE_ADDR -arm_get_next_pc_raw (struct frame_info *frame, CORE_ADDR pc) +arm_get_next_pc_raw (struct regcache *regcache, CORE_ADDR pc) { - struct gdbarch *gdbarch = get_frame_arch (frame); + struct gdbarch *gdbarch = get_regcache_arch (regcache); enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); enum bfd_endian byte_order_for_code = gdbarch_byte_order_for_code (gdbarch); unsigned long pc_val; @@ -4759,7 +4775,7 @@ arm_get_next_pc_raw (struct frame_info *frame, CORE_ADDR pc) pc_val = (unsigned long) pc; this_instr = read_memory_unsigned_integer (pc, 4, byte_order_for_code); - status = get_frame_register_unsigned (frame, ARM_PS_REGNUM); + status = regcache_raw_get_unsigned (regcache, ARM_PS_REGNUM); nextpc = (CORE_ADDR) (pc_val + 4); /* Default case */ if (bits (this_instr, 28, 31) == INST_NV) @@ -4809,7 +4825,7 @@ arm_get_next_pc_raw (struct frame_info *frame, CORE_ADDR pc) rn = bits (this_instr, 0, 3); nextpc = ((rn == ARM_PC_REGNUM) ? (pc_val + 8) - : get_frame_register_unsigned (frame, rn)); + : regcache_raw_get_unsigned (regcache, rn)); return nextpc; } @@ -4819,7 +4835,7 @@ arm_get_next_pc_raw (struct frame_info *frame, CORE_ADDR pc) rn = bits (this_instr, 16, 19); operand1 = ((rn == ARM_PC_REGNUM) ? (pc_val + 8) - : get_frame_register_unsigned (frame, rn)); + : regcache_raw_get_unsigned (regcache, rn)); if (bit (this_instr, 25)) { @@ -4829,7 +4845,7 @@ arm_get_next_pc_raw (struct frame_info *frame, CORE_ADDR pc) & 0xffffffff; } else /* operand 2 is a shifted register. */ - operand2 = shifted_reg_val (frame, this_instr, c, + operand2 = shifted_reg_val (regcache, this_instr, c, pc_val, status); switch (bits (this_instr, 21, 24)) @@ -4928,7 +4944,7 @@ arm_get_next_pc_raw (struct frame_info *frame, CORE_ADDR pc) rn = bits (this_instr, 16, 19); base = ((rn == ARM_PC_REGNUM) ? (pc_val + 8) - : get_frame_register_unsigned (frame, rn)); + : regcache_raw_get_unsigned (regcache, rn)); if (bit (this_instr, 24)) { @@ -4936,7 +4952,8 @@ arm_get_next_pc_raw (struct frame_info *frame, CORE_ADDR pc) int c = (status & FLAG_C) ? 1 : 0; unsigned long offset = (bit (this_instr, 25) - ? shifted_reg_val (frame, this_instr, c, pc_val, status) + ? shifted_reg_val (regcache, this_instr, c, pc_val, + status) : bits (this_instr, 0, 11)); if (bit (this_instr, 23)) @@ -4961,8 +4978,8 @@ arm_get_next_pc_raw (struct frame_info *frame, CORE_ADDR pc) /* loading pc */ int offset = 0; unsigned long rn_val - = get_frame_register_unsigned (frame, - bits (this_instr, 16, 19)); + = regcache_raw_get_unsigned (regcache, + bits (this_instr, 16, 19)); if (bit (this_instr, 23)) { @@ -5000,7 +5017,7 @@ arm_get_next_pc_raw (struct frame_info *frame, CORE_ADDR pc) tdep = gdbarch_tdep (gdbarch); if (tdep->syscall_next_pc != NULL) - nextpc = tdep->syscall_next_pc (frame); + nextpc = tdep->syscall_next_pc (regcache); } break; @@ -5019,14 +5036,14 @@ arm_get_next_pc_raw (struct frame_info *frame, CORE_ADDR pc) loop is detected. */ CORE_ADDR -arm_get_next_pc (struct frame_info *frame, CORE_ADDR pc) +arm_get_next_pc (struct regcache *regcache, CORE_ADDR pc) { CORE_ADDR nextpc; - if (arm_frame_is_thumb (frame)) - nextpc = thumb_get_next_pc_raw (frame, pc); + if (arm_is_thumb (regcache)) + nextpc = thumb_get_next_pc_raw (regcache, pc); else - nextpc = arm_get_next_pc_raw (frame, pc); + nextpc = arm_get_next_pc_raw (regcache, pc); return nextpc; } @@ -5057,12 +5074,12 @@ arm_insert_single_step_breakpoint (struct gdbarch *gdbarch, the sequence. */ static int -thumb_deal_with_atomic_sequence_raw (struct frame_info *frame) +thumb_deal_with_atomic_sequence_raw (struct regcache *regcache) { - struct gdbarch *gdbarch = get_frame_arch (frame); - struct address_space *aspace = get_frame_address_space (frame); + struct gdbarch *gdbarch = get_regcache_arch (regcache); + struct address_space *aspace = get_regcache_aspace (regcache); enum bfd_endian byte_order_for_code = gdbarch_byte_order_for_code (gdbarch); - CORE_ADDR pc = get_frame_pc (frame); + CORE_ADDR pc = regcache_read_pc (regcache); CORE_ADDR breaks[2] = {-1, -1}; CORE_ADDR loc = pc; unsigned short insn1, insn2; @@ -5073,7 +5090,7 @@ thumb_deal_with_atomic_sequence_raw (struct frame_info *frame) ULONGEST status, itstate; /* We currently do not support atomic sequences within an IT block. */ - status = get_frame_register_unsigned (frame, ARM_PS_REGNUM); + status = regcache_raw_get_unsigned (regcache, ARM_PS_REGNUM); itstate = ((status >> 8) & 0xfc) | ((status >> 25) & 0x3); if (itstate & 0x0f) return 0; @@ -5188,12 +5205,12 @@ thumb_deal_with_atomic_sequence_raw (struct frame_info *frame) } static int -arm_deal_with_atomic_sequence_raw (struct frame_info *frame) +arm_deal_with_atomic_sequence_raw (struct regcache *regcache) { - struct gdbarch *gdbarch = get_frame_arch (frame); - struct address_space *aspace = get_frame_address_space (frame); + struct gdbarch *gdbarch = get_regcache_arch (regcache); + struct address_space *aspace = get_regcache_aspace (regcache); enum bfd_endian byte_order_for_code = gdbarch_byte_order_for_code (gdbarch); - CORE_ADDR pc = get_frame_pc (frame); + CORE_ADDR pc = regcache_read_pc (regcache); CORE_ADDR breaks[2] = {-1, -1}; CORE_ADDR loc = pc; unsigned int insn; @@ -5263,12 +5280,12 @@ arm_deal_with_atomic_sequence_raw (struct frame_info *frame) } int -arm_deal_with_atomic_sequence (struct frame_info *frame) +arm_deal_with_atomic_sequence (struct regcache *regcache) { - if (arm_frame_is_thumb (frame)) - return thumb_deal_with_atomic_sequence_raw (frame); + if (arm_is_thumb (regcache)) + return thumb_deal_with_atomic_sequence_raw (regcache); else - return arm_deal_with_atomic_sequence_raw (frame); + return arm_deal_with_atomic_sequence_raw (regcache); } /* single_step() is called just before we want to resume the inferior, @@ -5279,14 +5296,15 @@ arm_deal_with_atomic_sequence (struct frame_info *frame) int arm_software_single_step (struct frame_info *frame) { - struct gdbarch *gdbarch = get_frame_arch (frame); - struct address_space *aspace = get_frame_address_space (frame); + struct regcache *regcache = get_current_regcache (); + struct gdbarch *gdbarch = get_regcache_arch (regcache); + struct address_space *aspace = get_regcache_aspace (regcache); CORE_ADDR next_pc; - if (arm_deal_with_atomic_sequence (frame)) + if (arm_deal_with_atomic_sequence (regcache)) return 1; - next_pc = arm_get_next_pc (frame, get_frame_pc (frame)); + next_pc = arm_get_next_pc (regcache, regcache_read_pc (regcache)); arm_insert_single_step_breakpoint (gdbarch, aspace, next_pc); return 1; diff --git a/gdb/arm-tdep.h b/gdb/arm-tdep.h index 9b8447b..0063fef 100644 --- a/gdb/arm-tdep.h +++ b/gdb/arm-tdep.h @@ -135,9 +135,9 @@ struct gdbarch_tdep struct type *neon_double_type; struct type *neon_quad_type; - /* Return the expected next PC if FRAME is stopped at a syscall + /* Return the expected next PC if the program is stopped at a syscall instruction. */ - CORE_ADDR (*syscall_next_pc) (struct frame_info *frame); + CORE_ADDR (*syscall_next_pc) (struct regcache *regcache); /* syscall record. */ int (*arm_syscall_record) (struct regcache *regcache, unsigned long svc_number); @@ -250,11 +250,12 @@ extern void ULONGEST val, enum pc_write_style write_pc); CORE_ADDR arm_skip_stub (struct frame_info *, CORE_ADDR); -CORE_ADDR arm_get_next_pc (struct frame_info *, CORE_ADDR); +CORE_ADDR arm_get_next_pc (struct regcache *regcache, CORE_ADDR pc); void arm_insert_single_step_breakpoint (struct gdbarch *, struct address_space *, CORE_ADDR); -int arm_deal_with_atomic_sequence (struct frame_info *); +int arm_deal_with_atomic_sequence (struct regcache *); int arm_software_single_step (struct frame_info *); +int arm_is_thumb (struct regcache *regcache); int arm_frame_is_thumb (struct frame_info *frame); extern struct displaced_step_closure * diff --git a/gdb/regcache.c b/gdb/regcache.c index 5ee31fb..7fb9d18 100644 --- a/gdb/regcache.c +++ b/gdb/regcache.c @@ -715,6 +715,21 @@ regcache_raw_read_unsigned (struct regcache *regcache, int regnum, return status; } +/* Return the register's value or throw if it's not available. */ + +ULONGEST +regcache_raw_get_unsigned (struct regcache *regcache, int regnum) +{ + ULONGEST value; + enum register_status status; + + status = regcache_raw_read_unsigned (regcache, regnum, &value); + if (status == REG_UNAVAILABLE) + throw_error (NOT_AVAILABLE_ERROR, + _("Register %d is not available"), regnum); + return value; +} + void regcache_raw_write_signed (struct regcache *regcache, int regnum, LONGEST val) { diff --git a/gdb/regcache.h b/gdb/regcache.h index a9fb44b..c9d9a7d 100644 --- a/gdb/regcache.h +++ b/gdb/regcache.h @@ -81,6 +81,10 @@ extern enum register_status extern enum register_status regcache_raw_read_unsigned (struct regcache *regcache, int regnum, ULONGEST *val); + +ULONGEST regcache_raw_get_unsigned (struct regcache *regcache, + int regnum); + extern void regcache_raw_write_signed (struct regcache *regcache, int regnum, LONGEST val); extern void regcache_raw_write_unsigned (struct regcache *regcache, |