aboutsummaryrefslogtreecommitdiff
path: root/gdb/arm-tdep.c
diff options
context:
space:
mode:
authorRichard Earnshaw <richard.earnshaw@arm.com>2002-02-11 18:34:12 +0000
committerRichard Earnshaw <richard.earnshaw@arm.com>2002-02-11 18:34:12 +0000
commit34e8f22dedd07c590a17569cb64d928f21433560 (patch)
treef88af499b3d9b7e7efcc5fd121ffcc4e683f2b8b /gdb/arm-tdep.c
parent56930d376b3c19f44f084e9db6eecd0a5390e445 (diff)
downloadgdb-34e8f22dedd07c590a17569cb64d928f21433560.zip
gdb-34e8f22dedd07c590a17569cb64d928f21433560.tar.gz
gdb-34e8f22dedd07c590a17569cb64d928f21433560.tar.bz2
* arm-tdep.h: New file.
* arm-tdep.c: Include arm-tdep.h. (arm_addr_bits_remove, arm_smash_text_address, arm_saved_pc_after_call) (arm_skip_prologue, arm_call_dummy_words, arm_fix_call_dummy) (arm_print_float_info, arm_register_type, convert_to_extended) (arm_elf_make_msymbols_special, arm_coff_make_msymbol_special) (arm_extract_return_value, arm_register_name): Make static. (arm_software_single_step): Similarly. Fix types in declaration. (arm_register_byte, arm_register_raw_size, arm_register_virtual_size) (arm_store_return_value, arm_store_struct_return): New functions. (arm_gdbarch_init): Register the above functions. Also register call_dummy_start_offset, sizeof_call_dummy_words, function_start_offset, inner_than, decr_pc_after_break, fp_regnum, sp_regnum, pc_regnum, register_bytes, num_regs, max_register_raw_size, max_register_virtual_size, register_size. Set up prologue_cache.saved_regs here, rather than ... (_initialize_arm_tdep): ... here. * config/arm/tm-arm.h (struct type, struct value): Delete forward declarations. (arm_addr_bits_remove, arm_smash_text_address, arm_saved_pc_after_call) (arm_skip_prologue, arm_call_dummy_words, arm_fix_call_dummy) (arm_print_float_info, arm_register_type, convert_to_extended) (arm_elf_make_msymbols_special, arm_coff_make_msymbol_special) (arm_extract_return_value, arm_register_name): Delete declarations. (SMASH_TEXT_ADDRESS, ADDR_BITS_REMOVE, FUNCTION_START_OFFSET) (SKIP_PROLOGUE, SAVED_PC_AFTER_CALL, INNER_THAN, BREAKPOINT_FROM_PC) (DECR_PC_AFTER_BREAK, PRINT_FLOAT_INFO, REGISTER_SIZE, NUM_REGS) (REGISTER_NAME, REGISTER_BYTES, REGISTER_BYTE, REGISTER_RAW_SIZE) (REGISTER_VIRTUAL_SIZE, MAX_REGISTER_RAW_SIZE) (MAX_REGISTER_VIRTUAL_SIZE, REGISTER_VIRTUAL_TYPE, STORE_STRUCT_RETURN) (EXTRACT_RETURN_VALUE, STORE_RETURN_VALUE, CALL_DUMMY_WORDS) (SIZEOF_CALL_DUMMY_WORDS, CALL_DUMMY_START_OFFSET, FIX_CALL_DUMMY) (SOFTWARE_SINGLE_STEP_P, SOFTWARE_SINGLE_STEP) (ELF_MAKE_MSYMBOL_SPECIAL, COFF_MAKE_MSYMBOL_SPECIAL) Delete. (arm_pc_is_thumb, arm_pc_is_thumb_dummy, thumb_get_next_pc) (arm_get_next_pc): No-longer static -- these are needed by the RDI interface. * arm-linux-nat.c arm-linux-tdep.c armnbsd-nat.c: Include arm-tdep.h. * remote-rdi.c remote-rdp.c: Likewise. * Makefile.in (arm-linux-nat.o, arm-linux-tdep.o arm-tdep.o) (armnbsd-nat.o, remote-rdi.o, remote_rdp.o): Update dependencies. * config/arm/tm-nbsd.h (SOFTWARE_SINGLE_STEP_P): Delete bogus definition. * arm-tdep.h (ARM_A1_REGNUM, ARM_A4_REGNUM, ARM_AP_REGNUM) (ARM_SP_REGNUM, ARM_LR_REGNUM, ARM_PC_REGNUM, ARM_F0_REGNUM) (ARM_F3_REGNUM, ARM_F7_REGNUM, ARM_FPS_REGNUM, ARM_PS_REGNUM): Renamed from non-ARM_ prefixed definitions. * arm-tdep.c armnbsd-nat.c arm-linux-nat.c arm-linux-tdep.c: Update all uses of above. * remote-rdi.c remote-rdp.c: Likewise. * arm-linux-nat.c (ARM_CPSR_REGNUM): Renamed from CPSR_REGNUM.
Diffstat (limited to 'gdb/arm-tdep.c')
-rw-r--r--gdb/arm-tdep.c316
1 files changed, 241 insertions, 75 deletions
diff --git a/gdb/arm-tdep.c b/gdb/arm-tdep.c
index 9e38d02..169441e 100644
--- a/gdb/arm-tdep.c
+++ b/gdb/arm-tdep.c
@@ -19,6 +19,8 @@
Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
+#include <ctype.h> /* XXX for isupper () */
+
#include "defs.h"
#include "frame.h"
#include "inferior.h"
@@ -26,13 +28,15 @@
#include "gdbcore.h"
#include "symfile.h"
#include "gdb_string.h"
-#include "coff/internal.h" /* Internal format of COFF symbols in BFD */
#include "dis-asm.h" /* For register flavors. */
-#include <ctype.h> /* for isupper () */
#include "regcache.h"
#include "doublest.h"
#include "value.h"
+#include "arch-utils.h"
#include "solib-svr4.h"
+
+#include "arm-tdep.h"
+
#include "elf-bfd.h"
#include "coff/internal.h"
@@ -262,7 +266,7 @@ static int caller_is_thumb;
/* Determine if the program counter specified in MEMADDR is in a Thumb
function. */
-static int
+int
arm_pc_is_thumb (CORE_ADDR memaddr)
{
struct minimal_symbol *sym;
@@ -286,7 +290,7 @@ arm_pc_is_thumb (CORE_ADDR memaddr)
/* Determine if the program counter specified in MEMADDR is in a call
dummy being called from a Thumb function. */
-static int
+int
arm_pc_is_thumb_dummy (CORE_ADDR memaddr)
{
CORE_ADDR sp = read_sp ();
@@ -305,7 +309,7 @@ arm_pc_is_thumb_dummy (CORE_ADDR memaddr)
}
/* Remove useless bits from addresses in a running program. */
-CORE_ADDR
+static CORE_ADDR
arm_addr_bits_remove (CORE_ADDR val)
{
if (arm_pc_is_thumb (val))
@@ -316,16 +320,21 @@ arm_addr_bits_remove (CORE_ADDR val)
/* When reading symbols, we need to zap the low bit of the address,
which may be set to 1 for Thumb functions. */
-CORE_ADDR
+static CORE_ADDR
arm_smash_text_address (CORE_ADDR val)
{
return val & ~1;
}
-CORE_ADDR
+/* Immediately after a function call, return the saved pc. Can't
+ always go through the frames for this because on some machines the
+ new frame is not set up until the new function executes some
+ instructions. */
+
+static CORE_ADDR
arm_saved_pc_after_call (struct frame_info *frame)
{
- return ADDR_BITS_REMOVE (read_register (LR_REGNUM));
+ return ADDR_BITS_REMOVE (read_register (ARM_LR_REGNUM));
}
/* Determine whether the function invocation represented by FI has a
@@ -456,7 +465,10 @@ thumb_skip_prologue (CORE_ADDR pc, CORE_ADDR func_end)
return current_pc;
}
-/* The APCS (ARM Procedure Call Standard) defines the following
+/* Advance the PC across any function entry prologue instructions to reach
+ some "real" code.
+
+ The APCS (ARM Procedure Call Standard) defines the following
prologue:
mov ip, sp
@@ -468,7 +480,7 @@ thumb_skip_prologue (CORE_ADDR pc, CORE_ADDR func_end)
[stfe f4, [sp, #-12]!]
sub fp, ip, #nn @@ nn == 20 or 4 depending on second insn */
-CORE_ADDR
+static CORE_ADDR
arm_skip_prologue (CORE_ADDR pc)
{
unsigned long inst;
@@ -626,7 +638,7 @@ thumb_scan_prologue (struct frame_info *fi)
mask = (insn & 0xff) | ((insn & 0x100) << 6);
/* Calculate offsets of saved R0-R7 and LR. */
- for (regno = LR_REGNUM; regno >= 0; regno--)
+ for (regno = ARM_LR_REGNUM; regno >= 0; regno--)
if (mask & (1 << regno))
{
fi->extra_info->framesize += 4;
@@ -662,7 +674,7 @@ thumb_scan_prologue (struct frame_info *fi)
findmask |= 2; /* setting of r7 found */
fi->extra_info->framereg = THUMB_FP_REGNUM;
fi->extra_info->frameoffset = 0;
- saved_reg[THUMB_FP_REGNUM] = SP_REGNUM;
+ saved_reg[THUMB_FP_REGNUM] = ARM_SP_REGNUM;
}
else if ((insn & 0xffc0) == 0x4640) /* mov r0-r7, r8-r15 */
{
@@ -809,7 +821,7 @@ arm_scan_prologue (struct frame_info *fi)
return;
/* Assume there is no frame until proven otherwise. */
- fi->extra_info->framereg = SP_REGNUM;
+ fi->extra_info->framereg = ARM_SP_REGNUM;
fi->extra_info->framesize = 0;
fi->extra_info->frameoffset = 0;
@@ -910,7 +922,7 @@ arm_scan_prologue (struct frame_info *fi)
int mask = insn & 0xffff;
/* Calculate offsets of saved registers. */
- for (regno = PC_REGNUM; regno >= 0; regno--)
+ for (regno = ARM_PC_REGNUM; regno >= 0; regno--)
if (mask & (1 << regno))
{
sp_offset -= 4;
@@ -923,7 +935,7 @@ arm_scan_prologue (struct frame_info *fi)
unsigned rot = (insn & 0xf00) >> 7; /* rotate amount */
imm = (imm >> rot) | (imm << (32 - rot));
fp_offset = -imm;
- fi->extra_info->framereg = FP_REGNUM;
+ fi->extra_info->framereg = ARM_FP_REGNUM;
}
else if ((insn & 0xfffff000) == 0xe24dd000) /* sub sp, sp #n */
{
@@ -935,7 +947,7 @@ arm_scan_prologue (struct frame_info *fi)
else if ((insn & 0xffff7fff) == 0xed6d0103) /* stfe f?, [sp, -#c]! */
{
sp_offset -= 12;
- regno = F0_REGNUM + ((insn >> 12) & 0x07);
+ regno = ARM_F0_REGNUM + ((insn >> 12) & 0x07);
fi->saved_regs[regno] = sp_offset;
}
else if ((insn & 0xffbf0fff) == 0xec2d0200) /* sfmfd f0, 4, [sp!] */
@@ -958,7 +970,7 @@ arm_scan_prologue (struct frame_info *fi)
n_saved_fp_regs = 4;
}
- fp_start_reg = F0_REGNUM + ((insn >> 12) & 0x7);
+ fp_start_reg = ARM_F0_REGNUM + ((insn >> 12) & 0x7);
fp_bound_reg = fp_start_reg + n_saved_fp_regs;
for (; fp_start_reg < fp_bound_reg; fp_start_reg++)
{
@@ -980,7 +992,7 @@ arm_scan_prologue (struct frame_info *fi)
of the last thing thing we pushed on the stack. The frame offset is
[new FP] - [new SP]. */
fi->extra_info->framesize = -sp_offset;
- if (fi->extra_info->framereg == FP_REGNUM)
+ if (fi->extra_info->framereg == ARM_FP_REGNUM)
fi->extra_info->frameoffset = fp_offset - sp_offset;
else
fi->extra_info->frameoffset = 0;
@@ -1028,7 +1040,7 @@ arm_frame_chain (struct frame_info *fi)
/* is caller-of-this a dummy frame? */
callers_pc = FRAME_SAVED_PC (fi); /* find out who called us: */
- fp = arm_find_callers_reg (fi, FP_REGNUM);
+ fp = arm_find_callers_reg (fi, ARM_FP_REGNUM);
if (PC_IN_CALL_DUMMY (callers_pc, fp, fp))
return fp; /* dummy frame's frame may bear no relation to ours */
@@ -1081,7 +1093,7 @@ arm_frame_chain (struct frame_info *fi)
/* If the caller used a frame register, return its value.
Otherwise, return the caller's stack pointer. */
- if (framereg == FP_REGNUM || framereg == THUMB_FP_REGNUM)
+ if (framereg == ARM_FP_REGNUM || framereg == THUMB_FP_REGNUM)
return arm_find_callers_reg (fi, framereg);
else
return fi->frame + fi->extra_info->framesize;
@@ -1122,7 +1134,8 @@ arm_init_extra_frame_info (int fromleaf, struct frame_info *fi)
{
/* We need to setup fi->frame here because run_stack_dummy gets it wrong
by assuming it's always FP. */
- fi->frame = generic_read_register_dummy (fi->pc, fi->frame, SP_REGNUM);
+ fi->frame = generic_read_register_dummy (fi->pc, fi->frame,
+ ARM_SP_REGNUM);
fi->extra_info->framesize = 0;
fi->extra_info->frameoffset = 0;
return;
@@ -1157,7 +1170,7 @@ arm_init_extra_frame_info (int fromleaf, struct frame_info *fi)
fi->saved_regs[reg] = SIGCONTEXT_REGISTER_ADDRESS (sp, fi->pc, reg);
/* FIXME: What about thumb mode? */
- fi->extra_info->framereg = SP_REGNUM;
+ fi->extra_info->framereg = ARM_SP_REGNUM;
fi->frame =
read_memory_integer (fi->saved_regs[fi->extra_info->framereg],
REGISTER_RAW_SIZE (fi->extra_info->framereg));
@@ -1174,17 +1187,17 @@ arm_init_extra_frame_info (int fromleaf, struct frame_info *fi)
rp = fi->frame - REGISTER_SIZE;
/* Fill in addresses of saved registers. */
- fi->saved_regs[PS_REGNUM] = rp;
- rp -= REGISTER_RAW_SIZE (PS_REGNUM);
- for (reg = PC_REGNUM; reg >= 0; reg--)
+ fi->saved_regs[ARM_PS_REGNUM] = rp;
+ rp -= REGISTER_RAW_SIZE (ARM_PS_REGNUM);
+ for (reg = ARM_PC_REGNUM; reg >= 0; reg--)
{
fi->saved_regs[reg] = rp;
rp -= REGISTER_RAW_SIZE (reg);
}
- callers_sp = read_memory_integer (fi->saved_regs[SP_REGNUM],
- REGISTER_RAW_SIZE (SP_REGNUM));
- fi->extra_info->framereg = FP_REGNUM;
+ callers_sp = read_memory_integer (fi->saved_regs[ARM_SP_REGNUM],
+ REGISTER_RAW_SIZE (ARM_SP_REGNUM));
+ fi->extra_info->framereg = ARM_FP_REGNUM;
fi->extra_info->framesize = callers_sp - sp;
fi->extra_info->frameoffset = fi->frame - sp;
}
@@ -1195,7 +1208,7 @@ arm_init_extra_frame_info (int fromleaf, struct frame_info *fi)
if (!fi->next)
/* this is the innermost frame? */
fi->frame = read_register (fi->extra_info->framereg);
- else if (fi->extra_info->framereg == FP_REGNUM
+ else if (fi->extra_info->framereg == ARM_FP_REGNUM
|| fi->extra_info->framereg == THUMB_FP_REGNUM)
{
/* not the innermost frame */
@@ -1220,7 +1233,7 @@ arm_init_extra_frame_info (int fromleaf, struct frame_info *fi)
}
-/* Find the caller of this frame. We do this by seeing if LR_REGNUM
+/* Find the caller of this frame. We do this by seeing if ARM_LR_REGNUM
is saved in the stack anywhere, otherwise we get it from the
registers.
@@ -1233,18 +1246,18 @@ arm_frame_saved_pc (struct frame_info *fi)
{
#if 0 /* FIXME: enable this code if we convert to new call dummy scheme. */
if (PC_IN_CALL_DUMMY (fi->pc, fi->frame, fi->frame))
- return generic_read_register_dummy (fi->pc, fi->frame, PC_REGNUM);
+ return generic_read_register_dummy (fi->pc, fi->frame, ARM_PC_REGNUM);
else
#endif
if (PC_IN_CALL_DUMMY (fi->pc, fi->frame - fi->extra_info->frameoffset,
fi->frame))
{
- return read_memory_integer (fi->saved_regs[PC_REGNUM],
- REGISTER_RAW_SIZE (PC_REGNUM));
+ return read_memory_integer (fi->saved_regs[ARM_PC_REGNUM],
+ REGISTER_RAW_SIZE (ARM_PC_REGNUM));
}
else
{
- CORE_ADDR pc = arm_find_callers_reg (fi, LR_REGNUM);
+ CORE_ADDR pc = arm_find_callers_reg (fi, ARM_LR_REGNUM);
return IS_THUMB_ADDR (pc) ? UNMAKE_THUMB_ADDR (pc) : pc;
}
}
@@ -1255,10 +1268,10 @@ arm_frame_saved_pc (struct frame_info *fi)
static CORE_ADDR
arm_read_fp (void)
{
- if (read_register (PS_REGNUM) & 0x20) /* Bit 5 is Thumb state bit */
+ if (read_register (ARM_PS_REGNUM) & 0x20) /* Bit 5 is Thumb state bit */
return read_register (THUMB_FP_REGNUM); /* R7 if Thumb */
else
- return read_register (FP_REGNUM); /* R11 if ARM */
+ return read_register (ARM_FP_REGNUM); /* R11 if ARM */
}
/* Store into a struct frame_saved_regs the addresses of the saved
@@ -1282,7 +1295,7 @@ arm_frame_init_saved_regs (struct frame_info *fip)
static void
arm_push_dummy_frame (void)
{
- CORE_ADDR old_sp = read_register (SP_REGNUM);
+ CORE_ADDR old_sp = read_register (ARM_SP_REGNUM);
CORE_ADDR sp = old_sp;
CORE_ADDR fp, prologue_start;
int regnum;
@@ -1300,16 +1313,16 @@ arm_push_dummy_frame (void)
fp = sp = push_word (sp, prologue_start + 12);
/* Push the processor status. */
- sp = push_word (sp, read_register (PS_REGNUM));
+ sp = push_word (sp, read_register (ARM_PS_REGNUM));
/* Push all 16 registers starting with r15. */
- for (regnum = PC_REGNUM; regnum >= 0; regnum--)
+ for (regnum = ARM_PC_REGNUM; regnum >= 0; regnum--)
sp = push_word (sp, read_register (regnum));
/* Update fp (for both Thumb and ARM) and sp. */
- write_register (FP_REGNUM, fp);
+ write_register (ARM_FP_REGNUM, fp);
write_register (THUMB_FP_REGNUM, fp);
- write_register (SP_REGNUM, sp);
+ write_register (ARM_SP_REGNUM, sp);
}
/* CALL_DUMMY_WORDS:
@@ -1321,7 +1334,7 @@ arm_push_dummy_frame (void)
Note this is 12 bytes. */
-LONGEST arm_call_dummy_words[] =
+static LONGEST arm_call_dummy_words[] =
{
0xe1a0e00f, 0xe1a0f004, 0xe7ffdefe
};
@@ -1341,7 +1354,7 @@ LONGEST arm_call_dummy_words[] =
All three call dummies expect to receive the target function
address in R4, with the low bit set if it's a Thumb function. */
-void
+static void
arm_fix_call_dummy (char *dummy, CORE_ADDR pc, CORE_ADDR fun, int nargs,
struct value **args, struct type *type, int gcc_p)
{
@@ -1452,7 +1465,7 @@ arm_push_arguments (int nargs, struct value **args, CORE_ADDR sp,
}
/* Initialize the integer argument register pointer. */
- argreg = A1_REGNUM;
+ argreg = ARM_A1_REGNUM;
/* The struct_return pointer occupies the first parameter passing
register. */
@@ -1553,8 +1566,8 @@ arm_pop_frame (void)
read_memory_integer (frame->saved_regs[regnum],
REGISTER_RAW_SIZE (regnum)));
- write_register (PC_REGNUM, FRAME_SAVED_PC (frame));
- write_register (SP_REGNUM, old_SP);
+ write_register (ARM_PC_REGNUM, FRAME_SAVED_PC (frame));
+ write_register (ARM_SP_REGNUM, old_SP);
flush_cached_frames ();
}
@@ -1577,10 +1590,10 @@ print_fpu_flags (int flags)
/* Print interesting information about the floating point processor
(if present) or emulator. */
-void
+static void
arm_print_float_info (void)
{
- register unsigned long status = read_register (FPS_REGNUM);
+ register unsigned long status = read_register (ARM_FPS_REGNUM);
int type;
type = (status >> 24) & 127;
@@ -1593,10 +1606,13 @@ arm_print_float_info (void)
print_fpu_flags (status);
}
-struct type *
+/* Return the GDB type object for the "standard" data type of data in
+ register N. */
+
+static struct type *
arm_register_type (int regnum)
{
- if (regnum >= F0_REGNUM && regnum < F0_REGNUM + NUM_FREGS)
+ if (regnum >= ARM_F0_REGNUM && regnum < ARM_F0_REGNUM + NUM_FREGS)
{
if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
return builtin_type_arm_ext_big;
@@ -1607,6 +1623,52 @@ arm_register_type (int regnum)
return builtin_type_int32;
}
+/* Index within `registers' of the first byte of the space for
+ register N. */
+
+static int
+arm_register_byte (int regnum)
+{
+ if (regnum < ARM_F0_REGNUM)
+ return regnum * INT_REGISTER_RAW_SIZE;
+ else if (regnum < ARM_PS_REGNUM)
+ return (NUM_GREGS * INT_REGISTER_RAW_SIZE
+ + (regnum - ARM_F0_REGNUM) * FP_REGISTER_RAW_SIZE);
+ else
+ return (NUM_GREGS * INT_REGISTER_RAW_SIZE
+ + NUM_FREGS * FP_REGISTER_RAW_SIZE
+ + (regnum - ARM_FPS_REGNUM) * STATUS_REGISTER_SIZE);
+}
+
+/* Number of bytes of storage in the actual machine representation for
+ register N. All registers are 4 bytes, except fp0 - fp7, which are
+ 12 bytes in length. */
+
+static int
+arm_register_raw_size (int regnum)
+{
+ if (regnum < ARM_F0_REGNUM)
+ return INT_REGISTER_RAW_SIZE;
+ else if (regnum < ARM_FPS_REGNUM)
+ return FP_REGISTER_RAW_SIZE;
+ else
+ return STATUS_REGISTER_SIZE;
+}
+
+/* Number of bytes of storage in a program's representation
+ for register N. */
+static int
+arm_register_virtual_size (int regnum)
+{
+ if (regnum < ARM_F0_REGNUM)
+ return INT_REGISTER_VIRTUAL_SIZE;
+ else if (regnum < ARM_FPS_REGNUM)
+ return FP_REGISTER_VIRTUAL_SIZE;
+ else
+ return STATUS_REGISTER_SIZE;
+}
+
+
/* NOTE: cagney/2001-08-20: Both convert_from_extended() and
convert_to_extended() use floatformat_arm_ext_littlebyte_bigword.
It is thought that this is is the floating-point register format on
@@ -1624,7 +1686,7 @@ convert_from_extended (void *ptr, void *dbl)
floatformat_from_doublest (TARGET_DOUBLE_FORMAT, &d, dbl);
}
-void
+static void
convert_to_extended (void *dbl, void *ptr)
{
DOUBLEST d;
@@ -1749,7 +1811,7 @@ bitcount (unsigned long val)
return nbits;
}
-static CORE_ADDR
+CORE_ADDR
thumb_get_next_pc (CORE_ADDR pc)
{
unsigned long pc_val = ((unsigned long) pc) + 4; /* PC after prefetch */
@@ -1764,7 +1826,7 @@ thumb_get_next_pc (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)) * REGISTER_SIZE;
- sp = read_register (SP_REGNUM);
+ sp = read_register (ARM_SP_REGNUM);
nextpc = (CORE_ADDR) read_memory_integer (sp + offset, 4);
nextpc = ADDR_BITS_REMOVE (nextpc);
if (nextpc == pc)
@@ -1772,7 +1834,7 @@ thumb_get_next_pc (CORE_ADDR pc)
}
else if ((inst1 & 0xf000) == 0xd000) /* conditional branch */
{
- unsigned long status = read_register (PS_REGNUM);
+ unsigned long status = read_register (ARM_PS_REGNUM);
unsigned long cond = bits (inst1, 8, 11);
if (cond != 0x0f && condition_true (cond, status)) /* 0x0f = SWI */
nextpc = pc_val + (sbits (inst1, 0, 7) << 1);
@@ -1791,7 +1853,7 @@ thumb_get_next_pc (CORE_ADDR pc)
return nextpc;
}
-static CORE_ADDR
+CORE_ADDR
arm_get_next_pc (CORE_ADDR pc)
{
unsigned long pc_val;
@@ -1804,7 +1866,7 @@ arm_get_next_pc (CORE_ADDR pc)
pc_val = (unsigned long) pc;
this_instr = read_memory_integer (pc, 4);
- status = read_register (PS_REGNUM);
+ status = read_register (ARM_PS_REGNUM);
nextpc = (CORE_ADDR) (pc_val + 4); /* Default case */
if (condition_true (bits (this_instr, 28, 31), status))
@@ -2021,15 +2083,15 @@ arm_get_next_pc (CORE_ADDR pc)
single_step is also called just after the inferior stops. If we had
set up a simulated single-step, we undo our damage. */
-void
-arm_software_single_step (int ignore, int insert_bpt)
+static void
+arm_software_single_step (enum target_signal sig, int insert_bpt)
{
static int next_pc; /* State between setting and unsetting. */
static char break_mem[BREAKPOINT_MAX]; /* Temporary storage for mem@bpt */
if (insert_bpt)
{
- next_pc = arm_get_next_pc (read_register (PC_REGNUM));
+ next_pc = arm_get_next_pc (read_register (ARM_PC_REGNUM));
target_insert_breakpoint (next_pc, break_mem);
}
else
@@ -2078,14 +2140,19 @@ gdb_print_insn_arm (bfd_vma memaddr, disassemble_info *info)
return print_insn_little_arm (memaddr, info);
}
-/* This function implements the BREAKPOINT_FROM_PC macro. It uses the
- program counter value to determine whether a 16-bit or 32-bit
+/* Determine the type and size of breakpoint to insert at PCPTR. Uses
+ the program counter value to determine whether a 16-bit or 32-bit
breakpoint should be used. It returns a pointer to a string of
bytes that encode a breakpoint instruction, stores the length of
the string to *lenptr, and adjusts the program counter (if
necessary) to point to the actual memory location where the
breakpoint should be inserted. */
+/* XXX ??? from old tm-arm.h: if we're using RDP, then we're inserting
+ breakpoints and storing their handles instread of what was in
+ memory. It is nice that this is the same size as a handle -
+ otherwise remote-rdp will have to change. */
+
unsigned char *
arm_breakpoint_from_pc (CORE_ADDR *pcptr, int *lenptr)
{
@@ -2127,15 +2194,44 @@ arm_breakpoint_from_pc (CORE_ADDR *pcptr, int *lenptr)
function return value of type TYPE, and copy that, in virtual
format, into VALBUF. */
-void
+static void
arm_extract_return_value (struct type *type,
char regbuf[REGISTER_BYTES],
char *valbuf)
{
if (TYPE_CODE_FLT == TYPE_CODE (type))
- convert_from_extended (&regbuf[REGISTER_BYTE (F0_REGNUM)], valbuf);
+ convert_from_extended (&regbuf[REGISTER_BYTE (ARM_F0_REGNUM)], valbuf);
else
- memcpy (valbuf, &regbuf[REGISTER_BYTE (A1_REGNUM)], TYPE_LENGTH (type));
+ memcpy (valbuf, &regbuf[REGISTER_BYTE (ARM_A1_REGNUM)],
+ TYPE_LENGTH (type));
+}
+
+/* Write into appropriate registers a function return value of type
+ TYPE, given in virtual format. */
+
+static void
+arm_store_return_value (struct type *type, char *valbuf)
+{
+ if (TYPE_CODE (type) == TYPE_CODE_FLT)
+ {
+ char buf[MAX_REGISTER_RAW_SIZE];
+
+ convert_to_extended (valbuf, buf);
+ /* XXX Is this correct for soft-float? */
+ write_register_bytes (REGISTER_BYTE (ARM_F0_REGNUM), buf,
+ MAX_REGISTER_RAW_SIZE);
+ }
+ else
+ write_register_bytes (0, valbuf, TYPE_LENGTH (type));
+}
+
+/* Store the address of the place in which to copy the structure the
+ subroutine will return. This is called from call_function. */
+
+static void
+arm_store_struct_return (CORE_ADDR addr, CORE_ADDR sp)
+{
+ write_register (ARM_A1_REGNUM, addr);
}
/* Return non-zero if the PC is inside a thumb call thunk. */
@@ -2200,8 +2296,8 @@ set_disassembly_flavor_sfunc (char *args, int from_tty,
}
/* Return the ARM register name corresponding to register I. */
-char *
-arm_register_name(int i)
+static char *
+arm_register_name (int i)
{
return arm_register_names[i];
}
@@ -2225,15 +2321,15 @@ set_disassembly_flavor (void)
arm_register_names[j] = (char *) regnames[j];
/* Adjust case. */
- if (isupper (*regnames[PC_REGNUM]))
+ if (isupper (*regnames[ARM_PC_REGNUM]))
{
- arm_register_names[FPS_REGNUM] = "FPS";
- arm_register_names[PS_REGNUM] = "CPSR";
+ arm_register_names[ARM_FPS_REGNUM] = "FPS";
+ arm_register_names[ARM_PS_REGNUM] = "CPSR";
}
else
{
- arm_register_names[FPS_REGNUM] = "fps";
- arm_register_names[PS_REGNUM] = "cpsr";
+ arm_register_names[ARM_FPS_REGNUM] = "fps";
+ arm_register_names[ARM_PS_REGNUM] = "cpsr";
}
/* Synchronize the disassembler. */
@@ -2318,7 +2414,7 @@ coff_sym_is_thumb (int val)
an address in thumb code, and set a "special" bit in a minimal
symbol to indicate that it does. */
-void
+static void
arm_elf_make_msymbol_special(asymbol *sym, struct minimal_symbol *msym)
{
/* Thumb symbols are of type STT_LOPROC, (synonymous with
@@ -2328,7 +2424,7 @@ arm_elf_make_msymbol_special(asymbol *sym, struct minimal_symbol *msym)
MSYMBOL_SET_SPECIAL (msym);
}
-void
+static void
arm_coff_make_msymbol_special(int val, struct minimal_symbol *msym)
{
if (coff_sym_is_thumb (val))
@@ -2354,6 +2450,12 @@ arm_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
set_gdbarch_call_dummy_p (gdbarch, 1);
set_gdbarch_call_dummy_stack_adjust_p (gdbarch, 0);
+ set_gdbarch_call_dummy_words (gdbarch, arm_call_dummy_words);
+ set_gdbarch_sizeof_call_dummy_words (gdbarch, sizeof (arm_call_dummy_words));
+ set_gdbarch_call_dummy_start_offset (gdbarch, 0);
+
+ set_gdbarch_fix_call_dummy (gdbarch, arm_fix_call_dummy);
+
set_gdbarch_pc_in_call_dummy (gdbarch, pc_in_call_dummy_on_stack);
set_gdbarch_get_saved_register (gdbarch, generic_get_saved_register);
@@ -2375,6 +2477,71 @@ arm_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
set_gdbarch_push_dummy_frame (gdbarch, arm_push_dummy_frame);
set_gdbarch_pop_frame (gdbarch, arm_pop_frame);
+ /* Address manipulation. */
+ set_gdbarch_smash_text_address (gdbarch, arm_smash_text_address);
+ set_gdbarch_addr_bits_remove (gdbarch, arm_addr_bits_remove);
+
+ /* Offset from address of function to start of its code. */
+ set_gdbarch_function_start_offset (gdbarch, 0);
+
+ /* Advance PC across function entry code. */
+ set_gdbarch_skip_prologue (gdbarch, arm_skip_prologue);
+
+ /* Get the PC when a frame might not be available. */
+ set_gdbarch_saved_pc_after_call (gdbarch, arm_saved_pc_after_call);
+
+ /* The stack grows downward. */
+ set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
+
+ /* Breakpoint manipulation. */
+ set_gdbarch_breakpoint_from_pc (gdbarch, arm_breakpoint_from_pc);
+ set_gdbarch_decr_pc_after_break (gdbarch, 0);
+
+ /* Information about registers, etc. */
+ set_gdbarch_print_float_info (gdbarch, arm_print_float_info);
+ set_gdbarch_fp_regnum (gdbarch, ARM_FP_REGNUM); /* ??? */
+ set_gdbarch_sp_regnum (gdbarch, ARM_SP_REGNUM);
+ set_gdbarch_pc_regnum (gdbarch, ARM_PC_REGNUM);
+ set_gdbarch_register_byte (gdbarch, arm_register_byte);
+ set_gdbarch_register_bytes (gdbarch,
+ (NUM_GREGS * INT_REGISTER_RAW_SIZE
+ + NUM_FREGS * FP_REGISTER_RAW_SIZE
+ + NUM_SREGS * STATUS_REGISTER_SIZE));
+ set_gdbarch_num_regs (gdbarch, NUM_GREGS + NUM_FREGS + NUM_SREGS);
+ set_gdbarch_register_raw_size (gdbarch, arm_register_raw_size);
+ set_gdbarch_register_virtual_size (gdbarch, arm_register_virtual_size);
+ set_gdbarch_max_register_raw_size (gdbarch, FP_REGISTER_RAW_SIZE);
+ set_gdbarch_max_register_virtual_size (gdbarch, FP_REGISTER_VIRTUAL_SIZE);
+ set_gdbarch_register_virtual_type (gdbarch, arm_register_type);
+
+ /* Integer registers are 4 bytes. */
+ set_gdbarch_register_size (gdbarch, 4);
+ set_gdbarch_register_name (gdbarch, arm_register_name);
+
+ /* Returning results. */
+ set_gdbarch_extract_return_value (gdbarch, arm_extract_return_value);
+ set_gdbarch_store_return_value (gdbarch, arm_store_return_value);
+ set_gdbarch_store_struct_return (gdbarch, arm_store_struct_return);
+
+ /* Single stepping. */
+ /* XXX For an RDI target we should ask the target if it can single-step. */
+ set_gdbarch_software_single_step (gdbarch, arm_software_single_step);
+
+ /* Minsymbol frobbing. */
+ set_gdbarch_elf_make_msymbol_special (gdbarch, arm_elf_make_msymbol_special);
+ set_gdbarch_coff_make_msymbol_special (gdbarch,
+ arm_coff_make_msymbol_special);
+
+ /* XXX We can't do this until NUM_REGS is set for the architecture.
+ Even then, we can't use SIZEOF_FRAME_SAVED_REGS, since that still
+ references the old architecture vector, not the one we are
+ building here. */
+ if (prologue_cache.saved_regs != NULL)
+ xfree (prologue_cache.saved_regs);
+
+ prologue_cache.saved_regs = (CORE_ADDR *)
+ xcalloc (1, (sizeof (CORE_ADDR)
+ * (NUM_GREGS + NUM_FREGS + NUM_SREGS + NUM_PSEUDO_REGS)));
return gdbarch;
}
@@ -2454,8 +2621,7 @@ The valid values are:\n");
"Switch to the next set of register names.");
/* Fill in the prologue_cache fields. */
+ prologue_cache.saved_regs = NULL;
prologue_cache.extra_info = (struct frame_extra_info *)
xcalloc (1, sizeof (struct frame_extra_info));
- prologue_cache.saved_regs = (CORE_ADDR *)
- xcalloc (1, SIZEOF_FRAME_SAVED_REGS);
}