/* Common target dependent code for GDB on ARM systems.
- Copyright (C) 1988-2019 Free Software Foundation, Inc.
+ Copyright (C) 1988-2022 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>
-#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"
+#include "producer.h"
#if GDB_SELF_TEST
#include "gdbsupport/selftest.h"
#endif
-static int arm_debug;
+static bool arm_debug;
+
+/* Print an "arm" debug statement. */
+
+#define arm_debug_printf(fmt, ...) \
+ debug_prefixed_printf_cond (arm_debug, "arm", fmt, ##__VA_ARGS__)
/* 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;
/* 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,
int framereg;
/* Saved register offsets. */
- struct trad_frame_saved_reg *saved_regs;
+ trad_frame_saved_reg *saved_regs;
+};
+
+namespace {
+
+/* Abstract class to read ARM instructions from memory. */
+
+class arm_instruction_reader
+{
+public:
+ /* Read a 4 bytes instruction from memory using the BYTE_ORDER endianness. */
+ virtual uint32_t read (CORE_ADDR memaddr, bfd_endian byte_order) const = 0;
+};
+
+/* Read instructions from target memory. */
+
+class target_arm_instruction_reader : public arm_instruction_reader
+{
+public:
+ uint32_t read (CORE_ADDR memaddr, bfd_endian byte_order) const override
+ {
+ return read_code_unsigned_integer (memaddr, 4, byte_order);
+ }
};
-static CORE_ADDR arm_analyze_prologue (struct gdbarch *gdbarch,
- CORE_ADDR prologue_start,
- CORE_ADDR prologue_end,
- struct arm_prologue_cache *cache);
+} /* namespace */
+
+static CORE_ADDR arm_analyze_prologue
+ (struct gdbarch *gdbarch, CORE_ADDR prologue_start, CORE_ADDR prologue_end,
+ struct arm_prologue_cache *cache, const arm_instruction_reader &insn_reader);
/* Architecture version for displaced stepping. This effects the behaviour of
certain instructions, and really should not be hard-wired. */
#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;
data->section_maps_sorted[section_idx] = true;
}
- struct arm_mapping_symbol map_key
- = { memaddr - obj_section_addr (sec), 0 };
+ arm_mapping_symbol map_key = { memaddr - sec->addr (), 0 };
arm_mapping_symbol_vec::const_iterator it
= std::lower_bound (map.begin (), map.end (), map_key);
if (it->value == map_key.value)
{
if (start)
- *start = it->value + obj_section_addr (sec);
+ *start = it->value + sec->addr ();
return it->type;
}
}
= it - 1;
if (start)
- *start = prev_it->value + obj_section_addr (sec);
+ *start = prev_it->value + sec->addr ();
return prev_it->type;
}
}
{
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 = nullptr;
+
+ if (gdbarch_displaced_step_copy_insn_closure_by_addr_p (gdbarch))
+ dsc = ((arm_displaced_step_copy_insn_closure * )
+ gdbarch_displaced_step_copy_insn_closure_by_addr
+ (gdbarch, current_inferior (), memaddr));
/* If checking the mode of displaced instruction in copy area, the mode
should be determined by instruction on the original address. */
if (dsc)
{
- if (debug_displaced)
- fprintf_unfiltered (gdb_stdlog,
- "displaced: check mode of %.8lx instead of %.8lx\n",
- (unsigned long) dsc->insn_addr,
- (unsigned long) memaddr);
+ displaced_debug_printf ("check mode of %.8lx instead of %.8lx",
+ (unsigned long) dsc->insn_addr,
+ (unsigned long) memaddr);
memaddr = dsc->insn_addr;
}
"display/i $pc" always show the correct mode (though if there is
a symbol table we will not reach here, so it still may not be
displayed in the mode it will be executed). */
- if (target_has_registers)
+ if (target_has_registers ())
return arm_frame_is_thumb (get_current_frame ());
/* Otherwise we're out of luck; we assume ARM. */
}
/* Determine if the address specified equals any of these magic return
- values, called EXC_RETURN, defined by the ARM v6-M and v7-M
+ values, called EXC_RETURN, defined by the ARM v6-M, v7-M and v8-M
architectures.
From ARMv6-M Reference Manual B1.5.8
0xFFFFFFFD Thread mode Process Basic
For more details see "B1.5.8 Exception return behavior"
- in both ARMv6-M and ARMv7-M Architecture Reference Manuals. */
+ in both ARMv6-M and ARMv7-M Architecture Reference Manuals.
+
+ In the ARMv8-M Architecture Technical Reference also adds
+ for implementations without the Security Extension:
+
+ EXC_RETURN Condition
+ 0xFFFFFFB0 Return to Handler mode.
+ 0xFFFFFFB8 Return to Thread mode using the main stack.
+ 0xFFFFFFBC Return to Thread mode using the process stack. */
static int
arm_m_addr_is_magic (CORE_ADDR addr)
{
switch (addr)
{
+ /* Values from ARMv8-M Architecture Technical Reference. */
+ case 0xffffffb0:
+ case 0xffffffb8:
+ case 0xffffffbc:
/* Values from Tables in B1.5.8 the EXC_RETURN definitions of
the exception return behavior. */
case 0xffffffe1:
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. */
start += 2;
}
- if (arm_debug)
- fprintf_unfiltered (gdb_stdlog, "Prologue scan stopped at %s\n",
- paddress (gdbarch, start));
+ arm_debug_printf ("Prologue scan stopped at %s",
+ paddress (gdbarch, start));
if (unrecognized_pc == 0)
unrecognized_pc = start;
for (i = 0; i < 16; i++)
if (stack.find_reg (gdbarch, i, &offset))
- cache->saved_regs[i].addr = offset;
+ cache->saved_regs[i].set_addr (offset);
return unrecognized_pc;
}
/* 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)
&& (cust == NULL
|| COMPUNIT_PRODUCER (cust) == NULL
|| startswith (COMPUNIT_PRODUCER (cust), "GNU ")
- || startswith (COMPUNIT_PRODUCER (cust), "clang ")))
+ || producer_is_llvm (COMPUNIT_PRODUCER (cust))))
return post_prologue_pc;
if (post_prologue_pc != 0)
analyzed_limit = thumb_analyze_prologue (gdbarch, func_addr,
post_prologue_pc, NULL);
else
- analyzed_limit = arm_analyze_prologue (gdbarch, func_addr,
- post_prologue_pc, NULL);
+ analyzed_limit
+ = arm_analyze_prologue (gdbarch, func_addr, post_prologue_pc,
+ NULL, target_arm_instruction_reader ());
if (analyzed_limit != post_prologue_pc)
return func_addr;
if (arm_pc_is_thumb (gdbarch, pc))
return thumb_analyze_prologue (gdbarch, pc, limit_pc, NULL);
else
- return arm_analyze_prologue (gdbarch, pc, limit_pc, NULL);
+ return arm_analyze_prologue (gdbarch, pc, limit_pc, NULL,
+ target_arm_instruction_reader ());
}
/* *INDENT-OFF* */
return 0;
}
+/* Implement immediate value decoding, as described in section A5.2.4
+ (Modified immediate constants in ARM instructions) of the ARM Architecture
+ Reference Manual (ARMv7-A and ARMv7-R edition). */
+
+static uint32_t
+arm_expand_immediate (uint32_t imm)
+{
+ /* Immediate values are 12 bits long. */
+ gdb_assert ((imm & 0xfffff000) == 0);
+
+ uint32_t unrotated_value = imm & 0xff;
+ uint32_t rotate_amount = (imm & 0xf00) >> 7;
+
+ if (rotate_amount == 0)
+ return unrotated_value;
+
+ return ((unrotated_value >> rotate_amount)
+ | (unrotated_value << (32 - rotate_amount)));
+}
+
/* Analyze an ARM mode prologue starting at PROLOGUE_START and
continuing no further than PROLOGUE_END. If CACHE is non-NULL,
fill it in. Return the first address not recognized as a prologue
static CORE_ADDR
arm_analyze_prologue (struct gdbarch *gdbarch,
CORE_ADDR prologue_start, CORE_ADDR prologue_end,
- struct arm_prologue_cache *cache)
+ struct arm_prologue_cache *cache,
+ const arm_instruction_reader &insn_reader)
{
enum bfd_endian byte_order_for_code = gdbarch_byte_order_for_code (gdbarch);
int regno;
current_pc < prologue_end;
current_pc += 4)
{
- unsigned int insn
- = read_code_unsigned_integer (current_pc, 4, byte_order_for_code);
+ uint32_t insn = insn_reader.read (current_pc, byte_order_for_code);
if (insn == 0xe1a0c00d) /* mov ip, sp */
{
else if ((insn & 0xfff00000) == 0xe2800000 /* add Rd, Rn, #n */
&& pv_is_register (regs[bits (insn, 16, 19)], ARM_SP_REGNUM))
{
- unsigned imm = insn & 0xff; /* immediate value */
- unsigned rot = (insn & 0xf00) >> 7; /* rotate amount */
+ uint32_t imm = arm_expand_immediate (insn & 0xfff);
int rd = bits (insn, 12, 15);
- imm = (imm >> rot) | (imm << (32 - rot));
regs[rd] = pv_add_constant (regs[bits (insn, 16, 19)], imm);
continue;
}
else if ((insn & 0xfff00000) == 0xe2400000 /* sub Rd, Rn, #n */
&& pv_is_register (regs[bits (insn, 16, 19)], ARM_SP_REGNUM))
{
- unsigned imm = insn & 0xff; /* immediate value */
- unsigned rot = (insn & 0xf00) >> 7; /* rotate amount */
+ uint32_t imm = arm_expand_immediate (insn & 0xfff);
int rd = bits (insn, 12, 15);
- imm = (imm >> rot) | (imm << (32 - rot));
regs[rd] = pv_add_constant (regs[bits (insn, 16, 19)], -imm);
continue;
}
}
else if ((insn & 0xfffff000) == 0xe24cb000) /* sub fp, ip #n */
{
- unsigned imm = insn & 0xff; /* immediate value */
- unsigned rot = (insn & 0xf00) >> 7; /* rotate amount */
- imm = (imm >> rot) | (imm << (32 - rot));
+ uint32_t imm = arm_expand_immediate (insn & 0xfff);
regs[ARM_FP_REGNUM] = pv_add_constant (regs[ARM_IP_REGNUM], -imm);
}
else if ((insn & 0xfffff000) == 0xe24dd000) /* sub sp, sp #n */
{
- unsigned imm = insn & 0xff; /* immediate value */
- unsigned rot = (insn & 0xf00) >> 7; /* rotate amount */
- imm = (imm >> rot) | (imm << (32 - rot));
+ uint32_t imm = arm_expand_immediate(insn & 0xfff);
regs[ARM_SP_REGNUM] = pv_add_constant (regs[ARM_SP_REGNUM], -imm);
}
else if ((insn & 0xffff7fff) == 0xed6d0103 /* stfe f?,
for (regno = 0; regno < ARM_FPS_REGNUM; regno++)
if (stack.find_reg (gdbarch, regno, &offset))
- cache->saved_regs[regno].addr = offset;
+ cache->saved_regs[regno].set_addr (offset);
}
- if (arm_debug)
- fprintf_unfiltered (gdb_stdlog, "Prologue scan stopped at %s\n",
- paddress (gdbarch, unrecognized_pc));
+ arm_debug_printf ("Prologue scan stopped at %s",
+ paddress (gdbarch, unrecognized_pc));
return unrecognized_pc;
}
&prologue_end))
{
/* One way to find the end of the prologue (which works well
- for unoptimized code) is to do the following:
+ for unoptimized code) is to do the following:
struct symtab_and_line sal = find_pc_line (prologue_start, 0);
/* AAPCS does not use a frame register, so we can abort here. */
if (gdbarch_tdep (gdbarch)->arm_abi == ARM_ABI_AAPCS)
- return;
+ 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))
- return;
+ return;
else
- {
- prologue_start = gdbarch_addr_bits_remove
+ {
+ prologue_start = gdbarch_addr_bits_remove
(gdbarch, return_value) - 8;
- prologue_end = prologue_start + 64; /* See above. */
- }
+ prologue_end = prologue_start + 64; /* See above. */
+ }
}
if (prev_pc < prologue_end)
prologue_end = prev_pc;
- arm_analyze_prologue (gdbarch, prologue_start, prologue_end, cache);
+ arm_analyze_prologue (gdbarch, prologue_start, prologue_end, cache,
+ target_arm_instruction_reader ());
}
static struct arm_prologue_cache *
/* Calculate actual addresses of saved registers using offsets
determined by arm_scan_prologue. */
for (reg = 0; reg < gdbarch_num_regs (get_frame_arch (this_frame)); reg++)
- if (trad_frame_addr_p (cache->saved_regs, reg))
- cache->saved_regs[reg].addr += cache->prev_sp;
+ if (cache->saved_regs[reg].is_addr ())
+ cache->saved_regs[reg].set_addr (cache->saved_regs[reg].addr ()
+ + cache->prev_sp);
return cache;
}
prev_regnum);
}
-struct frame_unwind arm_prologue_unwind = {
+static frame_unwind arm_prologue_unwind = {
+ "arm prologue",
NORMAL_FRAME,
arm_prologue_unwind_stop_reason,
arm_prologue_this_id,
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)
NULL
};
- CORE_ADDR pc = pers + obj_section_offset (pers_sec);
+ CORE_ADDR pc = pers + pers_sec->offset ();
int k;
for (k = 0; personality[k]; k++)
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;
+ struct arm_exidx_entry map_key = { memaddr - sec->addr (), 0 };
- 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 + sec->addr ();
+ 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 + sec->addr ();
+ return idx->entry;
}
}
}
actual value in the current frame. */
if (!vsp_valid)
{
- if (trad_frame_realreg_p (cache->saved_regs, ARM_SP_REGNUM))
+ if (cache->saved_regs[ARM_SP_REGNUM].is_realreg ())
{
- int reg = cache->saved_regs[ARM_SP_REGNUM].realreg;
+ int reg = cache->saved_regs[ARM_SP_REGNUM].realreg ();
vsp = get_frame_register_unsigned (this_frame, reg);
}
else
{
- CORE_ADDR addr = cache->saved_regs[ARM_SP_REGNUM].addr;
+ CORE_ADDR addr = cache->saved_regs[ARM_SP_REGNUM].addr ();
vsp = get_frame_memory_unsigned (this_frame, addr, 4);
}
for (i = 0; i < 12; i++)
if (mask & (1 << i))
{
- cache->saved_regs[4 + i].addr = vsp;
+ cache->saved_regs[4 + i].set_addr (vsp);
vsp += 4;
}
/* Pop r4..r[4+count]. */
for (i = 0; i <= count; i++)
{
- cache->saved_regs[4 + i].addr = vsp;
+ cache->saved_regs[4 + i].set_addr (vsp);
vsp += 4;
}
/* If indicated by flag, pop LR as well. */
if (pop_lr)
{
- cache->saved_regs[ARM_LR_REGNUM].addr = vsp;
+ cache->saved_regs[ARM_LR_REGNUM].set_addr (vsp);
vsp += 4;
}
}
{
/* We could only have updated PC by popping into it; if so, it
will show up as address. Otherwise, copy LR into PC. */
- if (!trad_frame_addr_p (cache->saved_regs, ARM_PC_REGNUM))
+ if (!cache->saved_regs[ARM_PC_REGNUM].is_addr ())
cache->saved_regs[ARM_PC_REGNUM]
= cache->saved_regs[ARM_LR_REGNUM];
for (i = 0; i < 4; i++)
if (mask & (1 << i))
{
- cache->saved_regs[i].addr = vsp;
+ cache->saved_regs[i].set_addr (vsp);
vsp += 4;
}
}
/* Pop VFP double-precision registers D[start]..D[start+count]. */
for (i = 0; i <= count; i++)
{
- cache->saved_regs[ARM_D0_REGNUM + start + i].addr = vsp;
+ cache->saved_regs[ARM_D0_REGNUM + start + i].set_addr (vsp);
vsp += 8;
}
/* Pop VFP double-precision registers D[8]..D[8+count]. */
for (i = 0; i <= count; i++)
{
- cache->saved_regs[ARM_D0_REGNUM + 8 + i].addr = vsp;
+ cache->saved_regs[ARM_D0_REGNUM + 8 + i].set_addr (vsp);
vsp += 8;
}
/* Pop iwmmx registers WR[start]..WR[start+count]. */
for (i = 0; i <= count; i++)
{
- cache->saved_regs[ARM_WR0_REGNUM + start + i].addr = vsp;
+ cache->saved_regs[ARM_WR0_REGNUM + start + i].set_addr (vsp);
vsp += 8;
}
}
for (i = 0; i < 4; i++)
if (mask & (1 << i))
{
- cache->saved_regs[ARM_WCGR0_REGNUM + i].addr = vsp;
+ cache->saved_regs[ARM_WCGR0_REGNUM + i].set_addr (vsp);
vsp += 4;
}
}
/* Pop iwmmx registers WR[10]..WR[10+count]. */
for (i = 0; i <= count; i++)
{
- cache->saved_regs[ARM_WR0_REGNUM + 10 + i].addr = vsp;
+ cache->saved_regs[ARM_WR0_REGNUM + 10 + i].set_addr (vsp);
vsp += 8;
}
}
D[16+start]..D[16+start+count]. */
for (i = 0; i <= count; i++)
{
- cache->saved_regs[ARM_D0_REGNUM + 16 + start + i].addr = vsp;
+ cache->saved_regs[ARM_D0_REGNUM + 16 + start + i].set_addr (vsp);
vsp += 8;
}
}
/* Pop VFP double-precision registers D[start]..D[start+count]. */
for (i = 0; i <= count; i++)
{
- cache->saved_regs[ARM_D0_REGNUM + start + i].addr = vsp;
+ cache->saved_regs[ARM_D0_REGNUM + start + i].set_addr (vsp);
vsp += 8;
}
}
/* Pop VFP double-precision registers D[8]..D[8+count]. */
for (i = 0; i <= count; i++)
{
- cache->saved_regs[ARM_D0_REGNUM + 8 + i].addr = vsp;
+ cache->saved_regs[ARM_D0_REGNUM + 8 + i].set_addr (vsp);
vsp += 8;
}
}
/* If we restore SP from a register, assume this was the frame register.
Otherwise just fall back to SP as frame register. */
- if (trad_frame_realreg_p (cache->saved_regs, ARM_SP_REGNUM))
- cache->framereg = cache->saved_regs[ARM_SP_REGNUM].realreg;
+ if (cache->saved_regs[ARM_SP_REGNUM].is_realreg ())
+ cache->framereg = cache->saved_regs[ARM_SP_REGNUM].realreg ();
else
cache->framereg = ARM_SP_REGNUM;
}
struct frame_unwind arm_exidx_unwind = {
+ "arm exidx",
NORMAL_FRAME,
default_frame_unwind_stop_reason,
arm_prologue_this_id,
/* Calculate actual addresses of saved registers using offsets
determined by arm_scan_prologue. */
for (reg = 0; reg < gdbarch_num_regs (get_frame_arch (this_frame)); reg++)
- if (trad_frame_addr_p (cache->saved_regs, reg))
- cache->saved_regs[reg].addr += cache->prev_sp;
+ if (cache->saved_regs[reg].is_addr ())
+ cache->saved_regs[reg].set_addr (cache->saved_regs[reg].addr ()
+ + cache->prev_sp);
return cache;
}
static const struct frame_unwind arm_epilogue_frame_unwind =
{
+ "arm epilogue",
NORMAL_FRAME,
default_frame_unwind_stop_reason,
arm_epilogue_frame_this_id,
}
struct frame_unwind arm_stub_unwind = {
+ "arm stub",
NORMAL_FRAME,
default_frame_unwind_stop_reason,
arm_stub_this_id,
struct gdbarch *gdbarch = get_frame_arch (this_frame);
enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
struct arm_prologue_cache *cache;
+ CORE_ADDR lr;
+ CORE_ADDR sp;
CORE_ADDR unwound_sp;
LONGEST xpsr;
+ uint32_t exc_return;
+ uint32_t process_stack_used;
+ uint32_t extended_frame_used;
+ uint32_t secure_stack_used;
cache = FRAME_OBSTACK_ZALLOC (struct arm_prologue_cache);
cache->saved_regs = trad_frame_alloc_saved_regs (this_frame);
- unwound_sp = get_frame_register_unsigned (this_frame,
- ARM_SP_REGNUM);
+ /* ARMv7-M Architecture Reference "B1.5.6 Exception entry behavior"
+ describes which bits in LR that define which stack was used prior
+ to the exception and if FPU is used (causing extended stack frame). */
+
+ lr = get_frame_register_unsigned (this_frame, ARM_LR_REGNUM);
+ sp = get_frame_register_unsigned (this_frame, ARM_SP_REGNUM);
+
+ /* Check EXC_RETURN indicator bits. */
+ exc_return = (((lr >> 28) & 0xf) == 0xf);
+
+ /* Check EXC_RETURN bit SPSEL if Main or Thread (process) stack used. */
+ process_stack_used = ((lr & (1 << 2)) != 0);
+ if (exc_return && process_stack_used)
+ {
+ /* Thread (process) stack used.
+ Potentially this could be other register defined by target, but PSP
+ can be considered a standard name for the "Process Stack Pointer".
+ To be fully aware of system registers like MSP and PSP, these could
+ be added to a separate XML arm-m-system-profile that is valid for
+ ARMv6-M and ARMv7-M architectures. Also to be able to debug eg a
+ corefile off-line, then these registers must be defined by GDB,
+ and also be included in the corefile regsets. */
+
+ int psp_regnum = user_reg_map_name_to_regnum (gdbarch, "psp", -1);
+ if (psp_regnum == -1)
+ {
+ /* Thread (process) stack could not be fetched,
+ give warning and exit. */
+
+ warning (_("no PSP thread stack unwinding supported."));
+
+ /* Terminate any further stack unwinding by refer to self. */
+ cache->prev_sp = sp;
+ return cache;
+ }
+ else
+ {
+ /* Thread (process) stack used, use PSP as SP. */
+ unwound_sp = get_frame_register_unsigned (this_frame, psp_regnum);
+ }
+ }
+ else
+ {
+ /* Main stack used, use MSP as SP. */
+ unwound_sp = sp;
+ }
/* The hardware saves eight 32-bit words, comprising xPSR,
ReturnAddress, LR (R14), R12, R3, R2, R1, R0. See details in
"B1.5.6 Exception entry behavior" in
"ARMv7-M Architecture Reference Manual". */
- cache->saved_regs[0].addr = unwound_sp;
- cache->saved_regs[1].addr = unwound_sp + 4;
- cache->saved_regs[2].addr = unwound_sp + 8;
- cache->saved_regs[3].addr = unwound_sp + 12;
- cache->saved_regs[12].addr = unwound_sp + 16;
- cache->saved_regs[14].addr = unwound_sp + 20;
- cache->saved_regs[15].addr = unwound_sp + 24;
- cache->saved_regs[ARM_PS_REGNUM].addr = unwound_sp + 28;
+ cache->saved_regs[0].set_addr (unwound_sp);
+ cache->saved_regs[1].set_addr (unwound_sp + 4);
+ cache->saved_regs[2].set_addr (unwound_sp + 8);
+ cache->saved_regs[3].set_addr (unwound_sp + 12);
+ cache->saved_regs[ARM_IP_REGNUM].set_addr (unwound_sp + 16);
+ cache->saved_regs[ARM_LR_REGNUM].set_addr (unwound_sp + 20);
+ cache->saved_regs[ARM_PC_REGNUM].set_addr (unwound_sp + 24);
+ cache->saved_regs[ARM_PS_REGNUM].set_addr (unwound_sp + 28);
+
+ /* Check EXC_RETURN bit FTYPE if extended stack frame (FPU regs stored)
+ type used. */
+ extended_frame_used = ((lr & (1 << 4)) == 0);
+ if (exc_return && extended_frame_used)
+ {
+ int i;
+ int fpu_regs_stack_offset;
+
+ /* This code does not take into account the lazy stacking, see "Lazy
+ context save of FP state", in B1.5.7, also ARM AN298, supported
+ by Cortex-M4F architecture.
+ To fully handle this the FPCCR register (Floating-point Context
+ Control Register) needs to be read out and the bits ASPEN and LSPEN
+ could be checked to setup correct lazy stacked FP registers.
+ This register is located at address 0xE000EF34. */
+
+ /* Extended stack frame type used. */
+ fpu_regs_stack_offset = unwound_sp + 0x20;
+ for (i = 0; i < 16; i++)
+ {
+ cache->saved_regs[ARM_D0_REGNUM + i].set_addr (fpu_regs_stack_offset);
+ fpu_regs_stack_offset += 4;
+ }
+ cache->saved_regs[ARM_FPSCR_REGNUM].set_addr (unwound_sp + 0x60);
+
+ /* Offset 0x64 is reserved. */
+ cache->prev_sp = unwound_sp + 0x68;
+ }
+ else
+ {
+ /* Standard stack frame type used. */
+ cache->prev_sp = unwound_sp + 0x20;
+ }
+
+ /* Check EXC_RETURN bit S if Secure or Non-secure stack used. */
+ secure_stack_used = ((lr & (1 << 6)) != 0);
+ if (exc_return && secure_stack_used)
+ {
+ /* ARMv8-M Exception and interrupt handling is not considered here.
+ In the ARMv8-M architecture also EXC_RETURN bit S is controlling if
+ the Secure or Non-secure stack was used. To separate Secure and
+ Non-secure stacks, processors that are based on the ARMv8-M
+ architecture support 4 stack pointers: MSP_S, PSP_S, MSP_NS, PSP_NS.
+ In addition, a stack limit feature is provided using stack limit
+ registers (accessible using MSR and MRS instructions) in Privileged
+ level. */
+ }
/* If bit 9 of the saved xPSR is set, then there is a four-byte
aligner between the top of the 32-byte stack frame and the
previous context's stack pointer. */
- cache->prev_sp = unwound_sp + 32;
if (safe_read_memory_integer (unwound_sp + 28, 4, byte_order, &xpsr)
&& (xpsr & (1 << 9)) != 0)
cache->prev_sp += 4;
struct frame_unwind arm_m_exception_unwind =
{
+ "arm m exception",
SIGTRAMP_FRAME,
default_frame_unwind_stop_reason,
arm_m_exception_this_id,
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 && t->is_vector ())
{
/* 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))
case TYPE_CODE_ARRAY:
{
- if (TYPE_VECTOR (t))
+ if (t->is_vector ())
{
/* A 64-bit or 128-bit containerized vector type are VFP
CPRCs. */
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)))
- sub_count = arm_vfp_cprc_sub_candidate (TYPE_FIELD_TYPE (t, i),
+ if (!field_is_static (&t->field (i)))
+ sub_count = arm_vfp_cprc_sub_candidate (t->field (i).type (),
base_type);
if (sub_count == -1)
return -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),
+ int sub_count = arm_vfp_cprc_sub_candidate (t->field (i).type (),
base_type);
if (sub_count == -1)
return -1;
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
/* Variadic functions always use the base ABI. Assume that functions
without debug info are not variadic. */
- if (func_type && TYPE_VARARGS (check_typedef (func_type)))
+ if (func_type && check_typedef (func_type)->has_varargs ())
return 0;
/* The VFP ABI is only supported as a variant of AAPCS. */
if (tdep->arm_abi != ARM_ABI_AAPCS)
/* 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);
passing register. */
if (return_method == return_method_struct)
{
- if (arm_debug)
- fprintf_unfiltered (gdb_stdlog, "struct return in %s = %s\n",
- gdbarch_register_name (gdbarch, argreg),
- paddress (gdbarch, struct_addr));
+ arm_debug_printf ("struct return in %s = %s",
+ gdbarch_register_name (gdbarch, argreg),
+ paddress (gdbarch, struct_addr));
+
regcache_cooked_write_unsigned (regcache, argreg, struct_addr);
argreg++;
}
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))
register. */
if (byte_order == BFD_ENDIAN_BIG)
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, ARM_INT_REGISTER_SIZE));
+
+ arm_debug_printf ("arg %d in %s = 0x%s", argnum,
+ gdbarch_register_name (gdbarch, argreg),
+ phex (regval, ARM_INT_REGISTER_SIZE));
+
regcache_cooked_write_unsigned (regcache, argreg, regval);
argreg++;
}
store_unsigned_integer (buf, partial_len, byte_order, regval);
/* Push the arguments onto the stack. */
- if (arm_debug)
- fprintf_unfiltered (gdb_stdlog, "arg %d @ sp + %d\n",
- argnum, nstack);
+ arm_debug_printf ("arg %d @ sp + %d", argnum, nstack);
si = push_stack_item (si, buf, ARM_INT_REGISTER_SIZE);
nstack += ARM_INT_REGISTER_SIZE;
}
elem = builtin_type (gdbarch)->builtin_double;
append_composite_type_field (t, "f64", elem);
- TYPE_VECTOR (t) = 1;
- TYPE_NAME (t) = "neon_d";
+ t->set_is_vector (true);
+ t->set_name ("neon_d");
tdep->neon_double_type = t;
}
elem = builtin_type (gdbarch)->builtin_double;
append_composite_type_field (t, "f64", init_vector_type (elem, 2));
- TYPE_VECTOR (t) = 1;
- TYPE_NAME (t) = "neon_q";
+ t->set_is_vector (true);
+ 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 (regcache *regs, arm_displaced_step_copy_insn_closure *dsc,
int regno)
{
ULONGEST ret;
else
from += 4;
- if (debug_displaced)
- fprintf_unfiltered (gdb_stdlog, "displaced: read pc value %.8lx\n",
- (unsigned long) from);
+ displaced_debug_printf ("read pc value %.8lx",
+ (unsigned long) from);
return (ULONGEST) from;
}
else
{
regcache_cooked_read_unsigned (regs, regno, &ret);
- if (debug_displaced)
- fprintf_unfiltered (gdb_stdlog, "displaced: read r%d value %.8lx\n",
- regno, (unsigned long) ret);
+
+ displaced_debug_printf ("read r%d value %.8lx",
+ regno, (unsigned long) ret);
+
return 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 (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 (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 (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 (regcache *regs, arm_displaced_step_copy_insn_closure *dsc,
int regno, ULONGEST val, enum pc_write_style write_pc)
{
if (regno == ARM_PC_REGNUM)
{
- if (debug_displaced)
- fprintf_unfiltered (gdb_stdlog, "displaced: writing pc %.8lx\n",
- (unsigned long) val);
+ displaced_debug_printf ("writing pc %.8lx", (unsigned long) val);
+
switch (write_pc)
{
case BRANCH_WRITE_PC:
case BX_WRITE_PC:
bx_write_pc (regs, val);
- break;
+ break;
case LOAD_WRITE_PC:
load_write_pc (regs, dsc, val);
- break;
+ break;
case ALU_WRITE_PC:
alu_write_pc (regs, dsc, val);
- break;
+ break;
case CANNOT_WRITE_PC:
warning (_("Instruction wrote to PC in an unexpected way when "
}
else
{
- if (debug_displaced)
- fprintf_unfiltered (gdb_stdlog, "displaced: writing r%d value %.8lx\n",
- regno, (unsigned long) val);
+ displaced_debug_printf ("writing r%d value %.8lx",
+ regno, (unsigned long) val);
regcache_cooked_write_unsigned (regs, regno, val);
}
}
matter what address they are executed at: in those cases, use this. */
static int
-arm_copy_unmodified (struct gdbarch *gdbarch, uint32_t insn,
- const char *iname, arm_displaced_step_closure *dsc)
+arm_copy_unmodified (struct gdbarch *gdbarch, uint32_t insn, const char *iname,
+ arm_displaced_step_copy_insn_closure *dsc)
{
- if (debug_displaced)
- fprintf_unfiltered (gdb_stdlog, "displaced: copying insn %.8lx, "
- "opcode/class '%s' unmodified\n", (unsigned long) insn,
- iname);
+ displaced_debug_printf ("copying insn %.8lx, opcode/class '%s' unmodified",
+ (unsigned long) insn, iname);
dsc->modinsn[0] = insn;
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, "
- "opcode/class '%s' unmodified\n", insn1, insn2,
- iname);
+ displaced_debug_printf ("copying insn %.4x %.4x, opcode/class '%s' "
+ "unmodified", insn1, insn2, iname);
dsc->modinsn[0] = insn1;
dsc->modinsn[1] = insn2;
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, "
- "opcode/class '%s' unmodified\n", insn,
- iname);
+ displaced_debug_printf ("copying insn %.4x, opcode/class '%s' unmodified",
+ insn, iname);
dsc->modinsn[0] = insn;
/* Preload instructions with immediate offset. */
static void
-cleanup_preload (struct gdbarch *gdbarch,
- struct regcache *regs, arm_displaced_step_closure *dsc)
+cleanup_preload (struct gdbarch *gdbarch, 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);
if (!insn_references_pc (insn, 0x000f0000ul))
return arm_copy_unmodified (gdbarch, insn, "preload", dsc);
- if (debug_displaced)
- fprintf_unfiltered (gdb_stdlog, "displaced: copying preload insn %.8lx\n",
- (unsigned long) insn);
+ displaced_debug_printf ("copying preload insn %.8lx", (unsigned long) insn);
dsc->modinsn[0] = insn & 0xfff0ffff;
static int
thumb2_copy_preload (struct gdbarch *gdbarch, uint16_t insn1, uint16_t insn2,
- struct regcache *regs, arm_displaced_step_closure *dsc)
+ regcache *regs, arm_displaced_step_copy_insn_closure *dsc)
{
unsigned int rn = bits (insn1, 0, 3);
unsigned int u_bit = bit (insn1, 7);
/* PC is only allowed to use in PLI (immediate,literal) Encoding T3, and
PLD (literal) Encoding T1. */
- if (debug_displaced)
- fprintf_unfiltered (gdb_stdlog,
- "displaced: copying pld/pli pc (0x%x) %c imm12 %.4x\n",
- (unsigned int) dsc->insn_addr, u_bit ? '+' : '-',
- imm12);
+ displaced_debug_printf ("copying pld/pli pc (0x%x) %c imm12 %.4x",
+ (unsigned int) dsc->insn_addr, u_bit ? '+' : '-',
+ imm12);
if (!u_bit)
imm12 = -1 * imm12;
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);
if (!insn_references_pc (insn, 0x000f000ful))
return arm_copy_unmodified (gdbarch, insn, "preload reg", dsc);
- if (debug_displaced)
- fprintf_unfiltered (gdb_stdlog, "displaced: copying preload insn %.8lx\n",
- (unsigned long) insn);
+ displaced_debug_printf ("copying preload insn %.8lx",
+ (unsigned long) insn);
dsc->modinsn[0] = (insn & 0xfff0fff0) | 0x1;
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);
if (!insn_references_pc (insn, 0x000f0000ul))
return arm_copy_unmodified (gdbarch, insn, "copro load/store", dsc);
- if (debug_displaced)
- fprintf_unfiltered (gdb_stdlog, "displaced: copying coprocessor "
- "load/store insn %.8lx\n", (unsigned long) insn);
+ displaced_debug_printf ("copying coprocessor load/store insn %.8lx",
+ (unsigned long) insn);
dsc->modinsn[0] = insn & 0xfff0ffff;
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);
return thumb_copy_unmodified_32bit (gdbarch, insn1, insn2,
"copro load/store", dsc);
- if (debug_displaced)
- fprintf_unfiltered (gdb_stdlog, "displaced: copying coprocessor "
- "load/store insn %.4x%.4x\n", insn1, insn2);
+ displaced_debug_printf ("copying coprocessor load/store insn %.4x%.4x",
+ insn1, insn2);
dsc->modinsn[0] = insn1 & 0xfff0;
dsc->modinsn[1] = insn2;
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)
+ regcache *regs, arm_displaced_step_copy_insn_closure *dsc)
{
unsigned int cond = bits (insn, 28, 31);
int exchange = (cond == 0xf);
int link = exchange || bit (insn, 24);
long offset;
- if (debug_displaced)
- fprintf_unfiltered (gdb_stdlog, "displaced: copying %s immediate insn "
- "%.8lx\n", (exchange) ? "blx" : (link) ? "bl" : "b",
- (unsigned long) insn);
+ displaced_debug_printf ("copying %s immediate insn %.8lx",
+ (exchange) ? "blx" : (link) ? "bl" : "b",
+ (unsigned long) insn);
if (exchange)
/* For BLX, set bit 0 of the destination. The cleanup_branch function will
then arrange the switch into Thumb mode. */
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);
(bits (insn2, 1, 10) << 2) : (bits (insn2, 0, 10) << 1);
}
- if (debug_displaced)
- fprintf_unfiltered (gdb_stdlog, "displaced: copying %s insn "
- "%.4x %.4x with offset %.8lx\n",
- link ? (exchange) ? "blx" : "bl" : "b",
- insn1, insn2, offset);
+ displaced_debug_printf ("copying %s insn %.4x %.4x with offset %.8lx",
+ link ? (exchange) ? "blx" : "bl" : "b",
+ insn1, insn2, offset);
dsc->modinsn[0] = THUMB_NOP;
/* 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;
cond = INST_AL;
}
- if (debug_displaced)
- fprintf_unfiltered (gdb_stdlog,
- "displaced: copying b immediate insn %.4x "
- "with offset %d\n", insn, offset);
+ displaced_debug_printf ("copying b immediate insn %.4x with offset %d",
+ insn, offset);
dsc->u.branch.cond = cond;
dsc->u.branch.link = 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)
+ regcache *regs, arm_displaced_step_copy_insn_closure *dsc)
{
unsigned int cond = bits (insn, 28, 31);
/* BX: x12xxx1x
int link = bit (insn, 5);
unsigned int rm = bits (insn, 0, 3);
- if (debug_displaced)
- fprintf_unfiltered (gdb_stdlog, "displaced: copying insn %.8lx",
- (unsigned long) insn);
+ displaced_debug_printf ("copying insn %.8lx", (unsigned long) insn);
dsc->modinsn[0] = ARM_NOP;
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);
- if (debug_displaced)
- fprintf_unfiltered (gdb_stdlog, "displaced: copying insn %.4x",
- (unsigned short) insn);
+ displaced_debug_printf ("copying insn %.4x", (unsigned short) insn);
dsc->modinsn[0] = THUMB_NOP;
static void
cleanup_alu_imm (struct gdbarch *gdbarch,
- struct regcache *regs, arm_displaced_step_closure *dsc)
+ 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);
if (!insn_references_pc (insn, 0x000ff000ul))
return arm_copy_unmodified (gdbarch, insn, "ALU immediate", dsc);
- if (debug_displaced)
- fprintf_unfiltered (gdb_stdlog, "displaced: copying immediate %s insn "
- "%.8lx\n", is_mov ? "move" : "ALU",
- (unsigned long) insn);
+ displaced_debug_printf ("copying immediate %s insn %.8lx",
+ is_mov ? "move" : "ALU",
+ (unsigned long) insn);
/* Instruction is of form:
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;
if (rm != ARM_PC_REGNUM && rd != ARM_PC_REGNUM)
return thumb_copy_unmodified_32bit (gdbarch, insn1, insn2, "ALU imm", dsc);
- if (debug_displaced)
- fprintf_unfiltered (gdb_stdlog, "displaced: copying reg %s insn %.4x%.4x\n",
- "ALU", insn1, insn2);
+ displaced_debug_printf ("copying reg %s insn %.4x%.4x", "ALU", insn1, insn2);
/* Instruction is of form:
static void
cleanup_alu_reg (struct gdbarch *gdbarch,
- struct regcache *regs, arm_displaced_step_closure *dsc)
+ 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);
if (!insn_references_pc (insn, 0x000ff00ful))
return arm_copy_unmodified (gdbarch, insn, "ALU reg", dsc);
- if (debug_displaced)
- fprintf_unfiltered (gdb_stdlog, "displaced: copying reg %s insn %.8lx\n",
- is_mov ? "move" : "ALU", (unsigned long) insn);
+ displaced_debug_printf ("copying reg %s insn %.8lx",
+ is_mov ? "move" : "ALU", (unsigned long) insn);
if (is_mov)
dsc->modinsn[0] = (insn & 0xfff00ff0) | 0x2;
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;
if (rd != ARM_PC_REGNUM && rm != ARM_PC_REGNUM)
return thumb_copy_unmodified_16bit (gdbarch, insn, "ALU reg", dsc);
- if (debug_displaced)
- fprintf_unfiltered (gdb_stdlog, "displaced: copying ALU reg insn %.4x\n",
- (unsigned short) insn);
+ displaced_debug_printf ("copying ALU reg insn %.4x", (unsigned short) insn);
dsc->modinsn[0] = ((insn & 0xff00) | 0x10);
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);
if (!insn_references_pc (insn, 0x000fff0ful))
return arm_copy_unmodified (gdbarch, insn, "ALU shifted reg", dsc);
- if (debug_displaced)
- fprintf_unfiltered (gdb_stdlog, "displaced: copying shifted reg %s insn "
- "%.8lx\n", is_mov ? "move" : "ALU",
- (unsigned long) insn);
+ displaced_debug_printf ("copying shifted reg %s insn %.8lx",
+ is_mov ? "move" : "ALU",
+ (unsigned long) insn);
rn = bits (insn, 16, 19);
rm = bits (insn, 0, 3);
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)
+ regcache *regs, arm_displaced_step_copy_insn_closure *dsc)
{
unsigned int op1 = bits (insn, 20, 24);
unsigned int op2 = bits (insn, 5, 6);
if (!insn_references_pc (insn, 0x000ff00ful))
return arm_copy_unmodified (gdbarch, insn, "extra load/store", dsc);
- if (debug_displaced)
- fprintf_unfiltered (gdb_stdlog, "displaced: copying %sextra load/store "
- "insn %.8lx\n", unprivileged ? "unprivileged " : "",
- (unsigned long) insn);
+ displaced_debug_printf ("copying %sextra load/store insn %.8lx",
+ unprivileged ? "unprivileged " : "",
+ (unsigned long) insn);
opcode = ((op2 << 2) | (op1 & 0x1) | ((op1 & 0x4) >> 1)) - 4;
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
Insn3: sub r4, r4, pc r4 = addr(Insn1) + offset - pc
- = addr(Insn1) + offset - addr(Insn3) - 8
- = offset - 16
+ = addr(Insn1) + offset - addr(Insn3) - 8
+ = offset - 16
Insn4: add r4, r4, #8 r4 = offset - 8
Insn5: add r0, r0, r4 r0 = from + 8 + offset - 8
- = from + offset
+ = from + offset
Insn6: str r0, [r2, #imm] (or str r0, [r2, r3])
Otherwise we don't know what value to write for PC, since the offset is
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);
int imm12 = bits (insn2, 0, 11);
ULONGEST pc_val;
- if (debug_displaced)
- fprintf_unfiltered (gdb_stdlog,
- "displaced: copying ldr pc (0x%x) R%d %c imm12 %.4x\n",
- (unsigned int) dsc->insn_addr, rt, u_bit ? '+' : '-',
- imm12);
+ displaced_debug_printf ("copying ldr pc (0x%x) R%d %c imm12 %.4x",
+ (unsigned int) dsc->insn_addr, rt, u_bit ? '+' : '-',
+ imm12);
if (!u_bit)
imm12 = -1 * imm12;
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);
return thumb_copy_unmodified_32bit (gdbarch, insn1, insn2, "load",
dsc);
- if (debug_displaced)
- fprintf_unfiltered (gdb_stdlog,
- "displaced: copying ldr r%d [r%d] insn %.4x%.4x\n",
- rt, rn, insn1, insn2);
+ displaced_debug_printf ("copying ldr r%d [r%d] insn %.4x%.4x",
+ rt, rn, insn1, insn2);
install_load_store (gdbarch, regs, dsc, 1, immed, writeback, 4,
0, rt, rm, rn);
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);
if (!insn_references_pc (insn, 0x000ff00ful))
return arm_copy_unmodified (gdbarch, insn, "load/store", dsc);
- if (debug_displaced)
- fprintf_unfiltered (gdb_stdlog,
- "displaced: copying %s%s r%d [r%d] insn %.8lx\n",
- load ? (size == 1 ? "ldrb" : "ldr")
- : (size == 1 ? "strb" : "str"), usermode ? "t" : "",
- rt, rn,
- (unsigned long) insn);
+ displaced_debug_printf ("copying %s%s r%d [r%d] insn %.8lx",
+ load ? (size == 1 ? "ldrb" : "ldr")
+ : (size == 1 ? "strb" : "str"),
+ usermode ? "t" : "",
+ rt, rn,
+ (unsigned long) insn);
install_load_store (gdbarch, regs, dsc, load, immed, writeback, size,
usermode, rt, rm, rn);
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;
/* We don't handle any stores here for now. */
gdb_assert (dsc->u.block.load != 0);
- if (debug_displaced)
- fprintf_unfiltered (gdb_stdlog, "displaced: emulating block transfer: "
- "%s %s %s\n", dsc->u.block.load ? "ldm" : "stm",
- dsc->u.block.increment ? "inc" : "dec",
- dsc->u.block.before ? "before" : "after");
+ displaced_debug_printf ("emulating block transfer: %s %s %s",
+ dsc->u.block.load ? "ldm" : "stm",
+ dsc->u.block.increment ? "inc" : "dec",
+ dsc->u.block.before ? "before" : "after");
while (regmask)
{
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;
stm_insn_addr = dsc->scratch_base;
offset = pc_val - stm_insn_addr;
- if (debug_displaced)
- fprintf_unfiltered (gdb_stdlog, "displaced: detected PC offset %.8lx for "
- "STM instruction\n", offset);
+ displaced_debug_printf ("detected PC offset %.8lx for STM instruction",
+ offset);
/* Rewrite the stored PC to the proper value for the non-displaced original
instruction. */
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
{
ULONGEST rval = displaced_read_reg (regs, dsc, read_reg);
displaced_write_reg (regs, dsc, write_reg, rval, LOAD_WRITE_PC);
- if (debug_displaced)
- fprintf_unfiltered (gdb_stdlog, _("displaced: LDM: move "
- "loaded register r%d to r%d\n"), read_reg,
- write_reg);
+ displaced_debug_printf ("LDM: move loaded register r%d to r%d",
+ read_reg, write_reg);
}
- else if (debug_displaced)
- fprintf_unfiltered (gdb_stdlog, _("displaced: LDM: register "
- "r%d already in the right place\n"),
- write_reg);
+ else
+ displaced_debug_printf ("LDM: register r%d already in the right "
+ "place", write_reg);
clobbered &= ~(1 << write_reg);
{
displaced_write_reg (regs, dsc, write_reg, dsc->tmp[write_reg],
CANNOT_WRITE_PC);
- if (debug_displaced)
- fprintf_unfiltered (gdb_stdlog, _("displaced: LDM: restored "
- "clobbered register r%d\n"), write_reg);
+ displaced_debug_printf ("LDM: restored clobbered register r%d",
+ write_reg);
clobbered &= ~(1 << write_reg);
}
}
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);
return arm_copy_unmodified (gdbarch, insn, "unpredictable ldm/stm", dsc);
}
- if (debug_displaced)
- fprintf_unfiltered (gdb_stdlog, "displaced: copying block transfer insn "
- "%.8lx\n", (unsigned long) insn);
+ displaced_debug_printf ("copying block transfer insn %.8lx",
+ (unsigned long) insn);
dsc->u.block.xfer_addr = displaced_read_reg (regs, dsc, rn);
dsc->u.block.rn = rn;
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++)
new_regmask = (1 << num_in_list) - 1;
- if (debug_displaced)
- fprintf_unfiltered (gdb_stdlog, _("displaced: LDM r%d%s, "
- "{..., pc}: original reg list %.4x, modified "
- "list %.4x\n"), rn, writeback ? "!" : "",
- (int) insn & 0xffff, new_regmask);
+ displaced_debug_printf ("LDM r%d%s, {..., pc}: original reg list "
+ "%.4x, modified list %.4x",
+ rn, writeback ? "!" : "",
+ (int) insn & 0xffff, new_regmask);
dsc->modinsn[0] = (insn & ~0xffff) | (new_regmask & 0xffff);
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);
"unpredictable ldm/stm", dsc);
}
- if (debug_displaced)
- fprintf_unfiltered (gdb_stdlog, "displaced: copying block transfer insn "
- "%.4x%.4x\n", insn1, insn2);
+ displaced_debug_printf ("copying block transfer insn %.4x%.4x",
+ insn1, insn2);
/* Clear bit 13, since it should be always zero. */
dsc->u.block.regmask = (insn2 & 0xdfff);
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++)
new_regmask = (1 << num_in_list) - 1;
- if (debug_displaced)
- fprintf_unfiltered (gdb_stdlog, _("displaced: LDM r%d%s, "
- "{..., pc}: original reg list %.4x, modified "
- "list %.4x\n"), rn, writeback ? "!" : "",
- (int) dsc->u.block.regmask, new_regmask);
+ displaced_debug_printf ("LDM r%d%s, {..., pc}: original reg list "
+ "%.4x, modified list %.4x",
+ rn, writeback ? "!" : "",
+ (int) dsc->u.block.regmask, new_regmask);
dsc->modinsn[0] = insn1;
dsc->modinsn[1] = (new_regmask & 0xffff);
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;
- if (debug_displaced)
- fprintf_unfiltered (gdb_stdlog, "displaced: cleanup for svc, resume at "
- "%.8lx\n", (unsigned long) resume_addr);
+ displaced_debug_printf ("cleanup for svc, resume at %.8lx",
+ (unsigned long) resume_addr);
displaced_write_reg (regs, dsc, ARM_PC_REGNUM, resume_addr, BRANCH_WRITE_PC);
}
-/* 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)
+ regcache *regs, arm_displaced_step_copy_insn_closure *dsc)
{
- if (debug_displaced)
- fprintf_unfiltered (gdb_stdlog, "displaced: copying svc insn %.8lx\n",
- (unsigned long) insn);
+ displaced_debug_printf ("copying svc insn %.8lx",
+ (unsigned long) insn);
dsc->modinsn[0] = insn;
static int
thumb_copy_svc (struct gdbarch *gdbarch, uint16_t insn,
- struct regcache *regs, arm_displaced_step_closure *dsc)
+ regcache *regs, arm_displaced_step_copy_insn_closure *dsc)
{
- if (debug_displaced)
- fprintf_unfiltered (gdb_stdlog, "displaced: copying svc insn %.4x\n",
- insn);
+ displaced_debug_printf ("copying svc insn %.4x", insn);
dsc->modinsn[0] = insn;
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,
- "displaced: copying undefined insn %.8lx\n",
- (unsigned long) insn);
+ displaced_debug_printf ("copying undefined insn %.8lx",
+ (unsigned long) insn);
dsc->modinsn[0] = insn;
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)
- fprintf_unfiltered (gdb_stdlog, "displaced: copying undefined insn "
- "%.4x %.4x\n", (unsigned short) insn1,
- (unsigned short) insn2);
+ displaced_debug_printf ("copying undefined insn %.4x %.4x",
+ (unsigned short) insn1, (unsigned short) insn2);
dsc->modinsn[0] = insn1;
dsc->modinsn[1] = insn2;
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 "
- "%.8lx\n", (unsigned long) insn);
+ displaced_debug_printf ("copying unpredictable insn %.8lx",
+ (unsigned long) insn);
dsc->modinsn[0] = 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);
case 0x65:
return arm_copy_preload_reg (gdbarch, insn, regs, dsc); /* pli reg. */
case 0x71: case 0x75:
- /* pld/pldw reg. */
+ /* pld/pldw reg. */
return arm_copy_preload_reg (gdbarch, insn, regs, dsc);
case 0x63: case 0x67: case 0x73: case 0x77:
return arm_copy_unpred (gdbarch, insn, dsc);
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);
case 0xb:
if (bits (insn, 16, 19) == 0xf)
- /* ldc/ldc2 lit. */
+ /* ldc/ldc2 lit. */
return arm_copy_copro_load_store (gdbarch, insn, regs, dsc);
else
return arm_copy_undef (gdbarch, insn, 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);
case 0x2:
if (op == 0x1)
- /* Not really supported. */
+ /* Not really supported. */
return arm_copy_unmodified (gdbarch, insn, "bxj", dsc);
else
return arm_copy_undef (gdbarch, insn, dsc);
if (op == 0x1)
return arm_copy_unmodified (gdbarch, insn, "bkpt", dsc);
else if (op == 0x3)
- /* Not really supported. */
+ /* Not really supported. */
return arm_copy_unmodified (gdbarch, insn, "smc", dsc);
/* Fall through. */
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)
+ 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);
- if (debug_displaced)
- fprintf_unfiltered (gdb_stdlog,
- "displaced: copying thumb adr r%d, #%d insn %.4x\n",
- rd, imm8, insn);
+ displaced_debug_printf ("copying thumb adr r%d, #%d insn %.4x",
+ rd, imm8, insn);
return thumb_copy_pc_relative_16bit (gdbarch, regs, dsc, rd, imm8);
}
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
unsigned int imm_3_8 = insn2 & 0x70ff;
unsigned int imm_i = insn1 & 0x0400; /* Clear all bits except bit 10. */
- if (debug_displaced)
- fprintf_unfiltered (gdb_stdlog,
- "displaced: copying thumb adr r%d, #%d:%d insn %.4x%.4x\n",
- rd, imm_i, imm_3_8, insn1, insn2);
+ displaced_debug_printf ("copying thumb adr r%d, #%d:%d insn %.4x%.4x",
+ rd, imm_i, imm_3_8, insn1, insn2);
if (bit (insn1, 7)) /* Encoding T2 */
{
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;
Insn: LDR R0, [R2, R3];
Cleanup: R2 <- tmp2, R3 <- tmp3, Rd <- R0, R0 <- tmp0 */
- if (debug_displaced)
- fprintf_unfiltered (gdb_stdlog,
- "displaced: copying thumb ldr r%d [pc #%d]\n"
- , rt, imm8);
+ displaced_debug_printf ("copying thumb ldr r%d [pc #%d]", rt, imm8);
dsc->tmp[0] = displaced_read_reg (regs, dsc, 0);
dsc->tmp[2] = displaced_read_reg (regs, dsc, 2);
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);
dsc->u.branch.link = 0;
dsc->u.branch.exchange = 0;
- if (debug_displaced)
- fprintf_unfiltered (gdb_stdlog, "displaced: copying %s [r%d = 0x%x]"
- " insn %.4x to %.8lx\n", non_zero ? "cbnz" : "cbz",
- rn, rn_val, insn1, dsc->u.branch.dest);
+ displaced_debug_printf ("copying %s [r%d = 0x%x] insn %.4x to %.8lx",
+ non_zero ? "cbnz" : "cbz",
+ rn, rn_val, insn1, dsc->u.branch.dest);
dsc->modinsn[0] = THUMB_NOP;
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);
halfwords = extract_unsigned_integer (buf, 1, byte_order);
}
- if (debug_displaced)
- fprintf_unfiltered (gdb_stdlog, "displaced: %s base 0x%x offset 0x%x"
- " offset 0x%x\n", is_tbh ? "tbh" : "tbb",
- (unsigned int) rn_val, (unsigned int) rm_val,
- (unsigned int) halfwords);
+ displaced_debug_printf ("%s base 0x%x offset 0x%x offset 0x%x",
+ is_tbh ? "tbh" : "tbb",
+ (unsigned int) rn_val, (unsigned int) rm_val,
+ (unsigned int) halfwords);
dsc->u.branch.cond = INST_AL;
dsc->u.branch.link = 0;
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;
Cleanup: Set registers in original reglist from r0 - rN. Restore r0 - rN
from tmp[] properly.
*/
- if (debug_displaced)
- fprintf_unfiltered (gdb_stdlog,
- "displaced: copying thumb pop {%.8x, pc} insn %.4x\n",
- dsc->u.block.regmask, insn1);
+ displaced_debug_printf ("copying thumb pop {%.8x, pc} insn %.4x",
+ dsc->u.block.regmask, insn1);
if (dsc->u.block.regmask == 0xff)
{
}
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;
new_regmask = (1 << (num_in_list + 1)) - 1;
- if (debug_displaced)
- fprintf_unfiltered (gdb_stdlog, _("displaced: POP "
- "{..., pc}: original reg list %.4x,"
- " modified list %.4x\n"),
- (int) dsc->u.block.regmask, new_regmask);
+ displaced_debug_printf ("POP {..., pc}: original reg list %.4x, "
+ "modified list %.4x",
+ (int) dsc->u.block.regmask, new_regmask);
dsc->u.block.regmask |= 0x8000;
dsc->u.block.writeback = 0;
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
= read_memory_unsigned_integer (from, 2, byte_order_for_code);
- if (debug_displaced)
- fprintf_unfiltered (gdb_stdlog, "displaced: process thumb insn %.4x "
- "at %.8lx\n", insn1, (unsigned long) from);
+ displaced_debug_printf ("process thumb insn %.4x at %.8lx",
+ insn1, (unsigned long) from);
dsc->is_thumb = 1;
dsc->insn_size = thumb_insn_size (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);
dsc->is_thumb = 0;
dsc->insn_size = 4;
insn = read_memory_unsigned_integer (from, 4, byte_order_for_code);
- if (debug_displaced)
- fprintf_unfiltered (gdb_stdlog, "displaced: stepping insn %.8lx "
- "at %.8lx\n", (unsigned long) insn,
- (unsigned long) from);
+ displaced_debug_printf ("stepping insn %.8lx at %.8lx",
+ (unsigned long) insn, (unsigned long) from);
if ((insn & 0xf0000000) == 0xf0000000)
err = arm_decode_unconditional (gdbarch, insn, regs, dsc);
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;
/* Poke modified instruction(s). */
for (i = 0; i < dsc->numinsns; i++)
{
- if (debug_displaced)
- {
- fprintf_unfiltered (gdb_stdlog, "displaced: writing insn ");
- if (size == 4)
- fprintf_unfiltered (gdb_stdlog, "%.8lx",
- dsc->modinsn[i]);
- else if (size == 2)
- fprintf_unfiltered (gdb_stdlog, "%.4x",
- (unsigned short)dsc->modinsn[i]);
-
- fprintf_unfiltered (gdb_stdlog, " at %.8lx\n",
- (unsigned long) to + offset);
+ if (size == 4)
+ displaced_debug_printf ("writing insn %.8lx at %.8lx",
+ dsc->modinsn[i], (unsigned long) to + offset);
+ else if (size == 2)
+ displaced_debug_printf ("writing insn %.4x at %.8lx",
+ (unsigned short) dsc->modinsn[i],
+ (unsigned long) to + offset);
- }
write_memory_unsigned_integer (to + offset, size,
byte_order_for_code,
dsc->modinsn[i]);
/* Put breakpoint afterwards. */
write_memory (to + offset, bkp_insn, len);
- if (debug_displaced)
- fprintf_unfiltered (gdb_stdlog, "displaced: copy %s->%s: ",
- paddress (gdbarch, from), paddress (gdbarch, to));
+ displaced_debug_printf ("copy %s->%s", paddress (gdbarch, from),
+ paddress (gdbarch, to));
}
/* Entry point for cleaning things up after a displaced instruction has been
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);
/* GDB is able to get bfd_mach from the exe_bfd, info->mach is
accurate, so mark USER_SPECIFIED_MACHINE_TYPE bit. Otherwise,
opcodes/arm-dis.c:print_insn reset info->mach, and it will trigger
- the assert on the mismatch of info->mach and bfd_get_mach (exec_bfd)
- in default_print_insn. */
- if (exec_bfd != NULL)
+ the assert on the mismatch of info->mach and
+ bfd_get_mach (current_program_space->exec_bfd ()) in
+ default_print_insn. */
+ if (current_program_space->exec_bfd () != NULL)
info->flags |= USER_SPECIFIED_MACHINE_TYPE;
return default_print_insn (memaddr, info);
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
else
{
/* For a structure or union the behaviour is as if the value had
- been stored to word-aligned memory and then loaded into
- registers with 32-bit load instruction(s). */
+ been stored to word-aligned memory and then loaded into
+ registers with 32-bit load instruction(s). */
int len = TYPE_LENGTH (type);
int regno = ARM_A1_REGNUM;
bfd_byte tmpbuf[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;
- if (TYPE_CODE_ARRAY == code && TYPE_VECTOR (type))
+ if (TYPE_CODE_ARRAY == code && type->is_vector ())
{
/* Vector values should be returned using ARM registers if they
are not over 16 bytes. */
--> 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 (i).type ())->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)
{
else
{
/* For a structure or union the behaviour is as if the value had
- been stored to word-aligned memory and then loaded into
- registers with 32-bit load instruction(s). */
+ been stored to word-aligned memory and then loaded into
+ registers with 32-bit load instruction(s). */
int len = TYPE_LENGTH (type);
int regno = ARM_A1_REGNUM;
bfd_byte tmpbuf[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;
*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. */
|| startswith (name, "__ARM_call_via_"))
{
/* Use the name suffix to determine which register contains the
- target PC. */
+ target PC. */
static const char *table[15] =
{"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
"r8", "r9", "sl", "fp", "ip", "sp", "lr"
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
arm_update_current_architecture (void)
{
- struct gdbarch_info info;
-
/* If the current architecture is not ARM, we have nothing to do. */
if (gdbarch_bfd_arch_info (target_gdbarch ())->arch != bfd_arch_arm)
return;
/* Update the architecture. */
- gdbarch_info_init (&info);
-
+ gdbarch_info info;
if (!gdbarch_update_p (info))
internal_error (__FILE__, __LINE__, _("could not update architecture"));
}
const char *opt;
FOR_EACH_DISASSEMBLER_OPTION (opt, options)
- if (CONST_STRNEQ (opt, "reg-names-"))
+ if (startswith (opt, "reg-names-"))
{
style = &opt[strlen ("reg-names-")];
len = strcspn (style, ",");
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];
if (elfosabi == ELFOSABI_ARM)
/* GNU tools use this value. Check note sections in this case,
as well. */
- bfd_map_over_sections (abfd,
- generic_elf_osabi_sniff_abi_tag_sections,
- &osabi);
+ {
+ for (asection *sect : gdb_bfd_sections (abfd))
+ generic_elf_osabi_sniff_abi_tag_sections (abfd, sect, &osabi);
+ }
/* Anything else will be handled by the generic ELF sniffer. */
return osabi;
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,
ARM_CORE_REGS_SIZE + ARM_FP_REGS_SIZE,
- tdesc_arm_with_m_fpa_layout);
+ tdesc);
/* The regular M-profile layout. */
+ tdesc = arm_read_mprofile_description (ARM_M_TYPE_M_PROFILE);
register_remote_g_packet_guess (gdbarch, ARM_CORE_REGS_SIZE,
- tdesc_arm_with_m);
+ tdesc);
/* M-profile plus M4F VFP. */
+ tdesc = arm_read_mprofile_description (ARM_M_TYPE_VFP_D16);
register_remote_g_packet_guess (gdbarch,
ARM_CORE_REGS_SIZE + ARM_VFP2_REGS_SIZE,
- tdesc_arm_with_m_vfp_d16);
+ tdesc);
}
/* Otherwise we don't have a useful guess. */
struct gdbarch_list *best_arch;
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;
+ tdesc_arch_data_up tdesc_data;
+ 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 ();
valid_p = 1;
for (i = 0; i < ARM_SP_REGNUM; i++)
- valid_p &= tdesc_numbered_register (feature, tdesc_data, i,
+ valid_p &= tdesc_numbered_register (feature, tdesc_data.get (), i,
arm_register_names[i]);
- valid_p &= tdesc_numbered_register_choices (feature, tdesc_data,
+ valid_p &= tdesc_numbered_register_choices (feature, tdesc_data.get (),
ARM_SP_REGNUM,
arm_sp_names);
- valid_p &= tdesc_numbered_register_choices (feature, tdesc_data,
+ valid_p &= tdesc_numbered_register_choices (feature, tdesc_data.get (),
ARM_LR_REGNUM,
arm_lr_names);
- valid_p &= tdesc_numbered_register_choices (feature, tdesc_data,
+ valid_p &= tdesc_numbered_register_choices (feature, tdesc_data.get (),
ARM_PC_REGNUM,
arm_pc_names);
if (is_m)
- valid_p &= tdesc_numbered_register (feature, tdesc_data,
+ valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),
ARM_PS_REGNUM, "xpsr");
else
- valid_p &= tdesc_numbered_register (feature, tdesc_data,
+ valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),
ARM_PS_REGNUM, "cpsr");
if (!valid_p)
- {
- tdesc_data_cleanup (tdesc_data);
- return NULL;
- }
+ return NULL;
feature = tdesc_find_feature (tdesc,
"org.gnu.gdb.arm.fpa");
{
valid_p = 1;
for (i = ARM_F0_REGNUM; i <= ARM_FPS_REGNUM; i++)
- valid_p &= tdesc_numbered_register (feature, tdesc_data, i,
+ valid_p &= tdesc_numbered_register (feature, tdesc_data.get (), i,
arm_register_names[i]);
if (!valid_p)
- {
- tdesc_data_cleanup (tdesc_data);
- return NULL;
- }
+ return NULL;
}
else
- have_fpa_registers = 0;
+ have_fpa_registers = false;
feature = tdesc_find_feature (tdesc,
"org.gnu.gdb.xscale.iwmmxt");
valid_p = 1;
for (i = ARM_WR0_REGNUM; i <= ARM_WR15_REGNUM; i++)
valid_p
- &= tdesc_numbered_register (feature, tdesc_data, i,
+ &= tdesc_numbered_register (feature, tdesc_data.get (), i,
iwmmxt_names[i - ARM_WR0_REGNUM]);
/* Check for the control registers, but do not fail if they
are missing. */
for (i = ARM_WC0_REGNUM; i <= ARM_WCASF_REGNUM; i++)
- tdesc_numbered_register (feature, tdesc_data, i,
+ tdesc_numbered_register (feature, tdesc_data.get (), i,
iwmmxt_names[i - ARM_WR0_REGNUM]);
for (i = ARM_WCGR0_REGNUM; i <= ARM_WCGR3_REGNUM; i++)
valid_p
- &= tdesc_numbered_register (feature, tdesc_data, i,
+ &= tdesc_numbered_register (feature, tdesc_data.get (), i,
iwmmxt_names[i - ARM_WR0_REGNUM]);
if (!valid_p)
- {
- tdesc_data_cleanup (tdesc_data);
- return NULL;
- }
+ return NULL;
- have_wmmx_registers = 1;
+ have_wmmx_registers = true;
}
/* If we have a VFP unit, check whether the single precision registers
valid_p = 1;
for (i = 0; i < 32; i++)
{
- valid_p &= tdesc_numbered_register (feature, tdesc_data,
+ valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),
ARM_D0_REGNUM + i,
vfp_double_names[i]);
if (!valid_p)
valid_p = 1;
/* Also require FPSCR. */
- valid_p &= tdesc_numbered_register (feature, tdesc_data,
+ valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),
ARM_FPSCR_REGNUM, "fpscr");
if (!valid_p)
- {
- tdesc_data_cleanup (tdesc_data);
- return NULL;
- }
+ return NULL;
if (tdesc_unnumbered_register (feature, "s0") == 0)
- have_vfp_pseudos = 1;
+ have_vfp_pseudos = true;
vfp_register_count = i;
{
/* NEON requires 32 double-precision registers. */
if (i != 32)
- {
- tdesc_data_cleanup (tdesc_data);
- return NULL;
- }
+ return NULL;
/* If there are quad registers defined by the stub, use
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;
}
}
}
}
if (best_arch != NULL)
- {
- if (tdesc_data != NULL)
- tdesc_data_cleanup (tdesc_data);
- return best_arch->gdbarch;
- }
+ return best_arch->gdbarch;
tdep = XCNEW (struct gdbarch_tdep);
gdbarch = gdbarch_alloc (&info, tdep);
set_gdbarch_pseudo_register_write (gdbarch, arm_pseudo_write);
}
- if (tdesc_data)
+ if (tdesc_data != nullptr)
{
set_tdesc_pseudo_register_name (gdbarch, arm_register_name);
- tdesc_use_registers (gdbarch, tdesc, tdesc_data);
+ tdesc_use_registers (gdbarch, tdesc, std::move (tdesc_data));
/* Override tdesc_register_type to adjust the types of VFP
registers for NEON. */
}
/* 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);
}
namespace selftests
{
static void arm_record_test (void);
+static void arm_analyze_prologue_test ();
}
#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);
/* 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);
+ gdb::observers::new_objfile.attach (arm_exidx_new_objfile, "arm-tdep");
/* 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, 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, 0, &showlist);
arm_disassembler_options = xstrdup ("reg-names-std");
= &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-"))
+ if (startswith (disasm_options->name[i], "reg-names-"))
num_disassembly_styles++;
/* Initialize the array that will be passed to add_setshow_enum_cmd(). */
valid_disassembly_styles = XNEWVEC (const char *,
num_disassembly_styles + 1);
for (i = j = 0; disasm_options->name[i] != NULL; i++)
- if (CONST_STRNEQ (disasm_options->name[i], "reg-names-"))
+ if (startswith (disasm_options->name[i], "reg-names-"))
{
size_t offset = strlen ("reg-names-");
const char *style = disasm_options->name[i];
#if GDB_SELF_TEST
selftests::register_test ("arm-record", selftests::arm_record_test);
+ selftests::register_test ("arm_analyze_prologue", selftests::arm_analyze_prologue_test);
#endif
}
#define INSN_S_L_BIT_NUM 20
#define REG_ALLOC(REGS, LENGTH, RECORD_BUF) \
- do \
- { \
- unsigned int reg_len = LENGTH; \
- if (reg_len) \
- { \
- REGS = XNEWVEC (uint32_t, reg_len); \
- memcpy(®S[0], &RECORD_BUF[0], sizeof(uint32_t)*LENGTH); \
- } \
- } \
- while (0)
+ do \
+ { \
+ unsigned int reg_len = LENGTH; \
+ if (reg_len) \
+ { \
+ REGS = XNEWVEC (uint32_t, reg_len); \
+ memcpy(®S[0], &RECORD_BUF[0], sizeof(uint32_t)*LENGTH); \
+ } \
+ } \
+ while (0)
#define MEM_ALLOC(MEMS, LENGTH, RECORD_BUF) \
- do \
- { \
- unsigned int mem_len = LENGTH; \
- if (mem_len) \
- { \
- MEMS = XNEWVEC (struct arm_mem_r, mem_len); \
- memcpy(&MEMS->len, &RECORD_BUF[0], \
- sizeof(struct arm_mem_r) * LENGTH); \
- } \
- } \
- while (0)
+ do \
+ { \
+ unsigned int mem_len = LENGTH; \
+ if (mem_len) \
+ { \
+ MEMS = XNEWVEC (struct arm_mem_r, mem_len); \
+ memcpy(&MEMS->len, &RECORD_BUF[0], \
+ sizeof(struct arm_mem_r) * LENGTH); \
+ } \
+ } \
+ while (0)
/* Checks whether insn is already recorded or yet to be decoded. (boolean expression). */
#define INSN_RECORDED(ARM_RECORD) \
- (0 != (ARM_RECORD)->reg_rec_count || 0 != (ARM_RECORD)->mem_rec_count)
+ (0 != (ARM_RECORD)->reg_rec_count || 0 != (ARM_RECORD)->mem_rec_count)
/* ARM memory record structure. */
struct arm_mem_r
while (ones)
{
if (!(ones & sbo))
- {
- return 0;
- }
+ {
+ return 0;
+ }
ones = ones >> 1;
}
return 1;
static int
arm_record_strx (insn_decode_record *arm_insn_r, uint32_t *record_buf,
- uint32_t *record_buf_mem, arm_record_strx_t str_type)
+ uint32_t *record_buf_mem, arm_record_strx_t str_type)
{
struct regcache *reg_cache = arm_insn_r->regcache;
immed_high = bits (arm_insn_r->arm_insn, 8, 11);
reg_src1 = bits (arm_insn_r->arm_insn, 16, 19);
regcache_raw_read_unsigned (reg_cache, reg_src1,
- &u_regval[0]);
+ &u_regval[0]);
if (ARM_PC_REGNUM == reg_src1)
- {
- /* If R15 was used as Rn, hence current PC+8. */
- u_regval[0] = u_regval[0] + 8;
- }
+ {
+ /* If R15 was used as Rn, hence current PC+8. */
+ u_regval[0] = u_regval[0] + 8;
+ }
offset_8 = (immed_high << 4) | immed_low;
/* Calculate target store address. */
if (14 == arm_insn_r->opcode)
- {
- tgt_mem_addr = u_regval[0] + offset_8;
- }
+ {
+ tgt_mem_addr = u_regval[0] + offset_8;
+ }
else
- {
- tgt_mem_addr = u_regval[0] - offset_8;
- }
+ {
+ tgt_mem_addr = u_regval[0] - offset_8;
+ }
if (ARM_RECORD_STRH == str_type)
- {
- record_buf_mem[0] = 2;
- record_buf_mem[1] = tgt_mem_addr;
- arm_insn_r->mem_rec_count = 1;
- }
+ {
+ record_buf_mem[0] = 2;
+ record_buf_mem[1] = tgt_mem_addr;
+ arm_insn_r->mem_rec_count = 1;
+ }
else if (ARM_RECORD_STRD == str_type)
- {
- record_buf_mem[0] = 4;
- record_buf_mem[1] = tgt_mem_addr;
- record_buf_mem[2] = 4;
- record_buf_mem[3] = tgt_mem_addr + 4;
- arm_insn_r->mem_rec_count = 2;
- }
+ {
+ record_buf_mem[0] = 4;
+ record_buf_mem[1] = tgt_mem_addr;
+ record_buf_mem[2] = 4;
+ record_buf_mem[3] = tgt_mem_addr + 4;
+ arm_insn_r->mem_rec_count = 2;
+ }
}
else if (12 == arm_insn_r->opcode || 8 == arm_insn_r->opcode)
{
regcache_raw_read_unsigned (reg_cache, reg_src1, &u_regval[0]);
regcache_raw_read_unsigned (reg_cache, reg_src2, &u_regval[1]);
if (15 == reg_src2)
- {
- /* If R15 was used as Rn, hence current PC+8. */
- u_regval[0] = u_regval[0] + 8;
- }
+ {
+ /* If R15 was used as Rn, hence current PC+8. */
+ u_regval[0] = u_regval[0] + 8;
+ }
/* Calculate target store address, Rn +/- Rm, register offset. */
if (12 == arm_insn_r->opcode)
- {
- tgt_mem_addr = u_regval[0] + u_regval[1];
- }
+ {
+ tgt_mem_addr = u_regval[0] + u_regval[1];
+ }
else
- {
- tgt_mem_addr = u_regval[1] - u_regval[0];
- }
+ {
+ tgt_mem_addr = u_regval[1] - u_regval[0];
+ }
if (ARM_RECORD_STRH == str_type)
- {
- record_buf_mem[0] = 2;
- record_buf_mem[1] = tgt_mem_addr;
- arm_insn_r->mem_rec_count = 1;
- }
+ {
+ record_buf_mem[0] = 2;
+ record_buf_mem[1] = tgt_mem_addr;
+ arm_insn_r->mem_rec_count = 1;
+ }
else if (ARM_RECORD_STRD == str_type)
- {
- record_buf_mem[0] = 4;
- record_buf_mem[1] = tgt_mem_addr;
- record_buf_mem[2] = 4;
- record_buf_mem[3] = tgt_mem_addr + 4;
- arm_insn_r->mem_rec_count = 2;
- }
+ {
+ record_buf_mem[0] = 4;
+ record_buf_mem[1] = tgt_mem_addr;
+ record_buf_mem[2] = 4;
+ record_buf_mem[3] = tgt_mem_addr + 4;
+ arm_insn_r->mem_rec_count = 2;
+ }
}
else if (11 == arm_insn_r->opcode || 15 == arm_insn_r->opcode
- || 2 == arm_insn_r->opcode || 6 == arm_insn_r->opcode)
+ || 2 == arm_insn_r->opcode || 6 == arm_insn_r->opcode)
{
/* 3) Store, immediate pre-indexed. */
/* 5) Store, immediate post-indexed. */
regcache_raw_read_unsigned (reg_cache, reg_src1, &u_regval[0]);
/* Calculate target store address, Rn +/- Rm, register offset. */
if (15 == arm_insn_r->opcode || 6 == arm_insn_r->opcode)
- {
- tgt_mem_addr = u_regval[0] + offset_8;
- }
+ {
+ tgt_mem_addr = u_regval[0] + offset_8;
+ }
else
- {
- tgt_mem_addr = u_regval[0] - offset_8;
- }
+ {
+ tgt_mem_addr = u_regval[0] - offset_8;
+ }
if (ARM_RECORD_STRH == str_type)
- {
- record_buf_mem[0] = 2;
- record_buf_mem[1] = tgt_mem_addr;
- arm_insn_r->mem_rec_count = 1;
- }
+ {
+ record_buf_mem[0] = 2;
+ record_buf_mem[1] = tgt_mem_addr;
+ arm_insn_r->mem_rec_count = 1;
+ }
else if (ARM_RECORD_STRD == str_type)
- {
- record_buf_mem[0] = 4;
- record_buf_mem[1] = tgt_mem_addr;
- record_buf_mem[2] = 4;
- record_buf_mem[3] = tgt_mem_addr + 4;
- arm_insn_r->mem_rec_count = 2;
- }
+ {
+ record_buf_mem[0] = 4;
+ record_buf_mem[1] = tgt_mem_addr;
+ record_buf_mem[2] = 4;
+ record_buf_mem[3] = tgt_mem_addr + 4;
+ arm_insn_r->mem_rec_count = 2;
+ }
/* Record Rn also as it changes. */
*(record_buf) = bits (arm_insn_r->arm_insn, 16, 19);
arm_insn_r->reg_rec_count = 1;
}
else if (9 == arm_insn_r->opcode || 13 == arm_insn_r->opcode
- || 0 == arm_insn_r->opcode || 4 == arm_insn_r->opcode)
+ || 0 == arm_insn_r->opcode || 4 == arm_insn_r->opcode)
{
/* 4) Store, register pre-indexed. */
/* 6) Store, register post -indexed. */
regcache_raw_read_unsigned (reg_cache, reg_src2, &u_regval[1]);
/* Calculate target store address, Rn +/- Rm, register offset. */
if (13 == arm_insn_r->opcode || 4 == arm_insn_r->opcode)
- {
- tgt_mem_addr = u_regval[0] + u_regval[1];
- }
+ {
+ tgt_mem_addr = u_regval[0] + u_regval[1];
+ }
else
- {
- tgt_mem_addr = u_regval[1] - u_regval[0];
- }
+ {
+ tgt_mem_addr = u_regval[1] - u_regval[0];
+ }
if (ARM_RECORD_STRH == str_type)
- {
- record_buf_mem[0] = 2;
- record_buf_mem[1] = tgt_mem_addr;
- arm_insn_r->mem_rec_count = 1;
- }
+ {
+ record_buf_mem[0] = 2;
+ record_buf_mem[1] = tgt_mem_addr;
+ arm_insn_r->mem_rec_count = 1;
+ }
else if (ARM_RECORD_STRD == str_type)
- {
- record_buf_mem[0] = 4;
- record_buf_mem[1] = tgt_mem_addr;
- record_buf_mem[2] = 4;
- record_buf_mem[3] = tgt_mem_addr + 4;
- arm_insn_r->mem_rec_count = 2;
- }
+ {
+ record_buf_mem[0] = 4;
+ record_buf_mem[1] = tgt_mem_addr;
+ record_buf_mem[2] = 4;
+ record_buf_mem[3] = tgt_mem_addr + 4;
+ arm_insn_r->mem_rec_count = 2;
+ }
/* Record Rn also as it changes. */
*(record_buf) = bits (arm_insn_r->arm_insn, 16, 19);
arm_insn_r->reg_rec_count = 1;
if (arm_insn_r->cond)
{
/* PLD has no affect on architectural state, it just affects
- the caches. */
+ the caches. */
if (5 == ((opcode1 & 0xE0) >> 5))
- {
- /* BLX(1) */
- record_buf[0] = ARM_PS_REGNUM;
- record_buf[1] = ARM_LR_REGNUM;
- arm_insn_r->reg_rec_count = 2;
- }
+ {
+ /* BLX(1) */
+ record_buf[0] = ARM_PS_REGNUM;
+ record_buf[1] = ARM_LR_REGNUM;
+ arm_insn_r->reg_rec_count = 2;
+ }
/* STC2, LDC2, MCR2, MRC2, CDP2: <TBD>, co-processor insn. */
}
{
ret = -1;
/* Undefined instruction on ARM V5; need to handle if later
- versions define it. */
+ versions define it. */
}
opcode1 = bits (arm_insn_r->arm_insn, 24, 27);
{
/* Handle MLA(S) and MUL(S). */
if (in_inclusive_range (insn_op1, 0U, 3U))
- {
- record_buf[0] = bits (arm_insn_r->arm_insn, 12, 15);
- record_buf[1] = ARM_PS_REGNUM;
- arm_insn_r->reg_rec_count = 2;
- }
+ {
+ record_buf[0] = bits (arm_insn_r->arm_insn, 12, 15);
+ record_buf[1] = ARM_PS_REGNUM;
+ arm_insn_r->reg_rec_count = 2;
+ }
else if (in_inclusive_range (insn_op1, 4U, 15U))
- {
- /* Handle SMLAL(S), SMULL(S), UMLAL(S), UMULL(S). */
- record_buf[0] = bits (arm_insn_r->arm_insn, 16, 19);
- record_buf[1] = bits (arm_insn_r->arm_insn, 12, 15);
- record_buf[2] = ARM_PS_REGNUM;
- arm_insn_r->reg_rec_count = 3;
- }
+ {
+ /* Handle SMLAL(S), SMULL(S), UMLAL(S), UMULL(S). */
+ record_buf[0] = bits (arm_insn_r->arm_insn, 16, 19);
+ record_buf[1] = bits (arm_insn_r->arm_insn, 12, 15);
+ record_buf[2] = ARM_PS_REGNUM;
+ arm_insn_r->reg_rec_count = 3;
+ }
}
opcode1 = bits (arm_insn_r->arm_insn, 26, 27);
&& 1 != arm_insn_r->cond && !INSN_RECORDED(arm_insn_r))
{
if (!bit (arm_insn_r->arm_insn,25))
- {
- if (!bits (arm_insn_r->arm_insn, 4, 7))
- {
- if ((0 == insn_op1) || (2 == insn_op1))
- {
- /* MRS. */
- record_buf[0] = bits (arm_insn_r->arm_insn, 12, 15);
- arm_insn_r->reg_rec_count = 1;
- }
- else if (1 == insn_op1)
- {
- /* CSPR is going to be changed. */
- record_buf[0] = ARM_PS_REGNUM;
- arm_insn_r->reg_rec_count = 1;
- }
- else if (3 == insn_op1)
- {
- /* SPSR is going to be changed. */
- /* We need to get SPSR value, which is yet to be done. */
- return -1;
- }
- }
- else if (1 == bits (arm_insn_r->arm_insn, 4, 7))
- {
- if (1 == insn_op1)
- {
- /* BX. */
- record_buf[0] = ARM_PS_REGNUM;
- arm_insn_r->reg_rec_count = 1;
- }
- else if (3 == insn_op1)
- {
- /* CLZ. */
- record_buf[0] = bits (arm_insn_r->arm_insn, 12, 15);
- arm_insn_r->reg_rec_count = 1;
- }
- }
- else if (3 == bits (arm_insn_r->arm_insn, 4, 7))
- {
- /* BLX. */
- record_buf[0] = ARM_PS_REGNUM;
- record_buf[1] = ARM_LR_REGNUM;
- arm_insn_r->reg_rec_count = 2;
- }
- else if (5 == bits (arm_insn_r->arm_insn, 4, 7))
- {
- /* QADD, QSUB, QDADD, QDSUB */
- record_buf[0] = ARM_PS_REGNUM;
- record_buf[1] = bits (arm_insn_r->arm_insn, 12, 15);
- arm_insn_r->reg_rec_count = 2;
- }
- else if (7 == bits (arm_insn_r->arm_insn, 4, 7))
- {
- /* BKPT. */
- record_buf[0] = ARM_PS_REGNUM;
- record_buf[1] = ARM_LR_REGNUM;
- arm_insn_r->reg_rec_count = 2;
-
- /* Save SPSR also;how? */
- return -1;
- }
- else if(8 == bits (arm_insn_r->arm_insn, 4, 7)
- || 10 == bits (arm_insn_r->arm_insn, 4, 7)
- || 12 == bits (arm_insn_r->arm_insn, 4, 7)
- || 14 == bits (arm_insn_r->arm_insn, 4, 7)
- )
- {
- if (0 == insn_op1 || 1 == insn_op1)
- {
- /* SMLA<x><y>, SMLAW<y>, SMULW<y>. */
- /* We dont do optimization for SMULW<y> where we
- need only Rd. */
- record_buf[0] = bits (arm_insn_r->arm_insn, 12, 15);
- record_buf[1] = ARM_PS_REGNUM;
- arm_insn_r->reg_rec_count = 2;
- }
- else if (2 == insn_op1)
- {
- /* SMLAL<x><y>. */
- record_buf[0] = bits (arm_insn_r->arm_insn, 12, 15);
- record_buf[1] = bits (arm_insn_r->arm_insn, 16, 19);
- arm_insn_r->reg_rec_count = 2;
- }
- else if (3 == insn_op1)
- {
- /* SMUL<x><y>. */
- record_buf[0] = bits (arm_insn_r->arm_insn, 12, 15);
- arm_insn_r->reg_rec_count = 1;
- }
- }
- }
- else
- {
- /* MSR : immediate form. */
- if (1 == insn_op1)
- {
- /* CSPR is going to be changed. */
- record_buf[0] = ARM_PS_REGNUM;
- arm_insn_r->reg_rec_count = 1;
- }
- else if (3 == insn_op1)
- {
- /* SPSR is going to be changed. */
- /* we need to get SPSR value, which is yet to be done */
- return -1;
- }
- }
- }
-
- opcode1 = bits (arm_insn_r->arm_insn, 25, 27);
- opcode2 = bits (arm_insn_r->arm_insn, 20, 24);
- insn_op1 = bits (arm_insn_r->arm_insn, 5, 6);
-
- /* Handle load/store insn extension space. */
+ {
+ if (!bits (arm_insn_r->arm_insn, 4, 7))
+ {
+ if ((0 == insn_op1) || (2 == insn_op1))
+ {
+ /* MRS. */
+ record_buf[0] = bits (arm_insn_r->arm_insn, 12, 15);
+ arm_insn_r->reg_rec_count = 1;
+ }
+ else if (1 == insn_op1)
+ {
+ /* CSPR is going to be changed. */
+ record_buf[0] = ARM_PS_REGNUM;
+ arm_insn_r->reg_rec_count = 1;
+ }
+ else if (3 == insn_op1)
+ {
+ /* SPSR is going to be changed. */
+ /* We need to get SPSR value, which is yet to be done. */
+ return -1;
+ }
+ }
+ else if (1 == bits (arm_insn_r->arm_insn, 4, 7))
+ {
+ if (1 == insn_op1)
+ {
+ /* BX. */
+ record_buf[0] = ARM_PS_REGNUM;
+ arm_insn_r->reg_rec_count = 1;
+ }
+ else if (3 == insn_op1)
+ {
+ /* CLZ. */
+ record_buf[0] = bits (arm_insn_r->arm_insn, 12, 15);
+ arm_insn_r->reg_rec_count = 1;
+ }
+ }
+ else if (3 == bits (arm_insn_r->arm_insn, 4, 7))
+ {
+ /* BLX. */
+ record_buf[0] = ARM_PS_REGNUM;
+ record_buf[1] = ARM_LR_REGNUM;
+ arm_insn_r->reg_rec_count = 2;
+ }
+ else if (5 == bits (arm_insn_r->arm_insn, 4, 7))
+ {
+ /* QADD, QSUB, QDADD, QDSUB */
+ record_buf[0] = ARM_PS_REGNUM;
+ record_buf[1] = bits (arm_insn_r->arm_insn, 12, 15);
+ arm_insn_r->reg_rec_count = 2;
+ }
+ else if (7 == bits (arm_insn_r->arm_insn, 4, 7))
+ {
+ /* BKPT. */
+ record_buf[0] = ARM_PS_REGNUM;
+ record_buf[1] = ARM_LR_REGNUM;
+ arm_insn_r->reg_rec_count = 2;
- if (!opcode1 && bit (arm_insn_r->arm_insn, 7)
- && bit (arm_insn_r->arm_insn, 4) && 1 != arm_insn_r->cond
- && !INSN_RECORDED(arm_insn_r))
- {
- /* SWP/SWPB. */
- if (0 == insn_op1)
- {
- /* These insn, changes register and memory as well. */
- /* SWP or SWPB insn. */
- /* Get memory address given by Rn. */
- reg_src1 = bits (arm_insn_r->arm_insn, 16, 19);
- regcache_raw_read_unsigned (reg_cache, reg_src1, &u_regval);
- /* SWP insn ?, swaps word. */
- if (8 == arm_insn_r->opcode)
- {
- record_buf_mem[0] = 4;
- }
- else
- {
- /* SWPB insn, swaps only byte. */
- record_buf_mem[0] = 1;
- }
- record_buf_mem[1] = u_regval;
- arm_insn_r->mem_rec_count = 1;
- record_buf[0] = bits (arm_insn_r->arm_insn, 12, 15);
- arm_insn_r->reg_rec_count = 1;
- }
- else if (1 == insn_op1 && !bit (arm_insn_r->arm_insn, 20))
- {
- /* STRH. */
- arm_record_strx(arm_insn_r, &record_buf[0], &record_buf_mem[0],
- ARM_RECORD_STRH);
- }
+ /* Save SPSR also;how? */
+ return -1;
+ }
+ else if(8 == bits (arm_insn_r->arm_insn, 4, 7)
+ || 10 == bits (arm_insn_r->arm_insn, 4, 7)
+ || 12 == bits (arm_insn_r->arm_insn, 4, 7)
+ || 14 == bits (arm_insn_r->arm_insn, 4, 7)
+ )
+ {
+ if (0 == insn_op1 || 1 == insn_op1)
+ {
+ /* SMLA<x><y>, SMLAW<y>, SMULW<y>. */
+ /* We dont do optimization for SMULW<y> where we
+ need only Rd. */
+ record_buf[0] = bits (arm_insn_r->arm_insn, 12, 15);
+ record_buf[1] = ARM_PS_REGNUM;
+ arm_insn_r->reg_rec_count = 2;
+ }
+ else if (2 == insn_op1)
+ {
+ /* SMLAL<x><y>. */
+ record_buf[0] = bits (arm_insn_r->arm_insn, 12, 15);
+ record_buf[1] = bits (arm_insn_r->arm_insn, 16, 19);
+ arm_insn_r->reg_rec_count = 2;
+ }
+ else if (3 == insn_op1)
+ {
+ /* SMUL<x><y>. */
+ record_buf[0] = bits (arm_insn_r->arm_insn, 12, 15);
+ arm_insn_r->reg_rec_count = 1;
+ }
+ }
+ }
+ else
+ {
+ /* MSR : immediate form. */
+ if (1 == insn_op1)
+ {
+ /* CSPR is going to be changed. */
+ record_buf[0] = ARM_PS_REGNUM;
+ arm_insn_r->reg_rec_count = 1;
+ }
+ else if (3 == insn_op1)
+ {
+ /* SPSR is going to be changed. */
+ /* we need to get SPSR value, which is yet to be done */
+ return -1;
+ }
+ }
+ }
+
+ opcode1 = bits (arm_insn_r->arm_insn, 25, 27);
+ opcode2 = bits (arm_insn_r->arm_insn, 20, 24);
+ insn_op1 = bits (arm_insn_r->arm_insn, 5, 6);
+
+ /* Handle load/store insn extension space. */
+
+ if (!opcode1 && bit (arm_insn_r->arm_insn, 7)
+ && bit (arm_insn_r->arm_insn, 4) && 1 != arm_insn_r->cond
+ && !INSN_RECORDED(arm_insn_r))
+ {
+ /* SWP/SWPB. */
+ if (0 == insn_op1)
+ {
+ /* These insn, changes register and memory as well. */
+ /* SWP or SWPB insn. */
+ /* Get memory address given by Rn. */
+ reg_src1 = bits (arm_insn_r->arm_insn, 16, 19);
+ regcache_raw_read_unsigned (reg_cache, reg_src1, &u_regval);
+ /* SWP insn ?, swaps word. */
+ if (8 == arm_insn_r->opcode)
+ {
+ record_buf_mem[0] = 4;
+ }
+ else
+ {
+ /* SWPB insn, swaps only byte. */
+ record_buf_mem[0] = 1;
+ }
+ record_buf_mem[1] = u_regval;
+ arm_insn_r->mem_rec_count = 1;
+ record_buf[0] = bits (arm_insn_r->arm_insn, 12, 15);
+ arm_insn_r->reg_rec_count = 1;
+ }
+ else if (1 == insn_op1 && !bit (arm_insn_r->arm_insn, 20))
+ {
+ /* STRH. */
+ arm_record_strx(arm_insn_r, &record_buf[0], &record_buf_mem[0],
+ ARM_RECORD_STRH);
+ }
else if (2 == insn_op1 && !bit (arm_insn_r->arm_insn, 20))
- {
- /* LDRD. */
- record_buf[0] = bits (arm_insn_r->arm_insn, 12, 15);
- record_buf[1] = record_buf[0] + 1;
- arm_insn_r->reg_rec_count = 2;
- }
+ {
+ /* LDRD. */
+ record_buf[0] = bits (arm_insn_r->arm_insn, 12, 15);
+ record_buf[1] = record_buf[0] + 1;
+ arm_insn_r->reg_rec_count = 2;
+ }
else if (3 == insn_op1 && !bit (arm_insn_r->arm_insn, 20))
- {
- /* STRD. */
- arm_record_strx(arm_insn_r, &record_buf[0], &record_buf_mem[0],
- ARM_RECORD_STRD);
- }
+ {
+ /* STRD. */
+ arm_record_strx(arm_insn_r, &record_buf[0], &record_buf_mem[0],
+ ARM_RECORD_STRD);
+ }
else if (bit (arm_insn_r->arm_insn, 20) && insn_op1 <= 3)
- {
- /* LDRH, LDRSB, LDRSH. */
- record_buf[0] = bits (arm_insn_r->arm_insn, 12, 15);
- arm_insn_r->reg_rec_count = 1;
- }
+ {
+ /* LDRH, LDRSB, LDRSH. */
+ record_buf[0] = bits (arm_insn_r->arm_insn, 12, 15);
+ arm_insn_r->reg_rec_count = 1;
+ }
}
/* Handle multiply instructions. */
/* MLA, MUL, SMLAL, SMULL, UMLAL, UMULL. */
if (0 == arm_insn_r->opcode || 1 == arm_insn_r->opcode)
- {
- /* Handle MLA and MUL. */
- record_buf[0] = bits (arm_insn_r->arm_insn, 16, 19);
- record_buf[1] = ARM_PS_REGNUM;
- arm_insn_r->reg_rec_count = 2;
- }
- else if (4 <= arm_insn_r->opcode && 7 >= arm_insn_r->opcode)
- {
- /* Handle SMLAL, SMULL, UMLAL, UMULL. */
- record_buf[0] = bits (arm_insn_r->arm_insn, 16, 19);
- record_buf[1] = bits (arm_insn_r->arm_insn, 12, 15);
- record_buf[2] = ARM_PS_REGNUM;
- arm_insn_r->reg_rec_count = 3;
- }
+ {
+ /* Handle MLA and MUL. */
+ record_buf[0] = bits (arm_insn_r->arm_insn, 16, 19);
+ record_buf[1] = ARM_PS_REGNUM;
+ arm_insn_r->reg_rec_count = 2;
+ }
+ else if (4 <= arm_insn_r->opcode && 7 >= arm_insn_r->opcode)
+ {
+ /* Handle SMLAL, SMULL, UMLAL, UMULL. */
+ record_buf[0] = bits (arm_insn_r->arm_insn, 16, 19);
+ record_buf[1] = bits (arm_insn_r->arm_insn, 12, 15);
+ record_buf[2] = ARM_PS_REGNUM;
+ arm_insn_r->reg_rec_count = 3;
+ }
}
else if (9 == arm_insn_r->decode && opcode1 > 0x10)
{
{
/* Handle MSR insn. */
if (9 == arm_insn_r->opcode)
- {
- /* CSPR is going to be changed. */
- record_buf[0] = ARM_PS_REGNUM;
- arm_insn_r->reg_rec_count = 1;
- }
+ {
+ /* CSPR is going to be changed. */
+ record_buf[0] = ARM_PS_REGNUM;
+ arm_insn_r->reg_rec_count = 1;
+ }
else
- {
- /* SPSR is going to be changed. */
- }
+ {
+ /* SPSR is going to be changed. */
+ }
}
else if (arm_insn_r->opcode <= 15)
{
/* Normal data processing insns. */
/* Out of 11 shifter operands mode, all the insn modifies destination
- register, which is specified by 13-16 decode. */
+ register, which is specified by 13-16 decode. */
record_buf[0] = bits (arm_insn_r->arm_insn, 12, 15);
record_buf[1] = ARM_PS_REGNUM;
arm_insn_r->reg_rec_count = 2;
{
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
- in that case, it emulates branch and link insn, and hence we
- need to save CSPR and PC as well. */
+ 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)
- {
- record_buf[0] = bits (arm_insn_r->arm_insn, 12, 15);
- arm_insn_r->reg_rec_count = 1;
- }
+ {
+ record_buf[0] = bits (arm_insn_r->arm_insn, 12, 15);
+ arm_insn_r->reg_rec_count = 1;
+ }
else
- {
- record_buf[0] = reg_dest;
- record_buf[1] = ARM_PS_REGNUM;
- arm_insn_r->reg_rec_count = 2;
- }
+ {
+ record_buf[0] = reg_dest;
+ record_buf[1] = ARM_PS_REGNUM;
+ arm_insn_r->reg_rec_count = 2;
+ }
}
else
{
if (! bits (arm_insn_r->arm_insn, 4, 11))
- {
- /* Store insn, register offset and register pre-indexed,
- register post-indexed. */
- /* Get Rm. */
- reg_src1 = bits (arm_insn_r->arm_insn, 0, 3);
- /* Get Rn. */
- reg_src2 = bits (arm_insn_r->arm_insn, 16, 19);
- regcache_raw_read_unsigned (reg_cache, reg_src1
- , &u_regval[0]);
- regcache_raw_read_unsigned (reg_cache, reg_src2
- , &u_regval[1]);
- if (15 == reg_src2)
- {
- /* If R15 was used as Rn, hence current PC+8. */
- /* Pre-indexed mode doesnt reach here ; illegal insn. */
- u_regval[0] = u_regval[0] + 8;
- }
- /* Calculate target store address, Rn +/- Rm, register offset. */
- /* U == 1. */
- if (bit (arm_insn_r->arm_insn, 23))
- {
- tgt_mem_addr = u_regval[0] + u_regval[1];
- }
- else
- {
- tgt_mem_addr = u_regval[1] - u_regval[0];
- }
-
- switch (arm_insn_r->opcode)
- {
- /* STR. */
- case 8:
- case 12:
- /* STR. */
- case 9:
- case 13:
- /* STRT. */
- case 1:
- case 5:
- /* STR. */
- case 0:
- case 4:
- record_buf_mem[0] = 4;
- break;
-
- /* STRB. */
- case 10:
- case 14:
- /* STRB. */
- case 11:
- case 15:
- /* STRBT. */
- case 3:
- case 7:
- /* STRB. */
- case 2:
- case 6:
- record_buf_mem[0] = 1;
- break;
-
- default:
- gdb_assert_not_reached ("no decoding pattern found");
- break;
- }
- record_buf_mem[1] = tgt_mem_addr;
- arm_insn_r->mem_rec_count = 1;
-
- if (9 == arm_insn_r->opcode || 11 == arm_insn_r->opcode
- || 13 == arm_insn_r->opcode || 15 == arm_insn_r->opcode
- || 0 == arm_insn_r->opcode || 2 == arm_insn_r->opcode
- || 4 == arm_insn_r->opcode || 6 == arm_insn_r->opcode
- || 1 == arm_insn_r->opcode || 3 == arm_insn_r->opcode
- || 5 == arm_insn_r->opcode || 7 == arm_insn_r->opcode
- )
- {
- /* Rn is going to be changed in pre-indexed mode and
- post-indexed mode as well. */
- record_buf[0] = reg_src2;
- arm_insn_r->reg_rec_count = 1;
- }
- }
+ {
+ /* Store insn, register offset and register pre-indexed,
+ register post-indexed. */
+ /* Get Rm. */
+ reg_src1 = bits (arm_insn_r->arm_insn, 0, 3);
+ /* Get Rn. */
+ reg_src2 = bits (arm_insn_r->arm_insn, 16, 19);
+ regcache_raw_read_unsigned (reg_cache, reg_src1
+ , &u_regval[0]);
+ regcache_raw_read_unsigned (reg_cache, reg_src2
+ , &u_regval[1]);
+ if (15 == reg_src2)
+ {
+ /* If R15 was used as Rn, hence current PC+8. */
+ /* Pre-indexed mode doesnt reach here ; illegal insn. */
+ u_regval[0] = u_regval[0] + 8;
+ }
+ /* Calculate target store address, Rn +/- Rm, register offset. */
+ /* U == 1. */
+ if (bit (arm_insn_r->arm_insn, 23))
+ {
+ tgt_mem_addr = u_regval[0] + u_regval[1];
+ }
+ else
+ {
+ tgt_mem_addr = u_regval[1] - u_regval[0];
+ }
+
+ switch (arm_insn_r->opcode)
+ {
+ /* STR. */
+ case 8:
+ case 12:
+ /* STR. */
+ case 9:
+ case 13:
+ /* STRT. */
+ case 1:
+ case 5:
+ /* STR. */
+ case 0:
+ case 4:
+ record_buf_mem[0] = 4;
+ break;
+
+ /* STRB. */
+ case 10:
+ case 14:
+ /* STRB. */
+ case 11:
+ case 15:
+ /* STRBT. */
+ case 3:
+ case 7:
+ /* STRB. */
+ case 2:
+ case 6:
+ record_buf_mem[0] = 1;
+ break;
+
+ default:
+ gdb_assert_not_reached ("no decoding pattern found");
+ break;
+ }
+ record_buf_mem[1] = tgt_mem_addr;
+ arm_insn_r->mem_rec_count = 1;
+
+ if (9 == arm_insn_r->opcode || 11 == arm_insn_r->opcode
+ || 13 == arm_insn_r->opcode || 15 == arm_insn_r->opcode
+ || 0 == arm_insn_r->opcode || 2 == arm_insn_r->opcode
+ || 4 == arm_insn_r->opcode || 6 == arm_insn_r->opcode
+ || 1 == arm_insn_r->opcode || 3 == arm_insn_r->opcode
+ || 5 == arm_insn_r->opcode || 7 == arm_insn_r->opcode
+ )
+ {
+ /* Rn is going to be changed in pre-indexed mode and
+ post-indexed mode as well. */
+ record_buf[0] = reg_src2;
+ arm_insn_r->reg_rec_count = 1;
+ }
+ }
else
- {
- /* Store insn, scaled register offset; scaled pre-indexed. */
- offset_12 = bits (arm_insn_r->arm_insn, 5, 6);
- /* Get Rm. */
- reg_src1 = bits (arm_insn_r->arm_insn, 0, 3);
- /* Get Rn. */
- reg_src2 = bits (arm_insn_r->arm_insn, 16, 19);
- /* Get shift_imm. */
- shift_imm = bits (arm_insn_r->arm_insn, 7, 11);
- regcache_raw_read_unsigned (reg_cache, reg_src1, &u_regval[0]);
- regcache_raw_read_signed (reg_cache, reg_src1, &s_word);
- regcache_raw_read_unsigned (reg_cache, reg_src2, &u_regval[1]);
- /* Offset_12 used as shift. */
- switch (offset_12)
- {
- case 0:
- /* Offset_12 used as index. */
- offset_12 = u_regval[0] << shift_imm;
- break;
-
- case 1:
- offset_12 = (!shift_imm)?0:u_regval[0] >> shift_imm;
- break;
-
- case 2:
- if (!shift_imm)
- {
- if (bit (u_regval[0], 31))
- {
- offset_12 = 0xFFFFFFFF;
- }
- else
- {
- offset_12 = 0;
- }
- }
- else
- {
- /* This is arithmetic shift. */
- offset_12 = s_word >> shift_imm;
- }
- break;
-
- case 3:
- if (!shift_imm)
- {
- regcache_raw_read_unsigned (reg_cache, ARM_PS_REGNUM,
- &u_regval[1]);
- /* Get C flag value and shift it by 31. */
- offset_12 = (((bit (u_regval[1], 29)) << 31) \
- | (u_regval[0]) >> 1);
- }
- else
- {
- offset_12 = (u_regval[0] >> shift_imm) \
- | (u_regval[0] <<
- (sizeof(uint32_t) - shift_imm));
- }
- break;
-
- default:
- gdb_assert_not_reached ("no decoding pattern found");
- break;
- }
-
- regcache_raw_read_unsigned (reg_cache, reg_src2, &u_regval[1]);
- /* bit U set. */
- if (bit (arm_insn_r->arm_insn, 23))
- {
- tgt_mem_addr = u_regval[1] + offset_12;
- }
- else
- {
- tgt_mem_addr = u_regval[1] - offset_12;
- }
-
- switch (arm_insn_r->opcode)
- {
- /* STR. */
- case 8:
- case 12:
- /* STR. */
- case 9:
- case 13:
- /* STRT. */
- case 1:
- case 5:
- /* STR. */
- case 0:
- case 4:
- record_buf_mem[0] = 4;
- break;
-
- /* STRB. */
- case 10:
- case 14:
- /* STRB. */
- case 11:
- case 15:
- /* STRBT. */
- case 3:
- case 7:
- /* STRB. */
- case 2:
- case 6:
- record_buf_mem[0] = 1;
- break;
-
- default:
- gdb_assert_not_reached ("no decoding pattern found");
- break;
- }
- record_buf_mem[1] = tgt_mem_addr;
- arm_insn_r->mem_rec_count = 1;
-
- if (9 == arm_insn_r->opcode || 11 == arm_insn_r->opcode
- || 13 == arm_insn_r->opcode || 15 == arm_insn_r->opcode
- || 0 == arm_insn_r->opcode || 2 == arm_insn_r->opcode
- || 4 == arm_insn_r->opcode || 6 == arm_insn_r->opcode
- || 1 == arm_insn_r->opcode || 3 == arm_insn_r->opcode
- || 5 == arm_insn_r->opcode || 7 == arm_insn_r->opcode
- )
- {
- /* Rn is going to be changed in register scaled pre-indexed
- mode,and scaled post indexed mode. */
- record_buf[0] = reg_src2;
- arm_insn_r->reg_rec_count = 1;
- }
- }
+ {
+ /* Store insn, scaled register offset; scaled pre-indexed. */
+ offset_12 = bits (arm_insn_r->arm_insn, 5, 6);
+ /* Get Rm. */
+ reg_src1 = bits (arm_insn_r->arm_insn, 0, 3);
+ /* Get Rn. */
+ reg_src2 = bits (arm_insn_r->arm_insn, 16, 19);
+ /* Get shift_imm. */
+ shift_imm = bits (arm_insn_r->arm_insn, 7, 11);
+ regcache_raw_read_unsigned (reg_cache, reg_src1, &u_regval[0]);
+ regcache_raw_read_signed (reg_cache, reg_src1, &s_word);
+ regcache_raw_read_unsigned (reg_cache, reg_src2, &u_regval[1]);
+ /* Offset_12 used as shift. */
+ switch (offset_12)
+ {
+ case 0:
+ /* Offset_12 used as index. */
+ offset_12 = u_regval[0] << shift_imm;
+ break;
+
+ case 1:
+ offset_12 = (!shift_imm)?0:u_regval[0] >> shift_imm;
+ break;
+
+ case 2:
+ if (!shift_imm)
+ {
+ if (bit (u_regval[0], 31))
+ {
+ offset_12 = 0xFFFFFFFF;
+ }
+ else
+ {
+ offset_12 = 0;
+ }
+ }
+ else
+ {
+ /* This is arithmetic shift. */
+ offset_12 = s_word >> shift_imm;
+ }
+ break;
+
+ case 3:
+ if (!shift_imm)
+ {
+ regcache_raw_read_unsigned (reg_cache, ARM_PS_REGNUM,
+ &u_regval[1]);
+ /* Get C flag value and shift it by 31. */
+ offset_12 = (((bit (u_regval[1], 29)) << 31) \
+ | (u_regval[0]) >> 1);
+ }
+ else
+ {
+ offset_12 = (u_regval[0] >> shift_imm) \
+ | (u_regval[0] <<
+ (sizeof(uint32_t) - shift_imm));
+ }
+ break;
+
+ default:
+ gdb_assert_not_reached ("no decoding pattern found");
+ break;
+ }
+
+ regcache_raw_read_unsigned (reg_cache, reg_src2, &u_regval[1]);
+ /* bit U set. */
+ if (bit (arm_insn_r->arm_insn, 23))
+ {
+ tgt_mem_addr = u_regval[1] + offset_12;
+ }
+ else
+ {
+ tgt_mem_addr = u_regval[1] - offset_12;
+ }
+
+ switch (arm_insn_r->opcode)
+ {
+ /* STR. */
+ case 8:
+ case 12:
+ /* STR. */
+ case 9:
+ case 13:
+ /* STRT. */
+ case 1:
+ case 5:
+ /* STR. */
+ case 0:
+ case 4:
+ record_buf_mem[0] = 4;
+ break;
+
+ /* STRB. */
+ case 10:
+ case 14:
+ /* STRB. */
+ case 11:
+ case 15:
+ /* STRBT. */
+ case 3:
+ case 7:
+ /* STRB. */
+ case 2:
+ case 6:
+ record_buf_mem[0] = 1;
+ break;
+
+ default:
+ gdb_assert_not_reached ("no decoding pattern found");
+ break;
+ }
+ record_buf_mem[1] = tgt_mem_addr;
+ arm_insn_r->mem_rec_count = 1;
+
+ if (9 == arm_insn_r->opcode || 11 == arm_insn_r->opcode
+ || 13 == arm_insn_r->opcode || 15 == arm_insn_r->opcode
+ || 0 == arm_insn_r->opcode || 2 == arm_insn_r->opcode
+ || 4 == arm_insn_r->opcode || 6 == arm_insn_r->opcode
+ || 1 == arm_insn_r->opcode || 3 == arm_insn_r->opcode
+ || 5 == arm_insn_r->opcode || 7 == arm_insn_r->opcode
+ )
+ {
+ /* Rn is going to be changed in register scaled pre-indexed
+ mode,and scaled post indexed mode. */
+ record_buf[0] = reg_src2;
+ arm_insn_r->reg_rec_count = 1;
+ }
+ }
}
REG_ALLOC (arm_insn_r->arm_regs, arm_insn_r->reg_rec_count, record_buf);
/* Note: BLX(1) doesnt fall here but instead it falls into
extension space. */
if (bit (arm_insn_r->arm_insn, 24))
- {
- record_buf[0] = ARM_LR_REGNUM;
- arm_insn_r->reg_rec_count = 1;
- }
+ {
+ record_buf[0] = ARM_LR_REGNUM;
+ arm_insn_r->reg_rec_count = 1;
+ }
REG_ALLOC (arm_insn_r->arm_regs, arm_insn_r->reg_rec_count, record_buf);
{
/* Handle VMOV instruction. */
if (bits_a == 0x00)
- {
+ {
record_buf[0] = reg_t;
- arm_insn_r->reg_rec_count = 1;
- }
+ arm_insn_r->reg_rec_count = 1;
+ }
/* Handle VMRS instruction. */
else if (bits_a == 0x07)
- {
- if (reg_t == 15)
- reg_t = ARM_PS_REGNUM;
+ {
+ if (reg_t == 15)
+ reg_t = ARM_PS_REGNUM;
- record_buf[0] = reg_t;
- arm_insn_r->reg_rec_count = 1;
- }
+ record_buf[0] = reg_t;
+ arm_insn_r->reg_rec_count = 1;
+ }
}
else if (!bit_l && !bit_c)
{
/* Handle VMOV instruction. */
if (bits_a == 0x00)
- {
+ {
record_buf[0] = ARM_D0_REGNUM + reg_v;
- arm_insn_r->reg_rec_count = 1;
- }
+ arm_insn_r->reg_rec_count = 1;
+ }
/* Handle VMSR instruction. */
else if (bits_a == 0x07)
- {
- record_buf[0] = ARM_FPSCR_REGNUM;
- arm_insn_r->reg_rec_count = 1;
- }
+ {
+ record_buf[0] = ARM_FPSCR_REGNUM;
+ arm_insn_r->reg_rec_count = 1;
+ }
}
else if (!bit_l && bit_c)
{
/* Handle VMOV instruction. */
if (!(bits_a & 0x04))
- {
- record_buf[0] = (reg_v | (bit (arm_insn_r->arm_insn, 7) << 4))
- + ARM_D0_REGNUM;
- arm_insn_r->reg_rec_count = 1;
- }
+ {
+ record_buf[0] = (reg_v | (bit (arm_insn_r->arm_insn, 7) << 4))
+ + ARM_D0_REGNUM;
+ arm_insn_r->reg_rec_count = 1;
+ }
/* Handle VDUP instruction. */
else
- {
- if (bit (arm_insn_r->arm_insn, 21))
- {
- reg_v = reg_v | (bit (arm_insn_r->arm_insn, 7) << 4);
- record_buf[0] = reg_v + ARM_D0_REGNUM;
- record_buf[1] = reg_v + ARM_D0_REGNUM + 1;
- arm_insn_r->reg_rec_count = 2;
- }
- else
- {
- reg_v = reg_v | (bit (arm_insn_r->arm_insn, 7) << 4);
- record_buf[0] = reg_v + ARM_D0_REGNUM;
- arm_insn_r->reg_rec_count = 1;
- }
- }
+ {
+ if (bit (arm_insn_r->arm_insn, 21))
+ {
+ reg_v = reg_v | (bit (arm_insn_r->arm_insn, 7) << 4);
+ record_buf[0] = reg_v + ARM_D0_REGNUM;
+ record_buf[1] = reg_v + ARM_D0_REGNUM + 1;
+ arm_insn_r->reg_rec_count = 2;
+ }
+ else
+ {
+ reg_v = reg_v | (bit (arm_insn_r->arm_insn, 7) << 4);
+ record_buf[0] = reg_v + ARM_D0_REGNUM;
+ arm_insn_r->reg_rec_count = 1;
+ }
+ }
}
REG_ALLOC (arm_insn_r->arm_regs, arm_insn_r->reg_rec_count, record_buf);
if (opc1 == 0x00)
{
if (bit (arm_insn_r->arm_insn, 10))
- {
- if (bit (arm_insn_r->arm_insn, 6))
- curr_insn_type = INSN_T0;
- else
- curr_insn_type = INSN_T1;
- }
+ {
+ if (bit (arm_insn_r->arm_insn, 6))
+ curr_insn_type = INSN_T0;
+ else
+ curr_insn_type = INSN_T1;
+ }
else
- {
- if (dp_op_sz)
- curr_insn_type = INSN_T1;
- else
- curr_insn_type = INSN_T2;
- }
+ {
+ if (dp_op_sz)
+ curr_insn_type = INSN_T1;
+ else
+ curr_insn_type = INSN_T2;
+ }
}
/* Handle VNMLA, VNMLS, VNMUL. */
else if (opc1 == 0x01)
{
if (dp_op_sz)
- curr_insn_type = INSN_T1;
+ curr_insn_type = INSN_T1;
else
- curr_insn_type = INSN_T2;
+ curr_insn_type = INSN_T2;
}
/* Handle VMUL. */
else if (opc1 == 0x02 && !(opc3 & 0x01))
{
if (bit (arm_insn_r->arm_insn, 10))
- {
- if (bit (arm_insn_r->arm_insn, 6))
- curr_insn_type = INSN_T0;
- else
- curr_insn_type = INSN_T1;
- }
+ {
+ if (bit (arm_insn_r->arm_insn, 6))
+ curr_insn_type = INSN_T0;
+ else
+ curr_insn_type = INSN_T1;
+ }
else
- {
- if (dp_op_sz)
- curr_insn_type = INSN_T1;
- else
- curr_insn_type = INSN_T2;
- }
+ {
+ if (dp_op_sz)
+ curr_insn_type = INSN_T1;
+ else
+ curr_insn_type = INSN_T2;
+ }
}
/* Handle VADD, VSUB. */
else if (opc1 == 0x03)
{
if (!bit (arm_insn_r->arm_insn, 9))
- {
- if (bit (arm_insn_r->arm_insn, 6))
- curr_insn_type = INSN_T0;
- else
- curr_insn_type = INSN_T1;
- }
+ {
+ if (bit (arm_insn_r->arm_insn, 6))
+ curr_insn_type = INSN_T0;
+ else
+ curr_insn_type = INSN_T1;
+ }
else
- {
- if (dp_op_sz)
- curr_insn_type = INSN_T1;
- else
- curr_insn_type = INSN_T2;
- }
+ {
+ if (dp_op_sz)
+ curr_insn_type = INSN_T1;
+ else
+ curr_insn_type = INSN_T2;
+ }
}
/* Handle VDIV. */
else if (opc1 == 0x08)
{
if (dp_op_sz)
- curr_insn_type = INSN_T1;
+ curr_insn_type = INSN_T1;
else
- curr_insn_type = INSN_T2;
+ curr_insn_type = INSN_T2;
}
/* Handle all other vfp data processing instructions. */
else if (opc1 == 0x0b)
{
/* Handle VMOV. */
if (!(opc3 & 0x01) || (opc2 == 0x00 && opc3 == 0x01))
- {
- if (bit (arm_insn_r->arm_insn, 4))
- {
- if (bit (arm_insn_r->arm_insn, 6))
- curr_insn_type = INSN_T0;
- else
- curr_insn_type = INSN_T1;
- }
- else
- {
- if (dp_op_sz)
- curr_insn_type = INSN_T1;
- else
- curr_insn_type = INSN_T2;
- }
- }
+ {
+ if (bit (arm_insn_r->arm_insn, 4))
+ {
+ if (bit (arm_insn_r->arm_insn, 6))
+ curr_insn_type = INSN_T0;
+ else
+ curr_insn_type = INSN_T1;
+ }
+ else
+ {
+ if (dp_op_sz)
+ curr_insn_type = INSN_T1;
+ else
+ curr_insn_type = INSN_T2;
+ }
+ }
/* Handle VNEG and VABS. */
else if ((opc2 == 0x01 && opc3 == 0x01)
- || (opc2 == 0x00 && opc3 == 0x03))
- {
- if (!bit (arm_insn_r->arm_insn, 11))
- {
- if (bit (arm_insn_r->arm_insn, 6))
- curr_insn_type = INSN_T0;
- else
- curr_insn_type = INSN_T1;
- }
- else
- {
- if (dp_op_sz)
- curr_insn_type = INSN_T1;
- else
- curr_insn_type = INSN_T2;
- }
- }
+ || (opc2 == 0x00 && opc3 == 0x03))
+ {
+ if (!bit (arm_insn_r->arm_insn, 11))
+ {
+ if (bit (arm_insn_r->arm_insn, 6))
+ curr_insn_type = INSN_T0;
+ else
+ curr_insn_type = INSN_T1;
+ }
+ else
+ {
+ if (dp_op_sz)
+ curr_insn_type = INSN_T1;
+ else
+ curr_insn_type = INSN_T2;
+ }
+ }
/* Handle VSQRT. */
else if (opc2 == 0x01 && opc3 == 0x03)
- {
- if (dp_op_sz)
- curr_insn_type = INSN_T1;
- else
- curr_insn_type = INSN_T2;
- }
+ {
+ if (dp_op_sz)
+ curr_insn_type = INSN_T1;
+ else
+ curr_insn_type = INSN_T2;
+ }
/* Handle VCVT. */
else if (opc2 == 0x07 && opc3 == 0x03)
- {
- if (!dp_op_sz)
- curr_insn_type = INSN_T1;
- else
- curr_insn_type = INSN_T2;
- }
+ {
+ if (!dp_op_sz)
+ curr_insn_type = INSN_T1;
+ else
+ curr_insn_type = INSN_T2;
+ }
else if (opc3 & 0x01)
- {
- /* Handle VCVT. */
- if ((opc2 == 0x08) || (opc2 & 0x0e) == 0x0c)
- {
- if (!bit (arm_insn_r->arm_insn, 18))
- curr_insn_type = INSN_T2;
- else
- {
- if (dp_op_sz)
- curr_insn_type = INSN_T1;
- else
- curr_insn_type = INSN_T2;
- }
- }
- /* Handle VCVT. */
- else if ((opc2 & 0x0e) == 0x0a || (opc2 & 0x0e) == 0x0e)
- {
- if (dp_op_sz)
- curr_insn_type = INSN_T1;
- else
- curr_insn_type = INSN_T2;
- }
- /* Handle VCVTB, VCVTT. */
- else if ((opc2 & 0x0e) == 0x02)
- curr_insn_type = INSN_T2;
- /* Handle VCMP, VCMPE. */
- else if ((opc2 & 0x0e) == 0x04)
- curr_insn_type = INSN_T3;
- }
+ {
+ /* Handle VCVT. */
+ if ((opc2 == 0x08) || (opc2 & 0x0e) == 0x0c)
+ {
+ if (!bit (arm_insn_r->arm_insn, 18))
+ curr_insn_type = INSN_T2;
+ else
+ {
+ if (dp_op_sz)
+ curr_insn_type = INSN_T1;
+ else
+ curr_insn_type = INSN_T2;
+ }
+ }
+ /* Handle VCVT. */
+ else if ((opc2 & 0x0e) == 0x0a || (opc2 & 0x0e) == 0x0e)
+ {
+ if (dp_op_sz)
+ curr_insn_type = INSN_T1;
+ else
+ curr_insn_type = INSN_T2;
+ }
+ /* Handle VCVTB, VCVTT. */
+ else if ((opc2 & 0x0e) == 0x02)
+ curr_insn_type = INSN_T2;
+ /* Handle VCMP, VCMPE. */
+ else if ((opc2 & 0x0e) == 0x04)
+ curr_insn_type = INSN_T3;
+ }
}
switch (curr_insn_type)
{
case INSN_T0:
- reg_vd = reg_vd | (bit_d << 4);
- record_buf[0] = reg_vd + ARM_D0_REGNUM;
- record_buf[1] = reg_vd + ARM_D0_REGNUM + 1;
- arm_insn_r->reg_rec_count = 2;
- break;
+ reg_vd = reg_vd | (bit_d << 4);
+ record_buf[0] = reg_vd + ARM_D0_REGNUM;
+ record_buf[1] = reg_vd + ARM_D0_REGNUM + 1;
+ arm_insn_r->reg_rec_count = 2;
+ break;
case INSN_T1:
- reg_vd = reg_vd | (bit_d << 4);
- record_buf[0] = reg_vd + ARM_D0_REGNUM;
- arm_insn_r->reg_rec_count = 1;
- break;
+ reg_vd = reg_vd | (bit_d << 4);
+ record_buf[0] = reg_vd + ARM_D0_REGNUM;
+ arm_insn_r->reg_rec_count = 1;
+ break;
case INSN_T2:
- reg_vd = (reg_vd << 1) | bit_d;
- record_buf[0] = reg_vd + ARM_D0_REGNUM;
- arm_insn_r->reg_rec_count = 1;
- break;
+ reg_vd = (reg_vd << 1) | bit_d;
+ record_buf[0] = reg_vd + ARM_D0_REGNUM;
+ arm_insn_r->reg_rec_count = 1;
+ break;
case INSN_T3:
- record_buf[0] = ARM_FPSCR_REGNUM;
- arm_insn_r->reg_rec_count = 1;
- break;
+ record_buf[0] = ARM_FPSCR_REGNUM;
+ arm_insn_r->reg_rec_count = 1;
+ break;
default:
- gdb_assert_not_reached ("no decoding pattern found");
- break;
+ gdb_assert_not_reached ("no decoding pattern found");
+ break;
}
REG_ALLOC (arm_insn_r->arm_regs, arm_insn_r->reg_rec_count, record_buf);
{
/* Handle extension register ld/st instructions. */
if (!(op1 & 0x20))
- return arm_record_exreg_ld_st_insn (arm_insn_r);
+ return arm_record_exreg_ld_st_insn (arm_insn_r);
/* 64-bit transfers between arm core and extension registers. */
if ((op1 & 0x3e) == 0x04)
- return arm_record_exreg_ld_st_insn (arm_insn_r);
+ return arm_record_exreg_ld_st_insn (arm_insn_r);
}
else
{
/* Handle coprocessor ld/st instructions. */
if (!(op1 & 0x3a))
- {
- /* Store. */
- if (!op1_ebit)
- return arm_record_unsupported_insn (arm_insn_r);
- else
- /* Load. */
- return arm_record_unsupported_insn (arm_insn_r);
- }
+ {
+ /* Store. */
+ if (!op1_ebit)
+ return arm_record_unsupported_insn (arm_insn_r);
+ else
+ /* Load. */
+ return arm_record_unsupported_insn (arm_insn_r);
+ }
/* Move to coprocessor from two arm core registers. */
if (op1 == 0x4)
- return arm_record_unsupported_insn (arm_insn_r);
+ return arm_record_unsupported_insn (arm_insn_r);
/* Move to two arm core registers from coprocessor. */
if (op1 == 0x5)
- {
- uint32_t reg_t[2];
+ {
+ uint32_t reg_t[2];
- reg_t[0] = bits (arm_insn_r->arm_insn, 12, 15);
- reg_t[1] = bits (arm_insn_r->arm_insn, 16, 19);
- arm_insn_r->reg_rec_count = 2;
+ reg_t[0] = bits (arm_insn_r->arm_insn, 12, 15);
+ reg_t[1] = bits (arm_insn_r->arm_insn, 16, 19);
+ arm_insn_r->reg_rec_count = 2;
- REG_ALLOC (arm_insn_r->arm_regs, arm_insn_r->reg_rec_count, reg_t);
- return 0;
+ REG_ALLOC (arm_insn_r->arm_regs, arm_insn_r->reg_rec_count, reg_t);
+ return 0;
}
}
return arm_record_unsupported_insn (arm_insn_r);
if (bits_24_25 == 0x3)
{
if (tdep->arm_syscall_record != NULL)
- {
- ULONGEST svc_operand, svc_number;
+ {
+ ULONGEST svc_operand, svc_number;
- svc_operand = (0x00ffffff & arm_insn_r->arm_insn);
+ svc_operand = (0x00ffffff & arm_insn_r->arm_insn);
- if (svc_operand) /* OABI. */
- svc_number = svc_operand - 0x900000;
- else /* EABI. */
- regcache_raw_read_unsigned (reg_cache, 7, &svc_number);
+ if (svc_operand) /* OABI. */
+ svc_number = svc_operand - 0x900000;
+ else /* EABI. */
+ regcache_raw_read_unsigned (reg_cache, 7, &svc_number);
- return tdep->arm_syscall_record (reg_cache, svc_number);
- }
+ return tdep->arm_syscall_record (reg_cache, svc_number);
+ }
else
- {
- printf_unfiltered (_("no syscall record support\n"));
- return -1;
- }
+ {
+ printf_unfiltered (_("no syscall record support\n"));
+ return -1;
+ }
}
else if (bits_24_25 == 0x02)
{
uint32_t opB = bits (thumb_insn_r->arm_insn, 9, 11);
if (in_inclusive_range (opB, 4U, 7U))
- {
- /* LDR(2), LDRB(2) , LDRH(2), LDRSB, LDRSH. */
- reg_src1 = bits (thumb_insn_r->arm_insn,0, 2);
- record_buf[0] = reg_src1;
- thumb_insn_r->reg_rec_count = 1;
- }
+ {
+ /* LDR(2), LDRB(2) , LDRH(2), LDRSB, LDRSH. */
+ reg_src1 = bits (thumb_insn_r->arm_insn,0, 2);
+ record_buf[0] = reg_src1;
+ thumb_insn_r->reg_rec_count = 1;
+ }
else if (in_inclusive_range (opB, 0U, 2U))
- {
- /* STR(2), STRB(2), STRH(2) . */
- reg_src1 = bits (thumb_insn_r->arm_insn, 3, 5);
- reg_src2 = bits (thumb_insn_r->arm_insn, 6, 8);
- regcache_raw_read_unsigned (reg_cache, reg_src1, &u_regval[0]);
- regcache_raw_read_unsigned (reg_cache, reg_src2, &u_regval[1]);
- if (0 == opB)
- record_buf_mem[0] = 4; /* STR (2). */
- else if (2 == opB)
- record_buf_mem[0] = 1; /* STRB (2). */
- else if (1 == opB)
- record_buf_mem[0] = 2; /* STRH (2). */
- record_buf_mem[1] = u_regval[0] + u_regval[1];
- thumb_insn_r->mem_rec_count = 1;
- }
+ {
+ /* STR(2), STRB(2), STRH(2) . */
+ reg_src1 = bits (thumb_insn_r->arm_insn, 3, 5);
+ reg_src2 = bits (thumb_insn_r->arm_insn, 6, 8);
+ regcache_raw_read_unsigned (reg_cache, reg_src1, &u_regval[0]);
+ regcache_raw_read_unsigned (reg_cache, reg_src2, &u_regval[1]);
+ if (0 == opB)
+ record_buf_mem[0] = 4; /* STR (2). */
+ else if (2 == opB)
+ record_buf_mem[0] = 1; /* STRB (2). */
+ else if (1 == opB)
+ record_buf_mem[0] = 2; /* STRH (2). */
+ record_buf_mem[1] = u_regval[0] + u_regval[1];
+ thumb_insn_r->mem_rec_count = 1;
+ }
}
else if (bit (thumb_insn_r->arm_insn, 11))
{
opcode2 = bits (thumb_insn_r->arm_insn, 8, 9);
opcode3 = bits (thumb_insn_r->arm_insn, 0, 2);
if ((3 == opcode2) && (!opcode3))
- {
- /* Branch with exchange. */
- record_buf[0] = ARM_PS_REGNUM;
- thumb_insn_r->reg_rec_count = 1;
- }
+ {
+ /* Branch with exchange. */
+ record_buf[0] = ARM_PS_REGNUM;
+ thumb_insn_r->reg_rec_count = 1;
+ }
else
- {
+ {
/* Format 8; special data processing insns. */
record_buf[0] = ARM_PS_REGNUM;
record_buf[1] = (bit (thumb_insn_r->arm_insn, 7) << 3
| bits (thumb_insn_r->arm_insn, 0, 2));
- thumb_insn_r->reg_rec_count = 2;
- }
+ thumb_insn_r->reg_rec_count = 2;
+ }
}
else
{
/* Format 5; data processing insns. */
reg_src1 = bits (thumb_insn_r->arm_insn, 0, 2);
if (bit (thumb_insn_r->arm_insn, 7))
- {
- reg_src1 = reg_src1 + 8;
- }
+ {
+ reg_src1 = reg_src1 + 8;
+ }
record_buf[0] = ARM_PS_REGNUM;
record_buf[1] = reg_src1;
thumb_insn_r->reg_rec_count = 2;
REG_ALLOC (thumb_insn_r->arm_regs, thumb_insn_r->reg_rec_count, record_buf);
MEM_ALLOC (thumb_insn_r->arm_mems, thumb_insn_r->mem_rec_count,
- record_buf_mem);
+ record_buf_mem);
return 0;
}
REG_ALLOC (thumb_insn_r->arm_regs, thumb_insn_r->reg_rec_count, record_buf);
MEM_ALLOC (thumb_insn_r->arm_mems, thumb_insn_r->mem_rec_count,
- record_buf_mem);
+ record_buf_mem);
return 0;
}
REG_ALLOC (thumb_insn_r->arm_regs, thumb_insn_r->reg_rec_count, record_buf);
MEM_ALLOC (thumb_insn_r->arm_mems, thumb_insn_r->mem_rec_count,
- record_buf_mem);
+ record_buf_mem);
return 0;
}
REG_ALLOC (thumb_insn_r->arm_regs, thumb_insn_r->reg_rec_count, record_buf);
MEM_ALLOC (thumb_insn_r->arm_mems, thumb_insn_r->mem_rec_count,
- record_buf_mem);
+ record_buf_mem);
return 0;
}
/* Get Rn. */
reg_src1 = bits (thumb_insn_r->arm_insn, 8, 10);
while (register_bits)
- {
- if (register_bits & 0x00000001)
- record_buf[index++] = register_count;
- register_bits = register_bits >> 1;
- register_count++;
- }
+ {
+ if (register_bits & 0x00000001)
+ record_buf[index++] = register_count;
+ register_bits = register_bits >> 1;
+ register_count++;
+ }
record_buf[index++] = reg_src1;
thumb_insn_r->reg_rec_count = index;
}
reg_src1 = bits (thumb_insn_r->arm_insn, 8, 10);
regcache_raw_read_unsigned (reg_cache, reg_src1, &u_regval);
while (register_bits)
- {
- if (register_bits & 0x00000001)
- register_count++;
- register_bits = register_bits >> 1;
- }
+ {
+ if (register_bits & 0x00000001)
+ register_count++;
+ register_bits = register_bits >> 1;
+ }
start_address = u_regval;
thumb_insn_r->mem_rec_count = register_count;
while (register_count)
- {
- record_buf_mem[(register_count * 2) - 1] = start_address;
- record_buf_mem[(register_count * 2) - 2] = 4;
- start_address = start_address + 4;
- register_count--;
- }
+ {
+ record_buf_mem[(register_count * 2) - 1] = start_address;
+ record_buf_mem[(register_count * 2) - 2] = 4;
+ start_address = start_address + 4;
+ register_count--;
+ }
}
else if (0x1F == opcode1)
{
- /* Handle arm syscall insn. */
- if (tdep->arm_syscall_record != NULL)
- {
- regcache_raw_read_unsigned (reg_cache, 7, &u_regval);
- ret = tdep->arm_syscall_record (reg_cache, u_regval);
- }
- else
- {
- printf_unfiltered (_("no syscall record support\n"));
- return -1;
- }
+ /* Handle arm syscall insn. */
+ if (tdep->arm_syscall_record != NULL)
+ {
+ regcache_raw_read_unsigned (reg_cache, 7, &u_regval);
+ ret = tdep->arm_syscall_record (reg_cache, u_regval);
+ }
+ else
+ {
+ printf_unfiltered (_("no syscall record support\n"));
+ return -1;
+ }
}
/* B (1), conditional branch is automatically taken care in process_record,
REG_ALLOC (thumb_insn_r->arm_regs, thumb_insn_r->reg_rec_count, record_buf);
MEM_ALLOC (thumb_insn_r->arm_mems, thumb_insn_r->mem_rec_count,
- record_buf_mem);
+ record_buf_mem);
return ret;
}
if (0 == op || 3 == op)
{
if (bit (thumb2_insn_r->arm_insn, INSN_S_L_BIT_NUM))
- {
- /* Handle RFE instruction. */
- record_buf[0] = ARM_PS_REGNUM;
- thumb2_insn_r->reg_rec_count = 1;
- }
+ {
+ /* Handle RFE instruction. */
+ record_buf[0] = ARM_PS_REGNUM;
+ thumb2_insn_r->reg_rec_count = 1;
+ }
else
- {
- /* Handle SRS instruction after reading banked SP. */
- return arm_record_unsupported_insn (thumb2_insn_r);
- }
+ {
+ /* Handle SRS instruction after reading banked SP. */
+ return arm_record_unsupported_insn (thumb2_insn_r);
+ }
}
else if (1 == op || 2 == op)
{
if (bit (thumb2_insn_r->arm_insn, INSN_S_L_BIT_NUM))
- {
- /* Handle LDM/LDMIA/LDMFD and LDMDB/LDMEA instructions. */
- register_bits = bits (thumb2_insn_r->arm_insn, 0, 15);
- while (register_bits)
- {
- if (register_bits & 0x00000001)
- record_buf[index++] = register_count;
-
- register_count++;
- register_bits = register_bits >> 1;
- }
- record_buf[index++] = reg_rn;
- record_buf[index++] = ARM_PS_REGNUM;
- thumb2_insn_r->reg_rec_count = index;
- }
+ {
+ /* Handle LDM/LDMIA/LDMFD and LDMDB/LDMEA instructions. */
+ register_bits = bits (thumb2_insn_r->arm_insn, 0, 15);
+ while (register_bits)
+ {
+ if (register_bits & 0x00000001)
+ record_buf[index++] = register_count;
+
+ register_count++;
+ register_bits = register_bits >> 1;
+ }
+ record_buf[index++] = reg_rn;
+ record_buf[index++] = ARM_PS_REGNUM;
+ thumb2_insn_r->reg_rec_count = index;
+ }
else
- {
- /* Handle STM/STMIA/STMEA and STMDB/STMFD. */
- register_bits = bits (thumb2_insn_r->arm_insn, 0, 15);
- regcache_raw_read_unsigned (reg_cache, reg_rn, &u_regval);
- while (register_bits)
- {
- if (register_bits & 0x00000001)
- register_count++;
-
- register_bits = register_bits >> 1;
- }
-
- if (1 == op)
- {
- /* Start address calculation for LDMDB/LDMEA. */
- start_address = u_regval;
- }
- else if (2 == op)
- {
- /* Start address calculation for LDMDB/LDMEA. */
- start_address = u_regval - register_count * 4;
- }
-
- thumb2_insn_r->mem_rec_count = register_count;
- while (register_count)
- {
- record_buf_mem[register_count * 2 - 1] = start_address;
- record_buf_mem[register_count * 2 - 2] = 4;
- start_address = start_address + 4;
- register_count--;
- }
- record_buf[0] = reg_rn;
- record_buf[1] = ARM_PS_REGNUM;
- thumb2_insn_r->reg_rec_count = 2;
- }
+ {
+ /* Handle STM/STMIA/STMEA and STMDB/STMFD. */
+ register_bits = bits (thumb2_insn_r->arm_insn, 0, 15);
+ regcache_raw_read_unsigned (reg_cache, reg_rn, &u_regval);
+ while (register_bits)
+ {
+ if (register_bits & 0x00000001)
+ register_count++;
+
+ register_bits = register_bits >> 1;
+ }
+
+ if (1 == op)
+ {
+ /* Start address calculation for LDMDB/LDMEA. */
+ start_address = u_regval;
+ }
+ else if (2 == op)
+ {
+ /* Start address calculation for LDMDB/LDMEA. */
+ start_address = u_regval - register_count * 4;
+ }
+
+ thumb2_insn_r->mem_rec_count = register_count;
+ while (register_count)
+ {
+ record_buf_mem[register_count * 2 - 1] = start_address;
+ record_buf_mem[register_count * 2 - 2] = 4;
+ start_address = start_address + 4;
+ register_count--;
+ }
+ record_buf[0] = reg_rn;
+ record_buf[1] = ARM_PS_REGNUM;
+ thumb2_insn_r->reg_rec_count = 2;
+ }
}
MEM_ALLOC (thumb2_insn_r->arm_mems, thumb2_insn_r->mem_rec_count,
- record_buf_mem);
+ record_buf_mem);
REG_ALLOC (thumb2_insn_r->arm_regs, thumb2_insn_r->reg_rec_count,
- record_buf);
+ record_buf);
return ARM_RECORD_SUCCESS;
}
if (bit (thumb2_insn_r->arm_insn, INSN_S_L_BIT_NUM))
{
if(!(1 == op1 && 1 == op2 && (0 == op3 || 1 == op3)))
- {
- reg_dest1 = bits (thumb2_insn_r->arm_insn, 12, 15);
- record_buf[0] = reg_dest1;
- record_buf[1] = ARM_PS_REGNUM;
- thumb2_insn_r->reg_rec_count = 2;
- }
+ {
+ reg_dest1 = bits (thumb2_insn_r->arm_insn, 12, 15);
+ record_buf[0] = reg_dest1;
+ record_buf[1] = ARM_PS_REGNUM;
+ thumb2_insn_r->reg_rec_count = 2;
+ }
if (3 == op2 || (op1 & 2) || (1 == op1 && 1 == op2 && 7 == op3))
- {
- reg_dest2 = bits (thumb2_insn_r->arm_insn, 8, 11);
- record_buf[2] = reg_dest2;
- thumb2_insn_r->reg_rec_count = 3;
- }
+ {
+ reg_dest2 = bits (thumb2_insn_r->arm_insn, 8, 11);
+ record_buf[2] = reg_dest2;
+ thumb2_insn_r->reg_rec_count = 3;
+ }
}
else
{
regcache_raw_read_unsigned (reg_cache, reg_rn, &u_regval[0]);
if (0 == op1 && 0 == op2)
- {
- /* Handle STREX. */
- offset_imm = bits (thumb2_insn_r->arm_insn, 0, 7);
- address = u_regval[0] + (offset_imm * 4);
- record_buf_mem[0] = 4;
- record_buf_mem[1] = address;
- thumb2_insn_r->mem_rec_count = 1;
- reg_rd = bits (thumb2_insn_r->arm_insn, 0, 3);
- record_buf[0] = reg_rd;
- thumb2_insn_r->reg_rec_count = 1;
- }
+ {
+ /* Handle STREX. */
+ offset_imm = bits (thumb2_insn_r->arm_insn, 0, 7);
+ address = u_regval[0] + (offset_imm * 4);
+ record_buf_mem[0] = 4;
+ record_buf_mem[1] = address;
+ thumb2_insn_r->mem_rec_count = 1;
+ reg_rd = bits (thumb2_insn_r->arm_insn, 0, 3);
+ record_buf[0] = reg_rd;
+ thumb2_insn_r->reg_rec_count = 1;
+ }
else if (1 == op1 && 0 == op2)
- {
- reg_rd = bits (thumb2_insn_r->arm_insn, 0, 3);
- record_buf[0] = reg_rd;
- thumb2_insn_r->reg_rec_count = 1;
- address = u_regval[0];
- record_buf_mem[1] = address;
-
- if (4 == op3)
- {
- /* Handle STREXB. */
- record_buf_mem[0] = 1;
- thumb2_insn_r->mem_rec_count = 1;
- }
- else if (5 == op3)
- {
- /* Handle STREXH. */
- record_buf_mem[0] = 2 ;
- thumb2_insn_r->mem_rec_count = 1;
- }
- else if (7 == op3)
- {
- /* Handle STREXD. */
- address = u_regval[0];
- record_buf_mem[0] = 4;
- record_buf_mem[2] = 4;
- record_buf_mem[3] = address + 4;
- thumb2_insn_r->mem_rec_count = 2;
- }
- }
+ {
+ reg_rd = bits (thumb2_insn_r->arm_insn, 0, 3);
+ record_buf[0] = reg_rd;
+ thumb2_insn_r->reg_rec_count = 1;
+ address = u_regval[0];
+ record_buf_mem[1] = address;
+
+ if (4 == op3)
+ {
+ /* Handle STREXB. */
+ record_buf_mem[0] = 1;
+ thumb2_insn_r->mem_rec_count = 1;
+ }
+ else if (5 == op3)
+ {
+ /* Handle STREXH. */
+ record_buf_mem[0] = 2 ;
+ thumb2_insn_r->mem_rec_count = 1;
+ }
+ else if (7 == op3)
+ {
+ /* Handle STREXD. */
+ address = u_regval[0];
+ record_buf_mem[0] = 4;
+ record_buf_mem[2] = 4;
+ record_buf_mem[3] = address + 4;
+ thumb2_insn_r->mem_rec_count = 2;
+ }
+ }
else
- {
- offset_imm = bits (thumb2_insn_r->arm_insn, 0, 7);
-
- if (bit (thumb2_insn_r->arm_insn, 24))
- {
- if (bit (thumb2_insn_r->arm_insn, 23))
- offset_addr = u_regval[0] + (offset_imm * 4);
- else
- offset_addr = u_regval[0] - (offset_imm * 4);
-
- address = offset_addr;
- }
- else
- address = u_regval[0];
-
- record_buf_mem[0] = 4;
- record_buf_mem[1] = address;
- record_buf_mem[2] = 4;
- record_buf_mem[3] = address + 4;
- thumb2_insn_r->mem_rec_count = 2;
- record_buf[0] = reg_rn;
- thumb2_insn_r->reg_rec_count = 1;
- }
+ {
+ offset_imm = bits (thumb2_insn_r->arm_insn, 0, 7);
+
+ if (bit (thumb2_insn_r->arm_insn, 24))
+ {
+ if (bit (thumb2_insn_r->arm_insn, 23))
+ offset_addr = u_regval[0] + (offset_imm * 4);
+ else
+ offset_addr = u_regval[0] - (offset_imm * 4);
+
+ address = offset_addr;
+ }
+ else
+ address = u_regval[0];
+
+ record_buf_mem[0] = 4;
+ record_buf_mem[1] = address;
+ record_buf_mem[2] = 4;
+ record_buf_mem[3] = address + 4;
+ thumb2_insn_r->mem_rec_count = 2;
+ record_buf[0] = reg_rn;
+ thumb2_insn_r->reg_rec_count = 1;
+ }
}
REG_ALLOC (thumb2_insn_r->arm_regs, thumb2_insn_r->reg_rec_count,
- record_buf);
+ record_buf);
MEM_ALLOC (thumb2_insn_r->arm_mems, thumb2_insn_r->mem_rec_count,
- record_buf_mem);
+ record_buf_mem);
return ARM_RECORD_SUCCESS;
}
}
REG_ALLOC (thumb2_insn_r->arm_regs, thumb2_insn_r->reg_rec_count,
- record_buf);
+ record_buf);
return ARM_RECORD_SUCCESS;
}
thumb2_insn_r->reg_rec_count = 2;
REG_ALLOC (thumb2_insn_r->arm_regs, thumb2_insn_r->reg_rec_count,
- record_buf);
+ record_buf);
return ARM_RECORD_SUCCESS;
}
if (!(op1 & 0x2) && 0x38 == op)
{
if (!(op2 & 0x3))
- {
- /* CPSR is going to be changed. */
- record_buf[0] = ARM_PS_REGNUM;
- thumb2_insn_r->reg_rec_count = 1;
- }
+ {
+ /* CPSR is going to be changed. */
+ record_buf[0] = ARM_PS_REGNUM;
+ thumb2_insn_r->reg_rec_count = 1;
+ }
else
- {
- arm_record_unsupported_insn(thumb2_insn_r);
- return -1;
- }
+ {
+ arm_record_unsupported_insn(thumb2_insn_r);
+ return -1;
+ }
}
else if (4 == (op1 & 0x5) || 5 == (op1 & 0x5))
{
}
REG_ALLOC (thumb2_insn_r->arm_regs, thumb2_insn_r->reg_rec_count,
- record_buf);
+ record_buf);
return ARM_RECORD_SUCCESS;
}
{
/* T3 encoding. */
if ((0 == op1 || 1 == op1 || 2 == op1) && !(op2 & 0x20))
- {
- /* Handle STRB (register). */
- reg_rm = bits (thumb2_insn_r->arm_insn, 0, 3);
- regcache_raw_read_unsigned (reg_cache, reg_rm, &u_regval[1]);
- shift_imm = bits (thumb2_insn_r->arm_insn, 4, 5);
- offset_addr = u_regval[1] << shift_imm;
- address = u_regval[0] + offset_addr;
- }
+ {
+ /* Handle STRB (register). */
+ reg_rm = bits (thumb2_insn_r->arm_insn, 0, 3);
+ regcache_raw_read_unsigned (reg_cache, reg_rm, &u_regval[1]);
+ shift_imm = bits (thumb2_insn_r->arm_insn, 4, 5);
+ offset_addr = u_regval[1] << shift_imm;
+ address = u_regval[0] + offset_addr;
+ }
else
- {
- offset_imm = bits (thumb2_insn_r->arm_insn, 0, 7);
- if (bit (thumb2_insn_r->arm_insn, 10))
- {
- if (bit (thumb2_insn_r->arm_insn, 9))
- offset_addr = u_regval[0] + offset_imm;
- else
- offset_addr = u_regval[0] - offset_imm;
-
- address = offset_addr;
- }
- else
- address = u_regval[0];
- }
+ {
+ offset_imm = bits (thumb2_insn_r->arm_insn, 0, 7);
+ if (bit (thumb2_insn_r->arm_insn, 10))
+ {
+ if (bit (thumb2_insn_r->arm_insn, 9))
+ offset_addr = u_regval[0] + offset_imm;
+ else
+ offset_addr = u_regval[0] - offset_imm;
+
+ address = offset_addr;
+ }
+ else
+ address = u_regval[0];
+ }
}
switch (op1)
/* Store byte instructions. */
case 4:
case 0:
- record_buf_mem[0] = 1;
- break;
+ record_buf_mem[0] = 1;
+ break;
/* Store half word instructions. */
case 1:
case 5:
- record_buf_mem[0] = 2;
- break;
+ record_buf_mem[0] = 2;
+ break;
/* Store word instructions. */
case 2:
case 6:
- record_buf_mem[0] = 4;
- break;
+ record_buf_mem[0] = 4;
+ break;
default:
- gdb_assert_not_reached ("no decoding pattern found");
- break;
+ gdb_assert_not_reached ("no decoding pattern found");
+ break;
}
record_buf_mem[1] = address;
thumb2_insn_r->reg_rec_count = 1;
REG_ALLOC (thumb2_insn_r->arm_regs, thumb2_insn_r->reg_rec_count,
- record_buf);
+ record_buf);
MEM_ALLOC (thumb2_insn_r->arm_mems, thumb2_insn_r->mem_rec_count,
- record_buf_mem);
+ record_buf_mem);
return ARM_RECORD_SUCCESS;
}
thumb2_insn_r->reg_rec_count = 3;
REG_ALLOC (thumb2_insn_r->arm_regs, thumb2_insn_r->reg_rec_count,
- record_buf);
+ record_buf);
return ARM_RECORD_SUCCESS;
}
thumb2_insn_r->reg_rec_count = 2;
REG_ALLOC (thumb2_insn_r->arm_regs, thumb2_insn_r->reg_rec_count,
- record_buf);
+ record_buf);
return ARM_RECORD_SUCCESS;
}
return ARM_RECORD_FAILURE;
REG_ALLOC (thumb2_insn_r->arm_regs, thumb2_insn_r->reg_rec_count,
- record_buf);
+ record_buf);
return ARM_RECORD_SUCCESS;
}
address = u_regval;
if (!a_bit)
- {
- /* Handle VST1. */
- if (b_bits == 0x02 || b_bits == 0x0a || (b_bits & 0x0e) == 0x06)
- {
- if (b_bits == 0x07)
- bf_regs = 1;
- else if (b_bits == 0x0a)
- bf_regs = 2;
- else if (b_bits == 0x06)
- bf_regs = 3;
- else if (b_bits == 0x02)
- bf_regs = 4;
- else
- bf_regs = 0;
-
- for (index_r = 0; index_r < bf_regs; index_r++)
- {
- for (index_e = 0; index_e < f_elem; index_e++)
- {
- record_buf_mem[index_m++] = f_ebytes;
- record_buf_mem[index_m++] = address;
- address = address + f_ebytes;
- thumb2_insn_r->mem_rec_count += 1;
- }
- }
- }
- /* Handle VST2. */
- else if (b_bits == 0x03 || (b_bits & 0x0e) == 0x08)
- {
- if (b_bits == 0x09 || b_bits == 0x08)
- bf_regs = 1;
- else if (b_bits == 0x03)
- bf_regs = 2;
- else
- bf_regs = 0;
-
- for (index_r = 0; index_r < bf_regs; index_r++)
- for (index_e = 0; index_e < f_elem; index_e++)
- {
- for (loop_t = 0; loop_t < 2; loop_t++)
- {
- record_buf_mem[index_m++] = f_ebytes;
- record_buf_mem[index_m++] = address + (loop_t * f_ebytes);
- thumb2_insn_r->mem_rec_count += 1;
- }
- address = address + (2 * f_ebytes);
- }
- }
- /* Handle VST3. */
- else if ((b_bits & 0x0e) == 0x04)
- {
- for (index_e = 0; index_e < f_elem; index_e++)
- {
- for (loop_t = 0; loop_t < 3; loop_t++)
- {
- record_buf_mem[index_m++] = f_ebytes;
- record_buf_mem[index_m++] = address + (loop_t * f_ebytes);
- thumb2_insn_r->mem_rec_count += 1;
- }
- address = address + (3 * f_ebytes);
- }
- }
- /* Handle VST4. */
- else if (!(b_bits & 0x0e))
- {
- for (index_e = 0; index_e < f_elem; index_e++)
- {
- for (loop_t = 0; loop_t < 4; loop_t++)
- {
- record_buf_mem[index_m++] = f_ebytes;
- record_buf_mem[index_m++] = address + (loop_t * f_ebytes);
- thumb2_insn_r->mem_rec_count += 1;
- }
- address = address + (4 * f_ebytes);
- }
- }
- }
+ {
+ /* Handle VST1. */
+ if (b_bits == 0x02 || b_bits == 0x0a || (b_bits & 0x0e) == 0x06)
+ {
+ if (b_bits == 0x07)
+ bf_regs = 1;
+ else if (b_bits == 0x0a)
+ bf_regs = 2;
+ else if (b_bits == 0x06)
+ bf_regs = 3;
+ else if (b_bits == 0x02)
+ bf_regs = 4;
+ else
+ bf_regs = 0;
+
+ for (index_r = 0; index_r < bf_regs; index_r++)
+ {
+ for (index_e = 0; index_e < f_elem; index_e++)
+ {
+ record_buf_mem[index_m++] = f_ebytes;
+ record_buf_mem[index_m++] = address;
+ address = address + f_ebytes;
+ thumb2_insn_r->mem_rec_count += 1;
+ }
+ }
+ }
+ /* Handle VST2. */
+ else if (b_bits == 0x03 || (b_bits & 0x0e) == 0x08)
+ {
+ if (b_bits == 0x09 || b_bits == 0x08)
+ bf_regs = 1;
+ else if (b_bits == 0x03)
+ bf_regs = 2;
+ else
+ bf_regs = 0;
+
+ for (index_r = 0; index_r < bf_regs; index_r++)
+ for (index_e = 0; index_e < f_elem; index_e++)
+ {
+ for (loop_t = 0; loop_t < 2; loop_t++)
+ {
+ record_buf_mem[index_m++] = f_ebytes;
+ record_buf_mem[index_m++] = address + (loop_t * f_ebytes);
+ thumb2_insn_r->mem_rec_count += 1;
+ }
+ address = address + (2 * f_ebytes);
+ }
+ }
+ /* Handle VST3. */
+ else if ((b_bits & 0x0e) == 0x04)
+ {
+ for (index_e = 0; index_e < f_elem; index_e++)
+ {
+ for (loop_t = 0; loop_t < 3; loop_t++)
+ {
+ record_buf_mem[index_m++] = f_ebytes;
+ record_buf_mem[index_m++] = address + (loop_t * f_ebytes);
+ thumb2_insn_r->mem_rec_count += 1;
+ }
+ address = address + (3 * f_ebytes);
+ }
+ }
+ /* Handle VST4. */
+ else if (!(b_bits & 0x0e))
+ {
+ for (index_e = 0; index_e < f_elem; index_e++)
+ {
+ for (loop_t = 0; loop_t < 4; loop_t++)
+ {
+ record_buf_mem[index_m++] = f_ebytes;
+ record_buf_mem[index_m++] = address + (loop_t * f_ebytes);
+ thumb2_insn_r->mem_rec_count += 1;
+ }
+ address = address + (4 * f_ebytes);
+ }
+ }
+ }
else
- {
- uint8_t bft_size = bits (thumb2_insn_r->arm_insn, 10, 11);
-
- if (bft_size == 0x00)
- f_ebytes = 1;
- else if (bft_size == 0x01)
- f_ebytes = 2;
- else if (bft_size == 0x02)
- f_ebytes = 4;
- else
- f_ebytes = 0;
-
- /* Handle VST1. */
- if (!(b_bits & 0x0b) || b_bits == 0x08)
- thumb2_insn_r->mem_rec_count = 1;
- /* Handle VST2. */
- else if ((b_bits & 0x0b) == 0x01 || b_bits == 0x09)
- thumb2_insn_r->mem_rec_count = 2;
- /* Handle VST3. */
- else if ((b_bits & 0x0b) == 0x02 || b_bits == 0x0a)
- thumb2_insn_r->mem_rec_count = 3;
- /* Handle VST4. */
- else if ((b_bits & 0x0b) == 0x03 || b_bits == 0x0b)
- thumb2_insn_r->mem_rec_count = 4;
-
- for (index_m = 0; index_m < thumb2_insn_r->mem_rec_count; index_m++)
- {
- record_buf_mem[index_m] = f_ebytes;
- record_buf_mem[index_m] = address + (index_m * f_ebytes);
- }
- }
+ {
+ uint8_t bft_size = bits (thumb2_insn_r->arm_insn, 10, 11);
+
+ if (bft_size == 0x00)
+ f_ebytes = 1;
+ else if (bft_size == 0x01)
+ f_ebytes = 2;
+ else if (bft_size == 0x02)
+ f_ebytes = 4;
+ else
+ f_ebytes = 0;
+
+ /* Handle VST1. */
+ if (!(b_bits & 0x0b) || b_bits == 0x08)
+ thumb2_insn_r->mem_rec_count = 1;
+ /* Handle VST2. */
+ else if ((b_bits & 0x0b) == 0x01 || b_bits == 0x09)
+ thumb2_insn_r->mem_rec_count = 2;
+ /* Handle VST3. */
+ else if ((b_bits & 0x0b) == 0x02 || b_bits == 0x0a)
+ thumb2_insn_r->mem_rec_count = 3;
+ /* Handle VST4. */
+ else if ((b_bits & 0x0b) == 0x03 || b_bits == 0x0b)
+ thumb2_insn_r->mem_rec_count = 4;
+
+ for (index_m = 0; index_m < thumb2_insn_r->mem_rec_count; index_m++)
+ {
+ record_buf_mem[index_m] = f_ebytes;
+ record_buf_mem[index_m] = address + (index_m * f_ebytes);
+ }
+ }
}
else
{
if (!a_bit)
- {
- /* Handle VLD1. */
- if (b_bits == 0x02 || b_bits == 0x0a || (b_bits & 0x0e) == 0x06)
- thumb2_insn_r->reg_rec_count = 1;
- /* Handle VLD2. */
- else if (b_bits == 0x03 || (b_bits & 0x0e) == 0x08)
- thumb2_insn_r->reg_rec_count = 2;
- /* Handle VLD3. */
- else if ((b_bits & 0x0e) == 0x04)
- thumb2_insn_r->reg_rec_count = 3;
- /* Handle VLD4. */
- else if (!(b_bits & 0x0e))
- thumb2_insn_r->reg_rec_count = 4;
- }
+ {
+ /* Handle VLD1. */
+ if (b_bits == 0x02 || b_bits == 0x0a || (b_bits & 0x0e) == 0x06)
+ thumb2_insn_r->reg_rec_count = 1;
+ /* Handle VLD2. */
+ else if (b_bits == 0x03 || (b_bits & 0x0e) == 0x08)
+ thumb2_insn_r->reg_rec_count = 2;
+ /* Handle VLD3. */
+ else if ((b_bits & 0x0e) == 0x04)
+ thumb2_insn_r->reg_rec_count = 3;
+ /* Handle VLD4. */
+ else if (!(b_bits & 0x0e))
+ thumb2_insn_r->reg_rec_count = 4;
+ }
else
- {
- /* Handle VLD1. */
- if (!(b_bits & 0x0b) || b_bits == 0x08 || b_bits == 0x0c)
- thumb2_insn_r->reg_rec_count = 1;
- /* Handle VLD2. */
- else if ((b_bits & 0x0b) == 0x01 || b_bits == 0x09 || b_bits == 0x0d)
- thumb2_insn_r->reg_rec_count = 2;
- /* Handle VLD3. */
- else if ((b_bits & 0x0b) == 0x02 || b_bits == 0x0a || b_bits == 0x0e)
- thumb2_insn_r->reg_rec_count = 3;
- /* Handle VLD4. */
- else if ((b_bits & 0x0b) == 0x03 || b_bits == 0x0b || b_bits == 0x0f)
- thumb2_insn_r->reg_rec_count = 4;
-
- for (index_r = 0; index_r < thumb2_insn_r->reg_rec_count; index_r++)
- record_buf[index_r] = reg_vd + ARM_D0_REGNUM + index_r;
- }
+ {
+ /* Handle VLD1. */
+ if (!(b_bits & 0x0b) || b_bits == 0x08 || b_bits == 0x0c)
+ thumb2_insn_r->reg_rec_count = 1;
+ /* Handle VLD2. */
+ else if ((b_bits & 0x0b) == 0x01 || b_bits == 0x09 || b_bits == 0x0d)
+ thumb2_insn_r->reg_rec_count = 2;
+ /* Handle VLD3. */
+ else if ((b_bits & 0x0b) == 0x02 || b_bits == 0x0a || b_bits == 0x0e)
+ thumb2_insn_r->reg_rec_count = 3;
+ /* Handle VLD4. */
+ else if ((b_bits & 0x0b) == 0x03 || b_bits == 0x0b || b_bits == 0x0f)
+ thumb2_insn_r->reg_rec_count = 4;
+
+ for (index_r = 0; index_r < thumb2_insn_r->reg_rec_count; index_r++)
+ record_buf[index_r] = reg_vd + ARM_D0_REGNUM + index_r;
+ }
}
if (bits (thumb2_insn_r->arm_insn, 0, 3) != 15)
}
REG_ALLOC (thumb2_insn_r->arm_regs, thumb2_insn_r->reg_rec_count,
- record_buf);
+ record_buf);
MEM_ALLOC (thumb2_insn_r->arm_mems, thumb2_insn_r->mem_rec_count,
- record_buf_mem);
+ record_buf_mem);
return 0;
}
if (op1 == 0x01)
{
if (!(op2 & 0x64 ))
- {
- /* Load/store multiple instruction. */
- return thumb2_record_ld_st_multiple (thumb2_insn_r);
- }
+ {
+ /* Load/store multiple instruction. */
+ return thumb2_record_ld_st_multiple (thumb2_insn_r);
+ }
else if ((op2 & 0x64) == 0x4)
- {
- /* Load/store (dual/exclusive) and table branch instruction. */
- return thumb2_record_ld_st_dual_ex_tbb (thumb2_insn_r);
- }
+ {
+ /* Load/store (dual/exclusive) and table branch instruction. */
+ return thumb2_record_ld_st_dual_ex_tbb (thumb2_insn_r);
+ }
else if ((op2 & 0x60) == 0x20)
- {
- /* Data-processing (shifted register). */
- return thumb2_record_data_proc_sreg_mimm (thumb2_insn_r);
- }
+ {
+ /* Data-processing (shifted register). */
+ return thumb2_record_data_proc_sreg_mimm (thumb2_insn_r);
+ }
else if (op2 & 0x40)
- {
- /* Co-processor instructions. */
- return thumb2_record_coproc_insn (thumb2_insn_r);
- }
+ {
+ /* Co-processor instructions. */
+ return thumb2_record_coproc_insn (thumb2_insn_r);
+ }
}
else if (op1 == 0x02)
{
if (op)
- {
- /* Branches and miscellaneous control instructions. */
- return thumb2_record_branch_misc_cntrl (thumb2_insn_r);
- }
+ {
+ /* Branches and miscellaneous control instructions. */
+ return thumb2_record_branch_misc_cntrl (thumb2_insn_r);
+ }
else if (op2 & 0x20)
- {
- /* Data-processing (plain binary immediate) instruction. */
- return thumb2_record_ps_dest_generic (thumb2_insn_r);
- }
+ {
+ /* Data-processing (plain binary immediate) instruction. */
+ return thumb2_record_ps_dest_generic (thumb2_insn_r);
+ }
else
- {
- /* Data-processing (modified immediate). */
- return thumb2_record_data_proc_sreg_mimm (thumb2_insn_r);
- }
+ {
+ /* Data-processing (modified immediate). */
+ return thumb2_record_data_proc_sreg_mimm (thumb2_insn_r);
+ }
}
else if (op1 == 0x03)
{
if (!(op2 & 0x71 ))
- {
- /* Store single data item. */
- return thumb2_record_str_single_data (thumb2_insn_r);
- }
+ {
+ /* Store single data item. */
+ return thumb2_record_str_single_data (thumb2_insn_r);
+ }
else if (!((op2 & 0x71) ^ 0x10))
- {
- /* Advanced SIMD or structure load/store instructions. */
- return thumb2_record_asimd_struct_ld_st (thumb2_insn_r);
- }
+ {
+ /* Advanced SIMD or structure load/store instructions. */
+ return thumb2_record_asimd_struct_ld_st (thumb2_insn_r);
+ }
else if (!((op2 & 0x67) ^ 0x01))
- {
- /* Load byte, memory hints instruction. */
- return thumb2_record_ld_mem_hints (thumb2_insn_r);
- }
+ {
+ /* Load byte, memory hints instruction. */
+ return thumb2_record_ld_mem_hints (thumb2_insn_r);
+ }
else if (!((op2 & 0x67) ^ 0x03))
- {
- /* Load halfword, memory hints instruction. */
- return thumb2_record_ld_mem_hints (thumb2_insn_r);
- }
+ {
+ /* Load halfword, memory hints instruction. */
+ return thumb2_record_ld_mem_hints (thumb2_insn_r);
+ }
else if (!((op2 & 0x67) ^ 0x05))
- {
- /* Load word instruction. */
- return thumb2_record_ld_word (thumb2_insn_r);
- }
+ {
+ /* Load word instruction. */
+ return thumb2_record_ld_word (thumb2_insn_r);
+ }
else if (!((op2 & 0x70) ^ 0x20))
- {
- /* Data-processing (register) instruction. */
- return thumb2_record_ps_dest_generic (thumb2_insn_r);
- }
+ {
+ /* Data-processing (register) instruction. */
+ return thumb2_record_ps_dest_generic (thumb2_insn_r);
+ }
else if (!((op2 & 0x78) ^ 0x30))
- {
- /* Multiply, multiply accumulate, abs diff instruction. */
- return thumb2_record_ps_dest_generic (thumb2_insn_r);
- }
+ {
+ /* Multiply, multiply accumulate, abs diff instruction. */
+ return thumb2_record_ps_dest_generic (thumb2_insn_r);
+ }
else if (!((op2 & 0x78) ^ 0x38))
- {
- /* Long multiply, long multiply accumulate, and divide. */
- return thumb2_record_lmul_lmla_div (thumb2_insn_r);
- }
+ {
+ /* Long multiply, long multiply accumulate, and divide. */
+ return thumb2_record_lmul_lmla_div (thumb2_insn_r);
+ }
else if (op2 & 0x40)
- {
- /* Co-processor instructions. */
- return thumb2_record_coproc_insn (thumb2_insn_r);
- }
+ {
+ /* Co-processor instructions. */
+ return thumb2_record_coproc_insn (thumb2_insn_r);
+ }
}
return -1;
} // 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,
if (!reader.read (insn_record->this_addr, buf, insn_size))
return 1;
insn_record->arm_insn = (uint32_t) extract_unsigned_integer (&buf[0],
- insn_size,
+ insn_size,
gdbarch_byte_order_for_code (insn_record->gdbarch));
return 0;
}
arm_record_test (void)
{
struct gdbarch_info info;
- gdbarch_info_init (&info);
info.bfd_arch_info = bfd_scan_arch ("arm");
struct gdbarch *gdbarch = gdbarch_find_by_info (info);
SELF_CHECK (arm_record.arm_regs[0] == 7);
}
}
+
+/* Instruction reader from manually cooked instruction sequences. */
+
+class test_arm_instruction_reader : public arm_instruction_reader
+{
+public:
+ explicit test_arm_instruction_reader (gdb::array_view<const uint32_t> insns)
+ : m_insns (insns)
+ {}
+
+ uint32_t read (CORE_ADDR memaddr, enum bfd_endian byte_order) const override
+ {
+ SELF_CHECK (memaddr % 4 == 0);
+ SELF_CHECK (memaddr / 4 < m_insns.size ());
+
+ return m_insns[memaddr / 4];
+ }
+
+private:
+ const gdb::array_view<const uint32_t> m_insns;
+};
+
+static void
+arm_analyze_prologue_test ()
+{
+ for (bfd_endian endianness : {BFD_ENDIAN_LITTLE, BFD_ENDIAN_BIG})
+ {
+ struct gdbarch_info info;
+ info.byte_order = endianness;
+ info.byte_order_for_code = endianness;
+ info.bfd_arch_info = bfd_scan_arch ("arm");
+
+ struct gdbarch *gdbarch = gdbarch_find_by_info (info);
+
+ SELF_CHECK (gdbarch != NULL);
+
+ /* The "sub" instruction contains an immediate value rotate count of 0,
+ which resulted in a 32-bit shift of a 32-bit value, caught by
+ UBSan. */
+ const uint32_t insns[] = {
+ 0xe92d4ff0, /* push {r4, r5, r6, r7, r8, r9, sl, fp, lr} */
+ 0xe1a05000, /* mov r5, r0 */
+ 0xe5903020, /* ldr r3, [r0, #32] */
+ 0xe24dd044, /* sub sp, sp, #68 ; 0x44 */
+ };
+
+ test_arm_instruction_reader mem_reader (insns);
+ arm_prologue_cache cache;
+ cache.saved_regs = trad_frame_alloc_saved_regs (gdbarch);
+
+ arm_analyze_prologue (gdbarch, 0, sizeof (insns) - 1, &cache, mem_reader);
+ }
+}
+
} // namespace selftests
#endif /* GDB_SELF_TEST */
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;
+}