/* Common target dependent code for GDB on ARM systems.
- Copyright (C) 1988-2019 Free Software Foundation, Inc.
+ Copyright (C) 1988-2020 Free Software Foundation, Inc.
This file is part of GDB.
#include "frame-base.h"
#include "trad-frame.h"
#include "objfiles.h"
-#include "dwarf2-frame.h"
+#include "dwarf2/frame.h"
#include "gdbtypes.h"
#include "prologue-value.h"
#include "remote.h"
#include "target-descriptions.h"
#include "user-regs.h"
#include "observable.h"
+#include "count-one-bits.h"
#include "arch/arm.h"
#include "arch/arm-get-next-pcs.h"
#include "coff/internal.h"
#include "elf/arm.h"
-#include "gdbsupport/vec.h"
-
#include "record.h"
#include "record-full.h"
#include <algorithm>
#if GDB_SELF_TEST
#include "gdbsupport/selftest.h"
-#include "aarch32-tdep.h"
#endif
-static int arm_debug;
+static bool arm_debug;
/* Macros for setting and testing a bit in a minimal symbol that marks
it as Thumb function. The MSB of the minimal symbol's "info" field
struct arm_mapping_symbol
{
- bfd_vma value;
+ CORE_ADDR value;
char type;
bool operator< (const arm_mapping_symbol &other) const
typedef std::vector<arm_mapping_symbol> arm_mapping_symbol_vec;
-struct arm_per_objfile
+struct arm_per_bfd
{
- explicit arm_per_objfile (size_t num_sections)
+ explicit arm_per_bfd (size_t num_sections)
: section_maps (new arm_mapping_symbol_vec[num_sections]),
section_maps_sorted (new bool[num_sections] ())
{}
- DISABLE_COPY_AND_ASSIGN (arm_per_objfile);
+ DISABLE_COPY_AND_ASSIGN (arm_per_bfd);
/* Information about mapping symbols ($a, $d, $t) in the objfile.
std::unique_ptr<bool[]> section_maps_sorted;
};
-/* Per-objfile data used for mapping symbols. */
-static objfile_key<arm_per_objfile> arm_objfile_data_key;
+/* Per-bfd data used for mapping symbols. */
+static bfd_key<arm_per_bfd> arm_bfd_data_key;
/* The list of available "set arm ..." and "show arm ..." commands. */
static struct cmd_list_element *setarmcmdlist = NULL;
#define DISPLACED_STEPPING_ARCH_VERSION 5
-/* Set to true if the 32-bit mode is in use. */
+/* See arm-tdep.h. */
-int arm_apcs_32 = 1;
+bool arm_apcs_32 = true;
/* Return the bit mask in ARM_PS_REGNUM that indicates Thumb mode. */
sec = find_pc_section (memaddr);
if (sec != NULL)
{
- arm_per_objfile *data = arm_objfile_data_key.get (sec->objfile);
+ arm_per_bfd *data = arm_bfd_data_key.get (sec->objfile->obfd);
if (data != NULL)
{
unsigned int section_idx = sec->the_bfd_section->index;
msym = lookup_minimal_symbol_by_pc (pc);
if (msym.minsym != NULL
&& BMSYMBOL_VALUE_ADDRESS (msym) == pc
- && MSYMBOL_LINKAGE_NAME (msym.minsym) != NULL)
+ && msym.minsym->linkage_name () != NULL)
{
- const char *name = MSYMBOL_LINKAGE_NAME (msym.minsym);
+ const char *name = msym.minsym->linkage_name ();
/* The GNU linker's Thumb call stub to foo is named
__foo_from_thumb. */
/* ADDR must correspond to a symbol whose name is __stack_chk_guard.
Otherwise, this sequence cannot be for stack protector. */
if (stack_chk_guard.minsym == NULL
- || !startswith (MSYMBOL_LINKAGE_NAME (stack_chk_guard.minsym), "__stack_chk_guard"))
+ || !startswith (stack_chk_guard.minsym->linkage_name (), "__stack_chk_guard"))
return pc;
if (is_thumb)
struct arm_exidx_entry
{
- bfd_vma addr;
+ CORE_ADDR addr;
gdb_byte *entry;
bool operator< (const arm_exidx_entry &other) const
std::vector<std::vector<arm_exidx_entry>> section_maps;
};
-static const struct objfile_key<arm_exidx_data> arm_exidx_data_key;
+/* Per-BFD key to store exception handling information. */
+static const struct bfd_key<arm_exidx_data> arm_exidx_data_key;
static struct obj_section *
arm_obj_section_from_vma (struct objfile *objfile, bfd_vma vma)
struct obj_section *osect;
ALL_OBJFILE_OSECTIONS (objfile, osect)
- if (bfd_get_section_flags (objfile->obfd,
- osect->the_bfd_section) & SEC_ALLOC)
+ if (bfd_section_flags (osect->the_bfd_section) & SEC_ALLOC)
{
bfd_vma start, size;
- start = bfd_get_section_vma (objfile->obfd, osect->the_bfd_section);
- size = bfd_get_section_size (osect->the_bfd_section);
+ start = bfd_section_vma (osect->the_bfd_section);
+ size = bfd_section_size (osect->the_bfd_section);
if (start <= vma && vma < start + size)
return osect;
LONGEST i;
/* If we've already touched this file, do nothing. */
- if (!objfile || arm_exidx_data_key.get (objfile) != NULL)
+ if (!objfile || arm_exidx_data_key.get (objfile->obfd) != NULL)
return;
/* Read contents of exception table and index. */
gdb::byte_vector exidx_data;
if (exidx)
{
- exidx_vma = bfd_section_vma (objfile->obfd, exidx);
- exidx_data.resize (bfd_get_section_size (exidx));
+ exidx_vma = bfd_section_vma (exidx);
+ exidx_data.resize (bfd_section_size (exidx));
if (!bfd_get_section_contents (objfile->obfd, exidx,
exidx_data.data (), 0,
gdb::byte_vector extab_data;
if (extab)
{
- extab_vma = bfd_section_vma (objfile->obfd, extab);
- extab_data.resize (bfd_get_section_size (extab));
+ extab_vma = bfd_section_vma (extab);
+ extab_data.resize (bfd_section_size (extab));
if (!bfd_get_section_contents (objfile->obfd, extab,
extab_data.data (), 0,
}
/* Allocate exception table data structure. */
- data = arm_exidx_data_key.emplace (objfile);
+ data = arm_exidx_data_key.emplace (objfile->obfd);
data->section_maps.resize (objfile->obfd->section_count);
/* Fill in exception table. */
sec = arm_obj_section_from_vma (objfile, idx);
if (sec == NULL)
continue;
- idx -= bfd_get_section_vma (objfile->obfd, sec->the_bfd_section);
+ idx -= bfd_section_vma (sec->the_bfd_section);
/* Determine address of exception table entry. */
if (val == 1)
struct arm_exidx_data *data;
struct arm_exidx_entry map_key = { memaddr - obj_section_addr (sec), 0 };
- data = arm_exidx_data_key.get (sec->objfile);
+ data = arm_exidx_data_key.get (sec->objfile->obfd);
if (data != NULL)
{
std::vector<arm_exidx_entry> &map
arm_type_align (gdbarch *gdbarch, struct type *t)
{
t = check_typedef (t);
- if (TYPE_CODE (t) == TYPE_CODE_ARRAY && TYPE_VECTOR (t))
+ if (t->code () == TYPE_CODE_ARRAY && TYPE_VECTOR (t))
{
/* Use the natural alignment for vector types (the same for
scalar type), but the maximum alignment is 64-bit. */
enum arm_vfp_cprc_base_type *base_type)
{
t = check_typedef (t);
- switch (TYPE_CODE (t))
+ switch (t->code ())
{
case TYPE_CODE_FLT:
switch (TYPE_LENGTH (t))
int count = 0;
unsigned unitlen;
int i;
- for (i = 0; i < TYPE_NFIELDS (t); i++)
+ for (i = 0; i < t->num_fields (); i++)
{
int sub_count = 0;
- if (!field_is_static (&TYPE_FIELD (t, i)))
+ if (!field_is_static (&t->field (i)))
sub_count = arm_vfp_cprc_sub_candidate (TYPE_FIELD_TYPE (t, i),
base_type);
if (sub_count == -1)
int count = 0;
unsigned unitlen;
int i;
- for (i = 0; i < TYPE_NFIELDS (t); i++)
+ for (i = 0; i < t->num_fields (); i++)
{
int sub_count = arm_vfp_cprc_sub_candidate (TYPE_FIELD_TYPE (t, i),
base_type);
/* Determine the type of this function and whether the VFP ABI
applies. */
ftype = check_typedef (value_type (function));
- if (TYPE_CODE (ftype) == TYPE_CODE_PTR)
+ if (ftype->code () == TYPE_CODE_PTR)
ftype = check_typedef (TYPE_TARGET_TYPE (ftype));
use_vfp_abi = arm_vfp_abi_for_function (gdbarch, ftype);
arg_type = check_typedef (value_type (args[argnum]));
len = TYPE_LENGTH (arg_type);
target_type = TYPE_TARGET_TYPE (arg_type);
- typecode = TYPE_CODE (arg_type);
+ typecode = arg_type->code ();
val = value_contents (args[argnum]);
align = type_align (arg_type);
}
}
- /* Push stack padding for dowubleword alignment. */
+ /* Push stack padding for doubleword alignment. */
if (nstack & (align - 1))
{
si = push_stack_item (si, val, ARM_INT_REGISTER_SIZE);
the THUMB bit in it. */
if (TYPE_CODE_PTR == typecode
&& target_type != NULL
- && TYPE_CODE_FUNC == TYPE_CODE (check_typedef (target_type)))
+ && TYPE_CODE_FUNC == check_typedef (target_type)->code ())
{
CORE_ADDR regval = extract_unsigned_integer (val, len, byte_order);
if (arm_pc_is_thumb (gdbarch, regval))
append_composite_type_field (t, "f64", elem);
TYPE_VECTOR (t) = 1;
- TYPE_NAME (t) = "neon_d";
+ t->set_name ("neon_d");
tdep->neon_double_type = t;
}
append_composite_type_field (t, "f64", init_vector_type (elem, 2));
TYPE_VECTOR (t) = 1;
- TYPE_NAME (t) = "neon_q";
+ t->set_name ("neon_q");
tdep->neon_quad_type = t;
}
struct type *t = tdesc_register_type (gdbarch, regnum);
if (regnum >= ARM_D0_REGNUM && regnum < ARM_D0_REGNUM + 32
- && TYPE_CODE (t) == TYPE_CODE_FLT
+ && t->code () == TYPE_CODE_FLT
&& gdbarch_tdep (gdbarch)->have_neon)
return arm_neon_double_type (gdbarch);
else
if (dsc->u.branch.link)
{
/* The value of LR should be the next insn of current one. In order
- not to confuse logic hanlding later insn `bx lr', if current insn mode
+ not to confuse logic handling later insn `bx lr', if current insn mode
is Thumb, the bit 0 of LR value should be set to 1. */
ULONGEST next_insn_addr = dsc->insn_addr + dsc->insn_size;
Before this sequence of instructions:
r0 is the PC value got from displaced_read_reg, so r0 = from + 8;
- r2 is the Rn value got from dispalced_read_reg.
+ r2 is the Rn value got from displaced_read_reg.
Insn1: push {pc} Write address of STR instruction + offset on stack
Insn2: pop {r4} Read it back from stack, r4 = addr(Insn1) + offset
{
uint32_t status = displaced_read_reg (regs, dsc, ARM_PS_REGNUM);
int store_executed = condition_true (dsc->u.block.cond, status);
- CORE_ADDR pc_stored_at, transferred_regs = bitcount (dsc->u.block.regmask);
+ CORE_ADDR pc_stored_at, transferred_regs
+ = count_one_bits (dsc->u.block.regmask);
CORE_ADDR stm_insn_addr;
uint32_t pc_val;
long offset;
uint32_t status = displaced_read_reg (regs, dsc, ARM_PS_REGNUM);
int load_executed = condition_true (dsc->u.block.cond, status);
unsigned int mask = dsc->u.block.regmask, write_reg = ARM_PC_REGNUM;
- unsigned int regs_loaded = bitcount (mask);
+ unsigned int regs_loaded = count_one_bits (mask);
unsigned int num_to_shuffle = regs_loaded, clobbered;
/* The method employed here will fail if the register list is fully populated
contiguous chunk r0...rX before doing the transfer, then shuffling
registers into the correct places in the cleanup routine. */
unsigned int regmask = insn & 0xffff;
- unsigned int num_in_list = bitcount (regmask), new_regmask;
+ unsigned int num_in_list = count_one_bits (regmask), new_regmask;
unsigned int i;
for (i = 0; i < num_in_list; i++)
else
{
unsigned int regmask = dsc->u.block.regmask;
- unsigned int num_in_list = bitcount (regmask), new_regmask;
+ unsigned int num_in_list = count_one_bits (regmask), new_regmask;
unsigned int i;
for (i = 0; i < num_in_list; i++)
}
-/* Common copy routine for svc instruciton. */
+/* Common copy routine for svc instruction. */
static int
install_svc (struct gdbarch *gdbarch, struct regcache *regs,
if (bit_4 == 0) /* STC/STC2. */
return thumb_copy_unmodified_32bit (gdbarch, insn1, insn2,
"stc/stc2", dsc);
- else /* LDC/LDC2 {literal, immeidate}. */
+ else /* LDC/LDC2 {literal, immediate}. */
return thumb2_copy_copro_load_store (gdbarch, insn1, insn2,
regs, dsc);
}
return 0;
}
-/* Copy Thumb cbnz/cbz insruction. */
+/* Copy Thumb cbnz/cbz instruction. */
static int
thumb_copy_cbnz_cbz (struct gdbarch *gdbarch, uint16_t insn1,
}
else
{
- unsigned int num_in_list = bitcount (dsc->u.block.regmask);
+ unsigned int num_in_list = count_one_bits (dsc->u.block.regmask);
unsigned int i;
unsigned int new_regmask;
case 0:
if (bit (insn1, 6))
{
- /* Load/store {dual, execlusive}, table branch. */
+ /* Load/store {dual, exclusive}, table branch. */
if (bits (insn1, 7, 8) == 1 && bits (insn1, 4, 5) == 1
&& bits (insn2, 5, 7) == 0)
err = thumb2_copy_table_branch (gdbarch, insn1, insn2, regs,
err = thumb_copy_unmodified_32bit (gdbarch, insn1, insn2,
"dp/pb", dsc);
}
- else /* Data processing (modified immeidate) */
+ else /* Data processing (modified immediate) */
err = thumb_copy_unmodified_32bit (gdbarch, insn1, insn2,
"dp/mi", dsc);
}
struct gdbarch *gdbarch = regs->arch ();
enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
- if (TYPE_CODE_FLT == TYPE_CODE (type))
+ if (TYPE_CODE_FLT == type->code ())
{
switch (gdbarch_tdep (gdbarch)->fp_model)
{
break;
}
}
- else if (TYPE_CODE (type) == TYPE_CODE_INT
- || TYPE_CODE (type) == TYPE_CODE_CHAR
- || TYPE_CODE (type) == TYPE_CODE_BOOL
- || TYPE_CODE (type) == TYPE_CODE_PTR
+ else if (type->code () == TYPE_CODE_INT
+ || type->code () == TYPE_CODE_CHAR
+ || type->code () == TYPE_CODE_BOOL
+ || type->code () == TYPE_CODE_PTR
|| TYPE_IS_REFERENCE (type)
- || TYPE_CODE (type) == TYPE_CODE_ENUM)
+ || type->code () == TYPE_CODE_ENUM)
{
/* If the type is a plain integer, then the access is
straight-forward. Otherwise we have to play around a bit
/* Simple, non-aggregate types (ie not including vectors and
complex) are always returned in a register (or registers). */
- code = TYPE_CODE (type);
+ code = type->code ();
if (TYPE_CODE_STRUCT != code && TYPE_CODE_UNION != code
&& TYPE_CODE_ARRAY != code && TYPE_CODE_COMPLEX != code)
return 0;
--> yes, nRc = 1
*/
- for (i = 0; i < TYPE_NFIELDS (type); i++)
+ for (i = 0; i < type->num_fields (); i++)
{
enum type_code field_type_code;
field_type_code
- = TYPE_CODE (check_typedef (TYPE_FIELD_TYPE (type,
- i)));
+ = check_typedef (TYPE_FIELD_TYPE (type, i))->code ();
/* Is it a floating point type field? */
if (field_type_code == TYPE_CODE_FLT)
struct gdbarch *gdbarch = regs->arch ();
enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
- if (TYPE_CODE (type) == TYPE_CODE_FLT)
+ if (type->code () == TYPE_CODE_FLT)
{
gdb_byte buf[ARM_FP_REGISTER_SIZE];
break;
}
}
- else if (TYPE_CODE (type) == TYPE_CODE_INT
- || TYPE_CODE (type) == TYPE_CODE_CHAR
- || TYPE_CODE (type) == TYPE_CODE_BOOL
- || TYPE_CODE (type) == TYPE_CODE_PTR
+ else if (type->code () == TYPE_CODE_INT
+ || type->code () == TYPE_CODE_CHAR
+ || type->code () == TYPE_CODE_BOOL
+ || type->code () == TYPE_CODE_PTR
|| TYPE_IS_REFERENCE (type)
- || TYPE_CODE (type) == TYPE_CODE_ENUM)
+ || type->code () == TYPE_CODE_ENUM)
{
if (TYPE_LENGTH (type) <= 4)
{
return RETURN_VALUE_REGISTER_CONVENTION;
}
- if (TYPE_CODE (valtype) == TYPE_CODE_STRUCT
- || TYPE_CODE (valtype) == TYPE_CODE_UNION
- || TYPE_CODE (valtype) == TYPE_CODE_ARRAY)
+ if (valtype->code () == TYPE_CODE_STRUCT
+ || valtype->code () == TYPE_CODE_UNION
+ || valtype->code () == TYPE_CODE_ARRAY)
{
if (tdep->struct_return == pcc_struct_return
|| arm_return_in_memory (gdbarch, valtype))
return RETURN_VALUE_STRUCT_CONVENTION;
}
- else if (TYPE_CODE (valtype) == TYPE_CODE_COMPLEX)
+ else if (valtype->code () == TYPE_CODE_COMPLEX)
{
if (arm_return_in_memory (gdbarch, valtype))
return RETURN_VALUE_STRUCT_CONVENTION;
*pc = extract_unsigned_integer (buf, ARM_INT_REGISTER_SIZE, byte_order);
return 1;
}
+/* A call to cmse secure entry function "foo" at "a" is modified by
+ GNU ld as "b".
+ a) bl xxxx <foo>
+
+ <foo>
+ xxxx:
+
+ b) bl yyyy <__acle_se_foo>
+
+ section .gnu.sgstubs:
+ <foo>
+ yyyy: sg // secure gateway
+ b.w xxxx <__acle_se_foo> // original_branch_dest
+
+ <__acle_se_foo>
+ xxxx:
+
+ When the control at "b", the pc contains "yyyy" (sg address) which is a
+ trampoline and does not exist in source code. This function returns the
+ target pc "xxxx". For more details please refer to section 5.4
+ (Entry functions) and section 3.4.4 (C level development flow of secure code)
+ of "armv8-m-security-extensions-requirements-on-development-tools-engineering-specification"
+ document on www.developer.arm.com. */
+
+static CORE_ADDR
+arm_skip_cmse_entry (CORE_ADDR pc, const char *name, struct objfile *objfile)
+{
+ int target_len = strlen (name) + strlen ("__acle_se_") + 1;
+ char *target_name = (char *) alloca (target_len);
+ xsnprintf (target_name, target_len, "%s%s", "__acle_se_", name);
+
+ struct bound_minimal_symbol minsym
+ = lookup_minimal_symbol (target_name, NULL, objfile);
+
+ if (minsym.minsym != nullptr)
+ return BMSYMBOL_VALUE_ADDRESS (minsym);
+
+ return 0;
+}
+
+/* Return true when SEC points to ".gnu.sgstubs" section. */
+
+static bool
+arm_is_sgstubs_section (struct obj_section *sec)
+{
+ return (sec != nullptr
+ && sec->the_bfd_section != nullptr
+ && sec->the_bfd_section->name != nullptr
+ && streq (sec->the_bfd_section->name, ".gnu.sgstubs"));
+}
/* Recognize GCC and GNU ld's trampolines. If we are in a trampoline,
return the target PC. Otherwise return 0. */
return 0;
}
- return 0; /* not a stub */
-}
+ struct obj_section *section = find_pc_section (pc);
-static void
-set_arm_command (const char *args, int from_tty)
-{
- printf_unfiltered (_("\
-\"set arm\" must be followed by an apporpriate subcommand.\n"));
- help_list (setarmcmdlist, "set arm ", all_commands, gdb_stdout);
-}
+ /* Check whether SECTION points to the ".gnu.sgstubs" section. */
+ if (arm_is_sgstubs_section (section))
+ return arm_skip_cmse_entry (pc, name, section->objfile);
-static void
-show_arm_command (const char *args, int from_tty)
-{
- cmd_show_list (showarmcmdlist, from_tty, "");
+ return 0; /* not a stub */
}
static void
asymbol *sym)
{
const char *name = bfd_asymbol_name (sym);
- struct arm_per_objfile *data;
+ struct arm_per_bfd *data;
struct arm_mapping_symbol new_map_sym;
gdb_assert (name[0] == '$');
if (name[1] != 'a' && name[1] != 't' && name[1] != 'd')
return;
- data = arm_objfile_data_key.get (objfile);
+ data = arm_bfd_data_key.get (objfile->obfd);
if (data == NULL)
- data = arm_objfile_data_key.emplace (objfile,
- objfile->obfd->section_count);
+ data = arm_bfd_data_key.emplace (objfile->obfd,
+ objfile->obfd->section_count);
arm_mapping_symbol_vec &map
- = data->section_maps[bfd_get_section (sym)->index];
+ = data->section_maps[bfd_asymbol_section (sym)->index];
new_map_sym.value = sym->value;
new_map_sym.type = name[1];
enum arm_abi_kind arm_abi = arm_abi_global;
enum arm_float_model fp_model = arm_fp_model;
struct tdesc_arch_data *tdesc_data = NULL;
- int i, is_m = 0;
- int vfp_register_count = 0, have_vfp_pseudos = 0, have_neon_pseudos = 0;
- int have_wmmx_registers = 0;
- int have_neon = 0;
- int have_fpa_registers = 1;
+ int i;
+ bool is_m = false;
+ int vfp_register_count = 0;
+ bool have_vfp_pseudos = false, have_neon_pseudos = false;
+ bool have_wmmx_registers = false;
+ bool have_neon = false;
+ bool have_fpa_registers = true;
const struct target_desc *tdesc = info.target_desc;
/* If we have an object to base this architecture on, try to determine
&& (attr_arch == TAG_CPU_ARCH_V6_M
|| attr_arch == TAG_CPU_ARCH_V6S_M
|| attr_profile == 'M'))
- is_m = 1;
+ is_m = true;
#endif
}
if (feature == NULL)
return NULL;
else
- is_m = 1;
+ is_m = true;
}
tdesc_data = tdesc_data_alloc ();
}
}
else
- have_fpa_registers = 0;
+ have_fpa_registers = false;
feature = tdesc_find_feature (tdesc,
"org.gnu.gdb.xscale.iwmmxt");
return NULL;
}
- have_wmmx_registers = 1;
+ have_wmmx_registers = true;
}
/* If we have a VFP unit, check whether the single precision registers
}
if (tdesc_unnumbered_register (feature, "s0") == 0)
- have_vfp_pseudos = 1;
+ have_vfp_pseudos = true;
vfp_register_count = i;
their type; otherwise (normally) provide them with
the default type. */
if (tdesc_unnumbered_register (feature, "q0") == 0)
- have_neon_pseudos = 1;
+ have_neon_pseudos = true;
- have_neon = 1;
+ have_neon = true;
}
}
}
}
/* Add standard register aliases. We add aliases even for those
- nanes which are used by the current architecture - it's simpler,
+ names which are used by the current architecture - it's simpler,
and does no harm, since nothing ever lists user registers. */
for (i = 0; i < ARRAY_SIZE (arm_register_aliases); i++)
user_reg_add (gdbarch, arm_register_aliases[i].name,
if (tdep == NULL)
return;
- fprintf_unfiltered (file, _("arm_dump_tdep: Lowest pc = 0x%lx"),
+ fprintf_unfiltered (file, _("arm_dump_tdep: fp_model = %i\n"),
+ (int) tdep->fp_model);
+ fprintf_unfiltered (file, _("arm_dump_tdep: have_fpa_registers = %i\n"),
+ (int) tdep->have_fpa_registers);
+ fprintf_unfiltered (file, _("arm_dump_tdep: have_wmmx_registers = %i\n"),
+ (int) tdep->have_wmmx_registers);
+ fprintf_unfiltered (file, _("arm_dump_tdep: vfp_register_count = %i\n"),
+ (int) tdep->vfp_register_count);
+ fprintf_unfiltered (file, _("arm_dump_tdep: have_vfp_pseudos = %i\n"),
+ (int) tdep->have_vfp_pseudos);
+ fprintf_unfiltered (file, _("arm_dump_tdep: have_neon_pseudos = %i\n"),
+ (int) tdep->have_neon_pseudos);
+ fprintf_unfiltered (file, _("arm_dump_tdep: have_neon = %i\n"),
+ (int) tdep->have_neon);
+ fprintf_unfiltered (file, _("arm_dump_tdep: Lowest pc = 0x%lx\n"),
(unsigned long) tdep->lowest_pc);
}
}
#endif
+void _initialize_arm_tdep ();
void
-_initialize_arm_tdep (void)
+_initialize_arm_tdep ()
{
long length;
int i, j;
arm_elf_osabi_sniffer);
/* Add root prefix command for all "set arm"/"show arm" commands. */
- add_prefix_cmd ("arm", no_class, set_arm_command,
- _("Various ARM-specific commands."),
- &setarmcmdlist, "set arm ", 0, &setlist);
+ add_basic_prefix_cmd ("arm", no_class,
+ _("Various ARM-specific commands."),
+ &setarmcmdlist, "set arm ", 0, &setlist);
- add_prefix_cmd ("arm", no_class, show_arm_command,
- _("Various ARM-specific commands."),
- &showarmcmdlist, "show arm ", 0, &showlist);
+ add_show_prefix_cmd ("arm", no_class,
+ _("Various ARM-specific commands."),
+ &showarmcmdlist, "show arm ", 0, &showlist);
arm_disassembler_options = xstrdup ("reg-names-std");
#if GDB_SELF_TEST
selftests::register_test ("arm-record", selftests::arm_record_test);
-
- const target_desc *tdesc;
-
- tdesc = arm_read_description (ARM_FP_TYPE_VFPV2);
- selftests::record_xml_tdesc ("arm/arm-with-vfpv2.xml", tdesc);
- tdesc = arm_read_description (ARM_FP_TYPE_VFPV3);
- selftests::record_xml_tdesc ("arm/arm-with-vfpv3.xml",tdesc);
- tdesc = arm_read_description (ARM_FP_TYPE_IWMMXT);
- selftests::record_xml_tdesc ("arm/arm-with-iwmmxt.xml", tdesc);
- tdesc = arm_read_mprofile_description (ARM_M_TYPE_M_PROFILE);
- selftests::record_xml_tdesc ("arm/arm-with-m.xml", tdesc);
- tdesc = arm_read_mprofile_description (ARM_M_TYPE_VFP_D16);
- selftests::record_xml_tdesc ("arm/arm-with-m-vfp-d16.xml", tdesc);
- tdesc = arm_read_mprofile_description (ARM_M_TYPE_WITH_FPA);
- selftests::record_xml_tdesc ("arm/arm-with-m-fpa-layout.xml", tdesc);
- tdesc = aarch32_read_description ();
- selftests::record_xml_tdesc ("arm/arm-with-neon.xml", tdesc);
#endif
}
{
reg_dest = bits (arm_insn_r->arm_insn, 12, 15);
/* LDR insn has a capability to do branching, if
- MOV LR, PC is precedded by LDR insn having Rn as R15
+ MOV LR, PC is preceded by LDR insn having Rn as R15
in that case, it emulates branch and link insn, and hence we
need to save CSPR and PC as well. */
if (15 != reg_dest)
} // namespace
/* Extracts arm/thumb/thumb2 insn depending on the size, and returns 0 on success
-and positive val on fauilure. */
+and positive val on failure. */
static int
extract_arm_insn (abstract_memory_reader& reader,