/* Target-dependent code for the IA-64 for GDB, the GNU debugger.
- Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software
- Foundation, Inc.
+ Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ Free Software Foundation, Inc.
This file is part of GDB.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA. */
+ Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA. */
#include "defs.h"
#include "inferior.h"
#include "gdbcore.h"
#include "arch-utils.h"
#include "floatformat.h"
+#include "gdbtypes.h"
#include "regcache.h"
#include "reggroups.h"
#include "frame.h"
#include "infcall.h"
#include "osabi.h"
#include "ia64-tdep.h"
+#include "cp-abi.h"
#ifdef HAVE_LIBUNWIND_IA64_H
#include "elf/ia64.h" /* for PT_IA_64_UNWIND value */
}
static int
-floatformat_valid (const struct floatformat *fmt, const char *from)
+floatformat_valid (const struct floatformat *fmt, const void *from)
{
return 1;
}
floatformat_intbit_yes, "floatformat_ia64_ext", floatformat_valid
};
+const struct floatformat *floatformats_ia64_ext[2] =
+{
+ &floatformat_ia64_ext,
+ &floatformat_ia64_ext
+};
+
/* Extract ``len'' bits from an instruction bundle starting at
bit ``from''. */
#define IA64_BREAKPOINT 0x00003333300LL
static int
-ia64_memory_insert_breakpoint (CORE_ADDR addr, bfd_byte *contents_cache)
+ia64_memory_insert_breakpoint (struct bp_target_info *bp_tgt)
{
+ CORE_ADDR addr = bp_tgt->placed_address;
char bundle[BUNDLE_LEN];
int slotnum = (int) (addr & 0x0f) / SLOT_MULTIPLIER;
long long instr;
}
instr = slotN_contents (bundle, slotnum);
- memcpy(contents_cache, &instr, sizeof(instr));
+ memcpy (bp_tgt->shadow_contents, &instr, sizeof (instr));
+ bp_tgt->placed_size = bp_tgt->shadow_len = sizeof (instr);
replace_slotN_contents (bundle, IA64_BREAKPOINT, slotnum);
if (val == 0)
target_write_memory (addr, bundle, BUNDLE_LEN);
}
static int
-ia64_memory_remove_breakpoint (CORE_ADDR addr, bfd_byte *contents_cache)
+ia64_memory_remove_breakpoint (struct bp_target_info *bp_tgt)
{
+ CORE_ADDR addr = bp_tgt->placed_address;
char bundle[BUNDLE_LEN];
int slotnum = (addr & 0x0f) / SLOT_MULTIPLIER;
long long instr;
slotnum = 2;
}
- memcpy (&instr, contents_cache, sizeof instr);
+ memcpy (&instr, bp_tgt->shadow_contents, sizeof instr);
replace_slotN_contents (bundle, instr, slotnum);
if (val == 0)
target_write_memory (addr, bundle, BUNDLE_LEN);
cache->cfm = cfm;
- cache->pc = frame_func_unwind (next_frame);
+ cache->pc = frame_func_unwind (next_frame, NORMAL_FRAME);
if (cache->pc != 0)
examine_prologue (cache->pc, frame_pc_unwind (next_frame), next_frame, cache);
}
/* Call low-level function to access the kernel unwind table. */
-static int
-getunwind_table (void *buf, size_t len)
+static LONGEST
+getunwind_table (gdb_byte **buf_p)
{
LONGEST x;
we want to preserve fall back to the running kernel's table, then
we should find a way to override the corefile layer's
xfer_partial method. */
- x = target_read_partial (¤t_target, TARGET_OBJECT_UNWIND_TABLE, NULL,
- buf, 0, len);
- return (int)x;
+ x = target_read_alloc (¤t_target, TARGET_OBJECT_UNWIND_TABLE,
+ NULL, buf_p);
+
+ return x;
}
/* Get the kernel unwind table. */
if (!ktab)
{
- size_t size;
- size = getunwind_table (NULL, 0);
- if ((int)size < 0)
- return -UNW_ENOINFO;
+ gdb_byte *ktab_buf;
+ LONGEST size;
+
+ size = getunwind_table (&ktab_buf);
+ if (size <= 0)
+ return -UNW_ENOINFO;
+
+ ktab = (struct ia64_table_entry *) ktab_buf;
ktab_size = size;
- ktab = xmalloc (ktab_size);
- getunwind_table (ktab, ktab_size);
-
+
for (etab = ktab; etab->start_offset; ++etab)
etab->info_offset += KERNEL_START;
}
and don't want to unwind past this frame. We return a null frame_id to
indicate this. */
libunwind_frame_prev_register (next_frame, this_cache, IA64_IP_REGNUM,
- &optimized, &lval, &addr, &realnum, &prev_ip);
+ &optimized, &lval, &addr, &realnum, buf);
+ prev_ip = extract_unsigned_integer (buf, 8);
if (prev_ip != 0)
(*this_id) = frame_id_build_special (id.stack_addr, id.code_addr, bsp);
int *realnump, gdb_byte *valuep)
{
+ gdb_byte buf[8];
CORE_ADDR prev_ip, addr;
int realnum, optimized;
enum lval_type lval;
/* If the previous frame pc value is 0, then we want to use the SIGCONTEXT
method of getting previous registers. */
libunwind_frame_prev_register (next_frame, this_cache, IA64_IP_REGNUM,
- &optimized, &lval, &addr, &realnum, &prev_ip);
+ &optimized, &lval, &addr, &realnum, buf);
+ prev_ip = extract_unsigned_integer (buf, 8);
if (prev_ip == 0)
{
ULONGEST val;
int offset = 0;
int regnum = IA64_GR8_REGNUM;
- int reglen = TYPE_LENGTH (ia64_register_type (NULL, IA64_GR8_REGNUM));
+ int reglen = TYPE_LENGTH (register_type (get_regcache_arch (regcache),
+ IA64_GR8_REGNUM));
int n = TYPE_LENGTH (type) / reglen;
int m = TYPE_LENGTH (type) % reglen;
if (s && strcmp (s->the_bfd_section->name, ".opd") == 0)
return read_memory_unsigned_integer (addr, 8);
+ /* There are also descriptors embedded in vtables. */
+ if (s)
+ {
+ struct minimal_symbol *minsym;
+
+ minsym = lookup_minimal_symbol_by_pc (addr);
+
+ if (minsym && is_vtable_name (SYMBOL_LINKAGE_NAME (minsym)))
+ return read_memory_unsigned_integer (addr, 8);
+ }
+
return addr;
}
builtin_type_ia64_ext =
init_type (TYPE_CODE_FLT, 128 / 8,
0, "builtin_type_ia64_ext", NULL);
- TYPE_FLOATFORMAT (builtin_type_ia64_ext) = &floatformat_ia64_ext;
+ TYPE_FLOATFORMAT (builtin_type_ia64_ext) = floatformats_ia64_ext;
/* According to the ia64 specs, instructions that store long double
floats in memory use a long-double format different than that
format for storing long doubles (e.g. HPUX). In the latter case,
the setting of the format may be moved/overridden in an
OS-specific tdep file. */
- set_gdbarch_long_double_format (gdbarch, &floatformat_i387_ext);
+ set_gdbarch_long_double_format (gdbarch, floatformats_i387_ext);
set_gdbarch_short_bit (gdbarch, 16);
set_gdbarch_int_bit (gdbarch, 32);
set_gdbarch_print_insn (gdbarch, ia64_print_insn);
set_gdbarch_convert_from_func_ptr_addr (gdbarch, ia64_convert_from_func_ptr_addr);
+ /* The virtual table contains 16-byte descriptors, not pointers to
+ descriptors. */
+ set_gdbarch_vtable_function_descriptors (gdbarch, 1);
+
/* Hook in ABI-specific overrides, if they have been registered. */
gdbarch_init_osabi (info, gdbarch);