Add "make pdf" and "make install-pdf", from Brooks Moses
[deliverable/binutils-gdb.git] / gdb / ia64-tdep.c
index ac43d26ad5632ccb89c3fb6a35fa46e7b32a115f..98ca406eb5fb2f7e7ba57ee5c6cdb45feb0581a7 100644 (file)
@@ -1,7 +1,7 @@
 /* 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"
@@ -40,6 +41,7 @@
 #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 */
@@ -324,7 +326,7 @@ ia64_dwarf_reg_to_regnum (int reg)
 }
 
 static int
-floatformat_valid (const struct floatformat *fmt, const char *from)
+floatformat_valid (const struct floatformat *fmt, const void *from)
 {
   return 1;
 }
@@ -335,6 +337,12 @@ const struct floatformat floatformat_ia64_ext =
   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''.  */
@@ -550,8 +558,9 @@ fetch_instruction (CORE_ADDR addr, instruction_type *it, long long *instr)
 #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;
@@ -574,7 +583,8 @@ ia64_memory_insert_breakpoint (CORE_ADDR addr, bfd_byte *contents_cache)
     }
 
   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);
@@ -583,8 +593,9 @@ ia64_memory_insert_breakpoint (CORE_ADDR addr, bfd_byte *contents_cache)
 }
 
 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;
@@ -603,7 +614,7 @@ ia64_memory_remove_breakpoint (CORE_ADDR addr, bfd_byte *contents_cache)
       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);
@@ -1544,7 +1555,7 @@ ia64_frame_cache (struct frame_info *next_frame, void **this_cache)
 
   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);
@@ -2455,8 +2466,8 @@ ia64_access_mem (unw_addr_space_t as,
 }
 
 /* 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;
 
@@ -2467,10 +2478,11 @@ getunwind_table (void *buf, size_t len)
      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 (&current_target, TARGET_OBJECT_UNWIND_TABLE, NULL,
-                          buf, 0, len);
 
-  return (int)x;
+  x = target_read_alloc (&current_target, TARGET_OBJECT_UNWIND_TABLE,
+                        NULL, buf_p);
+
+  return x;
 }
 
 /* Get the kernel unwind table.  */                             
@@ -2481,14 +2493,16 @@ get_kernel_table (unw_word_t ip, unw_dyn_info_t *di)
 
   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;
     }
@@ -2732,7 +2746,8 @@ ia64_libunwind_frame_this_id (struct frame_info *next_frame, void **this_cache,
      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);
@@ -2892,6 +2907,7 @@ ia64_libunwind_sigtramp_frame_prev_register (struct frame_info *next_frame,
                                             int *realnump, gdb_byte *valuep)
 
 {
+  gdb_byte buf[8];
   CORE_ADDR prev_ip, addr;
   int realnum, optimized;
   enum lval_type lval;
@@ -2900,7 +2916,8 @@ ia64_libunwind_sigtramp_frame_prev_register (struct frame_info *next_frame,
   /* 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)
     {
@@ -3024,7 +3041,8 @@ ia64_extract_return_value (struct type *type, struct regcache *regcache,
       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;
 
@@ -3297,6 +3315,17 @@ ia64_convert_from_func_ptr_addr (struct gdbarch *gdbarch, CORE_ADDR addr,
   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;
 }
 
@@ -3552,7 +3581,7 @@ ia64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   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
@@ -3562,7 +3591,7 @@ ia64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
      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);
@@ -3631,6 +3660,10 @@ ia64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   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);
 
This page took 0.026144 seconds and 4 git commands to generate.