/* Common target dependent code for GDB on ARM systems.
- Copyright (C) 1988-2016 Free Software Foundation, Inc.
+ Copyright (C) 1988-2017 Free Software Foundation, Inc.
This file is part of GDB.
#include "gdbcmd.h"
#include "gdbcore.h"
#include "dis-asm.h" /* For register styles. */
+#include "disasm.h"
#include "regcache.h"
#include "reggroups.h"
#include "doublest.h"
#include "record.h"
#include "record-full.h"
+#include <algorithm>
-#include "features/arm-with-m.c"
-#include "features/arm-with-m-fpa-layout.c"
-#include "features/arm-with-m-vfp-d16.c"
-#include "features/arm-with-iwmmxt.c"
-#include "features/arm-with-vfpv2.c"
-#include "features/arm-with-vfpv3.c"
-#include "features/arm-with-neon.c"
+#include "features/arm/arm-with-m.c"
+#include "features/arm/arm-with-m-fpa-layout.c"
+#include "features/arm/arm-with-m-vfp-d16.c"
+#include "features/arm/arm-with-iwmmxt.c"
+#include "features/arm/arm-with-vfpv2.c"
+#include "features/arm/arm-with-vfpv3.c"
+#include "features/arm/arm-with-neon.c"
static int arm_debug;
static const char *arm_fallback_mode_string = "auto";
static const char *arm_force_mode_string = "auto";
-/* Internal override of the execution mode. -1 means no override,
- 0 means override to ARM mode, 1 means override to Thumb mode.
- The effect is the same as if arm_force_mode has been set by the
- user (except the internal override has precedence over a user's
- arm_force_mode override). */
-static int arm_override_mode = -1;
-
-/* Number of different reg name sets (options). */
-static int num_disassembly_options;
-
/* The standard register names, and all the valid aliases for them. Note
that `fp', `sp' and `pc' are not added in this alias list, because they
have been added as builtin user registers in
"f4", "f5", "f6", "f7", /* 20 21 22 23 */
"fps", "cpsr" }; /* 24 25 */
+/* Holds the current set of options to be passed to the disassembler. */
+static char *arm_disassembler_options;
+
/* Valid register name styles. */
static const char **valid_disassembly_styles;
style. */
static void set_disassembly_style_sfunc(char *, int,
struct cmd_list_element *);
-static void set_disassembly_style (void);
+static void show_disassembly_style_sfunc (struct ui_file *, int,
+ struct cmd_list_element *,
+ const char *);
static void convert_from_extended (const struct floatformat *, const void *,
void *, int);
if (IS_THUMB_ADDR (memaddr))
return 1;
- /* Respect internal mode override if active. */
- if (arm_override_mode != -1)
- return arm_override_mode;
-
/* If the user wants to override the symbol table, let him. */
if (strcmp (arm_force_mode_string, "arm") == 0)
return 0;
return 0;
}
+/* Determine if the address specified equals any of these magic return
+ values, called EXC_RETURN, defined by the ARM v6-M and v7-M
+ architectures.
+
+ From ARMv6-M Reference Manual B1.5.8
+ Table B1-5 Exception return behavior
+
+ EXC_RETURN Return To Return Stack
+ 0xFFFFFFF1 Handler mode Main
+ 0xFFFFFFF9 Thread mode Main
+ 0xFFFFFFFD Thread mode Process
+
+ From ARMv7-M Reference Manual B1.5.8
+ Table B1-8 EXC_RETURN definition of exception return behavior, no FP
+
+ EXC_RETURN Return To Return Stack
+ 0xFFFFFFF1 Handler mode Main
+ 0xFFFFFFF9 Thread mode Main
+ 0xFFFFFFFD Thread mode Process
+
+ Table B1-9 EXC_RETURN definition of exception return behavior, with
+ FP
+
+ EXC_RETURN Return To Return Stack Frame Type
+ 0xFFFFFFE1 Handler mode Main Extended
+ 0xFFFFFFE9 Thread mode Main Extended
+ 0xFFFFFFED Thread mode Process Extended
+ 0xFFFFFFF1 Handler mode Main Basic
+ 0xFFFFFFF9 Thread mode Main Basic
+ 0xFFFFFFFD Thread mode Process Basic
+
+ For more details see "B1.5.8 Exception return behavior"
+ in both ARMv6-M and ARMv7-M Architecture Reference Manuals. */
+
+static int
+arm_m_addr_is_magic (CORE_ADDR addr)
+{
+ switch (addr)
+ {
+ /* Values from Tables in B1.5.8 the EXC_RETURN definitions of
+ the exception return behavior. */
+ case 0xffffffe1:
+ case 0xffffffe9:
+ case 0xffffffed:
+ case 0xfffffff1:
+ case 0xfffffff9:
+ case 0xfffffffd:
+ /* Address is magic. */
+ return 1;
+
+ default:
+ /* Address is not magic. */
+ return 0;
+ }
+}
+
/* Remove useless bits from addresses in a running program. */
static CORE_ADDR
arm_addr_bits_remove (struct gdbarch *gdbarch, CORE_ADDR val)
/* On M-profile devices, do not strip the low bit from EXC_RETURN
(the magic exception return address). */
if (gdbarch_tdep (gdbarch)->is_m
- && (val & 0xfffffff0) == 0xfffffff0)
+ && arm_m_addr_is_magic (val))
return val;
if (arm_apcs_32)
implementation (this is hand-written ARM assembler in glibc). */
if (!is_thumb
- && read_memory_unsigned_integer (pc, 4, byte_order_for_code)
+ && read_code_unsigned_integer (pc, 4, byte_order_for_code)
== 0xe3e00a0f /* mov r0, #0xffff0fff */
- && read_memory_unsigned_integer (pc + 4, 4, byte_order_for_code)
+ && read_code_unsigned_integer (pc + 4, 4, byte_order_for_code)
== 0xe240f01f) /* sub pc, r0, #31 */
return 1;
}
{
unsigned short insn;
- insn = read_memory_unsigned_integer (start, 2, byte_order_for_code);
+ insn = read_code_unsigned_integer (start, 2, byte_order_for_code);
if ((insn & 0xfe00) == 0xb400) /* push { rlist } */
{
{
unsigned short inst2;
- inst2 = read_memory_unsigned_integer (start + 2, 2,
- byte_order_for_code);
+ inst2 = read_code_unsigned_integer (start + 2, 2,
+ byte_order_for_code);
if ((insn & 0xf800) == 0xf000 && (inst2 & 0xe800) == 0xe800)
{
if (is_thumb)
{
unsigned short insn1
- = read_memory_unsigned_integer (pc, 2, byte_order_for_code);
+ = read_code_unsigned_integer (pc, 2, byte_order_for_code);
if ((insn1 & 0xf800) == 0x4800) /* ldr Rd, #immed */
{
else if ((insn1 & 0xfbf0) == 0xf240) /* movw Rd, #const */
{
unsigned short insn2
- = read_memory_unsigned_integer (pc + 2, 2, byte_order_for_code);
+ = read_code_unsigned_integer (pc + 2, 2, byte_order_for_code);
low = EXTRACT_MOVW_MOVT_IMM_T (insn1, insn2);
insn1
- = read_memory_unsigned_integer (pc + 4, 2, byte_order_for_code);
+ = read_code_unsigned_integer (pc + 4, 2, byte_order_for_code);
insn2
- = read_memory_unsigned_integer (pc + 6, 2, byte_order_for_code);
+ = read_code_unsigned_integer (pc + 6, 2, byte_order_for_code);
/* movt Rd, #const */
if ((insn1 & 0xfbc0) == 0xf2c0)
else
{
unsigned int insn
- = read_memory_unsigned_integer (pc, 4, byte_order_for_code);
+ = read_code_unsigned_integer (pc, 4, byte_order_for_code);
if ((insn & 0x0e5f0000) == 0x041f0000) /* ldr Rd, [PC, #immed] */
{
low = EXTRACT_MOVW_MOVT_IMM_A (insn);
insn
- = read_memory_unsigned_integer (pc + 4, 4, byte_order_for_code);
+ = read_code_unsigned_integer (pc + 4, 4, byte_order_for_code);
if ((insn & 0x0ff00000) == 0x03400000) /* movt Rd, #const */
{
{
unsigned int destreg;
unsigned short insn
- = read_memory_unsigned_integer (pc + offset, 2, byte_order_for_code);
+ = read_code_unsigned_integer (pc + offset, 2, byte_order_for_code);
/* Step 2: ldr Rd, [Rn, #immed], encoding T1. */
if ((insn & 0xf800) != 0x6800)
return pc;
destreg = bits (insn, 0, 2);
- insn = read_memory_unsigned_integer (pc + offset + 2, 2,
- byte_order_for_code);
+ insn = read_code_unsigned_integer (pc + offset + 2, 2,
+ byte_order_for_code);
/* Step 3: str Rd, [Rn, #immed], encoding T1. */
if ((insn & 0xf800) != 0x6000)
return pc;
{
unsigned int destreg;
unsigned int insn
- = read_memory_unsigned_integer (pc + offset, 4, byte_order_for_code);
+ = read_code_unsigned_integer (pc + offset, 4, byte_order_for_code);
/* Step 2: ldr Rd, [Rn, #immed], encoding A1. */
if ((insn & 0x0e500000) != 0x04100000)
return pc;
destreg = bits (insn, 12, 15);
/* Step 3: str Rd, [Rn, #immed], encoding A1. */
- insn = read_memory_unsigned_integer (pc + offset + 4,
+ insn = read_code_unsigned_integer (pc + offset + 4,
4, byte_order_for_code);
if ((insn & 0x0e500000) != 0x04000000)
return pc;
function is. */
return;
- prologue_end = min (prologue_end, prev_pc);
+ prologue_end = std::min (prologue_end, prev_pc);
thumb_analyze_prologue (gdbarch, prologue_start, prologue_end, cache);
}
current_pc += 4)
{
unsigned int insn
- = read_memory_unsigned_integer (current_pc, 4, byte_order_for_code);
+ = read_code_unsigned_integer (current_pc, 4, byte_order_for_code);
if (insn == 0xe1a0c00d) /* mov ip, sp */
{
the callee (or at the present moment if this is the innermost frame).
The value stored there should be the address of the stmfd + 8. */
CORE_ADDR frame_loc;
- LONGEST return_value;
+ ULONGEST return_value;
frame_loc = get_frame_register_unsigned (this_frame, ARM_FP_REGNUM);
- if (!safe_read_memory_integer (frame_loc, 4, byte_order, &return_value))
+ if (!safe_read_memory_unsigned_integer (frame_loc, 4, byte_order,
+ &return_value))
return;
else
{
ensure this, so that e.g. pthread cancellation works. */
if (arm_frame_is_thumb (this_frame))
{
- LONGEST insn;
+ ULONGEST insn;
- if (safe_read_memory_integer (get_frame_pc (this_frame) - 2, 2,
- byte_order_for_code, &insn)
+ if (safe_read_memory_unsigned_integer (get_frame_pc (this_frame) - 2,
+ 2, byte_order_for_code, &insn)
&& (insn & 0xff00) == 0xdf00 /* svc */)
exc_valid = 1;
}
else
{
- LONGEST insn;
+ ULONGEST insn;
- if (safe_read_memory_integer (get_frame_pc (this_frame) - 4, 4,
- byte_order_for_code, &insn)
+ if (safe_read_memory_unsigned_integer (get_frame_pc (this_frame) - 4,
+ 4, byte_order_for_code, &insn)
&& (insn & 0x0f000000) == 0x0f000000 /* svc */)
exc_valid = 1;
}
/* No need to check is_m; this sniffer is only registered for
M-profile architectures. */
- /* Exception frames return to one of these magic PCs. Other values
- are not defined as of v7-M. See details in "B1.5.8 Exception
- return behavior" in "ARMv7-M Architecture Reference Manual". */
- if (this_pc == 0xfffffff1 || this_pc == 0xfffffff9
- || this_pc == 0xfffffffd)
- return 1;
-
- return 0;
+ /* Check if exception frame returns to a magic PC value. */
+ return arm_m_addr_is_magic (this_pc);
}
/* Frame unwinder for M-profile exceptions. */
int i;
for (i = 0; i < TYPE_NFIELDS (t); i++)
{
- int sub_count = arm_vfp_cprc_sub_candidate (TYPE_FIELD_TYPE (t, i),
- base_type);
+ int sub_count = 0;
+
+ if (!field_is_static (&TYPE_FIELD (t, i)))
+ sub_count = arm_vfp_cprc_sub_candidate (TYPE_FIELD_TYPE (t, i),
+ base_type);
if (sub_count == -1)
return -1;
count += sub_count;
&d, dbl);
}
-/* Like insert_single_step_breakpoint, but make sure we use a breakpoint
- of the appropriate mode (as encoded in the PC value), even if this
- differs from what would be expected according to the symbol tables. */
-
-void
-arm_insert_single_step_breakpoint (struct gdbarch *gdbarch,
- struct address_space *aspace,
- CORE_ADDR pc)
-{
- struct cleanup *old_chain
- = make_cleanup_restore_integer (&arm_override_mode);
-
- arm_override_mode = IS_THUMB_ADDR (pc);
- pc = gdbarch_addr_bits_remove (gdbarch, pc);
-
- insert_single_step_breakpoint (gdbarch, aspace, pc);
-
- do_cleanups (old_chain);
-}
-
/* Given BUF, which is OLD_LEN bytes ending at ENDADDR, expand
the buffer to be NEW_LEN bytes ending at ENDADDR. Return
NULL if an error occurs. BUF is freed. */
new_buf = (gdb_byte *) xmalloc (new_len);
memcpy (new_buf + bytes_to_read, buf, old_len);
xfree (buf);
- if (target_read_memory (endaddr - new_len, new_buf, bytes_to_read) != 0)
+ if (target_read_code (endaddr - new_len, new_buf, bytes_to_read) != 0)
{
xfree (new_buf);
return NULL;
footwork to distinguish a real IT instruction from the second
half of a 32-bit instruction, but there is no need for that if
there's no candidate. */
- buf_len = min (bpaddr - boundary, MAX_IT_BLOCK_PREFIX);
+ buf_len = std::min (bpaddr - boundary, (CORE_ADDR) MAX_IT_BLOCK_PREFIX);
if (buf_len == 0)
/* No room for an IT instruction. */
return bpaddr;
buf = (gdb_byte *) xmalloc (buf_len);
- if (target_read_memory (bpaddr - buf_len, buf, buf_len) != 0)
+ if (target_read_code (bpaddr - buf_len, buf, buf_len) != 0)
return bpaddr;
any = 0;
for (i = 0; i < buf_len; i += 2)
single-step support. We find the target of the coming instructions
and breakpoint them. */
-int
-arm_software_single_step (struct frame_info *frame)
+VEC (CORE_ADDR) *
+arm_software_single_step (struct regcache *regcache)
{
- struct regcache *regcache = get_current_regcache ();
struct gdbarch *gdbarch = get_regcache_arch (regcache);
- struct address_space *aspace = get_regcache_aspace (regcache);
struct arm_get_next_pcs next_pcs_ctx;
CORE_ADDR pc;
int i;
next_pcs = arm_get_next_pcs (&next_pcs_ctx);
for (i = 0; VEC_iterate (CORE_ADDR, next_pcs, i, pc); i++)
- arm_insert_single_step_breakpoint (gdbarch, aspace, pc);
+ {
+ pc = gdbarch_addr_bits_remove (gdbarch, pc);
+ VEC_replace (CORE_ADDR, next_pcs, i, pc);
+ }
- do_cleanups (old_chain);
+ discard_cleanups (old_chain);
- return 1;
+ return next_pcs;
}
/* Cleanup/copy SVC (SWI) instructions. These two functions are overridden
static int
gdb_print_insn_arm (bfd_vma memaddr, disassemble_info *info)
{
- struct gdbarch *gdbarch = (struct gdbarch *) info->application_data;
+ gdb_disassembler *di
+ = static_cast<gdb_disassembler *>(info->application_data);
+ struct gdbarch *gdbarch = di->arch ();
if (arm_pc_is_thumb (gdbarch, memaddr))
{
static const gdb_byte arm_default_thumb_le_breakpoint[] = THUMB_LE_BREAKPOINT;
static const gdb_byte 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
- 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. */
+/* Implement the breakpoint_kind_from_pc gdbarch method. */
-static const unsigned char *
-arm_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr, int *lenptr)
+static int
+arm_breakpoint_kind_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr)
{
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
enum bfd_endian byte_order_for_code = gdbarch_byte_order_for_code (gdbarch);
if (tdep->thumb2_breakpoint != NULL)
{
gdb_byte buf[2];
+
if (target_read_memory (*pcptr, buf, 2) == 0)
{
unsigned short inst1;
+
inst1 = extract_unsigned_integer (buf, 2, byte_order_for_code);
if (thumb_insn_size (inst1) == 4)
- {
- *lenptr = tdep->thumb2_breakpoint_size;
- return tdep->thumb2_breakpoint;
- }
+ return ARM_BP_KIND_THUMB2;
}
}
- *lenptr = tdep->thumb_breakpoint_size;
- return tdep->thumb_breakpoint;
+ return ARM_BP_KIND_THUMB;
}
else
+ return ARM_BP_KIND_ARM;
+
+}
+
+/* Implement the sw_breakpoint_from_kind gdbarch method. */
+
+static const gdb_byte *
+arm_sw_breakpoint_from_kind (struct gdbarch *gdbarch, int kind, int *size)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+ switch (kind)
{
- *lenptr = tdep->arm_breakpoint_size;
+ case ARM_BP_KIND_ARM:
+ *size = tdep->arm_breakpoint_size;
return tdep->arm_breakpoint;
+ case ARM_BP_KIND_THUMB:
+ *size = tdep->thumb_breakpoint_size;
+ return tdep->thumb_breakpoint;
+ case ARM_BP_KIND_THUMB2:
+ *size = tdep->thumb2_breakpoint_size;
+ return tdep->thumb2_breakpoint;
+ default:
+ gdb_assert_not_reached ("unexpected arm breakpoint kind");
}
}
-static void
-arm_remote_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr,
- int *kindptr)
+/* Implement the breakpoint_kind_from_current_state gdbarch method. */
+
+static int
+arm_breakpoint_kind_from_current_state (struct gdbarch *gdbarch,
+ struct regcache *regcache,
+ CORE_ADDR *pcptr)
{
- arm_breakpoint_from_pc (gdbarch, pcptr, kindptr);
+ gdb_byte buf[4];
+
+ /* Check the memory pointed by PC is readable. */
+ if (target_read_memory (regcache_read_pc (regcache), buf, 4) == 0)
+ {
+ struct arm_get_next_pcs next_pcs_ctx;
+ CORE_ADDR pc;
+ int i;
+ VEC (CORE_ADDR) *next_pcs = NULL;
+ struct cleanup *old_chain
+ = make_cleanup (VEC_cleanup (CORE_ADDR), &next_pcs);
+
+ arm_get_next_pcs_ctor (&next_pcs_ctx,
+ &arm_get_next_pcs_ops,
+ gdbarch_byte_order (gdbarch),
+ gdbarch_byte_order_for_code (gdbarch),
+ 0,
+ regcache);
+
+ next_pcs = arm_get_next_pcs (&next_pcs_ctx);
+
+ /* If MEMADDR is the next instruction of current pc, do the
+ software single step computation, and get the thumb mode by
+ the destination address. */
+ for (i = 0; VEC_iterate (CORE_ADDR, next_pcs, i, pc); i++)
+ {
+ if (UNMAKE_THUMB_ADDR (pc) == *pcptr)
+ {
+ do_cleanups (old_chain);
+
+ if (IS_THUMB_ADDR (pc))
+ {
+ *pcptr = MAKE_THUMB_ADDR (*pcptr);
+ return arm_breakpoint_kind_from_pc (gdbarch, pcptr);
+ }
+ else
+ return ARM_BP_KIND_ARM;
+ }
+ }
- if (arm_pc_is_thumb (gdbarch, *pcptr) && *kindptr == 4)
- /* The documented magic value for a 32-bit Thumb-2 breakpoint, so
- that this is not confused with a 32-bit ARM breakpoint. */
- *kindptr = 3;
+ do_cleanups (old_chain);
+ }
+
+ return arm_breakpoint_kind_from_pc (gdbarch, pcptr);
}
/* Extract from an array REGBUF containing the (raw) register state a
static void
set_disassembly_style_sfunc (char *args, int from_tty,
- struct cmd_list_element *c)
+ struct cmd_list_element *c)
{
- set_disassembly_style ();
+ /* Convert the short style name into the long style name (eg, reg-names-*)
+ before calling the generic set_disassembler_options() function. */
+ std::string long_name = std::string ("reg-names-") + disassembly_style;
+ set_disassembler_options (&long_name[0]);
+}
+
+static void
+show_disassembly_style_sfunc (struct ui_file *file, int from_tty,
+ struct cmd_list_element *c, const char *value)
+{
+ struct gdbarch *gdbarch = get_current_arch ();
+ char *options = get_disassembler_options (gdbarch);
+ const char *style = "";
+ int len = 0;
+ char *opt;
+
+ FOR_EACH_DISASSEMBLER_OPTION (opt, options)
+ if (CONST_STRNEQ (opt, "reg-names-"))
+ {
+ style = &opt[strlen ("reg-names-")];
+ len = strcspn (style, ",");
+ }
+
+ fprintf_unfiltered (file, "The disassembly style is \"%.*s\".\n", len, style);
}
\f
/* Return the ARM register name corresponding to register I. */
return arm_register_names[i];
}
-static void
-set_disassembly_style (void)
-{
- int current;
-
- /* Find the style that the user wants. */
- for (current = 0; current < num_disassembly_options; current++)
- if (disassembly_style == valid_disassembly_styles[current])
- break;
- gdb_assert (current < num_disassembly_options);
-
- /* Synchronize the disassembler. */
- set_arm_regname_option (current);
-}
-
/* Test whether the coff symbol specific value corresponds to a Thumb
function. */
switch (bfd_get_flavour (info.abfd))
{
- case bfd_target_aout_flavour:
- /* Assume it's an old APCS-style ABI. */
- arm_abi = ARM_ABI_APCS;
- break;
-
case bfd_target_coff_flavour:
/* Assume it's an old APCS-style ABI. */
/* XXX WinCE? */
set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
/* Breakpoint manipulation. */
- set_gdbarch_breakpoint_from_pc (gdbarch, arm_breakpoint_from_pc);
- set_gdbarch_remote_breakpoint_from_pc (gdbarch,
- arm_remote_breakpoint_from_pc);
+ set_gdbarch_breakpoint_kind_from_pc (gdbarch, arm_breakpoint_kind_from_pc);
+ set_gdbarch_sw_breakpoint_from_kind (gdbarch, arm_sw_breakpoint_from_kind);
+ set_gdbarch_breakpoint_kind_from_current_state (gdbarch,
+ arm_breakpoint_kind_from_current_state);
/* Information about registers, etc. */
set_gdbarch_sp_regnum (gdbarch, ARM_SP_REGNUM);
user_reg_add (gdbarch, arm_register_aliases[i].name,
value_of_arm_user_reg, &arm_register_aliases[i].regnum);
+ set_gdbarch_disassembler_options (gdbarch, &arm_disassembler_options);
+ set_gdbarch_valid_disassembler_options (gdbarch, disassembler_options_arm ());
+
return gdbarch;
}
void
_initialize_arm_tdep (void)
{
- struct ui_file *stb;
long length;
const char *setname;
const char *setdesc;
- const char *const *regnames;
- int i;
- static char *helptext;
+ int i, j;
char regdesc[1024], *rdptr = regdesc;
size_t rest = sizeof (regdesc);
initialize_tdesc_arm_with_vfpv3 ();
initialize_tdesc_arm_with_neon ();
- /* Get the number of possible sets of register names defined in opcodes. */
- num_disassembly_options = get_arm_regname_num_options ();
-
/* Add root prefix command for all "set arm"/"show arm" commands. */
add_prefix_cmd ("arm", no_class, set_arm_command,
_("Various ARM-specific commands."),
_("Various ARM-specific commands."),
&showarmcmdlist, "show arm ", 0, &showlist);
- /* Sync the opcode insn printer with our register viewer. */
- parse_arm_disassembler_option ("reg-names-std");
- /* Initialize the array that will be passed to
- add_setshow_enum_cmd(). */
+ arm_disassembler_options = xstrdup ("reg-names-std");
+ const disasm_options_t *disasm_options = disassembler_options_arm ();
+ int num_disassembly_styles = 0;
+ for (i = 0; disasm_options->name[i] != NULL; i++)
+ if (CONST_STRNEQ (disasm_options->name[i], "reg-names-"))
+ num_disassembly_styles++;
+
+ /* Initialize the array that will be passed to add_setshow_enum_cmd(). */
valid_disassembly_styles = XNEWVEC (const char *,
- num_disassembly_options + 1);
- for (i = 0; i < num_disassembly_options; i++)
- {
- get_arm_regnames (i, &setname, &setdesc, ®names);
- valid_disassembly_styles[i] = setname;
- length = snprintf (rdptr, rest, "%s - %s\n", setname, setdesc);
- rdptr += length;
- rest -= length;
- /* When we find the default names, tell the disassembler to use
- them. */
- if (!strcmp (setname, "std"))
- {
- disassembly_style = setname;
- set_arm_regname_option (i);
- }
- }
+ num_disassembly_styles + 1);
+ for (i = j = 0; disasm_options->name[i] != NULL; i++)
+ if (CONST_STRNEQ (disasm_options->name[i], "reg-names-"))
+ {
+ size_t offset = strlen ("reg-names-");
+ const char *style = disasm_options->name[i];
+ valid_disassembly_styles[j++] = &style[offset];
+ length = snprintf (rdptr, rest, "%s - %s\n", &style[offset],
+ disasm_options->description[i]);
+ rdptr += length;
+ rest -= length;
+ }
/* Mark the end of valid options. */
- valid_disassembly_styles[num_disassembly_options] = NULL;
+ valid_disassembly_styles[num_disassembly_styles] = NULL;
/* Create the help text. */
- stb = mem_fileopen ();
- fprintf_unfiltered (stb, "%s%s%s",
- _("The valid values are:\n"),
- regdesc,
- _("The default is \"std\"."));
- helptext = ui_file_xstrdup (stb, NULL);
- ui_file_delete (stb);
+ std::string helptext = string_printf ("%s%s%s",
+ _("The valid values are:\n"),
+ regdesc,
+ _("The default is \"std\"."));
add_setshow_enum_cmd("disassembler", no_class,
valid_disassembly_styles, &disassembly_style,
_("Set the disassembly style."),
_("Show the disassembly style."),
- helptext,
+ helptext.c_str (),
set_disassembly_style_sfunc,
- NULL, /* FIXME: i18n: The disassembly style is
- \"%s\". */
+ show_disassembly_style_sfunc,
&setarmcmdlist, &showarmcmdlist);
add_setshow_boolean_cmd ("apcs32", no_class, &arm_apcs_32,