/* 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 "common/vec.h"
-
#include "record.h"
#include "record-full.h"
#include <algorithm>
-#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"
-
#if GDB_SELF_TEST
-#include "common/selftest.h"
+#include "gdbsupport/selftest.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
#define MSYMBOL_IS_SPECIAL(msym) \
MSYMBOL_TARGET_FLAG_1 (msym)
-/* Per-objfile data used for mapping symbols. */
-static const struct objfile_data *arm_objfile_data_key;
-
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-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;
static struct cmd_list_element *showarmcmdlist = NULL;
/* Disassembly style to use. Default to "std" register names. */
static const char *disassembly_style;
+/* All possible arm target descriptors. */
+static struct target_desc *tdesc_arm_list[ARM_FP_TYPE_INVALID];
+static struct target_desc *tdesc_arm_mprofile_list[ARM_M_TYPE_INVALID];
+
/* This is used to keep the bfd arch_info in sync with the disassembly
style. */
static void set_disassembly_style_sfunc (const char *, int,
#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
- = (struct arm_per_objfile *) objfile_data (sec->objfile,
- arm_objfile_data_key);
+ arm_per_bfd *data = arm_bfd_data_key.get (sec->objfile->obfd);
if (data != NULL)
{
unsigned int section_idx = sec->the_bfd_section->index;
{
struct bound_minimal_symbol sym;
char type;
- arm_displaced_step_closure *dsc
- = ((arm_displaced_step_closure * )
- get_displaced_step_closure_by_addr (memaddr));
+ arm_displaced_step_copy_insn_closure *dsc
+ = ((arm_displaced_step_copy_insn_closure * )
+ get_displaced_step_copy_insn_closure_by_addr (memaddr));
/* If checking the mode of displaced instruction in copy area, the mode
should be determined by instruction on the original address. */
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. */
parameters from memory. */
;
- else if ((insn & 0xffb0) == 0xe950 /* ldrd Rt, Rt2,
+ else if ((insn & 0xff70) == 0xe950 /* ldrd Rt, Rt2,
[Rn, #+/-imm] */
&& pv_is_register (regs[bits (insn, 0, 3)], ARM_SP_REGNUM))
/* Similarly ignore dual loads from the stack. */
/* 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)
personality routines; the cache will contain only the frame unwinding
instructions associated with the entry (not the descriptors). */
-static const struct objfile_data *arm_exidx_data_key;
-
struct arm_exidx_entry
{
- bfd_vma addr;
+ CORE_ADDR addr;
gdb_byte *entry;
+
+ bool operator< (const arm_exidx_entry &other) const
+ {
+ return addr < other.addr;
+ }
};
-typedef struct arm_exidx_entry arm_exidx_entry_s;
-DEF_VEC_O(arm_exidx_entry_s);
struct arm_exidx_data
{
- VEC(arm_exidx_entry_s) **section_maps;
+ std::vector<std::vector<arm_exidx_entry>> section_maps;
};
-static void
-arm_exidx_data_free (struct objfile *objfile, void *arg)
-{
- struct arm_exidx_data *data = (struct arm_exidx_data *) arg;
- unsigned int i;
-
- for (i = 0; i < objfile->obfd->section_count; i++)
- VEC_free (arm_exidx_entry_s, data->section_maps[i]);
-}
-
-static inline int
-arm_compare_exidx_entries (const struct arm_exidx_entry *lhs,
- const struct arm_exidx_entry *rhs)
-{
- return lhs->addr < rhs->addr;
-}
+/* 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 || objfile_data (objfile, arm_exidx_data_key) != 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 = OBSTACK_ZALLOC (&objfile->objfile_obstack, struct arm_exidx_data);
- set_objfile_data (objfile, arm_exidx_data_key, data);
- data->section_maps = OBSTACK_CALLOC (&objfile->objfile_obstack,
- objfile->obfd->section_count,
- VEC(arm_exidx_entry_s) *);
+ data = arm_exidx_data_key.emplace (objfile->obfd);
+ data->section_maps.resize (objfile->obfd->section_count);
/* Fill in exception table. */
for (i = 0; i < exidx_data.size () / 8; i++)
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)
appear in order of increasing addresses. */
new_exidx_entry.addr = idx;
new_exidx_entry.entry = entry;
- VEC_safe_push (arm_exidx_entry_s,
- data->section_maps[sec->the_bfd_section->index],
- &new_exidx_entry);
+ data->section_maps[sec->the_bfd_section->index].push_back
+ (new_exidx_entry);
}
}
if (sec != NULL)
{
struct arm_exidx_data *data;
- VEC(arm_exidx_entry_s) *map;
struct arm_exidx_entry map_key = { memaddr - obj_section_addr (sec), 0 };
- unsigned int idx;
- data = ((struct arm_exidx_data *)
- objfile_data (sec->objfile, arm_exidx_data_key));
+ data = arm_exidx_data_key.get (sec->objfile->obfd);
if (data != NULL)
{
- map = data->section_maps[sec->the_bfd_section->index];
- if (!VEC_empty (arm_exidx_entry_s, map))
+ std::vector<arm_exidx_entry> &map
+ = data->section_maps[sec->the_bfd_section->index];
+ if (!map.empty ())
{
- struct arm_exidx_entry *map_sym;
-
- idx = VEC_lower_bound (arm_exidx_entry_s, map, &map_key,
- arm_compare_exidx_entries);
+ auto idx = std::lower_bound (map.begin (), map.end (), map_key);
- /* VEC_lower_bound finds the earliest ordered insertion
+ /* std::lower_bound finds the earliest ordered insertion
point. If the following symbol starts at this exact
address, we use that; otherwise, the preceding
exception table entry covers this address. */
- if (idx < VEC_length (arm_exidx_entry_s, map))
+ if (idx < map.end ())
{
- map_sym = VEC_index (arm_exidx_entry_s, map, idx);
- if (map_sym->addr == map_key.addr)
+ if (idx->addr == map_key.addr)
{
if (start)
- *start = map_sym->addr + obj_section_addr (sec);
- return map_sym->entry;
+ *start = idx->addr + obj_section_addr (sec);
+ return idx->entry;
}
}
- if (idx > 0)
+ if (idx > map.begin ())
{
- map_sym = VEC_index (arm_exidx_entry_s, map, idx - 1);
+ idx = idx - 1;
if (start)
- *start = map_sym->addr + obj_section_addr (sec);
- return map_sym->entry;
+ *start = idx->addr + obj_section_addr (sec);
+ return idx->entry;
}
}
}
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);
/* Round alignment up to a whole number of words. */
- align = (align + INT_REGISTER_SIZE - 1) & ~(INT_REGISTER_SIZE - 1);
+ align = (align + ARM_INT_REGISTER_SIZE - 1)
+ & ~(ARM_INT_REGISTER_SIZE - 1);
/* Different ABIs have different maximum alignments. */
if (gdbarch_tdep (gdbarch)->arm_abi == ARM_ABI_APCS)
{
/* The APCS ABI only requires word alignment. */
- align = INT_REGISTER_SIZE;
+ align = ARM_INT_REGISTER_SIZE;
}
else
{
/* The AAPCS requires at most doubleword alignment. */
- if (align > INT_REGISTER_SIZE * 2)
- align = INT_REGISTER_SIZE * 2;
+ if (align > ARM_INT_REGISTER_SIZE * 2)
+ align = ARM_INT_REGISTER_SIZE * 2;
}
if (use_vfp_abi
}
}
- /* Push stack padding for dowubleword alignment. */
+ /* Push stack padding for doubleword alignment. */
if (nstack & (align - 1))
{
- si = push_stack_item (si, val, INT_REGISTER_SIZE);
- nstack += INT_REGISTER_SIZE;
+ si = push_stack_item (si, val, ARM_INT_REGISTER_SIZE);
+ nstack += ARM_INT_REGISTER_SIZE;
}
/* Doubleword aligned quantities must go in even register pairs. */
if (may_use_core_reg
&& argreg <= ARM_LAST_ARG_REGNUM
- && align > INT_REGISTER_SIZE
+ && align > ARM_INT_REGISTER_SIZE
&& argreg & 1)
argreg++;
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))
registers and stack. */
while (len > 0)
{
- int partial_len = len < INT_REGISTER_SIZE ? len : INT_REGISTER_SIZE;
+ int partial_len = len < ARM_INT_REGISTER_SIZE
+ ? len : ARM_INT_REGISTER_SIZE;
CORE_ADDR regval
= extract_unsigned_integer (val, partial_len, byte_order);
/* The argument is being passed in a general purpose
register. */
if (byte_order == BFD_ENDIAN_BIG)
- regval <<= (INT_REGISTER_SIZE - partial_len) * 8;
+ regval <<= (ARM_INT_REGISTER_SIZE - partial_len) * 8;
if (arm_debug)
fprintf_unfiltered (gdb_stdlog, "arg %d in %s = 0x%s\n",
argnum,
gdbarch_register_name
(gdbarch, argreg),
- phex (regval, INT_REGISTER_SIZE));
+ phex (regval, ARM_INT_REGISTER_SIZE));
regcache_cooked_write_unsigned (regcache, argreg, regval);
argreg++;
}
else
{
- gdb_byte buf[INT_REGISTER_SIZE];
+ gdb_byte buf[ARM_INT_REGISTER_SIZE];
memset (buf, 0, sizeof (buf));
store_unsigned_integer (buf, partial_len, byte_order, regval);
if (arm_debug)
fprintf_unfiltered (gdb_stdlog, "arg %d @ sp + %d\n",
argnum, nstack);
- si = push_stack_item (si, buf, INT_REGISTER_SIZE);
- nstack += INT_REGISTER_SIZE;
+ si = push_stack_item (si, buf, ARM_INT_REGISTER_SIZE);
+ nstack += ARM_INT_REGISTER_SIZE;
}
len -= partial_len;
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
location. */
ULONGEST
-displaced_read_reg (struct regcache *regs, arm_displaced_step_closure *dsc,
+displaced_read_reg (struct regcache *regs, arm_displaced_step_copy_insn_closure *dsc,
int regno)
{
ULONGEST ret;
/* Write to the PC as from a branch instruction. */
static void
-branch_write_pc (struct regcache *regs, arm_displaced_step_closure *dsc,
+branch_write_pc (struct regcache *regs, arm_displaced_step_copy_insn_closure *dsc,
ULONGEST val)
{
if (!dsc->is_thumb)
/* Write to the PC as if from a load instruction. */
static void
-load_write_pc (struct regcache *regs, arm_displaced_step_closure *dsc,
+load_write_pc (struct regcache *regs, arm_displaced_step_copy_insn_closure *dsc,
ULONGEST val)
{
if (DISPLACED_STEPPING_ARCH_VERSION >= 5)
/* Write to the PC as if from an ALU instruction. */
static void
-alu_write_pc (struct regcache *regs, arm_displaced_step_closure *dsc,
+alu_write_pc (struct regcache *regs, arm_displaced_step_copy_insn_closure *dsc,
ULONGEST val)
{
if (DISPLACED_STEPPING_ARCH_VERSION >= 7 && !dsc->is_thumb)
this is controlled by the WRITE_PC argument. */
void
-displaced_write_reg (struct regcache *regs, arm_displaced_step_closure *dsc,
+displaced_write_reg (struct regcache *regs, arm_displaced_step_copy_insn_closure *dsc,
int regno, ULONGEST val, enum pc_write_style write_pc)
{
if (regno == ARM_PC_REGNUM)
static int
arm_copy_unmodified (struct gdbarch *gdbarch, uint32_t insn,
- const char *iname, arm_displaced_step_closure *dsc)
+ const char *iname, arm_displaced_step_copy_insn_closure *dsc)
{
if (debug_displaced)
fprintf_unfiltered (gdb_stdlog, "displaced: copying insn %.8lx, "
static int
thumb_copy_unmodified_32bit (struct gdbarch *gdbarch, uint16_t insn1,
uint16_t insn2, const char *iname,
- arm_displaced_step_closure *dsc)
+ arm_displaced_step_copy_insn_closure *dsc)
{
if (debug_displaced)
fprintf_unfiltered (gdb_stdlog, "displaced: copying insn %.4x %.4x, "
static int
thumb_copy_unmodified_16bit (struct gdbarch *gdbarch, uint16_t insn,
const char *iname,
- arm_displaced_step_closure *dsc)
+ arm_displaced_step_copy_insn_closure *dsc)
{
if (debug_displaced)
fprintf_unfiltered (gdb_stdlog, "displaced: copying insn %.4x, "
static void
cleanup_preload (struct gdbarch *gdbarch,
- struct regcache *regs, arm_displaced_step_closure *dsc)
+ struct regcache *regs, arm_displaced_step_copy_insn_closure *dsc)
{
displaced_write_reg (regs, dsc, 0, dsc->tmp[0], CANNOT_WRITE_PC);
if (!dsc->u.preload.immed)
static void
install_preload (struct gdbarch *gdbarch, struct regcache *regs,
- arm_displaced_step_closure *dsc, unsigned int rn)
+ arm_displaced_step_copy_insn_closure *dsc, unsigned int rn)
{
ULONGEST rn_val;
/* Preload instructions:
static int
arm_copy_preload (struct gdbarch *gdbarch, uint32_t insn, struct regcache *regs,
- arm_displaced_step_closure *dsc)
+ arm_displaced_step_copy_insn_closure *dsc)
{
unsigned int rn = bits (insn, 16, 19);
static int
thumb2_copy_preload (struct gdbarch *gdbarch, uint16_t insn1, uint16_t insn2,
- struct regcache *regs, arm_displaced_step_closure *dsc)
+ struct regcache *regs, arm_displaced_step_copy_insn_closure *dsc)
{
unsigned int rn = bits (insn1, 0, 3);
unsigned int u_bit = bit (insn1, 7);
static void
install_preload_reg(struct gdbarch *gdbarch, struct regcache *regs,
- arm_displaced_step_closure *dsc, unsigned int rn,
+ arm_displaced_step_copy_insn_closure *dsc, unsigned int rn,
unsigned int rm)
{
ULONGEST rn_val, rm_val;
static int
arm_copy_preload_reg (struct gdbarch *gdbarch, uint32_t insn,
struct regcache *regs,
- arm_displaced_step_closure *dsc)
+ arm_displaced_step_copy_insn_closure *dsc)
{
unsigned int rn = bits (insn, 16, 19);
unsigned int rm = bits (insn, 0, 3);
static void
cleanup_copro_load_store (struct gdbarch *gdbarch,
struct regcache *regs,
- arm_displaced_step_closure *dsc)
+ arm_displaced_step_copy_insn_closure *dsc)
{
ULONGEST rn_val = displaced_read_reg (regs, dsc, 0);
static void
install_copro_load_store (struct gdbarch *gdbarch, struct regcache *regs,
- arm_displaced_step_closure *dsc,
+ arm_displaced_step_copy_insn_closure *dsc,
int writeback, unsigned int rn)
{
ULONGEST rn_val;
static int
arm_copy_copro_load_store (struct gdbarch *gdbarch, uint32_t insn,
struct regcache *regs,
- arm_displaced_step_closure *dsc)
+ arm_displaced_step_copy_insn_closure *dsc)
{
unsigned int rn = bits (insn, 16, 19);
static int
thumb2_copy_copro_load_store (struct gdbarch *gdbarch, uint16_t insn1,
uint16_t insn2, struct regcache *regs,
- arm_displaced_step_closure *dsc)
+ arm_displaced_step_copy_insn_closure *dsc)
{
unsigned int rn = bits (insn1, 0, 3);
static void
cleanup_branch (struct gdbarch *gdbarch, struct regcache *regs,
- arm_displaced_step_closure *dsc)
+ arm_displaced_step_copy_insn_closure *dsc)
{
uint32_t status = displaced_read_reg (regs, dsc, ARM_PS_REGNUM);
int branch_taken = condition_true (dsc->u.branch.cond, status);
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;
static void
install_b_bl_blx (struct gdbarch *gdbarch, struct regcache *regs,
- arm_displaced_step_closure *dsc,
+ arm_displaced_step_copy_insn_closure *dsc,
unsigned int cond, int exchange, int link, long offset)
{
/* Implement "BL<cond> <label>" as:
}
static int
arm_copy_b_bl_blx (struct gdbarch *gdbarch, uint32_t insn,
- struct regcache *regs, arm_displaced_step_closure *dsc)
+ struct regcache *regs, arm_displaced_step_copy_insn_closure *dsc)
{
unsigned int cond = bits (insn, 28, 31);
int exchange = (cond == 0xf);
static int
thumb2_copy_b_bl_blx (struct gdbarch *gdbarch, uint16_t insn1,
uint16_t insn2, struct regcache *regs,
- arm_displaced_step_closure *dsc)
+ arm_displaced_step_copy_insn_closure *dsc)
{
int link = bit (insn2, 14);
int exchange = link && !bit (insn2, 12);
/* Copy B Thumb instructions. */
static int
thumb_copy_b (struct gdbarch *gdbarch, uint16_t insn,
- arm_displaced_step_closure *dsc)
+ arm_displaced_step_copy_insn_closure *dsc)
{
unsigned int cond = 0;
int offset = 0;
static void
install_bx_blx_reg (struct gdbarch *gdbarch, struct regcache *regs,
- arm_displaced_step_closure *dsc, int link,
+ arm_displaced_step_copy_insn_closure *dsc, int link,
unsigned int cond, unsigned int rm)
{
/* Implement {BX,BLX}<cond> <reg>" as:
static int
arm_copy_bx_blx_reg (struct gdbarch *gdbarch, uint32_t insn,
- struct regcache *regs, arm_displaced_step_closure *dsc)
+ struct regcache *regs, arm_displaced_step_copy_insn_closure *dsc)
{
unsigned int cond = bits (insn, 28, 31);
/* BX: x12xxx1x
static int
thumb_copy_bx_blx_reg (struct gdbarch *gdbarch, uint16_t insn,
struct regcache *regs,
- arm_displaced_step_closure *dsc)
+ arm_displaced_step_copy_insn_closure *dsc)
{
int link = bit (insn, 7);
unsigned int rm = bits (insn, 3, 6);
static void
cleanup_alu_imm (struct gdbarch *gdbarch,
- struct regcache *regs, arm_displaced_step_closure *dsc)
+ struct regcache *regs, arm_displaced_step_copy_insn_closure *dsc)
{
ULONGEST rd_val = displaced_read_reg (regs, dsc, 0);
displaced_write_reg (regs, dsc, 0, dsc->tmp[0], CANNOT_WRITE_PC);
static int
arm_copy_alu_imm (struct gdbarch *gdbarch, uint32_t insn, struct regcache *regs,
- arm_displaced_step_closure *dsc)
+ arm_displaced_step_copy_insn_closure *dsc)
{
unsigned int rn = bits (insn, 16, 19);
unsigned int rd = bits (insn, 12, 15);
static int
thumb2_copy_alu_imm (struct gdbarch *gdbarch, uint16_t insn1,
uint16_t insn2, struct regcache *regs,
- arm_displaced_step_closure *dsc)
+ arm_displaced_step_copy_insn_closure *dsc)
{
unsigned int op = bits (insn1, 5, 8);
unsigned int rn, rm, rd;
static void
cleanup_alu_reg (struct gdbarch *gdbarch,
- struct regcache *regs, arm_displaced_step_closure *dsc)
+ struct regcache *regs, arm_displaced_step_copy_insn_closure *dsc)
{
ULONGEST rd_val;
int i;
static void
install_alu_reg (struct gdbarch *gdbarch, struct regcache *regs,
- arm_displaced_step_closure *dsc,
+ arm_displaced_step_copy_insn_closure *dsc,
unsigned int rd, unsigned int rn, unsigned int rm)
{
ULONGEST rd_val, rn_val, rm_val;
static int
arm_copy_alu_reg (struct gdbarch *gdbarch, uint32_t insn, struct regcache *regs,
- arm_displaced_step_closure *dsc)
+ arm_displaced_step_copy_insn_closure *dsc)
{
unsigned int op = bits (insn, 21, 24);
int is_mov = (op == 0xd);
static int
thumb_copy_alu_reg (struct gdbarch *gdbarch, uint16_t insn,
struct regcache *regs,
- arm_displaced_step_closure *dsc)
+ arm_displaced_step_copy_insn_closure *dsc)
{
unsigned rm, rd;
static void
cleanup_alu_shifted_reg (struct gdbarch *gdbarch,
struct regcache *regs,
- arm_displaced_step_closure *dsc)
+ arm_displaced_step_copy_insn_closure *dsc)
{
ULONGEST rd_val = displaced_read_reg (regs, dsc, 0);
int i;
static void
install_alu_shifted_reg (struct gdbarch *gdbarch, struct regcache *regs,
- arm_displaced_step_closure *dsc,
+ arm_displaced_step_copy_insn_closure *dsc,
unsigned int rd, unsigned int rn, unsigned int rm,
unsigned rs)
{
static int
arm_copy_alu_shifted_reg (struct gdbarch *gdbarch, uint32_t insn,
struct regcache *regs,
- arm_displaced_step_closure *dsc)
+ arm_displaced_step_copy_insn_closure *dsc)
{
unsigned int op = bits (insn, 21, 24);
int is_mov = (op == 0xd);
static void
cleanup_load (struct gdbarch *gdbarch, struct regcache *regs,
- arm_displaced_step_closure *dsc)
+ arm_displaced_step_copy_insn_closure *dsc)
{
ULONGEST rt_val, rt_val2 = 0, rn_val;
static void
cleanup_store (struct gdbarch *gdbarch, struct regcache *regs,
- arm_displaced_step_closure *dsc)
+ arm_displaced_step_copy_insn_closure *dsc)
{
ULONGEST rn_val = displaced_read_reg (regs, dsc, 2);
static int
arm_copy_extra_ld_st (struct gdbarch *gdbarch, uint32_t insn, int unprivileged,
- struct regcache *regs, arm_displaced_step_closure *dsc)
+ struct regcache *regs, arm_displaced_step_copy_insn_closure *dsc)
{
unsigned int op1 = bits (insn, 20, 24);
unsigned int op2 = bits (insn, 5, 6);
static void
install_load_store (struct gdbarch *gdbarch, struct regcache *regs,
- arm_displaced_step_closure *dsc, int load,
+ arm_displaced_step_copy_insn_closure *dsc, int load,
int immed, int writeback, int size, int usermode,
int rt, int rm, int rn)
{
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
static int
thumb2_copy_load_literal (struct gdbarch *gdbarch, uint16_t insn1,
uint16_t insn2, struct regcache *regs,
- arm_displaced_step_closure *dsc, int size)
+ arm_displaced_step_copy_insn_closure *dsc, int size)
{
unsigned int u_bit = bit (insn1, 7);
unsigned int rt = bits (insn2, 12, 15);
static int
thumb2_copy_load_reg_imm (struct gdbarch *gdbarch, uint16_t insn1,
uint16_t insn2, struct regcache *regs,
- arm_displaced_step_closure *dsc,
+ arm_displaced_step_copy_insn_closure *dsc,
int writeback, int immed)
{
unsigned int rt = bits (insn2, 12, 15);
static int
arm_copy_ldr_str_ldrb_strb (struct gdbarch *gdbarch, uint32_t insn,
struct regcache *regs,
- arm_displaced_step_closure *dsc,
+ arm_displaced_step_copy_insn_closure *dsc,
int load, int size, int usermode)
{
int immed = !bit (insn, 25);
static void
cleanup_block_load_all (struct gdbarch *gdbarch, struct regcache *regs,
- arm_displaced_step_closure *dsc)
+ arm_displaced_step_copy_insn_closure *dsc)
{
int inc = dsc->u.block.increment;
int bump_before = dsc->u.block.before ? (inc ? 4 : -4) : 0;
static void
cleanup_block_store_pc (struct gdbarch *gdbarch, struct regcache *regs,
- arm_displaced_step_closure *dsc)
+ arm_displaced_step_copy_insn_closure *dsc)
{
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;
static void
cleanup_block_load_pc (struct gdbarch *gdbarch,
struct regcache *regs,
- arm_displaced_step_closure *dsc)
+ arm_displaced_step_copy_insn_closure *dsc)
{
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
static int
arm_copy_block_xfer (struct gdbarch *gdbarch, uint32_t insn,
struct regcache *regs,
- arm_displaced_step_closure *dsc)
+ arm_displaced_step_copy_insn_closure *dsc)
{
int load = bit (insn, 20);
int user = bit (insn, 22);
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++)
static int
thumb2_copy_block_xfer (struct gdbarch *gdbarch, uint16_t insn1, uint16_t insn2,
struct regcache *regs,
- arm_displaced_step_closure *dsc)
+ arm_displaced_step_copy_insn_closure *dsc)
{
int rn = bits (insn1, 0, 3);
int load = bit (insn1, 4);
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++)
static void
cleanup_svc (struct gdbarch *gdbarch, struct regcache *regs,
- arm_displaced_step_closure *dsc)
+ arm_displaced_step_copy_insn_closure *dsc)
{
CORE_ADDR resume_addr = dsc->insn_addr + dsc->insn_size;
}
-/* Common copy routine for svc instruciton. */
+/* Common copy routine for svc instruction. */
static int
install_svc (struct gdbarch *gdbarch, struct regcache *regs,
- arm_displaced_step_closure *dsc)
+ arm_displaced_step_copy_insn_closure *dsc)
{
/* Preparation: none.
Insn: unmodified svc.
static int
arm_copy_svc (struct gdbarch *gdbarch, uint32_t insn,
- struct regcache *regs, arm_displaced_step_closure *dsc)
+ struct regcache *regs, arm_displaced_step_copy_insn_closure *dsc)
{
if (debug_displaced)
static int
thumb_copy_svc (struct gdbarch *gdbarch, uint16_t insn,
- struct regcache *regs, arm_displaced_step_closure *dsc)
+ struct regcache *regs, arm_displaced_step_copy_insn_closure *dsc)
{
if (debug_displaced)
static int
arm_copy_undef (struct gdbarch *gdbarch, uint32_t insn,
- arm_displaced_step_closure *dsc)
+ arm_displaced_step_copy_insn_closure *dsc)
{
if (debug_displaced)
fprintf_unfiltered (gdb_stdlog,
static int
thumb_32bit_copy_undef (struct gdbarch *gdbarch, uint16_t insn1, uint16_t insn2,
- arm_displaced_step_closure *dsc)
+ arm_displaced_step_copy_insn_closure *dsc)
{
if (debug_displaced)
static int
arm_copy_unpred (struct gdbarch *gdbarch, uint32_t insn,
- arm_displaced_step_closure *dsc)
+ arm_displaced_step_copy_insn_closure *dsc)
{
if (debug_displaced)
fprintf_unfiltered (gdb_stdlog, "displaced: copying unpredictable insn "
static int
arm_decode_misc_memhint_neon (struct gdbarch *gdbarch, uint32_t insn,
struct regcache *regs,
- arm_displaced_step_closure *dsc)
+ arm_displaced_step_copy_insn_closure *dsc)
{
unsigned int op1 = bits (insn, 20, 26), op2 = bits (insn, 4, 7);
unsigned int rn = bits (insn, 16, 19);
static int
arm_decode_unconditional (struct gdbarch *gdbarch, uint32_t insn,
struct regcache *regs,
- arm_displaced_step_closure *dsc)
+ arm_displaced_step_copy_insn_closure *dsc)
{
if (bit (insn, 27) == 0)
return arm_decode_misc_memhint_neon (gdbarch, insn, regs, dsc);
static int
arm_decode_miscellaneous (struct gdbarch *gdbarch, uint32_t insn,
struct regcache *regs,
- arm_displaced_step_closure *dsc)
+ arm_displaced_step_copy_insn_closure *dsc)
{
unsigned int op2 = bits (insn, 4, 6);
unsigned int op = bits (insn, 21, 22);
static int
arm_decode_dp_misc (struct gdbarch *gdbarch, uint32_t insn,
struct regcache *regs,
- arm_displaced_step_closure *dsc)
+ arm_displaced_step_copy_insn_closure *dsc)
{
if (bit (insn, 25))
switch (bits (insn, 20, 24))
static int
arm_decode_ld_st_word_ubyte (struct gdbarch *gdbarch, uint32_t insn,
struct regcache *regs,
- arm_displaced_step_closure *dsc)
+ arm_displaced_step_copy_insn_closure *dsc)
{
int a = bit (insn, 25), b = bit (insn, 4);
uint32_t op1 = bits (insn, 20, 24);
static int
arm_decode_media (struct gdbarch *gdbarch, uint32_t insn,
- arm_displaced_step_closure *dsc)
+ arm_displaced_step_copy_insn_closure *dsc)
{
switch (bits (insn, 20, 24))
{
static int
arm_decode_b_bl_ldmstm (struct gdbarch *gdbarch, uint32_t insn,
struct regcache *regs,
- arm_displaced_step_closure *dsc)
+ arm_displaced_step_copy_insn_closure *dsc)
{
if (bit (insn, 25))
return arm_copy_b_bl_blx (gdbarch, insn, regs, dsc);
static int
arm_decode_ext_reg_ld_st (struct gdbarch *gdbarch, uint32_t insn,
struct regcache *regs,
- arm_displaced_step_closure *dsc)
+ arm_displaced_step_copy_insn_closure *dsc)
{
unsigned int opcode = bits (insn, 20, 24);
static int
thumb2_decode_dp_shift_reg (struct gdbarch *gdbarch, uint16_t insn1,
uint16_t insn2, struct regcache *regs,
- arm_displaced_step_closure *dsc)
+ arm_displaced_step_copy_insn_closure *dsc)
{
/* PC is only allowed to be used in instruction MOV. */
static int
thumb2_decode_ext_reg_ld_st (struct gdbarch *gdbarch, uint16_t insn1,
uint16_t insn2, struct regcache *regs,
- arm_displaced_step_closure *dsc)
+ arm_displaced_step_copy_insn_closure *dsc)
{
unsigned int opcode = bits (insn1, 4, 8);
static int
arm_decode_svc_copro (struct gdbarch *gdbarch, uint32_t insn,
- struct regcache *regs, arm_displaced_step_closure *dsc)
+ struct regcache *regs, arm_displaced_step_copy_insn_closure *dsc)
{
unsigned int op1 = bits (insn, 20, 25);
int op = bit (insn, 4);
static int
thumb2_decode_svc_copro (struct gdbarch *gdbarch, uint16_t insn1,
uint16_t insn2, struct regcache *regs,
- arm_displaced_step_closure *dsc)
+ arm_displaced_step_copy_insn_closure *dsc)
{
unsigned int coproc = bits (insn2, 8, 11);
unsigned int bit_5_8 = bits (insn1, 5, 8);
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);
}
static void
install_pc_relative (struct gdbarch *gdbarch, struct regcache *regs,
- arm_displaced_step_closure *dsc, int rd)
+ arm_displaced_step_copy_insn_closure *dsc, int rd)
{
/* ADR Rd, #imm
static int
thumb_copy_pc_relative_16bit (struct gdbarch *gdbarch, struct regcache *regs,
- arm_displaced_step_closure *dsc,
+ arm_displaced_step_copy_insn_closure *dsc,
int rd, unsigned int imm)
{
static int
thumb_decode_pc_relative_16bit (struct gdbarch *gdbarch, uint16_t insn,
struct regcache *regs,
- arm_displaced_step_closure *dsc)
+ arm_displaced_step_copy_insn_closure *dsc)
{
unsigned int rd = bits (insn, 8, 10);
unsigned int imm8 = bits (insn, 0, 7);
static int
thumb_copy_pc_relative_32bit (struct gdbarch *gdbarch, uint16_t insn1,
uint16_t insn2, struct regcache *regs,
- arm_displaced_step_closure *dsc)
+ arm_displaced_step_copy_insn_closure *dsc)
{
unsigned int rd = bits (insn2, 8, 11);
/* Since immediate has the same encoding in ADR ADD and SUB, so we simply
static int
thumb_copy_16bit_ldr_literal (struct gdbarch *gdbarch, uint16_t insn1,
struct regcache *regs,
- arm_displaced_step_closure *dsc)
+ arm_displaced_step_copy_insn_closure *dsc)
{
unsigned int rt = bits (insn1, 8, 10);
unsigned int pc;
return 0;
}
-/* Copy Thumb cbnz/cbz insruction. */
+/* Copy Thumb cbnz/cbz instruction. */
static int
thumb_copy_cbnz_cbz (struct gdbarch *gdbarch, uint16_t insn1,
struct regcache *regs,
- arm_displaced_step_closure *dsc)
+ arm_displaced_step_copy_insn_closure *dsc)
{
int non_zero = bit (insn1, 11);
unsigned int imm5 = (bit (insn1, 9) << 6) | (bits (insn1, 3, 7) << 1);
static int
thumb2_copy_table_branch (struct gdbarch *gdbarch, uint16_t insn1,
uint16_t insn2, struct regcache *regs,
- arm_displaced_step_closure *dsc)
+ arm_displaced_step_copy_insn_closure *dsc)
{
ULONGEST rn_val, rm_val;
int is_tbh = bit (insn2, 4);
static void
cleanup_pop_pc_16bit_all (struct gdbarch *gdbarch, struct regcache *regs,
- arm_displaced_step_closure *dsc)
+ arm_displaced_step_copy_insn_closure *dsc)
{
/* PC <- r7 */
int val = displaced_read_reg (regs, dsc, 7);
static int
thumb_copy_pop_pc_16bit (struct gdbarch *gdbarch, uint16_t insn1,
struct regcache *regs,
- arm_displaced_step_closure *dsc)
+ arm_displaced_step_copy_insn_closure *dsc)
{
dsc->u.block.regmask = insn1 & 0x00ff;
}
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;
static void
thumb_process_displaced_16bit_insn (struct gdbarch *gdbarch, uint16_t insn1,
struct regcache *regs,
- arm_displaced_step_closure *dsc)
+ arm_displaced_step_copy_insn_closure *dsc)
{
unsigned short op_bit_12_15 = bits (insn1, 12, 15);
unsigned short op_bit_10_11 = bits (insn1, 10, 11);
decode_thumb_32bit_ld_mem_hints (struct gdbarch *gdbarch,
uint16_t insn1, uint16_t insn2,
struct regcache *regs,
- arm_displaced_step_closure *dsc)
+ arm_displaced_step_copy_insn_closure *dsc)
{
int rt = bits (insn2, 12, 15);
int rn = bits (insn1, 0, 3);
static void
thumb_process_displaced_32bit_insn (struct gdbarch *gdbarch, uint16_t insn1,
uint16_t insn2, struct regcache *regs,
- arm_displaced_step_closure *dsc)
+ arm_displaced_step_copy_insn_closure *dsc)
{
int err = 0;
unsigned short op = bit (insn2, 15);
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);
}
static void
thumb_process_displaced_insn (struct gdbarch *gdbarch, CORE_ADDR from,
struct regcache *regs,
- arm_displaced_step_closure *dsc)
+ arm_displaced_step_copy_insn_closure *dsc)
{
enum bfd_endian byte_order_for_code = gdbarch_byte_order_for_code (gdbarch);
uint16_t insn1
void
arm_process_displaced_insn (struct gdbarch *gdbarch, CORE_ADDR from,
CORE_ADDR to, struct regcache *regs,
- arm_displaced_step_closure *dsc)
+ arm_displaced_step_copy_insn_closure *dsc)
{
int err = 0;
enum bfd_endian byte_order_for_code = gdbarch_byte_order_for_code (gdbarch);
void
arm_displaced_init_closure (struct gdbarch *gdbarch, CORE_ADDR from,
- CORE_ADDR to, arm_displaced_step_closure *dsc)
+ CORE_ADDR to, arm_displaced_step_copy_insn_closure *dsc)
{
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
unsigned int i, len, offset;
void
arm_displaced_step_fixup (struct gdbarch *gdbarch,
- struct displaced_step_closure *dsc_,
+ struct displaced_step_copy_insn_closure *dsc_,
CORE_ADDR from, CORE_ADDR to,
struct regcache *regs)
{
- arm_displaced_step_closure *dsc = (arm_displaced_step_closure *) dsc_;
+ arm_displaced_step_copy_insn_closure *dsc = (arm_displaced_step_copy_insn_closure *) dsc_;
if (dsc->cleanup)
dsc->cleanup (gdbarch, regs, 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)
{
/* The value is in register F0 in internal format. We need to
extract the raw value and then convert it to the desired
internal type. */
- bfd_byte tmpbuf[FP_REGISTER_SIZE];
+ bfd_byte tmpbuf[ARM_FP_REGISTER_SIZE];
regs->cooked_read (ARM_F0_REGNUM, tmpbuf);
target_float_convert (tmpbuf, arm_ext_type (gdbarch),
case ARM_FLOAT_VFP:
regs->cooked_read (ARM_A1_REGNUM, valbuf);
if (TYPE_LENGTH (type) > 4)
- regs->cooked_read (ARM_A1_REGNUM + 1, valbuf + INT_REGISTER_SIZE);
+ regs->cooked_read (ARM_A1_REGNUM + 1,
+ valbuf + ARM_INT_REGISTER_SIZE);
break;
default:
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
anything special for small big-endian values. */
regcache_cooked_read_unsigned (regs, regno++, &tmp);
store_unsigned_integer (valbuf,
- (len > INT_REGISTER_SIZE
- ? INT_REGISTER_SIZE : len),
+ (len > ARM_INT_REGISTER_SIZE
+ ? ARM_INT_REGISTER_SIZE : len),
byte_order, tmp);
- len -= INT_REGISTER_SIZE;
- valbuf += INT_REGISTER_SIZE;
+ len -= ARM_INT_REGISTER_SIZE;
+ valbuf += ARM_INT_REGISTER_SIZE;
}
}
else
registers with 32-bit load instruction(s). */
int len = TYPE_LENGTH (type);
int regno = ARM_A1_REGNUM;
- bfd_byte tmpbuf[INT_REGISTER_SIZE];
+ bfd_byte tmpbuf[ARM_INT_REGISTER_SIZE];
while (len > 0)
{
regs->cooked_read (regno++, tmpbuf);
memcpy (valbuf, tmpbuf,
- len > INT_REGISTER_SIZE ? INT_REGISTER_SIZE : len);
- len -= INT_REGISTER_SIZE;
- valbuf += INT_REGISTER_SIZE;
+ len > ARM_INT_REGISTER_SIZE ? ARM_INT_REGISTER_SIZE : len);
+ len -= ARM_INT_REGISTER_SIZE;
+ valbuf += ARM_INT_REGISTER_SIZE;
}
}
}
/* 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;
{
/* The AAPCS says all aggregates not larger than a word are returned
in a register. */
- if (TYPE_LENGTH (type) <= INT_REGISTER_SIZE)
+ if (TYPE_LENGTH (type) <= ARM_INT_REGISTER_SIZE)
return 0;
return 1;
/* All aggregate types that won't fit in a register must be returned
in memory. */
- if (TYPE_LENGTH (type) > INT_REGISTER_SIZE)
+ if (TYPE_LENGTH (type) > ARM_INT_REGISTER_SIZE)
return 1;
/* In the ARM ABI, "integer" like aggregate types are returned in
registers. For an aggregate type to be integer like, its size
- must be less than or equal to INT_REGISTER_SIZE and the
+ must be less than or equal to ARM_INT_REGISTER_SIZE and the
offset of each addressable subfield must be zero. Note that bit
fields are not addressable, and all addressable subfields of
unions always start at offset zero.
int i;
/* Need to check if this struct/union is "integer" like. For
this to be true, its size must be less than or equal to
- INT_REGISTER_SIZE and the offset of each addressable
+ ARM_INT_REGISTER_SIZE and the offset of each addressable
subfield must be zero. Note that bit fields are not
addressable, and unions always start at offset zero. If any
of the subfields is a floating point type, the struct/union
--> 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[FP_REGISTER_SIZE];
+ gdb_byte buf[ARM_FP_REGISTER_SIZE];
switch (gdbarch_tdep (gdbarch)->fp_model)
{
case ARM_FLOAT_VFP:
regs->cooked_write (ARM_A1_REGNUM, valbuf);
if (TYPE_LENGTH (type) > 4)
- regs->cooked_write (ARM_A1_REGNUM + 1, valbuf + INT_REGISTER_SIZE);
+ regs->cooked_write (ARM_A1_REGNUM + 1,
+ valbuf + ARM_INT_REGISTER_SIZE);
break;
default:
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)
{
/* Values of one word or less are zero/sign-extended and
returned in r0. */
- bfd_byte tmpbuf[INT_REGISTER_SIZE];
+ bfd_byte tmpbuf[ARM_INT_REGISTER_SIZE];
LONGEST val = unpack_long (type, valbuf);
- store_signed_integer (tmpbuf, INT_REGISTER_SIZE, byte_order, val);
+ store_signed_integer (tmpbuf, ARM_INT_REGISTER_SIZE, byte_order, val);
regs->cooked_write (ARM_A1_REGNUM, tmpbuf);
}
else
while (len > 0)
{
regs->cooked_write (regno++, valbuf);
- len -= INT_REGISTER_SIZE;
- valbuf += INT_REGISTER_SIZE;
+ len -= ARM_INT_REGISTER_SIZE;
+ valbuf += ARM_INT_REGISTER_SIZE;
}
}
}
registers with 32-bit load instruction(s). */
int len = TYPE_LENGTH (type);
int regno = ARM_A1_REGNUM;
- bfd_byte tmpbuf[INT_REGISTER_SIZE];
+ bfd_byte tmpbuf[ARM_INT_REGISTER_SIZE];
while (len > 0)
{
memcpy (tmpbuf, valbuf,
- len > INT_REGISTER_SIZE ? INT_REGISTER_SIZE : len);
+ len > ARM_INT_REGISTER_SIZE ? ARM_INT_REGISTER_SIZE : len);
regs->cooked_write (regno++, tmpbuf);
- len -= INT_REGISTER_SIZE;
- valbuf += INT_REGISTER_SIZE;
+ len -= ARM_INT_REGISTER_SIZE;
+ valbuf += ARM_INT_REGISTER_SIZE;
}
}
}
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;
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
CORE_ADDR jb_addr;
- gdb_byte buf[INT_REGISTER_SIZE];
+ gdb_byte buf[ARM_INT_REGISTER_SIZE];
jb_addr = get_frame_register_unsigned (frame, ARM_A1_REGNUM);
if (target_read_memory (jb_addr + tdep->jb_pc * tdep->jb_elt_size, buf,
- INT_REGISTER_SIZE))
+ ARM_INT_REGISTER_SIZE))
return 0;
- *pc = extract_unsigned_integer (buf, INT_REGISTER_SIZE, byte_order);
+ *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
MSYMBOL_SET_SPECIAL (msym);
}
-static void
-arm_objfile_data_free (struct objfile *objfile, void *arg)
-{
- struct arm_per_objfile *data = (struct arm_per_objfile *) arg;
-
- delete data;
-}
-
static void
arm_record_special_symbol (struct gdbarch *gdbarch, struct objfile *objfile,
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 = (struct arm_per_objfile *) objfile_data (objfile,
- arm_objfile_data_key);
+ data = arm_bfd_data_key.get (objfile->obfd);
if (data == NULL)
- {
- data = new arm_per_objfile (objfile->obfd->section_count);
- set_objfile_data (objfile, arm_objfile_data_key, data);
- }
+ 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];
return default_register_reggroup_p (gdbarch, regnum, group);
}
-\f
/* For backward-compatibility we allow two 'g' packet lengths with
the remote protocol depending on whether FPA registers are
supplied. M-profile targets do not have FPA registers, but some
{
if (gdbarch_tdep (gdbarch)->is_m)
{
+ const target_desc *tdesc;
+
/* If we know from the executable this is an M-profile target,
cater for remote targets whose register set layout is the
same as the FPA layout. */
+ tdesc = arm_read_mprofile_description (ARM_M_TYPE_WITH_FPA);
register_remote_g_packet_guess (gdbarch,
- /* r0-r12,sp,lr,pc; f0-f7; fps,xpsr */
- (16 * INT_REGISTER_SIZE)
- + (8 * FP_REGISTER_SIZE)
- + (2 * INT_REGISTER_SIZE),
- tdesc_arm_with_m_fpa_layout);
+ ARM_CORE_REGS_SIZE + ARM_FP_REGS_SIZE,
+ tdesc);
/* The regular M-profile layout. */
- register_remote_g_packet_guess (gdbarch,
- /* r0-r12,sp,lr,pc; xpsr */
- (16 * INT_REGISTER_SIZE)
- + INT_REGISTER_SIZE,
- tdesc_arm_with_m);
+ tdesc = arm_read_mprofile_description (ARM_M_TYPE_M_PROFILE);
+ register_remote_g_packet_guess (gdbarch, ARM_CORE_REGS_SIZE,
+ tdesc);
/* M-profile plus M4F VFP. */
+ tdesc = arm_read_mprofile_description (ARM_M_TYPE_VFP_D16);
register_remote_g_packet_guess (gdbarch,
- /* r0-r12,sp,lr,pc; d0-d15; fpscr,xpsr */
- (16 * INT_REGISTER_SIZE)
- + (16 * VFP_REGISTER_SIZE)
- + (2 * INT_REGISTER_SIZE),
- tdesc_arm_with_m_vfp_d16);
+ ARM_CORE_REGS_SIZE + ARM_VFP2_REGS_SIZE,
+ tdesc);
}
/* Otherwise we don't have a useful guess. */
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;
}
}
}
/* Note: for displaced stepping, this includes the breakpoint, and one word
of additional scratch space. This setting isn't used for anything beside
displaced stepping at present. */
- set_gdbarch_max_insn_length (gdbarch, 4 * DISPLACED_MODIFIED_INSNS);
+ set_gdbarch_max_insn_length (gdbarch, 4 * ARM_DISPLACED_MODIFIED_INSNS);
/* This should be low enough for everything. */
tdep->lowest_pc = 0x20;
}
/* 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;
gdbarch_register (bfd_arch_arm, arm_gdbarch_init, arm_dump_tdep);
- arm_objfile_data_key
- = register_objfile_data_with_cleanup (NULL, arm_objfile_data_free);
-
/* Add ourselves to objfile event chain. */
gdb::observers::new_objfile.attach (arm_exidx_new_objfile);
- arm_exidx_data_key
- = register_objfile_data_with_cleanup (NULL, arm_exidx_data_free);
/* Register an ELF OS ABI sniffer for ARM binaries. */
gdbarch_register_osabi_sniffer (bfd_arch_arm,
bfd_target_elf_flavour,
arm_elf_osabi_sniffer);
- /* Initialize the standard target descriptions. */
- initialize_tdesc_arm_with_m ();
- initialize_tdesc_arm_with_m_fpa_layout ();
- initialize_tdesc_arm_with_m_vfp_d16 ();
- initialize_tdesc_arm_with_iwmmxt ();
- initialize_tdesc_arm_with_vfpv2 ();
- initialize_tdesc_arm_with_vfpv3 ();
- initialize_tdesc_arm_with_neon ();
-
/* 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");
{
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)
/* STMDA (STMED): Decrement after. */
case 0:
record_buf_mem[1] = (uint32_t) u_regval
- - register_count * INT_REGISTER_SIZE + 4;
+ - register_count * ARM_INT_REGISTER_SIZE + 4;
break;
/* STM (STMIA, STMEA): Increment after. */
case 1:
/* STMDB (STMFD): Decrement before. */
case 2:
record_buf_mem[1] = (uint32_t) u_regval
- - register_count * INT_REGISTER_SIZE;
+ - register_count * ARM_INT_REGISTER_SIZE;
break;
/* STMIB (STMFA): Increment before. */
case 3:
- record_buf_mem[1] = (uint32_t) u_regval + INT_REGISTER_SIZE;
+ record_buf_mem[1] = (uint32_t) u_regval + ARM_INT_REGISTER_SIZE;
break;
default:
gdb_assert_not_reached ("no decoding pattern found");
break;
}
- record_buf_mem[0] = register_count * INT_REGISTER_SIZE;
+ record_buf_mem[0] = register_count * ARM_INT_REGISTER_SIZE;
arm_insn_r->mem_rec_count = 1;
/* If wback is true, also save the base register, which is going to be
} // 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,
return ret;
}
+
+/* See arm-tdep.h. */
+
+const target_desc *
+arm_read_description (arm_fp_type fp_type)
+{
+ struct target_desc *tdesc = tdesc_arm_list[fp_type];
+
+ if (tdesc == nullptr)
+ {
+ tdesc = arm_create_target_description (fp_type);
+ tdesc_arm_list[fp_type] = tdesc;
+ }
+
+ return tdesc;
+}
+
+/* See arm-tdep.h. */
+
+const target_desc *
+arm_read_mprofile_description (arm_m_profile_type m_type)
+{
+ struct target_desc *tdesc = tdesc_arm_mprofile_list[m_type];
+
+ if (tdesc == nullptr)
+ {
+ tdesc = arm_create_mprofile_target_description (m_type);
+ tdesc_arm_mprofile_list[m_type] = tdesc;
+ }
+
+ return tdesc;
+}