/* Target-dependent code for the IA-64 for GDB, the GNU debugger.
- Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
- 2009, 2010, 2011 Free Software Foundation, Inc.
+ Copyright (C) 1999-2019 Free Software Foundation, Inc.
This file is part of GDB.
#include "frame.h"
#include "frame-base.h"
#include "frame-unwind.h"
-#include "doublest.h"
+#include "target-float.h"
#include "value.h"
-#include "gdb_assert.h"
#include "objfiles.h"
#include "elf/common.h" /* for DT_PLTGOT value */
#include "elf-bfd.h"
#ifdef HAVE_LIBUNWIND_IA64_H
#include "elf/ia64.h" /* for PT_IA_64_UNWIND value */
-#include "libunwind-frame.h"
-#include "libunwind-ia64.h"
+#include "ia64-libunwind-tdep.h"
/* Note: KERNEL_START is supposed to be an address which is not going
to ever contain any valid unwind info. For ia64 linux, the choice
};
static struct ia64_table_entry *ktab = NULL;
+static gdb::optional<gdb::byte_vector> ktab_buf;
#endif
#define NUM_IA64_RAW_REGS 462
+/* Big enough to hold a FP register in bytes. */
+#define IA64_FP_REGISTER_SIZE 16
+
static int sp_regnum = IA64_GR12_REGNUM;
-static int fp_regnum = IA64_VFP_REGNUM;
-static int lr_regnum = IA64_VRAP_REGNUM;
/* NOTE: we treat the register stack registers r32-r127 as
pseudo-registers because they may not be accessible via the ptrace
/* Array of register names; There should be ia64_num_regs strings in
the initializer. */
-static char *ia64_register_names[] =
+static const char *ia64_register_names[] =
{ "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
"r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
"r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
bit ``from''. */
static long long
-extract_bit_field (const char *bundle, int from, int len)
+extract_bit_field (const gdb_byte *bundle, int from, int len)
{
long long result = 0LL;
int to = from + len;
/* Replace the specified bits in an instruction bundle. */
static void
-replace_bit_field (char *bundle, long long val, int from, int len)
+replace_bit_field (gdb_byte *bundle, long long val, int from, int len)
{
int to = from + len;
int from_byte = from / 8;
and instruction bundle. */
static long long
-slotN_contents (char *bundle, int slotnum)
+slotN_contents (gdb_byte *bundle, int slotnum)
{
return extract_bit_field (bundle, 5+41*slotnum, 41);
}
/* Store an instruction in an instruction bundle. */
static void
-replace_slotN_contents (char *bundle, long long instr, int slotnum)
+replace_slotN_contents (gdb_byte *bundle, long long instr, int slotnum)
{
replace_bit_field (bundle, instr, 5+41*slotnum, 41);
}
static CORE_ADDR
fetch_instruction (CORE_ADDR addr, instruction_type *it, long long *instr)
{
- char bundle[BUNDLE_LEN];
+ gdb_byte bundle[BUNDLE_LEN];
int slotnum = (int) (addr & 0x0f) / SLOT_MULTIPLIER;
- long long template;
+ long long templ;
int val;
/* Warn about slot numbers greater than 2. We used to generate
return 0;
*instr = slotN_contents (bundle, slotnum);
- template = extract_bit_field (bundle, 0, 5);
- *it = template_encoding_table[(int)template][slotnum];
+ templ = extract_bit_field (bundle, 0, 5);
+ *it = template_encoding_table[(int)templ][slotnum];
if (slotnum == 2 || (slotnum == 1 && *it == L))
addr += 16;
ia64_memory_insert_breakpoint (struct gdbarch *gdbarch,
struct bp_target_info *bp_tgt)
{
- CORE_ADDR addr = bp_tgt->placed_address;
+ CORE_ADDR addr = bp_tgt->placed_address = bp_tgt->reqstd_address;
gdb_byte bundle[BUNDLE_LEN];
int slotnum = (int) (addr & 0x0f) / SLOT_MULTIPLIER, shadow_slotnum;
long long instr_breakpoint;
int val;
- int template;
- struct cleanup *cleanup;
+ int templ;
if (slotnum > 2)
error (_("Can't insert breakpoint for slot numbers greater than 2."));
Otherwise, we could possibly store into the shadow parts of the adjacent
placed breakpoints. It is due to our SHADOW_CONTENTS overlapping the real
breakpoint instruction bits region. */
- cleanup = make_show_memory_breakpoints_cleanup (0);
+ scoped_restore restore_memory_0
+ = make_scoped_restore_show_memory_breakpoints (0);
val = target_read_memory (addr, bundle, BUNDLE_LEN);
if (val != 0)
- {
- do_cleanups (cleanup);
- return val;
- }
+ return val;
/* SHADOW_SLOTNUM saves the original slot number as expected by the caller
for addressing the SHADOW_CONTENTS placement. */
a breakpoint on an L-X instruction. */
bp_tgt->shadow_len = BUNDLE_LEN - shadow_slotnum;
- template = extract_bit_field (bundle, 0, 5);
- if (template_encoding_table[template][slotnum] == X)
+ templ = extract_bit_field (bundle, 0, 5);
+ if (template_encoding_table[templ][slotnum] == X)
{
/* X unit types can only be used in slot 2, and are actually
part of a 2-slot L-X instruction. We cannot break at this
gdb_assert (slotnum == 2);
error (_("Can't insert breakpoint for non-existing slot X"));
}
- if (template_encoding_table[template][slotnum] == L)
+ if (template_encoding_table[templ][slotnum] == L)
{
/* L unit types can only be used in slot 1. But the associated
opcode for that instruction is in slot 2, so bump the slot number
restoration mechanism kicks in and we would possibly remove parts of the
adjacent placed breakpoints. It is due to our SHADOW_CONTENTS overlapping
the real breakpoint instruction bits region. */
- make_show_memory_breakpoints_cleanup (1);
+ scoped_restore restore_memory_1
+ = make_scoped_restore_show_memory_breakpoints (1);
val = target_read_memory (addr, bundle, BUNDLE_LEN);
if (val != 0)
- {
- do_cleanups (cleanup);
- return val;
- }
+ return val;
/* Breakpoints already present in the code will get deteacted and not get
reinserted by bp_loc_is_permanent. Multiple breakpoints at the same
paddress (gdbarch, bp_tgt->placed_address));
replace_slotN_contents (bundle, IA64_BREAKPOINT, slotnum);
- bp_tgt->placed_size = bp_tgt->shadow_len;
-
val = target_write_memory (addr + shadow_slotnum, bundle + shadow_slotnum,
bp_tgt->shadow_len);
- do_cleanups (cleanup);
return val;
}
int slotnum = (addr & 0x0f) / SLOT_MULTIPLIER, shadow_slotnum;
long long instr_breakpoint, instr_saved;
int val;
- int template;
- struct cleanup *cleanup;
+ int templ;
addr &= ~0x0f;
mechanism kicks in and we would possibly remove parts of the adjacent
placed breakpoints. It is due to our SHADOW_CONTENTS overlapping the real
breakpoint instruction bits region. */
- cleanup = make_show_memory_breakpoints_cleanup (1);
+ scoped_restore restore_memory_1
+ = make_scoped_restore_show_memory_breakpoints (1);
val = target_read_memory (addr, bundle_mem, BUNDLE_LEN);
if (val != 0)
- {
- do_cleanups (cleanup);
- return val;
- }
+ return val;
/* SHADOW_SLOTNUM saves the original slot number as expected by the caller
for addressing the SHADOW_CONTENTS placement. */
shadow_slotnum = slotnum;
- template = extract_bit_field (bundle_mem, 0, 5);
- if (template_encoding_table[template][slotnum] == X)
+ templ = extract_bit_field (bundle_mem, 0, 5);
+ if (template_encoding_table[templ][slotnum] == X)
{
/* X unit types can only be used in slot 2, and are actually
part of a 2-slot L-X instruction. We refuse to insert
warning (_("Cannot remove breakpoint at address %s from non-existing "
"X-type slot, memory has changed underneath"),
paddress (gdbarch, bp_tgt->placed_address));
- do_cleanups (cleanup);
return -1;
}
- if (template_encoding_table[template][slotnum] == L)
+ if (template_encoding_table[templ][slotnum] == L)
{
/* L unit types can only be used in slot 1. But the breakpoint
was actually saved using slot 2, so update the slot number
slotnum = 2;
}
- gdb_assert (bp_tgt->placed_size == BUNDLE_LEN - shadow_slotnum);
- gdb_assert (bp_tgt->placed_size == bp_tgt->shadow_len);
+ gdb_assert (bp_tgt->shadow_len == BUNDLE_LEN - shadow_slotnum);
instr_breakpoint = slotN_contents (bundle_mem, slotnum);
if (instr_breakpoint != IA64_BREAKPOINT)
warning (_("Cannot remove breakpoint at address %s, "
"no break instruction at such address."),
paddress (gdbarch, bp_tgt->placed_address));
- do_cleanups (cleanup);
return -1;
}
/* In BUNDLE_MEM, be careful to modify only the bits belonging to SLOTNUM
and not any of the other ones that are stored in SHADOW_CONTENTS. */
replace_slotN_contents (bundle_mem, instr_saved, slotnum);
- val = target_write_memory (addr, bundle_mem, BUNDLE_LEN);
+ val = target_write_raw_memory (addr, bundle_mem, BUNDLE_LEN);
- do_cleanups (cleanup);
return val;
}
+/* Implement the breakpoint_kind_from_pc gdbarch method. */
+
+static int
+ia64_breakpoint_kind_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr)
+{
+ /* A place holder of gdbarch method breakpoint_kind_from_pc. */
+ return 0;
+}
+
/* As gdbarch_breakpoint_from_pc ranges have byte granularity and ia64
instruction slots ranges are bit-granular (41 bits) we have to provide an
extended range as described for ia64_memory_insert_breakpoint. We also take
int slotnum = (int) (*pcptr & 0x0f) / SLOT_MULTIPLIER, shadow_slotnum;
long long instr_fetched;
int val;
- int template;
- struct cleanup *cleanup;
+ int templ;
if (slotnum > 2)
error (_("Can't insert breakpoint for slot numbers greater than 2."));
/* Enable the automatic memory restoration from breakpoints while
we read our instruction bundle to match bp_loc_is_permanent. */
- cleanup = make_show_memory_breakpoints_cleanup (0);
- val = target_read_memory (addr, bundle, BUNDLE_LEN);
- do_cleanups (cleanup);
+ {
+ scoped_restore restore_memory_0
+ = make_scoped_restore_show_memory_breakpoints (0);
+ val = target_read_memory (addr, bundle, BUNDLE_LEN);
+ }
/* The memory might be unreachable. This can happen, for instance,
when the user inserts a breakpoint at an invalid address. */
/* Check for L type instruction in slot 1, if present then bump up the slot
number to the slot 2. */
- template = extract_bit_field (bundle, 0, 5);
- if (template_encoding_table[template][slotnum] == X)
+ templ = extract_bit_field (bundle, 0, 5);
+ if (template_encoding_table[templ][slotnum] == X)
{
gdb_assert (slotnum == 2);
error (_("Can't insert breakpoint for non-existing slot X"));
}
- if (template_encoding_table[template][slotnum] == L)
+ if (template_encoding_table[templ][slotnum] == L)
{
gdb_assert (slotnum == 1);
slotnum = 2;
}
static CORE_ADDR
-ia64_read_pc (struct regcache *regcache)
+ia64_read_pc (readable_regcache *regcache)
{
ULONGEST psr_value, pc_value;
int slot_num;
- regcache_cooked_read_unsigned (regcache, IA64_PSR_REGNUM, &psr_value);
- regcache_cooked_read_unsigned (regcache, IA64_IP_REGNUM, &pc_value);
+ regcache->cooked_read (IA64_PSR_REGNUM, &psr_value);
+ regcache->cooked_read (IA64_IP_REGNUM, &pc_value);
slot_num = (psr_value >> 41) & 3;
return pc_value | (slot_num * SLOT_MULTIPLIER);
return new_addr;
}
-static void
-ia64_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
+static enum register_status
+ia64_pseudo_register_read (struct gdbarch *gdbarch, readable_regcache *regcache,
int regnum, gdb_byte *buf)
{
enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+ enum register_status status;
if (regnum >= V32_REGNUM && regnum <= V127_REGNUM)
{
ULONGEST cfm;
ULONGEST bsp;
CORE_ADDR reg;
- regcache_cooked_read_unsigned (regcache, IA64_BSP_REGNUM, &bsp);
- regcache_cooked_read_unsigned (regcache, IA64_CFM_REGNUM, &cfm);
-
+
+ status = regcache->cooked_read (IA64_BSP_REGNUM, &bsp);
+ if (status != REG_VALID)
+ return status;
+
+ status = regcache->cooked_read (IA64_CFM_REGNUM, &cfm);
+ if (status != REG_VALID)
+ return status;
+
/* The bsp points at the end of the register frame so we
subtract the size of frame from it to get start of
register frame. */
{
ULONGEST unatN_val;
ULONGEST unat;
- regcache_cooked_read_unsigned (regcache, IA64_UNAT_REGNUM, &unat);
+
+ status = regcache->cooked_read (IA64_UNAT_REGNUM, &unat);
+ if (status != REG_VALID)
+ return status;
unatN_val = (unat & (1LL << (regnum - IA64_NAT0_REGNUM))) != 0;
store_unsigned_integer (buf, register_size (gdbarch, regnum),
byte_order, unatN_val);
ULONGEST bsp;
ULONGEST cfm;
CORE_ADDR gr_addr = 0;
- regcache_cooked_read_unsigned (regcache, IA64_BSP_REGNUM, &bsp);
- regcache_cooked_read_unsigned (regcache, IA64_CFM_REGNUM, &cfm);
+
+ status = regcache->cooked_read (IA64_BSP_REGNUM, &bsp);
+ if (status != REG_VALID)
+ return status;
+
+ status = regcache->cooked_read (IA64_CFM_REGNUM, &cfm);
+ if (status != REG_VALID)
+ return status;
/* The bsp points at the end of the register frame so we
subtract the size of frame from it to get start of register frame. */
{
/* Compute address of nat collection bits. */
CORE_ADDR nat_addr = gr_addr | 0x1f8;
- CORE_ADDR nat_collection;
+ ULONGEST nat_collection;
int nat_bit;
/* If our nat collection address is bigger than bsp, we have to get
the nat collection from rnat. Otherwise, we fetch the nat
collection from the computed address. */
if (nat_addr >= bsp)
- regcache_cooked_read_unsigned (regcache, IA64_RNAT_REGNUM,
- &nat_collection);
+ regcache->cooked_read (IA64_RNAT_REGNUM, &nat_collection);
else
nat_collection = read_memory_integer (nat_addr, 8, byte_order);
nat_bit = (gr_addr >> 3) & 0x3f;
It can be calculated as the bsp - sof (sizeof frame). */
ULONGEST bsp, vbsp;
ULONGEST cfm;
- CORE_ADDR reg;
- regcache_cooked_read_unsigned (regcache, IA64_BSP_REGNUM, &bsp);
- regcache_cooked_read_unsigned (regcache, IA64_CFM_REGNUM, &cfm);
+
+ status = regcache->cooked_read (IA64_BSP_REGNUM, &bsp);
+ if (status != REG_VALID)
+ return status;
+ status = regcache->cooked_read (IA64_CFM_REGNUM, &cfm);
+ if (status != REG_VALID)
+ return status;
/* The bsp points at the end of the register frame so we
subtract the size of frame from it to get beginning of frame. */
ULONGEST pr;
ULONGEST cfm;
ULONGEST prN_val;
- CORE_ADDR reg;
- regcache_cooked_read_unsigned (regcache, IA64_PR_REGNUM, &pr);
- regcache_cooked_read_unsigned (regcache, IA64_CFM_REGNUM, &cfm);
+
+ status = regcache->cooked_read (IA64_PR_REGNUM, &pr);
+ if (status != REG_VALID)
+ return status;
+ status = regcache->cooked_read (IA64_CFM_REGNUM, &cfm);
+ if (status != REG_VALID)
+ return status;
if (VP16_REGNUM <= regnum && regnum <= VP63_REGNUM)
{
}
else
memset (buf, 0, register_size (gdbarch, regnum));
+
+ return REG_VALID;
}
static void
{
ULONGEST bsp;
ULONGEST cfm;
- CORE_ADDR reg;
regcache_cooked_read_unsigned (regcache, IA64_BSP_REGNUM, &bsp);
regcache_cooked_read_unsigned (regcache, IA64_CFM_REGNUM, &cfm);
if ((cfm & 0x7f) > regnum - V32_REGNUM)
{
ULONGEST reg_addr = rse_address_add (bsp, (regnum - V32_REGNUM));
- write_memory (reg_addr, (void *) buf, 8);
+ write_memory (reg_addr, buf, 8);
}
}
else if (IA64_NAT0_REGNUM <= regnum && regnum <= IA64_NAT31_REGNUM)
collection from the computed address. */
if (nat_addr >= bsp)
{
- regcache_cooked_read_unsigned (regcache, IA64_RNAT_REGNUM,
+ regcache_cooked_read_unsigned (regcache,
+ IA64_RNAT_REGNUM,
&nat_collection);
if (natN_val)
nat_collection |= natN_mask;
}
else
{
- char nat_buf[8];
+ gdb_byte nat_buf[8];
nat_collection = read_memory_integer (nat_addr, 8, byte_order);
if (natN_val)
nat_collection |= natN_mask;
ia64_convert_register_p (struct gdbarch *gdbarch, int regno, struct type *type)
{
return (regno >= IA64_FR0_REGNUM && regno <= IA64_FR127_REGNUM
+ && TYPE_CODE (type) == TYPE_CODE_FLT
&& type != ia64_ext_type (gdbarch));
}
-static void
+static int
ia64_register_to_value (struct frame_info *frame, int regnum,
- struct type *valtype, gdb_byte *out)
+ struct type *valtype, gdb_byte *out,
+ int *optimizedp, int *unavailablep)
{
struct gdbarch *gdbarch = get_frame_arch (frame);
- char in[MAX_REGISTER_SIZE];
- frame_register_read (frame, regnum, in);
- convert_typed_floating (in, ia64_ext_type (gdbarch), out, valtype);
+ gdb_byte in[IA64_FP_REGISTER_SIZE];
+
+ /* Convert to TYPE. */
+ if (!get_frame_register_bytes (frame, regnum, 0,
+ register_size (gdbarch, regnum),
+ in, optimizedp, unavailablep))
+ return 0;
+
+ target_float_convert (in, ia64_ext_type (gdbarch), out, valtype);
+ *optimizedp = *unavailablep = 0;
+ return 1;
}
static void
struct type *valtype, const gdb_byte *in)
{
struct gdbarch *gdbarch = get_frame_arch (frame);
- char out[MAX_REGISTER_SIZE];
- convert_typed_floating (in, valtype, out, ia64_ext_type (gdbarch));
+ gdb_byte out[IA64_FP_REGISTER_SIZE];
+ target_float_convert (in, valtype, out, ia64_ext_type (gdbarch));
put_frame_register (frame, regnum, out);
}
int frameless = 1;
int i;
CORE_ADDR addr;
- char buf[8];
+ gdb_byte buf[8];
CORE_ADDR bof, sor, sol, sof, cfm, rrb_gr;
memset (instores, 0, sizeof instores);
&& it == M && ((instr & 0x1ee0000003fLL) == 0x02c00000000LL))
{
/* alloc - start of a regular function. */
- int sor = (int) ((instr & 0x00078000000LL) >> 27);
- int sol = (int) ((instr & 0x00007f00000LL) >> 20);
- int sof = (int) ((instr & 0x000000fe000LL) >> 13);
+ int sol_bits = (int) ((instr & 0x00007f00000LL) >> 20);
+ int sof_bits = (int) ((instr & 0x000000fe000LL) >> 13);
int rN = (int) ((instr & 0x00000001fc0LL) >> 6);
/* Verify that the current cfm matches what we think is the
addresses of various registers such as the return address.
We will instead treat the frame as frameless. */
if (!this_frame ||
- (sof == (cache->cfm & 0x7f) &&
- sol == ((cache->cfm >> 7) & 0x7f)))
+ (sof_bits == (cache->cfm & 0x7f) &&
+ sol_bits == ((cache->cfm >> 7) & 0x7f)))
frameless = 0;
cfm_reg = rN;
else if (qp == 0 && rN == 2
&& ((rM == fp_reg && fp_reg != 0) || rM == 12))
{
- char buf[MAX_REGISTER_SIZE];
CORE_ADDR saved_sp = 0;
/* adds r2, spilloffset, rFramePointer
or
where the pc is. If it's still early in the prologue
this'll be wrong. FIXME */
if (this_frame)
- {
- struct gdbarch *gdbarch = get_frame_arch (this_frame);
- enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
- get_frame_register (this_frame, sp_regnum, buf);
- saved_sp = extract_unsigned_integer (buf, 8, byte_order);
- }
+ saved_sp = get_frame_register_unsigned (this_frame,
+ sp_regnum);
spill_addr = saved_sp
+ (rM == 12 ? 0 : mem_stack_frame_size)
+ imm;
struct gdbarch *gdbarch = get_frame_arch (this_frame);
enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
struct ia64_frame_cache *cache;
- char buf[8];
- CORE_ADDR cfm, sof, sol, bsp, psr;
- int i;
+ gdb_byte buf[8];
+ CORE_ADDR cfm;
if (*this_cache)
- return *this_cache;
+ return (struct ia64_frame_cache *) *this_cache;
cache = ia64_alloc_frame_cache ();
*this_cache = cache;
cache->bsp = extract_unsigned_integer (buf, 8, byte_order);
get_frame_register (this_frame, IA64_PSR_REGNUM, buf);
- psr = extract_unsigned_integer (buf, 8, byte_order);
get_frame_register (this_frame, IA64_CFM_REGNUM, buf);
cfm = extract_unsigned_integer (buf, 8, byte_order);
struct gdbarch *gdbarch = get_frame_arch (this_frame);
enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
struct ia64_frame_cache *cache = ia64_frame_cache (this_frame, this_cache);
- char buf[8];
+ gdb_byte buf[8];
gdb_assert (regnum >= 0);
static const struct frame_unwind ia64_frame_unwind =
{
NORMAL_FRAME,
+ default_frame_unwind_stop_reason,
&ia64_frame_this_id,
&ia64_frame_prev_register,
NULL,
struct gdbarch *gdbarch = get_frame_arch (this_frame);
enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
struct ia64_frame_cache *cache;
- CORE_ADDR addr;
- char buf[8];
- int i;
+ gdb_byte buf[8];
if (*this_cache)
- return *this_cache;
+ return (struct ia64_frame_cache *) *this_cache;
cache = ia64_alloc_frame_cache ();
ia64_sigtramp_frame_prev_register (struct frame_info *this_frame,
void **this_cache, int regnum)
{
- char buf[MAX_REGISTER_SIZE];
-
- struct gdbarch *gdbarch = get_frame_arch (this_frame);
- enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
struct ia64_frame_cache *cache =
ia64_sigtramp_frame_cache (this_frame, this_cache);
if (addr != 0)
{
- read_memory (addr, buf, register_size (gdbarch, IA64_IP_REGNUM));
- pc = extract_unsigned_integer (buf, 8, byte_order);
+ struct gdbarch *gdbarch = get_frame_arch (this_frame);
+ enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+ pc = read_memory_unsigned_integer (addr, 8, byte_order);
}
pc &= ~0xf;
return frame_unwind_got_constant (this_frame, regnum, pc);
static const struct frame_unwind ia64_sigtramp_frame_unwind =
{
SIGTRAMP_FRAME,
+ default_frame_unwind_stop_reason,
ia64_sigtramp_frame_this_id,
ia64_sigtramp_frame_prev_register,
NULL,
return addr + ((num_regs + delta/0x3f) << 3);
}
-/* Gdb libunwind-frame callback function to convert from an ia64 gdb register
- number to a libunwind register number. */
+/* Gdb ia64-libunwind-tdep callback function to convert from an ia64 gdb
+ register number to a libunwind register number. */
static int
ia64_gdb2uw_regnum (int regnum)
{
return -1;
}
-/* Gdb libunwind-frame callback function to convert from a libunwind register
- number to a ia64 gdb register number. */
+/* Gdb ia64-libunwind-tdep callback function to convert from a libunwind
+ register number to a ia64 gdb register number. */
static int
ia64_uw2gdb_regnum (int uw_regnum)
{
return -1;
}
-/* Gdb libunwind-frame callback function to reveal if register is a float
- register or not. */
+/* Gdb ia64-libunwind-tdep callback function to reveal if register is
+ a float register or not. */
static int
ia64_is_fpreg (int uw_regnum)
{
int write, void *arg)
{
int regnum = ia64_uw2gdb_regnum (uw_regnum);
- unw_word_t bsp, sof, sol, cfm, psr, ip;
- struct frame_info *this_frame = arg;
+ unw_word_t bsp, sof, cfm, psr, ip;
+ struct frame_info *this_frame = (struct frame_info *) arg;
struct gdbarch *gdbarch = get_frame_arch (this_frame);
- enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
- long new_sof, old_sof;
- char buf[MAX_REGISTER_SIZE];
/* We never call any libunwind routines that need to write registers. */
gdb_assert (!write);
case UNW_REG_IP:
/* Libunwind expects to see the pc value which means the slot number
from the psr must be merged with the ip word address. */
- get_frame_register (this_frame, IA64_IP_REGNUM, buf);
- ip = extract_unsigned_integer (buf, 8, byte_order);
- get_frame_register (this_frame, IA64_PSR_REGNUM, buf);
- psr = extract_unsigned_integer (buf, 8, byte_order);
+ ip = get_frame_register_unsigned (this_frame, IA64_IP_REGNUM);
+ psr = get_frame_register_unsigned (this_frame, IA64_PSR_REGNUM);
*val = ip | ((psr >> 41) & 0x3);
break;
register frame so we must account for the fact that
ptrace() will return a value for bsp that points *after*
the current register frame. */
- get_frame_register (this_frame, IA64_BSP_REGNUM, buf);
- bsp = extract_unsigned_integer (buf, 8, byte_order);
- get_frame_register (this_frame, IA64_CFM_REGNUM, buf);
- cfm = extract_unsigned_integer (buf, 8, byte_order);
+ bsp = get_frame_register_unsigned (this_frame, IA64_BSP_REGNUM);
+ cfm = get_frame_register_unsigned (this_frame, IA64_CFM_REGNUM);
sof = gdbarch_tdep (gdbarch)->size_of_register_frame (this_frame, cfm);
*val = ia64_rse_skip_regs (bsp, -sof);
break;
case UNW_IA64_AR_BSPSTORE:
/* Libunwind wants bspstore to be after the current register frame.
This is what ptrace() and gdb treats as the regular bsp value. */
- get_frame_register (this_frame, IA64_BSP_REGNUM, buf);
- *val = extract_unsigned_integer (buf, 8, byte_order);
+ *val = get_frame_register_unsigned (this_frame, IA64_BSP_REGNUM);
break;
default:
/* For all other registers, just unwind the value directly. */
- get_frame_register (this_frame, regnum, buf);
- *val = extract_unsigned_integer (buf, 8, byte_order);
+ *val = get_frame_register_unsigned (this_frame, regnum);
break;
}
unw_fpreg_t *val, int write, void *arg)
{
int regnum = ia64_uw2gdb_regnum (uw_regnum);
- struct frame_info *this_frame = arg;
+ struct frame_info *this_frame = (struct frame_info *) arg;
/* We never call any libunwind routines that need to write registers. */
gdb_assert (!write);
- get_frame_register (this_frame, regnum, (char *) val);
+ get_frame_register (this_frame, regnum, (gdb_byte *) val);
return 0;
}
unw_word_t *val, int write, void *arg)
{
int regnum = ia64_uw2gdb_regnum (uw_regnum);
- unw_word_t bsp, sof, sol, cfm, psr, ip;
- struct regcache *regcache = arg;
- struct gdbarch *gdbarch = get_regcache_arch (regcache);
- enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
- long new_sof, old_sof;
- char buf[MAX_REGISTER_SIZE];
+ unw_word_t bsp, sof, cfm, psr, ip;
+ struct regcache *regcache = (struct regcache *) arg;
+ struct gdbarch *gdbarch = regcache->arch ();
/* We never call any libunwind routines that need to write registers. */
gdb_assert (!write);
case UNW_REG_IP:
/* Libunwind expects to see the pc value which means the slot number
from the psr must be merged with the ip word address. */
- regcache_cooked_read (regcache, IA64_IP_REGNUM, buf);
- ip = extract_unsigned_integer (buf, 8, byte_order);
- regcache_cooked_read (regcache, IA64_PSR_REGNUM, buf);
- psr = extract_unsigned_integer (buf, 8, byte_order);
+ regcache_cooked_read_unsigned (regcache, IA64_IP_REGNUM, &ip);
+ regcache_cooked_read_unsigned (regcache, IA64_PSR_REGNUM, &psr);
*val = ip | ((psr >> 41) & 0x3);
break;
register frame so we must account for the fact that
ptrace() will return a value for bsp that points *after*
the current register frame. */
- regcache_cooked_read (regcache, IA64_BSP_REGNUM, buf);
- bsp = extract_unsigned_integer (buf, 8, byte_order);
- regcache_cooked_read (regcache, IA64_CFM_REGNUM, buf);
- cfm = extract_unsigned_integer (buf, 8, byte_order);
+ regcache_cooked_read_unsigned (regcache, IA64_BSP_REGNUM, &bsp);
+ regcache_cooked_read_unsigned (regcache, IA64_CFM_REGNUM, &cfm);
sof = (cfm & 0x7f);
*val = ia64_rse_skip_regs (bsp, -sof);
break;
case UNW_IA64_AR_BSPSTORE:
/* Libunwind wants bspstore to be after the current register frame.
This is what ptrace() and gdb treats as the regular bsp value. */
- regcache_cooked_read (regcache, IA64_BSP_REGNUM, buf);
- *val = extract_unsigned_integer (buf, 8, byte_order);
+ regcache_cooked_read_unsigned (regcache, IA64_BSP_REGNUM, val);
break;
default:
/* For all other registers, just unwind the value directly. */
- regcache_cooked_read (regcache, regnum, buf);
- *val = extract_unsigned_integer (buf, 8, byte_order);
+ regcache_cooked_read_unsigned (regcache, regnum, val);
break;
}
unw_fpreg_t *val, int write, void *arg)
{
int regnum = ia64_uw2gdb_regnum (uw_regnum);
- struct regcache *regcache = arg;
+ struct regcache *regcache = (struct regcache *) arg;
/* We never call any libunwind routines that need to write registers. */
gdb_assert (!write);
- regcache_cooked_read (regcache, regnum, (char *) val);
+ regcache->cooked_read (regnum, (gdb_byte *) val);
return 0;
}
/* XXX do we need to normalize byte-order here? */
if (write)
- return target_write_memory (addr, (char *) val, sizeof (unw_word_t));
+ return target_write_memory (addr, (gdb_byte *) val, sizeof (unw_word_t));
else
- return target_read_memory (addr, (char *) val, sizeof (unw_word_t));
+ return target_read_memory (addr, (gdb_byte *) val, sizeof (unw_word_t));
}
/* Call low-level function to access the kernel unwind table. */
-static LONGEST
-getunwind_table (gdb_byte **buf_p)
+static gdb::optional<gdb::byte_vector>
+getunwind_table ()
{
- LONGEST x;
-
/* FIXME drow/2005-09-10: This code used to call
ia64_linux_xfer_unwind_table directly to fetch the unwind table
for the currently running ia64-linux kernel. That data should
we should find a way to override the corefile layer's
xfer_partial method. */
- x = target_read_alloc (¤t_target, TARGET_OBJECT_UNWIND_TABLE,
- NULL, buf_p);
-
- return x;
+ return target_read_alloc (current_top_target (), TARGET_OBJECT_UNWIND_TABLE,
+ NULL);
}
/* Get the kernel unwind table. */
if (!ktab)
{
- gdb_byte *ktab_buf;
- LONGEST size;
-
- size = getunwind_table (&ktab_buf);
- if (size <= 0)
+ ktab_buf = getunwind_table ();
+ if (!ktab_buf)
return -UNW_ENOINFO;
- ktab = (struct ia64_table_entry *) ktab_buf;
- ktab_size = size;
+ ktab = (struct ia64_table_entry *) ktab_buf->data ();
+ ktab_size = ktab_buf->size ();
for (etab = ktab; etab->start_offset; ++etab)
etab->info_offset += KERNEL_START;
unw_word_t *dilap, void *arg)
{
struct obj_section *text_sec;
- struct objfile *objfile;
unw_word_t ip, addr;
unw_dyn_info_t di;
int ret;
if (!libunwind_is_initialized ())
return -UNW_ENOINFO;
- for (objfile = object_files; objfile; objfile = objfile->next)
+ for (objfile *objfile : current_program_space->objfiles ())
{
void *buf = NULL;
struct gdbarch *gdbarch = get_frame_arch (this_frame);
enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
struct frame_id id = outer_frame_id;
- char buf[8];
+ gdb_byte buf[8];
CORE_ADDR bsp;
libunwind_frame_this_id (this_frame, this_cache, &id);
{
int rrb_pr = 0;
ULONGEST cfm;
- unsigned char buf[MAX_REGISTER_SIZE];
/* Fetch predicate register rename base from current frame
marker for this frame. */
- get_frame_register (this_frame, IA64_CFM_REGNUM, buf);
- cfm = extract_unsigned_integer (buf, 8, byte_order);
+ cfm = get_frame_register_unsigned (this_frame, IA64_CFM_REGNUM);
rrb_pr = (cfm >> 32) & 0x3f;
/* Adjust the register number to account for register rotation. */
static const struct frame_unwind ia64_libunwind_frame_unwind =
{
NORMAL_FRAME,
+ default_frame_unwind_stop_reason,
ia64_libunwind_frame_this_id,
ia64_libunwind_frame_prev_register,
NULL,
{
struct gdbarch *gdbarch = get_frame_arch (this_frame);
enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
- char buf[8];
+ gdb_byte buf[8];
CORE_ADDR bsp;
struct frame_id id = outer_frame_id;
- CORE_ADDR prev_ip;
libunwind_frame_this_id (this_frame, this_cache, &id);
if (frame_id_eq (id, outer_frame_id))
static const struct frame_unwind ia64_libunwind_sigtramp_frame_unwind =
{
SIGTRAMP_FRAME,
+ default_frame_unwind_stop_reason,
ia64_libunwind_sigtramp_frame_this_id,
ia64_libunwind_sigtramp_frame_prev_register,
NULL,
};
/* Set of libunwind callback acccessor functions. */
-static unw_accessors_t ia64_unw_accessors =
+unw_accessors_t ia64_unw_accessors =
{
ia64_find_proc_info_x,
ia64_put_unwind_info,
the rse registers. At the top of the stack, we want libunwind to figure out
how to read r32 - r127. Though usually they are found sequentially in
memory starting from $bof, this is not always true. */
-static unw_accessors_t ia64_unw_rse_accessors =
+unw_accessors_t ia64_unw_rse_accessors =
{
ia64_find_proc_info_x,
ia64_put_unwind_info,
/* get_proc_name */
};
-/* Set of ia64 gdb libunwind-frame callbacks and data for generic
- libunwind-frame code to use. */
-static struct libunwind_descr ia64_libunwind_descr =
+/* Set of ia64-libunwind-tdep gdb callbacks and data for generic
+ ia64-libunwind-tdep code to use. */
+struct libunwind_descr ia64_libunwind_descr =
{
ia64_gdb2uw_regnum,
ia64_uw2gdb_regnum,
ia64_extract_return_value (struct type *type, struct regcache *regcache,
gdb_byte *valbuf)
{
- struct gdbarch *gdbarch = get_regcache_arch (regcache);
+ struct gdbarch *gdbarch = regcache->arch ();
struct type *float_elt_type;
float_elt_type = is_float_or_hfa_type (type);
if (float_elt_type != NULL)
{
- char from[MAX_REGISTER_SIZE];
+ gdb_byte from[IA64_FP_REGISTER_SIZE];
int offset = 0;
int regnum = IA64_FR8_REGNUM;
int n = TYPE_LENGTH (type) / TYPE_LENGTH (float_elt_type);
while (n-- > 0)
{
- regcache_cooked_read (regcache, regnum, from);
- convert_typed_floating (from, ia64_ext_type (gdbarch),
- (char *)valbuf + offset, float_elt_type);
+ regcache->cooked_read (regnum, from);
+ target_float_convert (from, ia64_ext_type (gdbarch),
+ valbuf + offset, float_elt_type);
offset += TYPE_LENGTH (float_elt_type);
regnum++;
}
while (n-- > 0)
{
- ULONGEST val;
- regcache_cooked_read_unsigned (regcache, regnum, &val);
- memcpy ((char *)valbuf + offset, &val, reglen);
+ ULONGEST regval;
+ regcache_cooked_read_unsigned (regcache, regnum, ®val);
+ memcpy ((char *)valbuf + offset, ®val, reglen);
offset += reglen;
regnum++;
}
ia64_store_return_value (struct type *type, struct regcache *regcache,
const gdb_byte *valbuf)
{
- struct gdbarch *gdbarch = get_regcache_arch (regcache);
+ struct gdbarch *gdbarch = regcache->arch ();
struct type *float_elt_type;
float_elt_type = is_float_or_hfa_type (type);
if (float_elt_type != NULL)
{
- char to[MAX_REGISTER_SIZE];
+ gdb_byte to[IA64_FP_REGISTER_SIZE];
int offset = 0;
int regnum = IA64_FR8_REGNUM;
int n = TYPE_LENGTH (type) / TYPE_LENGTH (float_elt_type);
while (n-- > 0)
{
- convert_typed_floating ((char *)valbuf + offset, float_elt_type,
- to, ia64_ext_type (gdbarch));
- regcache_cooked_write (regcache, regnum, to);
+ target_float_convert (valbuf + offset, float_elt_type,
+ to, ia64_ext_type (gdbarch));
+ regcache->cooked_write (regnum, to);
offset += TYPE_LENGTH (float_elt_type);
regnum++;
}
}
else
{
- ULONGEST val;
int offset = 0;
int regnum = IA64_GR8_REGNUM;
int reglen = TYPE_LENGTH (register_type (gdbarch, IA64_GR8_REGNUM));
if (m)
{
+ ULONGEST val;
memcpy (&val, (char *)valbuf + offset, m);
regcache_cooked_write_unsigned (regcache, regnum, val);
}
}
static enum return_value_convention
-ia64_return_value (struct gdbarch *gdbarch, struct type *func_type,
+ia64_return_value (struct gdbarch *gdbarch, struct value *function,
struct type *valtype, struct regcache *regcache,
gdb_byte *readbuf, const gdb_byte *writebuf)
{
{
int status;
LONGEST tag;
- char buf[8];
+ gdb_byte buf[8];
status = target_read_memory (addr, buf, sizeof (buf));
if (status != 0)
{
int status;
LONGEST faddr2;
- char buf[8];
+ gdb_byte buf[8];
status = target_read_memory (addr, buf, sizeof (buf));
if (status != 0)
static CORE_ADDR
find_func_descr (struct regcache *regcache, CORE_ADDR faddr, CORE_ADDR *fdaptr)
{
- struct gdbarch *gdbarch = get_regcache_arch (regcache);
+ struct gdbarch *gdbarch = regcache->arch ();
enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
CORE_ADDR fdesc;
if (fdesc == 0)
{
ULONGEST global_pointer;
- char buf[16];
+ gdb_byte buf[16];
fdesc = *fdaptr;
*fdaptr += 16;
/* There are also descriptors embedded in vtables. */
if (s)
{
- struct minimal_symbol *minsym;
+ struct bound_minimal_symbol minsym;
minsym = lookup_minimal_symbol_by_pc (addr);
- if (minsym && is_vtable_name (SYMBOL_LINKAGE_NAME (minsym)))
+ if (minsym.minsym
+ && is_vtable_name (MSYMBOL_LINKAGE_NAME (minsym.minsym)))
return read_memory_unsigned_integer (addr, 8, byte_order);
}
ia64_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
struct regcache *regcache, CORE_ADDR bp_addr,
int nargs, struct value **args, CORE_ADDR sp,
- int struct_return, CORE_ADDR struct_addr)
+ function_call_return_method return_method,
+ CORE_ADDR struct_addr)
{
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
int nslots, rseslots, memslots, slotnum, nfuncargs;
int floatreg;
ULONGEST bsp;
- CORE_ADDR funcdescaddr, pc, global_pointer;
+ CORE_ADDR funcdescaddr, global_pointer;
CORE_ADDR func_addr = find_function_addr (function, NULL);
nslots = 0;
&& TYPE_CODE (type) == TYPE_CODE_PTR
&& TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_FUNC)
{
- char val_buf[8];
+ gdb_byte val_buf[8];
ULONGEST faddr = extract_unsigned_integer (value_contents (arg),
8, byte_order);
store_unsigned_integer (val_buf, 8, byte_order,
argoffset = 0;
while (len > 0)
{
- char val_buf[8];
+ gdb_byte val_buf[8];
memset (val_buf, 0, 8);
if (!ia64_struct_type_p (type) && len < 8)
len = TYPE_LENGTH (type);
while (len > 0 && floatreg < IA64_FR16_REGNUM)
{
- char to[MAX_REGISTER_SIZE];
- convert_typed_floating (value_contents (arg) + argoffset,
- float_elt_type, to,
- ia64_ext_type (gdbarch));
- regcache_cooked_write (regcache, floatreg, (void *)to);
+ gdb_byte to[IA64_FP_REGISTER_SIZE];
+ target_float_convert (value_contents (arg) + argoffset,
+ float_elt_type, to,
+ ia64_ext_type (gdbarch));
+ regcache->cooked_write (floatreg, to);
floatreg++;
argoffset += TYPE_LENGTH (float_elt_type);
len -= TYPE_LENGTH (float_elt_type);
}
/* Store the struct return value in r8 if necessary. */
- if (struct_return)
- {
- regcache_cooked_write_unsigned (regcache, IA64_GR8_REGNUM,
- (ULONGEST) struct_addr);
- }
+ if (return_method == return_method_struct)
+ regcache_cooked_write_unsigned (regcache, IA64_GR8_REGNUM,
+ (ULONGEST) struct_addr);
global_pointer = ia64_find_global_pointer (gdbarch, func_addr);
ia64_dummy_id (struct gdbarch *gdbarch, struct frame_info *this_frame)
{
enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
- char buf[8];
+ gdb_byte buf[8];
CORE_ADDR sp, bsp;
get_frame_register (this_frame, sp_regnum, buf);
ia64_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
{
enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
- char buf[8];
+ gdb_byte buf[8];
CORE_ADDR ip, psr, pc;
frame_unwind_register (next_frame, IA64_IP_REGNUM, buf);
ia64_print_insn (bfd_vma memaddr, struct disassemble_info *info)
{
info->bytes_per_line = SLOT_MULTIPLIER;
- return print_insn_ia64 (memaddr, info);
+ return default_print_insn (memaddr, info);
}
/* The default "size_of_register_frame" gdbarch_tdep routine for ia64. */
if (arches != NULL)
return arches->gdbarch;
- tdep = xzalloc (sizeof (struct gdbarch_tdep));
+ tdep = XCNEW (struct gdbarch_tdep);
gdbarch = gdbarch_alloc (&info, tdep);
tdep->size_of_register_frame = ia64_size_of_register_frame;
set_gdbarch_memory_remove_breakpoint (gdbarch,
ia64_memory_remove_breakpoint);
set_gdbarch_breakpoint_from_pc (gdbarch, ia64_breakpoint_from_pc);
+ set_gdbarch_breakpoint_kind_from_pc (gdbarch, ia64_breakpoint_kind_from_pc);
set_gdbarch_read_pc (gdbarch, ia64_read_pc);
set_gdbarch_write_pc (gdbarch, ia64_write_pc);
return gdbarch;
}
-extern initialize_file_ftype _initialize_ia64_tdep; /* -Wmissing-prototypes */
-
void
_initialize_ia64_tdep (void)
{