diff options
author | Richard Earnshaw <richard.earnshaw@arm.com> | 2002-02-11 18:34:12 +0000 |
---|---|---|
committer | Richard Earnshaw <richard.earnshaw@arm.com> | 2002-02-11 18:34:12 +0000 |
commit | 34e8f22dedd07c590a17569cb64d928f21433560 (patch) | |
tree | f88af499b3d9b7e7efcc5fd121ffcc4e683f2b8b /gdb/arm-tdep.c | |
parent | 56930d376b3c19f44f084e9db6eecd0a5390e445 (diff) | |
download | gdb-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.c | 316 |
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 (®buf[REGISTER_BYTE (F0_REGNUM)], valbuf); + convert_from_extended (®buf[REGISTER_BYTE (ARM_F0_REGNUM)], valbuf); else - memcpy (valbuf, ®buf[REGISTER_BYTE (A1_REGNUM)], TYPE_LENGTH (type)); + memcpy (valbuf, ®buf[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); } |