/* Target-dependent code for the IA-64 for GDB, the GNU debugger.
- Copyright 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+ Copyright 1999, 2000, 2001, 2002, 2003, 2004 Free Software
+ Foundation, Inc.
This file is part of GDB.
#include "defs.h"
#include "inferior.h"
-#include "symfile.h" /* for entry_point_address */
#include "gdbcore.h"
#include "arch-utils.h"
#include "floatformat.h"
#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 "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
#define BUNDLE_LEN 16
-/* FIXME: These extern declarations should go in ia64-tdep.h. */
-extern CORE_ADDR ia64_linux_sigcontext_register_address (CORE_ADDR, int);
-extern CORE_ADDR ia64_aix_sigcontext_register_address (CORE_ADDR, int);
-extern unsigned long ia64_linux_getunwind_table (void *, size_t);
-
static gdbarch_init_ftype ia64_gdbarch_init;
static gdbarch_register_name_ftype ia64_register_name;
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_extract_struct_value_address_ftype ia64_extract_struct_value_address;
static gdbarch_use_struct_convention_ftype ia64_use_struct_convention;
static struct type *is_float_or_hfa_type (struct type *t);
};
-/* Read the given register from a sigcontext structure in the
- specified frame. */
-
-static CORE_ADDR
-read_sigcontext_register (struct frame_info *frame, int regnum)
-{
- CORE_ADDR regaddr;
-
- if (frame == NULL)
- internal_error (__FILE__, __LINE__,
- "read_sigcontext_register: NULL frame");
- if (!(get_frame_type (frame) == SIGTRAMP_FRAME))
- internal_error (__FILE__, __LINE__,
- "read_sigcontext_register: frame not a signal trampoline");
- if (SIGCONTEXT_REGISTER_ADDRESS == 0)
- internal_error (__FILE__, __LINE__,
- "read_sigcontext_register: SIGCONTEXT_REGISTER_ADDRESS is 0");
-
- regaddr = SIGCONTEXT_REGISTER_ADDRESS (get_frame_base (frame), regnum);
- if (regaddr)
- return read_memory_integer (regaddr, register_size (current_gdbarch, regnum));
- else
- internal_error (__FILE__, __LINE__,
- "read_sigcontext_register: Register %d not in struct sigcontext", regnum);
-}
-
/* Extract ``len'' bits from an instruction bundle starting at
bit ``from''. */
return breakpoint;
}
-static CORE_ADDR
-ia64_read_fp (void)
-{
- /* We won't necessarily have a frame pointer and even if we do, it
- winds up being extraordinarly messy when attempting to find the
- frame chain. So for the purposes of creating frames (which is
- all deprecated_read_fp() is used for), simply use the stack
- pointer value instead. */
- gdb_assert (SP_REGNUM >= 0);
- return read_register (SP_REGNUM);
-}
-
static CORE_ADDR
ia64_read_pc (ptid_t ptid)
{
return pc_value | (slot_num * SLOT_MULTIPLIER);
}
-static void
+void
ia64_write_pc (CORE_ADDR new_pc, ptid_t ptid)
{
int slot_num = (int) (new_pc & 0xf) / SLOT_MULTIPLIER;
used with no further scanning in the event that the function is
frameless. */
+/* FIXME: cagney/2004-02-14: This function and logic have largely been
+ superseded by skip_prologue_using_sal. */
+
static CORE_ADDR
refine_prologue_limit (CORE_ADDR pc, CORE_ADDR lim_pc, int *trust_limit)
{
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 */
(*this_id) = frame_id_build_special (cache->base, cache->pc, cache->bsp);
if (gdbarch_debug >= 1)
fprintf_unfiltered (gdb_stdlog,
- "regular frame id: code %lx, stack %lx, special %lx, next_frame %p\n",
- this_id->code_addr, this_id->stack_addr, cache->bsp, next_frame);
+ "regular frame id: code 0x%s, stack 0x%s, special 0x%s, next_frame %p\n",
+ paddr_nz (this_id->code_addr),
+ paddr_nz (this_id->stack_addr),
+ paddr_nz (cache->bsp), next_frame);
}
static void
if (gdbarch_debug >= 1)
fprintf_unfiltered (gdb_stdlog,
- "regular prev register <%d> <%s> is %lx\n", regnum,
+ "regular prev register <%d> <%s> is 0x%s\n", regnum,
(((unsigned) regnum <= IA64_NAT127_REGNUM)
- ? ia64_register_names[regnum] : "r??"), extract_unsigned_integer (valuep, 8));
+ ? ia64_register_names[regnum] : "r??"),
+ paddr_nz (extract_unsigned_integer (valuep, 8)));
}
static const struct frame_unwind ia64_frame_unwind =
(*this_id) = frame_id_build_special (cache->base, frame_pc_unwind (next_frame), cache->bsp);
if (gdbarch_debug >= 1)
fprintf_unfiltered (gdb_stdlog,
- "sigtramp frame id: code %lx, stack %lx, special %lx, next_frame %p\n",
- this_id->code_addr, this_id->stack_addr, cache->bsp, next_frame);
+ "sigtramp frame id: code 0x%s, stack 0x%s, special 0x%s, next_frame %p\n",
+ paddr_nz (this_id->code_addr),
+ paddr_nz (this_id->stack_addr),
+ paddr_nz (cache->bsp), next_frame);
}
static void
if (gdbarch_debug >= 1)
fprintf_unfiltered (gdb_stdlog,
- "sigtramp prev register <%s> is %lx\n",
+ "sigtramp prev register <%s> is 0x%s\n",
(((unsigned) regnum <= IA64_NAT127_REGNUM)
- ? ia64_register_names[regnum] : "r??"), extract_unsigned_integer (valuep, 8));
+ ? ia64_register_names[regnum] : "r??"),
+ paddr_nz (extract_unsigned_integer (valuep, 8)));
}
static const struct frame_unwind ia64_sigtramp_frame_unwind =
CORE_ADDR pc = frame_pc_unwind (next_frame);
find_pc_partial_function (pc, &name, NULL, NULL);
- if (PC_IN_SIGTRAMP (pc, name))
+ if (legacy_pc_in_sigtramp (pc, name))
return &ia64_sigtramp_frame_unwind;
return NULL;
}
if (gdbarch_debug >= 1)
fprintf_unfiltered (gdb_stdlog,
- " access_reg: to cache: %4s=%016lx\n",
+ " access_reg: to cache: %4s=0x%s\n",
(((unsigned) regnum <= IA64_NAT127_REGNUM)
- ? ia64_register_names[regnum] : "r??"), *val);
+ ? ia64_register_names[regnum] : "r??"),
+ paddr_nz (*val));
}
else
{
if (gdbarch_debug >= 1)
fprintf_unfiltered (gdb_stdlog,
- " access_reg: from cache: %4s=%016lx\n",
+ " access_reg: from cache: %4s=0x%s\n",
(((unsigned) regnum <= IA64_NAT127_REGNUM)
- ? ia64_register_names[regnum] : "r??"), *val);
+ ? ia64_register_names[regnum] : "r??"),
+ paddr_nz (*val));
}
return 0;
}
if (gdbarch_debug >= 1)
fprintf_unfiltered (gdb_stdlog, "get_kernel_table: found table `%s': "
- "segbase=%lx, length=%lu, gp=%lx\n",
- (char *) di->u.ti.name_ptr, di->u.ti.segbase,
- di->u.ti.table_len, di->gp);
+ "segbase=0x%s, length=%s, gp=0x%s\n",
+ (char *) di->u.ti.name_ptr,
+ paddr_nz (di->u.ti.segbase),
+ paddr_u (di->u.ti.table_len),
+ paddr_nz (di->gp));
return 0;
}
return -UNW_ENOINFO;
if (gdbarch_debug >= 1)
- fprintf_unfiltered (gdb_stdlog, "ia64_find_proc_info_x: %lx -> "
- "(name=`%s',segbase=%lx,start=%lx,end=%lx,gp=%lx,"
- "length=%lu,data=%p)\n",
- ip, (char *)di.u.ti.name_ptr,
- di.u.ti.segbase, di.start_ip, di.end_ip,
- di.gp, di.u.ti.table_len, di.u.ti.table_data);
+ fprintf_unfiltered (gdb_stdlog, "ia64_find_proc_info_x: 0x%s -> "
+ "(name=`%s',segbase=0x%s,start=0x%s,end=0x%s,gp=0x%s,"
+ "length=%s,data=0x%s)\n",
+ paddr_nz (ip), (char *)di.u.ti.name_ptr,
+ paddr_nz (di.u.ti.segbase),
+ paddr_nz (di.start_ip), paddr_nz (di.end_ip),
+ paddr_nz (di.gp),
+ paddr_u (di.u.ti.table_len),
+ paddr_nz ((CORE_ADDR)di.u.ti.table_data));
}
else
{
return ret;
if (gdbarch_debug >= 1)
- fprintf_unfiltered (gdb_stdlog, "ia64_find_proc_info_x: %lx -> "
- "(name=`%s',segbase=%lx,start=%lx,end=%lx,gp=%lx,"
- "length=%lu,data=%lx)\n",
- ip, (char *)di.u.rti.name_ptr,
- di.u.rti.segbase, di.start_ip, di.end_ip,
- di.gp, di.u.rti.table_len, di.u.rti.table_data);
+ fprintf_unfiltered (gdb_stdlog, "ia64_find_proc_info_x: 0x%s -> "
+ "(name=`%s',segbase=0x%s,start=0x%s,end=0x%s,gp=0x%s,"
+ "length=%s,data=0x%s)\n",
+ paddr_nz (ip), (char *)di.u.rti.name_ptr,
+ paddr_nz (di.u.rti.segbase),
+ paddr_nz (di.start_ip), paddr_nz (di.end_ip),
+ paddr_nz (di.gp),
+ paddr_u (di.u.rti.table_len),
+ paddr_nz (di.u.rti.table_data));
}
ret = libunwind_search_unwind_table (&as, ip, &di, pi, need_unwind_info,
if (gdbarch_debug >= 1)
fprintf_unfiltered (gdb_stdlog,
"dynamic unwind table in objfile %s "
- "at %lx (gp=%lx)\n",
+ "at 0x%s (gp=0x%s)\n",
bfd_get_filename (objfile->obfd),
- addr, di.gp);
+ paddr_nz (addr), paddr_nz (di.gp));
*dilap = addr;
return 0;
}
if (gdbarch_debug >= 1)
fprintf_unfiltered (gdb_stdlog,
- "libunwind frame id: code %lx, stack %lx, special %lx, next_frame %p\n",
- id.code_addr, id.stack_addr, bsp, next_frame);
+ "libunwind frame id: code 0x%s, stack 0x%s, special 0x%s, next_frame %p\n",
+ paddr_nz (id.code_addr), paddr_nz (id.stack_addr),
+ paddr_nz (bsp), next_frame);
}
static void
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;
if (gdbarch_debug >= 1)
fprintf_unfiltered (gdb_stdlog,
- "libunwind prev register <%s> is %lx\n",
+ "libunwind prev register <%s> is 0x%s\n",
(((unsigned) regnum <= IA64_NAT127_REGNUM)
- ? ia64_register_names[regnum] : "r??"), extract_unsigned_integer (valuep, 8));
+ ? ia64_register_names[regnum] : "r??"),
+ paddr_nz (extract_unsigned_integer (valuep, 8)));
}
static const struct frame_unwind ia64_libunwind_frame_unwind =
#endif /* HAVE_LIBUNWIND_IA64_H */
-/* Should we use EXTRACT_STRUCT_VALUE_ADDRESS instead of
- EXTRACT_RETURN_VALUE? GCC_P is true if compiled with gcc
- and TYPE is the type (which is known to be struct, union or array). */
+/* Should we use DEPRECATED_EXTRACT_STRUCT_VALUE_ADDRESS instead of
+ EXTRACT_RETURN_VALUE? GCC_P is true if compiled with gcc and TYPE
+ is the type (which is known to be struct, union or array). */
int
ia64_use_struct_convention (int gcc_p, struct type *type)
{
}
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;
if (gdbarch_debug >= 1)
fprintf_unfiltered (gdb_stdlog,
- "dummy frame id: code %lx, stack %lx, special %lx\n",
- frame_pc_unwind (next_frame), sp, bsp);
+ "dummy frame id: code 0x%s, stack 0x%s, special 0x%s\n",
+ paddr_nz (frame_pc_unwind (next_frame)),
+ paddr_nz (sp), paddr_nz (bsp));
return frame_id_build_special (sp, frame_pc_unwind (next_frame), bsp);
}
*targ_len = nr_bytes;
}
-static void
-process_note_abi_tag_sections (bfd *abfd, asection *sect, void *obj)
-{
- int *os_ident_ptr = obj;
- const char *name;
- unsigned int sectsize;
-
- name = bfd_get_section_name (abfd, sect);
- sectsize = bfd_section_size (abfd, sect);
- if (strcmp (name, ".note.ABI-tag") == 0 && sectsize > 0)
- {
- unsigned int name_length, data_length, note_type;
- char *note = alloca (sectsize);
-
- bfd_get_section_contents (abfd, sect, note,
- (file_ptr) 0, (bfd_size_type) sectsize);
-
- name_length = bfd_h_get_32 (abfd, note);
- data_length = bfd_h_get_32 (abfd, note + 4);
- note_type = bfd_h_get_32 (abfd, note + 8);
-
- if (name_length == 4 && data_length == 16 && note_type == 1
- && strcmp (note + 12, "GNU") == 0)
- {
- int os_number = bfd_h_get_32 (abfd, note + 16);
-
- /* The case numbers are from abi-tags in glibc. */
- switch (os_number)
- {
- case 0 :
- *os_ident_ptr = ELFOSABI_LINUX;
- break;
- case 1 :
- *os_ident_ptr = ELFOSABI_HURD;
- break;
- case 2 :
- *os_ident_ptr = ELFOSABI_SOLARIS;
- break;
- default :
- internal_error (__FILE__, __LINE__,
- "process_note_abi_sections: unknown OS number %d", os_number);
- break;
- }
- }
- }
-}
-
static int
ia64_print_insn (bfd_vma memaddr, struct disassemble_info *info)
{
set_gdbarch_extract_return_value (gdbarch, ia64_extract_return_value);
set_gdbarch_store_return_value (gdbarch, ia64_store_return_value);
- set_gdbarch_extract_struct_value_address (gdbarch, ia64_extract_struct_value_address);
+ set_gdbarch_deprecated_extract_struct_value_address (gdbarch, ia64_extract_struct_value_address);
set_gdbarch_memory_insert_breakpoint (gdbarch, ia64_memory_insert_breakpoint);
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);
- set_gdbarch_write_pc (gdbarch, ia64_write_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);
/* Settings for calling functions in the inferior. */
set_gdbarch_push_dummy_call (gdbarch, ia64_push_dummy_call);
/* Settings that should be unnecessary. */
set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
- set_gdbarch_decr_pc_after_break (gdbarch, 0);
- set_gdbarch_function_start_offset (gdbarch, 0);
- set_gdbarch_frame_args_skip (gdbarch, 0);
-
set_gdbarch_remote_translate_xfer_address (
gdbarch, ia64_remote_translate_xfer_address);