/* Target-dependent code for the IA-64 for GDB, the GNU debugger.
- Copyright 1999, 2000, 2001, 2002, 2003, 2004 Free Software
+ Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software
Foundation, Inc.
This file is part of GDB.
#include "objfiles.h"
#include "elf/common.h" /* for DT_PLTGOT value */
#include "elf-bfd.h"
-#include "elf.h" /* for PT_IA64_UNWIND value */
#include "dis-asm.h"
+#include "infcall.h"
+#include "osabi.h"
#include "ia64-tdep.h"
#ifdef HAVE_LIBUNWIND_IA64_H
+#include "elf/ia64.h" /* for PT_IA_64_UNWIND value */
#include "libunwind-frame.h"
#include "libunwind-ia64.h"
#endif
-/* Hook for determining the global pointer when calling functions in
- the inferior under AIX. The initialization code in ia64-aix-nat.c
- sets this hook to the address of a function which will find the
- global pointer for a given address.
-
- The generic code which uses the dynamic section in the inferior for
- finding the global pointer is not of much use on AIX since the
- values obtained from the inferior have not been relocated. */
-
-CORE_ADDR (*native_find_global_pointer) (CORE_ADDR) = 0;
-
/* An enumeration of the different IA-64 instruction types. */
typedef enum instruction_type
static gdbarch_breakpoint_from_pc_ftype ia64_breakpoint_from_pc;
static gdbarch_skip_prologue_ftype ia64_skip_prologue;
static gdbarch_extract_return_value_ftype ia64_extract_return_value;
-static gdbarch_use_struct_convention_ftype ia64_use_struct_convention;
static struct type *is_float_or_hfa_type (struct type *t);
+static CORE_ADDR ia64_find_global_pointer (CORE_ADDR faddr);
static struct type *builtin_type_ia64_ext;
};
-struct gdbarch_tdep
- {
- CORE_ADDR (*sigcontext_register_address) (CORE_ADDR, int);
- /* OS specific function which, given a frame address
- and register number, returns the offset to the
- given register from the start of the frame. */
- CORE_ADDR (*find_global_pointer) (CORE_ADDR);
- };
-
#define SIGCONTEXT_REGISTER_ADDRESS \
(gdbarch_tdep (current_gdbarch)->sigcontext_register_address)
-#define FIND_GLOBAL_POINTER \
- (gdbarch_tdep (current_gdbarch)->find_global_pointer)
int
ia64_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
at the assembly language level. */
if (slotnum > 2)
{
- warning ("Can't fetch instructions for slot numbers greater than 2.\n"
- "Using slot 0 instead");
+ warning (_("Can't fetch instructions for slot numbers greater than 2.\n"
+ "Using slot 0 instead"));
slotnum = 0;
}
#define IA64_BREAKPOINT 0x00003333300LL
static int
-ia64_memory_insert_breakpoint (CORE_ADDR addr, char *contents_cache)
+ia64_memory_insert_breakpoint (CORE_ADDR addr, bfd_byte *contents_cache)
{
char bundle[BUNDLE_LEN];
int slotnum = (int) (addr & 0x0f) / SLOT_MULTIPLIER;
int template;
if (slotnum > 2)
- error("Can't insert breakpoint for slot numbers greater than 2.");
+ error (_("Can't insert breakpoint for slot numbers greater than 2."));
addr &= ~0x0f;
}
static int
-ia64_memory_remove_breakpoint (CORE_ADDR addr, char *contents_cache)
+ia64_memory_remove_breakpoint (CORE_ADDR addr, bfd_byte *contents_cache)
{
char bundle[BUNDLE_LEN];
int slotnum = (addr & 0x0f) / SLOT_MULTIPLIER;
if (next_pc == 0)
break;
- if (it == B && ((instr & 0x1e1f800003f) != 0x04000000000))
+ if (it == B && ((instr & 0x1e1f800003fLL) != 0x04000000000LL))
{
/* Exit loop upon hitting a non-nop branch instruction. */
if (trust_limit)
{
cache->saved_regs[IA64_FR0_REGNUM + fM] = spill_addr;
- if ((instr & 0x1efc0000000) == 0x0eec0000000)
+ if ((instr & 0x1efc0000000LL) == 0x0eec0000000LL)
spill_addr += imm;
else
spill_addr = 0; /* last one; must be done */
gdb_assert (regnum >= 0);
if (!target_has_registers)
- error ("No registers.");
+ error (_("No registers."));
*optimizedp = 0;
*addrp = 0;
gdb_assert (regnum >= 0);
if (!target_has_registers)
- error ("No registers.");
+ error (_("No registers."));
*optimizedp = 0;
*addrp = 0;
CORE_ADDR pc = frame_pc_unwind (next_frame);
find_pc_partial_function (pc, &name, NULL, NULL);
- if (DEPRECATED_PC_IN_SIGTRAMP (pc, name))
+ if (legacy_pc_in_sigtramp (pc, name))
return &ia64_sigtramp_frame_unwind;
return NULL;
dip->start_ip = segbase;
dip->end_ip = dip->start_ip + p_text->p_memsz;
- dip->gp = FIND_GLOBAL_POINTER (ip);
+ dip->gp = ia64_find_global_pointer (ip);
dip->format = UNW_INFO_FORMAT_REMOTE_TABLE;
dip->u.rti.name_ptr = (unw_word_t) bfd_get_filename (bfd);
dip->u.rti.segbase = segbase;
static void
ia64_libunwind_frame_this_id (struct frame_info *next_frame, void **this_cache,
- struct frame_id *this_id)
+ struct frame_id *this_id)
{
char buf[8];
CORE_ADDR bsp;
libunwind_frame_prev_register (next_frame, this_cache, reg,
optimizedp, lvalp, addrp, realnump, valuep);
+ /* No more to do if the value is not supposed to be supplied. */
+ if (!valuep)
+ return;
+
if (VP0_REGNUM <= regnum && regnum <= VP63_REGNUM)
{
ULONGEST prN_val;
CORE_ADDR
ia64_extract_struct_value_address (struct regcache *regcache)
{
- error ("ia64_extract_struct_value_address called and cannot get struct value address");
+ error (_("ia64_extract_struct_value_address called and cannot get struct value address"));
return 0;
}
d_un.d_ptr value is the global pointer. */
static CORE_ADDR
-generic_elf_find_global_pointer (CORE_ADDR faddr)
+ia64_find_global_pointer (CORE_ADDR faddr)
{
struct obj_section *faddr_sect;
fdesc = *fdaptr;
*fdaptr += 16;
- global_pointer = FIND_GLOBAL_POINTER (faddr);
+ global_pointer = ia64_find_global_pointer (faddr);
if (global_pointer == 0)
global_pointer = read_register (IA64_GR1_REGNUM);
}
static CORE_ADDR
-ia64_push_dummy_call (struct gdbarch *gdbarch, CORE_ADDR func_addr,
+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)
int nslots, rseslots, memslots, slotnum, nfuncargs;
int floatreg;
CORE_ADDR bsp, cfm, pfs, new_bsp, funcdescaddr, pc, global_pointer;
+ CORE_ADDR func_addr = find_function_addr (function, NULL);
nslots = 0;
nfuncargs = 0;
for (argno = 0; argno < nargs; argno++)
{
arg = args[argno];
- type = check_typedef (VALUE_TYPE (arg));
+ type = check_typedef (value_type (arg));
len = TYPE_LENGTH (type);
if ((nslots & 1) && slot_alignment_is_next_even (type))
struct type *float_elt_type;
arg = args[argno];
- type = check_typedef (VALUE_TYPE (arg));
+ type = check_typedef (value_type (arg));
len = TYPE_LENGTH (type);
/* Special handling for function parameters. */
char val_buf[8];
store_unsigned_integer (val_buf, 8,
- find_func_descr (extract_unsigned_integer (VALUE_CONTENTS (arg), 8),
+ find_func_descr (extract_unsigned_integer (value_contents (arg), 8),
&funcdescaddr));
if (slotnum < rseslots)
write_memory (rse_address_add (bsp, slotnum), val_buf, 8);
char val_buf[8];
memset (val_buf, 0, 8);
- memcpy (val_buf, VALUE_CONTENTS (arg) + argoffset, (len > 8) ? 8 : len);
+ memcpy (val_buf, value_contents (arg) + argoffset, (len > 8) ? 8 : len);
if (slotnum < rseslots)
write_memory (rse_address_add (bsp, slotnum), val_buf, 8);
while (len > 0 && floatreg < IA64_FR16_REGNUM)
{
char to[MAX_REGISTER_SIZE];
- convert_typed_floating (VALUE_CONTENTS (arg) + argoffset, float_elt_type,
+ convert_typed_floating (value_contents (arg) + argoffset, float_elt_type,
to, builtin_type_ia64_ext);
regcache_cooked_write (regcache, floatreg, (void *)to);
floatreg++;
regcache_cooked_write_unsigned (regcache, IA64_GR8_REGNUM, (ULONGEST)struct_addr);
}
- global_pointer = FIND_GLOBAL_POINTER (func_addr);
+ global_pointer = ia64_find_global_pointer (func_addr);
if (global_pointer != 0)
write_register (IA64_GR1_REGNUM, global_pointer);
tdep = xmalloc (sizeof (struct gdbarch_tdep));
gdbarch = gdbarch_alloc (&info, tdep);
- /* Set the method of obtaining the sigcontext addresses at which
- registers are saved. The method of checking to see if
- native_find_global_pointer is nonzero to indicate that we're
- on AIX is kind of hokey, but I can't think of a better way
- to do it. */
- if (info.osabi == GDB_OSABI_LINUX)
- tdep->sigcontext_register_address = ia64_linux_sigcontext_register_address;
- else if (native_find_global_pointer != 0)
- tdep->sigcontext_register_address = ia64_aix_sigcontext_register_address;
- else
- tdep->sigcontext_register_address = 0;
-
- /* We know that GNU/Linux won't have to resort to the
- native_find_global_pointer hackery. But that's the only one we
- know about so far, so if native_find_global_pointer is set to
- something non-zero, then use it. Otherwise fall back to using
- generic_elf_find_global_pointer. This arrangement should (in
- theory) allow us to cross debug GNU/Linux binaries from an AIX
- machine. */
- if (info.osabi == GDB_OSABI_LINUX)
- tdep->find_global_pointer = generic_elf_find_global_pointer;
- else if (native_find_global_pointer != 0)
- tdep->find_global_pointer = native_find_global_pointer;
- else
- tdep->find_global_pointer = generic_elf_find_global_pointer;
+ tdep->sigcontext_register_address = 0;
/* Define the ia64 floating-point format to gdb. */
builtin_type_ia64_ext =
set_gdbarch_skip_prologue (gdbarch, ia64_skip_prologue);
- set_gdbarch_use_struct_convention (gdbarch, ia64_use_struct_convention);
+ set_gdbarch_deprecated_use_struct_convention (gdbarch, ia64_use_struct_convention);
set_gdbarch_extract_return_value (gdbarch, ia64_extract_return_value);
set_gdbarch_store_return_value (gdbarch, ia64_store_return_value);
set_gdbarch_memory_remove_breakpoint (gdbarch, ia64_memory_remove_breakpoint);
set_gdbarch_breakpoint_from_pc (gdbarch, ia64_breakpoint_from_pc);
set_gdbarch_read_pc (gdbarch, ia64_read_pc);
- if (info.osabi == GDB_OSABI_LINUX)
- set_gdbarch_write_pc (gdbarch, ia64_linux_write_pc);
- else
- set_gdbarch_write_pc (gdbarch, ia64_write_pc);
+ set_gdbarch_write_pc (gdbarch, ia64_write_pc);
/* Settings for calling functions in the inferior. */
set_gdbarch_push_dummy_call (gdbarch, ia64_push_dummy_call);
set_gdbarch_print_insn (gdbarch, ia64_print_insn);
set_gdbarch_convert_from_func_ptr_addr (gdbarch, ia64_convert_from_func_ptr_addr);
+ /* Hook in ABI-specific overrides, if they have been registered. */
+ gdbarch_init_osabi (info, gdbarch);
+
return gdbarch;
}
void
_initialize_ia64_tdep (void)
{
- register_gdbarch_init (bfd_arch_ia64, ia64_gdbarch_init);
+ gdbarch_register (bfd_arch_ia64, ia64_gdbarch_init, NULL);
}