/* Common target dependent code for GDB on ARM systems.
- Copyright (C) 1988-2018 Free Software Foundation, Inc.
+ Copyright (C) 1988-2019 Free Software Foundation, Inc.
This file is part of GDB.
#include "remote.h"
#include "target-descriptions.h"
#include "user-regs.h"
-#include "observer.h"
+#include "observable.h"
#include "arch/arm.h"
#include "arch/arm-get-next-pcs.h"
#include "coff/internal.h"
#include "elf/arm.h"
-#include "vec.h"
+#include "common/vec.h"
#include "record.h"
#include "record-full.h"
#include "features/arm/arm-with-neon.c"
#if GDB_SELF_TEST
-#include "selftest.h"
+#include "common/selftest.h"
#endif
static int arm_debug;
#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;
char type;
+
+ bool operator< (const arm_mapping_symbol &other) const
+ { return this->value < other.value; }
};
-typedef struct arm_mapping_symbol arm_mapping_symbol_s;
-DEF_VEC_O(arm_mapping_symbol_s);
+
+typedef std::vector<arm_mapping_symbol> arm_mapping_symbol_vec;
struct arm_per_objfile
{
- VEC(arm_mapping_symbol_s) **section_maps;
+ explicit arm_per_objfile (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);
+
+ /* Information about mapping symbols ($a, $d, $t) in the objfile.
+
+ The format is an array of vectors of arm_mapping_symbols, there is one
+ vector for each section of the objfile (the array is index by BFD section
+ index).
+
+ For each section, the vector of arm_mapping_symbol is sorted by
+ symbol value (address). */
+ std::unique_ptr<arm_mapping_symbol_vec[]> section_maps;
+
+ /* For each corresponding element of section_maps above, is this vector
+ sorted. */
+ std::unique_ptr<bool[]> section_maps_sorted;
};
+/* Per-objfile data used for mapping symbols. */
+static objfile_key<arm_per_objfile> arm_objfile_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;
return (cpsr & t_bit) != 0;
}
-/* Callback for VEC_lower_bound. */
-
-static inline int
-arm_compare_mapping_symbols (const struct arm_mapping_symbol *lhs,
- const struct arm_mapping_symbol *rhs)
-{
- return lhs->value < rhs->value;
-}
-
/* Search for the mapping symbol covering MEMADDR. If one is found,
return its type. Otherwise, return 0. If START is non-NULL,
set *START to the location of the mapping symbol. */
sec = find_pc_section (memaddr);
if (sec != NULL)
{
- struct arm_per_objfile *data;
- VEC(arm_mapping_symbol_s) *map;
- struct arm_mapping_symbol map_key = { memaddr - obj_section_addr (sec),
- 0 };
- unsigned int idx;
-
- data = (struct arm_per_objfile *) objfile_data (sec->objfile,
- arm_objfile_data_key);
+ arm_per_objfile *data = arm_objfile_data_key.get (sec->objfile);
if (data != NULL)
{
- map = data->section_maps[sec->the_bfd_section->index];
- if (!VEC_empty (arm_mapping_symbol_s, map))
- {
- struct arm_mapping_symbol *map_sym;
+ unsigned int section_idx = sec->the_bfd_section->index;
+ arm_mapping_symbol_vec &map
+ = data->section_maps[section_idx];
- idx = VEC_lower_bound (arm_mapping_symbol_s, map, &map_key,
- arm_compare_mapping_symbols);
+ /* Sort the vector on first use. */
+ if (!data->section_maps_sorted[section_idx])
+ {
+ std::sort (map.begin (), map.end ());
+ data->section_maps_sorted[section_idx] = true;
+ }
- /* VEC_lower_bound finds the earliest ordered insertion
- point. If the following symbol starts at this exact
- address, we use that; otherwise, the preceding
- mapping symbol covers this address. */
- if (idx < VEC_length (arm_mapping_symbol_s, map))
- {
- map_sym = VEC_index (arm_mapping_symbol_s, map, idx);
- if (map_sym->value == map_key.value)
- {
- if (start)
- *start = map_sym->value + obj_section_addr (sec);
- return map_sym->type;
- }
- }
+ struct arm_mapping_symbol map_key
+ = { memaddr - obj_section_addr (sec), 0 };
+ arm_mapping_symbol_vec::const_iterator it
+ = std::lower_bound (map.begin (), map.end (), map_key);
- if (idx > 0)
+ /* std::lower_bound finds the earliest ordered insertion
+ point. If the symbol at this position starts at this exact
+ address, we use that; otherwise, the preceding
+ mapping symbol covers this address. */
+ if (it < map.end ())
+ {
+ if (it->value == map_key.value)
{
- map_sym = VEC_index (arm_mapping_symbol_s, map, idx - 1);
if (start)
- *start = map_sym->value + obj_section_addr (sec);
- return map_sym->type;
+ *start = it->value + obj_section_addr (sec);
+ return it->type;
}
}
+
+ if (it > map.begin ())
+ {
+ arm_mapping_symbol_vec::const_iterator prev_it
+ = it - 1;
+
+ if (start)
+ *start = prev_it->value + obj_section_addr (sec);
+ return prev_it->type;
+ }
}
}
CORE_ADDR frame_loc;
ULONGEST return_value;
+ /* AAPCS does not use a frame register, so we can abort here. */
+ if (gdbarch_tdep (gdbarch)->arm_abi == ARM_ABI_AAPCS)
+ return;
+
frame_loc = get_frame_register_unsigned (this_frame, ARM_FP_REGNUM);
if (!safe_read_memory_unsigned_integer (frame_loc, 4, byte_order,
&return_value))
static void
arm_exidx_new_objfile (struct objfile *objfile)
{
- struct cleanup *cleanups;
struct arm_exidx_data *data;
asection *exidx, *extab;
bfd_vma exidx_vma = 0, extab_vma = 0;
- bfd_size_type exidx_size = 0, extab_size = 0;
- gdb_byte *exidx_data = NULL, *extab_data = NULL;
LONGEST i;
/* If we've already touched this file, do nothing. */
if (!objfile || objfile_data (objfile, arm_exidx_data_key) != NULL)
return;
- cleanups = make_cleanup (null_cleanup, NULL);
/* Read contents of exception table and index. */
exidx = bfd_get_section_by_name (objfile->obfd, ELF_STRING_ARM_unwind);
+ gdb::byte_vector exidx_data;
if (exidx)
{
exidx_vma = bfd_section_vma (objfile->obfd, exidx);
- exidx_size = bfd_get_section_size (exidx);
- exidx_data = (gdb_byte *) xmalloc (exidx_size);
- make_cleanup (xfree, exidx_data);
+ exidx_data.resize (bfd_get_section_size (exidx));
if (!bfd_get_section_contents (objfile->obfd, exidx,
- exidx_data, 0, exidx_size))
- {
- do_cleanups (cleanups);
- return;
- }
+ exidx_data.data (), 0,
+ exidx_data.size ()))
+ return;
}
extab = bfd_get_section_by_name (objfile->obfd, ".ARM.extab");
+ gdb::byte_vector extab_data;
if (extab)
{
extab_vma = bfd_section_vma (objfile->obfd, extab);
- extab_size = bfd_get_section_size (extab);
- extab_data = (gdb_byte *) xmalloc (extab_size);
- make_cleanup (xfree, extab_data);
+ extab_data.resize (bfd_get_section_size (extab));
if (!bfd_get_section_contents (objfile->obfd, extab,
- extab_data, 0, extab_size))
- {
- do_cleanups (cleanups);
- return;
- }
+ extab_data.data (), 0,
+ extab_data.size ()))
+ return;
}
/* Allocate exception table data structure. */
VEC(arm_exidx_entry_s) *);
/* Fill in exception table. */
- for (i = 0; i < exidx_size / 8; i++)
+ for (i = 0; i < exidx_data.size () / 8; i++)
{
struct arm_exidx_entry new_exidx_entry;
- bfd_vma idx = bfd_h_get_32 (objfile->obfd, exidx_data + i * 8);
- bfd_vma val = bfd_h_get_32 (objfile->obfd, exidx_data + i * 8 + 4);
+ bfd_vma idx = bfd_h_get_32 (objfile->obfd, exidx_data.data () + i * 8);
+ bfd_vma val = bfd_h_get_32 (objfile->obfd,
+ exidx_data.data () + i * 8 + 4);
bfd_vma addr = 0, word = 0;
int n_bytes = 0, n_words = 0;
struct obj_section *sec;
addr = ((val & 0x7fffffff) ^ 0x40000000) - 0x40000000;
addr += exidx_vma + i * 8 + 4;
- if (addr >= extab_vma && addr + 4 <= extab_vma + extab_size)
+ if (addr >= extab_vma && addr + 4 <= extab_vma + extab_data.size ())
{
word = bfd_h_get_32 (objfile->obfd,
- extab_data + addr - extab_vma);
+ extab_data.data () + addr - extab_vma);
addr += 4;
if ((word & 0xff000000) == 0x80000000)
byte, followed by the same unwind instructions as the
pre-defined forms. */
if (gnu_personality
- && addr + 4 <= extab_vma + extab_size)
+ && addr + 4 <= extab_vma + extab_data.size ())
{
word = bfd_h_get_32 (objfile->obfd,
- extab_data + addr - extab_vma);
+ (extab_data.data ()
+ + addr - extab_vma));
addr += 4;
n_bytes = 3;
n_words = ((word >> 24) & 0xff);
/* Sanity check address. */
if (n_words)
- if (addr < extab_vma || addr + 4 * n_words > extab_vma + extab_size)
+ if (addr < extab_vma
+ || addr + 4 * n_words > extab_vma + extab_data.size ())
n_words = n_bytes = 0;
/* The unwind instructions reside in WORD (only the N_BYTES least
while (n_words--)
{
word = bfd_h_get_32 (objfile->obfd,
- extab_data + addr - extab_vma);
+ extab_data.data () + addr - extab_vma);
addr += 4;
*p++ = (gdb_byte) ((word >> 24) & 0xff);
data->section_maps[sec->the_bfd_section->index],
&new_exidx_entry);
}
-
- do_cleanups (cleanups);
}
/* Search for the exception table entry covering MEMADDR. If one is found,
arm_normal_frame_base
};
-/* Assuming THIS_FRAME is a dummy, return the frame ID of that
- dummy frame. The frame ID's base needs to match the TOS value
- saved by save_dummy_frame_tos() and returned from
- arm_push_dummy_call, and the PC needs to match the dummy frame's
- breakpoint. */
-
-static struct frame_id
-arm_dummy_id (struct gdbarch *gdbarch, struct frame_info *this_frame)
-{
- return frame_id_build (get_frame_register_unsigned (this_frame,
- ARM_SP_REGNUM),
- get_frame_pc (this_frame));
-}
-
-/* Given THIS_FRAME, find the previous frame's resume PC (which will
- be used to construct the previous frame's ID, after looking up the
- containing function). */
-
-static CORE_ADDR
-arm_unwind_pc (struct gdbarch *gdbarch, struct frame_info *this_frame)
-{
- CORE_ADDR pc;
- pc = frame_unwind_register_unsigned (this_frame, ARM_PC_REGNUM);
- return arm_addr_bits_remove (gdbarch, pc);
-}
-
-static CORE_ADDR
-arm_unwind_sp (struct gdbarch *gdbarch, struct frame_info *this_frame)
-{
- return frame_unwind_register_unsigned (this_frame, ARM_SP_REGNUM);
-}
-
static struct value *
arm_dwarf2_prev_register (struct frame_info *this_frame, void **this_cache,
int regnum)
return si;
}
+/* Implement the gdbarch type alignment method, overrides the generic
+ alignment algorithm for anything that is arm specific. */
-/* Return the alignment (in bytes) of the given type. */
-
-static int
-arm_type_align (struct type *t)
+static ULONGEST
+arm_type_align (gdbarch *gdbarch, struct type *t)
{
- int n;
- int align;
- int falign;
-
t = check_typedef (t);
- switch (TYPE_CODE (t))
+ if (TYPE_CODE (t) == TYPE_CODE_ARRAY && TYPE_VECTOR (t))
{
- default:
- /* Should never happen. */
- internal_error (__FILE__, __LINE__, _("unknown type alignment"));
- return 4;
-
- case TYPE_CODE_PTR:
- case TYPE_CODE_ENUM:
- case TYPE_CODE_INT:
- case TYPE_CODE_FLT:
- case TYPE_CODE_SET:
- case TYPE_CODE_RANGE:
- case TYPE_CODE_REF:
- case TYPE_CODE_RVALUE_REF:
- case TYPE_CODE_CHAR:
- case TYPE_CODE_BOOL:
- return TYPE_LENGTH (t);
-
- case TYPE_CODE_ARRAY:
- if (TYPE_VECTOR (t))
- {
- /* Use the natural alignment for vector types (the same for
- scalar type), but the maximum alignment is 64-bit. */
- if (TYPE_LENGTH (t) > 8)
- return 8;
- else
- return TYPE_LENGTH (t);
- }
+ /* Use the natural alignment for vector types (the same for
+ scalar type), but the maximum alignment is 64-bit. */
+ if (TYPE_LENGTH (t) > 8)
+ return 8;
else
- return arm_type_align (TYPE_TARGET_TYPE (t));
- case TYPE_CODE_COMPLEX:
- return arm_type_align (TYPE_TARGET_TYPE (t));
-
- case TYPE_CODE_STRUCT:
- case TYPE_CODE_UNION:
- align = 1;
- for (n = 0; n < TYPE_NFIELDS (t); n++)
- {
- falign = arm_type_align (TYPE_FIELD_TYPE (t, n));
- if (falign > align)
- align = falign;
- }
- return align;
+ return TYPE_LENGTH (t);
}
+
+ /* Allow the common code to calculate the alignment. */
+ return 0;
}
/* Possible base types for a candidate for passing and returning in
static CORE_ADDR
arm_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
struct regcache *regcache, CORE_ADDR bp_addr, int nargs,
- struct value **args, CORE_ADDR sp, int struct_return,
+ struct value **args, CORE_ADDR sp,
+ function_call_return_method return_method,
CORE_ADDR struct_addr)
{
enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
/* The struct_return pointer occupies the first parameter
passing register. */
- if (struct_return)
+ if (return_method == return_method_struct)
{
if (arm_debug)
fprintf_unfiltered (gdb_stdlog, "struct return in %s = %s\n",
typecode = TYPE_CODE (arg_type);
val = value_contents (args[argnum]);
- align = arm_type_align (arg_type);
+ align = type_align (arg_type);
/* Round alignment up to a whole number of words. */
align = (align + INT_REGISTER_SIZE - 1) & ~(INT_REGISTER_SIZE - 1);
/* Different ABIs have different maximum alignments. */
reg_char, reg_scaled + i);
regnum = user_reg_map_name_to_regnum (gdbarch, name_buf,
strlen (name_buf));
- regcache_cooked_write (regcache, regnum,
- val + i * unit_length);
+ regcache->cooked_write (regnum, val + i * unit_length);
}
}
continue;
else if (op == 0x3)
/* Not really supported. */
return arm_copy_unmodified (gdbarch, insn, "smc", dsc);
+ /* Fall through. */
default:
return arm_copy_undef (gdbarch, insn, dsc);
{
if (bit (insn1, 9)) /* Data processing (plain binary imm). */
{
- int op = bits (insn1, 4, 8);
+ int dp_op = bits (insn1, 4, 8);
int rn = bits (insn1, 0, 3);
- if ((op == 0 || op == 0xa) && rn == 0xf)
+ if ((dp_op == 0 || dp_op == 0xa) && rn == 0xf)
err = thumb_copy_pc_relative_32bit (gdbarch, insn1, insn2,
regs, dsc);
else
internal type. */
bfd_byte tmpbuf[FP_REGISTER_SIZE];
- regcache_cooked_read (regs, ARM_F0_REGNUM, tmpbuf);
+ regs->cooked_read (ARM_F0_REGNUM, tmpbuf);
target_float_convert (tmpbuf, arm_ext_type (gdbarch),
valbuf, type);
}
/* ARM_FLOAT_VFP can arise if this is a variadic function so
not using the VFP ABI code. */
case ARM_FLOAT_VFP:
- regcache_cooked_read (regs, ARM_A1_REGNUM, valbuf);
+ regs->cooked_read (ARM_A1_REGNUM, valbuf);
if (TYPE_LENGTH (type) > 4)
- regcache_cooked_read (regs, ARM_A1_REGNUM + 1,
- valbuf + INT_REGISTER_SIZE);
+ regs->cooked_read (ARM_A1_REGNUM + 1, valbuf + INT_REGISTER_SIZE);
break;
default:
while (len > 0)
{
- regcache_cooked_read (regs, regno++, tmpbuf);
+ regs->cooked_read (regno++, tmpbuf);
memcpy (valbuf, tmpbuf,
len > INT_REGISTER_SIZE ? INT_REGISTER_SIZE : len);
len -= INT_REGISTER_SIZE;
case ARM_FLOAT_FPA:
target_float_convert (valbuf, type, buf, arm_ext_type (gdbarch));
- regcache_cooked_write (regs, ARM_F0_REGNUM, buf);
+ regs->cooked_write (ARM_F0_REGNUM, buf);
break;
case ARM_FLOAT_SOFT_FPA:
/* ARM_FLOAT_VFP can arise if this is a variadic function so
not using the VFP ABI code. */
case ARM_FLOAT_VFP:
- regcache_cooked_write (regs, ARM_A1_REGNUM, valbuf);
+ regs->cooked_write (ARM_A1_REGNUM, valbuf);
if (TYPE_LENGTH (type) > 4)
- regcache_cooked_write (regs, ARM_A1_REGNUM + 1,
- valbuf + INT_REGISTER_SIZE);
+ regs->cooked_write (ARM_A1_REGNUM + 1, valbuf + INT_REGISTER_SIZE);
break;
default:
LONGEST val = unpack_long (type, valbuf);
store_signed_integer (tmpbuf, INT_REGISTER_SIZE, byte_order, val);
- regcache_cooked_write (regs, ARM_A1_REGNUM, tmpbuf);
+ regs->cooked_write (ARM_A1_REGNUM, tmpbuf);
}
else
{
while (len > 0)
{
- regcache_cooked_write (regs, regno++, valbuf);
+ regs->cooked_write (regno++, valbuf);
len -= INT_REGISTER_SIZE;
valbuf += INT_REGISTER_SIZE;
}
{
memcpy (tmpbuf, valbuf,
len > INT_REGISTER_SIZE ? INT_REGISTER_SIZE : len);
- regcache_cooked_write (regs, regno++, tmpbuf);
+ regs->cooked_write (regno++, tmpbuf);
len -= INT_REGISTER_SIZE;
valbuf += INT_REGISTER_SIZE;
}
regnum = user_reg_map_name_to_regnum (gdbarch, name_buf,
strlen (name_buf));
if (writebuf)
- regcache_cooked_write (regcache, regnum,
- writebuf + i * unit_length);
+ regcache->cooked_write (regnum, writebuf + i * unit_length);
if (readbuf)
- regcache_cooked_read (regcache, regnum,
- readbuf + i * unit_length);
+ regcache->cooked_read (regnum, readbuf + i * unit_length);
}
}
return RETURN_VALUE_REGISTER_CONVENTION;
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;
- unsigned int i;
-
- for (i = 0; i < objfile->obfd->section_count; i++)
- VEC_free (arm_mapping_symbol_s, data->section_maps[i]);
-}
-
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;
- VEC(arm_mapping_symbol_s) **map_p;
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_objfile_data_key.get (objfile);
if (data == NULL)
- {
- data = OBSTACK_ZALLOC (&objfile->objfile_obstack,
- struct arm_per_objfile);
- set_objfile_data (objfile, arm_objfile_data_key, data);
- data->section_maps = OBSTACK_CALLOC (&objfile->objfile_obstack,
- objfile->obfd->section_count,
- VEC(arm_mapping_symbol_s) *);
- }
- map_p = &data->section_maps[bfd_get_section (sym)->index];
+ data = arm_objfile_data_key.emplace (objfile,
+ objfile->obfd->section_count);
+ arm_mapping_symbol_vec &map
+ = data->section_maps[bfd_get_section (sym)->index];
new_map_sym.value = sym->value;
new_map_sym.type = name[1];
- /* Assume that most mapping symbols appear in order of increasing
- value. If they were randomly distributed, it would be faster to
- always push here and then sort at first use. */
- if (!VEC_empty (arm_mapping_symbol_s, *map_p))
- {
- struct arm_mapping_symbol *prev_map_sym;
-
- prev_map_sym = VEC_last (arm_mapping_symbol_s, *map_p);
- if (prev_map_sym->value >= sym->value)
- {
- unsigned int idx;
- idx = VEC_lower_bound (arm_mapping_symbol_s, *map_p, &new_map_sym,
- arm_compare_mapping_symbols);
- VEC_safe_insert (arm_mapping_symbol_s, *map_p, idx, &new_map_sym);
- return;
- }
- }
-
- VEC_safe_push (arm_mapping_symbol_s, *map_p, &new_map_sym);
+ /* Insert at the end, the vector will be sorted on first use. */
+ map.push_back (new_map_sym);
}
static void
else
offset = 0;
- regcache_raw_write (regcache, double_regnum, buf + offset);
+ regcache->raw_write (double_regnum, buf + offset);
offset = 8 - offset;
- regcache_raw_write (regcache, double_regnum + 1, buf + offset);
+ regcache->raw_write (double_regnum + 1, buf + offset);
}
static void
double_regnum = user_reg_map_name_to_regnum (gdbarch, name_buf,
strlen (name_buf));
- regcache_raw_read (regcache, double_regnum, reg_buf);
+ regcache->raw_read (double_regnum, reg_buf);
memcpy (reg_buf + offset, buf, 4);
- regcache_raw_write (regcache, double_regnum, reg_buf);
+ regcache->raw_write (double_regnum, reg_buf);
}
}
return 1;
}
-\f
+/* Implement gdbarch_gnu_triplet_regexp. If the arch name is arm then allow it
+ to be postfixed by a version (eg armv7hl). */
+
+static const char *
+arm_gnu_triplet_regexp (struct gdbarch *gdbarch)
+{
+ if (strcmp (gdbarch_bfd_arch_info (gdbarch)->arch_name, "arm") == 0)
+ return "arm(v[^- ]*)?";
+ return gdbarch_bfd_arch_info (gdbarch)->arch_name;
+}
+
/* Initialize the current architecture based on INFO. If possible,
re-use an architecture from ARCHES, which is a list of
architectures already created during this debugging session.
else if (ei_osabi == ELFOSABI_NONE || ei_osabi == ELFOSABI_GNU)
{
int eabi_ver = EF_ARM_EABI_VERSION (e_flags);
- int attr_arch, attr_profile;
switch (eabi_ver)
{
executable file includes build attributes; GCC does
copy them to the executable, but e.g. RealView does
not. */
- attr_arch = bfd_elf_get_obj_attr_int (info.abfd, OBJ_ATTR_PROC,
- Tag_CPU_arch);
- attr_profile = bfd_elf_get_obj_attr_int (info.abfd,
- OBJ_ATTR_PROC,
- Tag_CPU_arch_profile);
+ int attr_arch
+ = bfd_elf_get_obj_attr_int (info.abfd, OBJ_ATTR_PROC,
+ Tag_CPU_arch);
+ int attr_profile
+ = bfd_elf_get_obj_attr_int (info.abfd, OBJ_ATTR_PROC,
+ Tag_CPU_arch_profile);
+
/* GCC specifies the profile for v6-M; RealView only
specifies the profile for architectures starting with
V7 (as opposed to architectures with a tag
if (fp_model == ARM_FLOAT_AUTO)
{
- int e_flags = elf_elfheader (info.abfd)->e_flags;
-
switch (e_flags & (EF_ARM_SOFT_FLOAT | EF_ARM_VFP_FLOAT))
{
case 0:
else
set_gdbarch_wchar_signed (gdbarch, 1);
+ /* Compute type alignment. */
+ set_gdbarch_type_align (gdbarch, arm_type_align);
+
/* 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_write_pc (gdbarch, arm_write_pc);
- /* Frame handling. */
- set_gdbarch_dummy_id (gdbarch, arm_dummy_id);
- set_gdbarch_unwind_pc (gdbarch, arm_unwind_pc);
- set_gdbarch_unwind_sp (gdbarch, arm_unwind_sp);
-
frame_base_set_default (gdbarch, &arm_normal_base);
/* Address manipulation. */
set_gdbarch_disassembler_options (gdbarch, &arm_disassembler_options);
set_gdbarch_valid_disassembler_options (gdbarch, disassembler_options_arm ());
+ set_gdbarch_gnu_triplet_regexp (gdbarch, arm_gnu_triplet_regexp);
+
return gdbarch;
}
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. */
- observer_attach_new_objfile (arm_exidx_new_objfile);
+ gdb::observers::new_objfile.attach (arm_exidx_new_objfile);
arm_exidx_data_key
= register_objfile_data_with_cleanup (NULL, arm_exidx_data_free);
arm_disassembler_options = xstrdup ("reg-names-std");
- const disasm_options_t *disasm_options = disassembler_options_arm ();
+ const disasm_options_t *disasm_options
+ = &disassembler_options_arm ()->options;
int num_disassembly_styles = 0;
for (i = 0; disasm_options->name[i] != NULL; i++)
if (CONST_STRNEQ (disasm_options->name[i], "reg-names-"))
uint32_t record_buf[8], record_buf_mem[8];
ULONGEST u_regval[2] = {0};
- uint32_t reg_src1 = 0, reg_dest = 0;
+ uint32_t reg_src1 = 0;
uint32_t opcode1 = 0;
arm_insn_r->opcode = bits (arm_insn_r->arm_insn, 21, 24);
opc3 = bits (arm_insn_r->arm_insn, 6, 7);
dp_op_sz = bit (arm_insn_r->arm_insn, 8);
bit_d = bit (arm_insn_r->arm_insn, 22);
- opc1 = opc1 & 0x04;
+ /* Mask off the "D" bit. */
+ opc1 = opc1 & ~0x04;
/* Handle VMLA, VMLS. */
if (opc1 == 0x00)
}
}
/* Handle VDIV. */
- else if (opc1 == 0x0b)
+ else if (opc1 == 0x08)
{
if (dp_op_sz)
curr_insn_type = INSN_T1;
class instruction_reader : public abstract_memory_reader
{
public:
- bool read (CORE_ADDR memaddr, gdb_byte *buf, const size_t len)
+ bool read (CORE_ADDR memaddr, gdb_byte *buf, const size_t len) override
{
if (target_read_memory (memaddr, buf, len))
return false;
: m_endian (endian), m_insns (insns), m_insns_size (SIZE)
{}
- bool read (CORE_ADDR memaddr, gdb_byte *buf, const size_t len)
+ bool read (CORE_ADDR memaddr, gdb_byte *buf, const size_t len) override
{
SELF_CHECK (len == 4 || len == 2);
SELF_CHECK (memaddr % 2 == 0);