aboutsummaryrefslogtreecommitdiff
path: root/gdb
diff options
context:
space:
mode:
Diffstat (limited to 'gdb')
-rw-r--r--gdb/ChangeLog22
-rw-r--r--gdb/arm-linux-tdep.c109
-rw-r--r--gdb/arm-tdep.c132
-rw-r--r--gdb/arm-tdep.h9
-rw-r--r--gdb/regcache.c15
-rw-r--r--gdb/regcache.h4
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,