diff options
author | Richard Earnshaw <richard.earnshaw@arm.com> | 2002-02-15 16:12:24 +0000 |
---|---|---|
committer | Richard Earnshaw <richard.earnshaw@arm.com> | 2002-02-15 16:12:24 +0000 |
commit | 66e810cd098c57a4483f33cedc272486506eb485 (patch) | |
tree | 4f63c94878bbbe7303466f05708c5915015e2c33 /gdb/arm-tdep.c | |
parent | 97e03143bb83533b4cf4fcd9d283b05722b4c128 (diff) | |
download | gdb-66e810cd098c57a4483f33cedc272486506eb485.zip gdb-66e810cd098c57a4483f33cedc272486506eb485.tar.gz gdb-66e810cd098c57a4483f33cedc272486506eb485.tar.bz2 |
* arm-tdep.h (struct gdbarch_tdep): Add fields for breakpoint
descriptions.
* arm-tdep.c (arm_default_arm_le_breakpoint)
(arm_default_arm_be_breakpoint, arm_default_thumb_le_breakpoint)
(arm_default_thumb_be_breakpoint): New. Initialize them from
traditional breakpoint defines.
(arm_breakpoint_from_pc): Use new gdbarch_tdep entries.
(arm_gdbarch_init): Initialize new breakpoint variables.
* arm-linux-tdep.c (arm_linux_arm_le_breakpoint): New.
(arm_linux_init_abi): Initialize linux-specific breakpoint.
* armnbsd-tdep.c (arm_nbsd_arm_le_breakpoint): New.
(arm_netbsd_aout_init_abi, arm_netbsd_elf_init_abi): Split common
code out to ...
(arm_netbsd_init_abi_common): ... here; new function.
* config/arm/tm-arm.h (ARM_LE_BREAKPOINT, ARM_BE_BREAKPOINT)
(THUMB_LE_BREAKPOINT, THUMB_BE_BREAKPOINT): Delete.
* config/arm/tm-linux.h (ARM_LE_BREAKPOINT): Delete.
* config/arm/tm-nbsd.h (ARM_LE_BREAKPOINT): Delete.
Diffstat (limited to 'gdb/arm-tdep.c')
-rw-r--r-- | gdb/arm-tdep.c | 97 |
1 files changed, 70 insertions, 27 deletions
diff --git a/gdb/arm-tdep.c b/gdb/arm-tdep.c index 9577f0a..a60f497 100644 --- a/gdb/arm-tdep.c +++ b/gdb/arm-tdep.c @@ -2044,6 +2044,56 @@ gdb_print_insn_arm (bfd_vma memaddr, disassemble_info *info) return print_insn_little_arm (memaddr, info); } +/* The following define instruction sequences that will cause ARM + cpu's to take an undefined instruction trap. These are used to + signal a breakpoint to GDB. + + The newer ARMv4T cpu's are capable of operating in ARM or Thumb + modes. A different instruction is required for each mode. The ARM + cpu's can also be big or little endian. Thus four different + instructions are needed to support all cases. + + Note: ARMv4 defines several new instructions that will take the + undefined instruction trap. ARM7TDMI is nominally ARMv4T, but does + not in fact add the new instructions. The new undefined + instructions in ARMv4 are all instructions that had no defined + behaviour in earlier chips. There is no guarantee that they will + raise an exception, but may be treated as NOP's. In practice, it + may only safe to rely on instructions matching: + + 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 + 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 + C C C C 0 1 1 x x x x x x x x x x x x x x x x x x x x 1 x x x x + + Even this may only true if the condition predicate is true. The + following use a condition predicate of ALWAYS so it is always TRUE. + + There are other ways of forcing a breakpoint. GNU/Linux, RISC iX, + and NetBSD all use a software interrupt rather than an undefined + instruction to force a trap. This can be handled by by the + abi-specific code during establishment of the gdbarch vector. */ + + +/* XXX for now we allow a non-multi-arch gdb to override these + definitions. */ +#ifndef ARM_LE_BREAKPOINT +#define ARM_LE_BREAKPOINT {0xFE,0xDE,0xFF,0xE7} +#endif +#ifndef ARM_BE_BREAKPOINT +#define ARM_BE_BREAKPOINT {0xE7,0xFF,0xDE,0xFE} +#endif +#ifndef THUMB_LE_BREAKPOINT +#define THUMB_LE_BREAKPOINT {0xfe,0xdf} +#endif +#ifndef THUMB_BE_BREAKPOINT +#define THUMB_BE_BREAKPOINT {0xdf,0xfe} +#endif + +static const char arm_default_arm_le_breakpoint[] = ARM_LE_BREAKPOINT; +static const char arm_default_arm_be_breakpoint[] = ARM_BE_BREAKPOINT; +static const char arm_default_thumb_le_breakpoint[] = THUMB_LE_BREAKPOINT; +static const char arm_default_thumb_be_breakpoint[] = THUMB_BE_BREAKPOINT; + /* 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 @@ -2060,37 +2110,18 @@ gdb_print_insn_arm (bfd_vma memaddr, disassemble_info *info) unsigned char * arm_breakpoint_from_pc (CORE_ADDR *pcptr, int *lenptr) { + struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); + if (arm_pc_is_thumb (*pcptr) || arm_pc_is_thumb_dummy (*pcptr)) { - if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG) - { - static char thumb_breakpoint[] = THUMB_BE_BREAKPOINT; - *pcptr = UNMAKE_THUMB_ADDR (*pcptr); - *lenptr = sizeof (thumb_breakpoint); - return thumb_breakpoint; - } - else - { - static char thumb_breakpoint[] = THUMB_LE_BREAKPOINT; - *pcptr = UNMAKE_THUMB_ADDR (*pcptr); - *lenptr = sizeof (thumb_breakpoint); - return thumb_breakpoint; - } + *pcptr = UNMAKE_THUMB_ADDR (*pcptr); + *lenptr = tdep->thumb_breakpoint_size; + return tdep->thumb_breakpoint; } else { - if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG) - { - static char arm_breakpoint[] = ARM_BE_BREAKPOINT; - *lenptr = sizeof (arm_breakpoint); - return arm_breakpoint; - } - else - { - static char arm_breakpoint[] = ARM_LE_BREAKPOINT; - *lenptr = sizeof (arm_breakpoint); - return arm_breakpoint; - } + *lenptr = tdep->arm_breakpoint_size; + return tdep->arm_breakpoint; } } @@ -2710,21 +2741,33 @@ arm_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) tdep->abi_name = "<invalid>"; } - /* Floating point sizes and format. */ + /* Breakpoints and floating point sizes and format. */ switch (info.byte_order) { case BFD_ENDIAN_BIG: + tdep->arm_breakpoint = arm_default_arm_be_breakpoint; + tdep->arm_breakpoint_size = sizeof (arm_default_arm_be_breakpoint); + tdep->thumb_breakpoint = arm_default_thumb_be_breakpoint; + tdep->thumb_breakpoint_size = sizeof (arm_default_thumb_be_breakpoint); + set_gdbarch_float_format (gdbarch, &floatformat_ieee_single_big); set_gdbarch_double_format (gdbarch, &floatformat_ieee_double_big); set_gdbarch_long_double_format (gdbarch, &floatformat_ieee_double_big); + break; case BFD_ENDIAN_LITTLE: + tdep->arm_breakpoint = arm_default_arm_le_breakpoint; + tdep->arm_breakpoint_size = sizeof (arm_default_arm_le_breakpoint); + tdep->thumb_breakpoint = arm_default_thumb_le_breakpoint; + tdep->thumb_breakpoint_size = sizeof (arm_default_thumb_le_breakpoint); + set_gdbarch_float_format (gdbarch, &floatformat_ieee_single_little); set_gdbarch_double_format (gdbarch, &floatformat_ieee_double_littlebyte_bigword); set_gdbarch_long_double_format (gdbarch, &floatformat_ieee_double_littlebyte_bigword); + break; default: |