2002-11-18 Andrew Cagney <ac131313@redhat.com>
[deliverable/binutils-gdb.git] / gdb / cris-tdep.c
index d3376b5ae6ad90d26ce26f517a2b78f192dbe9c6..d3325f037581e2e9bbd4c847f3ea63cc3a8c9e43 100644 (file)
@@ -35,6 +35,11 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 /* To get entry_point_address.  */
 #include "symfile.h"
 
+#include "solib.h"              /* Support for shared libraries. */
+#include "solib-svr4.h"         /* For struct link_map_offsets.  */
+#include "gdb_string.h"
+
+
 enum cris_num_regs
 {
   /* There are no floating point registers.  Used in gdbserver low-linux.c.  */
@@ -387,7 +392,7 @@ static CORE_ADDR bfd_lookup_symbol (bfd *, const char *);
 
    CORE_ADDR frame
    CORE_ADDR pc
-   int signal_handler_caller
+   enum frame_type type;
    CORE_ADDR return_pc
    int leaf_function
 
@@ -400,8 +405,9 @@ static CORE_ADDR bfd_lookup_symbol (bfd *, const char *);
    of the register PC.  All other frames contain the content of the
    register PC in the next frame.
 
-   The variable signal_handler_caller is non-zero when the frame is
-   associated with the call of a signal handler.
+   The variable `type' indicates the frame's type: normal, SIGTRAMP
+   (associated with a signal handler), dummy (associated with a dummy
+   frame).
 
    The variable return_pc contains the address where execution should be
    resumed when the present frame has finished, the return address.
@@ -512,7 +518,10 @@ cris_examine (CORE_ADDR ip, CORE_ADDR limit, struct frame_info *fi,
           insn_next = read_memory_unsigned_integer (ip, sizeof (short));
           ip += sizeof (short);
           regno = cris_get_operand2 (insn_next);
-          if (regno == (SRP_REGNUM - NUM_GENREGS))
+
+          /* This check, meant to recognize srp, used to be regno == 
+             (SRP_REGNUM - NUM_GENREGS), but that covers r11 also.  */
+          if (insn_next == 0xBE7E)
             {
               if (frameless_p)
                 {
@@ -755,7 +764,7 @@ cris_skip_prologue_main (CORE_ADDR pc, int frameless_p)
    adjusts pcptr (if necessary) to point to the actual memory location where
    the breakpoint should be inserted.  */
 
-unsigned char *
+const unsigned char *
 cris_breakpoint_from_pc (CORE_ADDR *pcptr, int *lenptr)
 {
   static unsigned char break_insn[] = {0x38, 0xe9};
@@ -767,8 +776,8 @@ cris_breakpoint_from_pc (CORE_ADDR *pcptr, int *lenptr)
 /* Returns the register SRP (subroutine return pointer) which must contain 
    the content of the register PC after a function call.  */
 
-CORE_ADDR
-cris_saved_pc_after_call ()
+static CORE_ADDR
+cris_saved_pc_after_call (struct frame_info *frame)
 {
   return read_register (SRP_REGNUM);
 }
@@ -964,7 +973,7 @@ cris_abi_original_store_return_value (struct type *type, char *valbuf)
   int len = TYPE_LENGTH (type);
   
   if (len <= REGISTER_SIZE) 
-    write_register_bytes (REGISTER_BYTE (RET_REGNUM), valbuf, len);
+    deprecated_write_register_bytes (REGISTER_BYTE (RET_REGNUM), valbuf, len);
   else
     internal_error (__FILE__, __LINE__, "cris_abi_original_store_return_value: type length too large.");
 }
@@ -979,7 +988,8 @@ cris_abi_v2_store_return_value (struct type *type, char *valbuf)
   if (len <= 2 * REGISTER_SIZE)
     {
       /* Note that this works since R10 and R11 are consecutive registers.  */
-      write_register_bytes (REGISTER_BYTE (RET_REGNUM), valbuf, len);
+      deprecated_write_register_bytes (REGISTER_BYTE (RET_REGNUM), valbuf,
+                                      len);
     }
   else
     internal_error (__FILE__, __LINE__, "cris_abi_v2_store_return_value: type length too large.");
@@ -988,7 +998,7 @@ cris_abi_v2_store_return_value (struct type *type, char *valbuf)
 /* Return the name of register regno as a string. Return NULL for an invalid or
    unimplemented register.  */
 
-char *
+const char *
 cris_register_name (int regno)
 {
   static char *cris_genreg_names[] =
@@ -1131,7 +1141,7 @@ cris_abi_v2_reg_struct_has_addr (int gcc_p, struct type *type)
 int
 cris_frameless_function_invocation (struct frame_info *fi)
 {
-  if (fi->signal_handler_caller)
+  if ((get_frame_type (fi) == SIGTRAMP_FRAME))
     return 0;
   else
     return frameless_look_for_prologue (fi);
@@ -1148,7 +1158,7 @@ cris_frame_init_saved_regs (struct frame_info *fi)
   CORE_ADDR ip;
   struct symtab_and_line sal;
   int best_limit;
-  char *dummy_regs = generic_find_dummy_frame (fi->pc, fi->frame);
+  char *dummy_regs = deprecated_generic_find_dummy_frame (fi->pc, fi->frame);
   
   /* Examine the entire prologue.  */
   register int frameless_p = 0; 
@@ -1207,9 +1217,10 @@ cris_init_extra_frame_info (int fromleaf, struct frame_info *fi)
     {    
       /* We need to setup fi->frame here because run_stack_dummy gets it wrong
          by assuming it's always FP.  */
-      fi->frame = generic_read_register_dummy (fi->pc, fi->frame, SP_REGNUM);
+      fi->frame = deprecated_read_register_dummy (fi->pc, fi->frame,
+                                                 SP_REGNUM);
       fi->extra_info->return_pc = 
-        generic_read_register_dummy (fi->pc, fi->frame, PC_REGNUM);
+        deprecated_read_register_dummy (fi->pc, fi->frame, PC_REGNUM);
 
       /* FIXME: Is this necessarily true?  */
       fi->extra_info->leaf_function = 0;
@@ -1513,7 +1524,7 @@ cris_push_return_address (CORE_ADDR pc, CORE_ADDR sp)
    all saved registers.  */
 
 void 
-cris_pop_frame ()
+cris_pop_frame (void)
 {
   register struct frame_info *fi = get_current_frame ();
   register int regno;
@@ -3555,6 +3566,307 @@ cris_delayed_get_disassembler (bfd_vma addr, disassemble_info *info)
   return TARGET_PRINT_INSN (addr, info);
 }
 
+/* Copied from <asm/elf.h>.  */
+typedef unsigned long elf_greg_t;
+
+/* Same as user_regs_struct struct in <asm/user.h>.  */
+typedef elf_greg_t elf_gregset_t[35];
+
+/* Unpack an elf_gregset_t into GDB's register cache.  */
+
+void 
+supply_gregset (elf_gregset_t *gregsetp)
+{
+  int i;
+  elf_greg_t *regp = *gregsetp;
+  static char zerobuf[4] = {0};
+
+  /* The kernel dumps all 32 registers as unsigned longs, but supply_register
+     knows about the actual size of each register so that's no problem.  */
+  for (i = 0; i < NUM_GENREGS + NUM_SPECREGS; i++)
+    {
+      supply_register (i, (char *)&regp[i]);
+    }
+}
+
+/*  Use a local version of this function to get the correct types for
+    regsets, until multi-arch core support is ready.  */
+
+static void
+fetch_core_registers (char *core_reg_sect, unsigned core_reg_size,
+                      int which, CORE_ADDR reg_addr)
+{
+  elf_gregset_t gregset;
+
+  switch (which)
+    {
+    case 0:
+      if (core_reg_size != sizeof (gregset))
+        {
+          warning ("wrong size gregset struct in core file");
+        }
+      else
+        {
+          memcpy (&gregset, core_reg_sect, sizeof (gregset));
+          supply_gregset (&gregset);
+        }
+
+    default:
+      /* We've covered all the kinds of registers we know about here,
+         so this must be something we wouldn't know what to do with
+         anyway.  Just ignore it.  */
+      break;
+    }
+}
+
+static struct core_fns cris_elf_core_fns =
+{
+  bfd_target_elf_flavour,               /* core_flavour */
+  default_check_format,                 /* check_format */
+  default_core_sniffer,                 /* core_sniffer */
+  fetch_core_registers,                 /* core_read_registers */
+  NULL                                  /* next */
+};
+
+/* Fetch (and possibly build) an appropriate link_map_offsets
+   structure for native GNU/Linux CRIS targets using the struct
+   offsets defined in link.h (but without actual reference to that
+   file).
+
+   This makes it possible to access GNU/Linux CRIS shared libraries
+   from a GDB that was not built on an GNU/Linux CRIS host (for cross
+   debugging).
+
+   See gdb/solib-svr4.h for an explanation of these fields.  */
+
+struct link_map_offsets *
+cris_linux_svr4_fetch_link_map_offsets (void)
+{ 
+  static struct link_map_offsets lmo;
+  static struct link_map_offsets *lmp = NULL;
+
+  if (lmp == NULL)
+    { 
+      lmp = &lmo;
+
+      lmo.r_debug_size = 8;    /* The actual size is 20 bytes, but
+                                  this is all we need.  */
+      lmo.r_map_offset = 4;
+      lmo.r_map_size   = 4;
+
+      lmo.link_map_size = 20;
+
+      lmo.l_addr_offset = 0;
+      lmo.l_addr_size   = 4;
+
+      lmo.l_name_offset = 4;
+      lmo.l_name_size   = 4;
+
+      lmo.l_next_offset = 12;
+      lmo.l_next_size   = 4;
+
+      lmo.l_prev_offset = 16;
+      lmo.l_prev_size   = 4;
+    }
+
+  return lmp;
+}
+
+static void
+cris_fpless_backtrace (char *noargs, int from_tty)
+{
+  /* Points at the instruction after the jsr (except when in innermost frame
+     where it points at the original pc).  */
+  CORE_ADDR pc = 0;
+
+  /* Temporary variable, used for parsing from the start of the function that
+     the pc is in, up to the pc.  */
+  CORE_ADDR tmp_pc = 0;
+  CORE_ADDR sp = 0;
+
+  /* Information about current frame.  */
+  struct symtab_and_line sal;
+  char* func_name;
+
+  /* Present instruction.  */
+  unsigned short insn;
+  
+  /* Next instruction, lookahead.  */
+  unsigned short insn_next; 
+
+  /* This is to store the offset between sp at start of function and until we
+     reach push srp (if any).  */
+  int sp_add_later = 0;
+  int push_srp_found = 0;
+
+  int val = 0;
+
+  /* Frame counter.  */
+  int frame = 0;
+
+  /* For the innermost frame, we want to look at srp in case it's a leaf
+     function (since there's no push srp in that case).  */
+  int innermost_frame = 1;
+  
+  deprecated_read_register_gen (PC_REGNUM, (char *) &pc);
+  deprecated_read_register_gen (SP_REGNUM, (char *) &sp);
+  
+  /* We make an explicit return when we can't find an outer frame.  */
+  while (1)
+    {
+      /* Get file name and line number.  */
+      sal = find_pc_line (pc, 0);
+
+      /* Get function name.  */
+      find_pc_partial_function (pc, &func_name, (CORE_ADDR *) NULL,
+                                (CORE_ADDR *) NULL);
+
+      /* Print information about current frame.  */
+      printf_unfiltered ("#%i  0x%08lx in %s", frame++, pc, func_name);
+      if (sal.symtab)
+        {    
+          printf_unfiltered (" at %s:%i", sal.symtab->filename, sal.line);
+        }
+      printf_unfiltered ("\n");
+      
+      /* Get the start address of this function.  */
+      tmp_pc = get_pc_function_start (pc);
+  
+      /* Mini parser, only meant to find push sp and sub ...,sp from the start
+         of the function, up to the pc.  */
+      while (tmp_pc < pc)
+        {
+          insn = read_memory_unsigned_integer (tmp_pc, sizeof (short));
+          tmp_pc += sizeof (short);
+          if (insn == 0xE1FC)
+            {
+              /* push <reg> 32 bit instruction */
+              insn_next = read_memory_unsigned_integer (tmp_pc, 
+                                                        sizeof (short));
+              tmp_pc += sizeof (short);
+
+              /* Recognize srp.  */
+              if (insn_next == 0xBE7E)
+                {
+                  /* For subsequent (not this one though) push or sub which
+                     affects sp, adjust sp immediately.  */
+                  push_srp_found = 1;
+
+                  /* Note: this will break if we ever encounter a 
+                     push vr (1 byte) or push ccr (2 bytes).  */
+                  sp_add_later += 4;
+                }
+              else
+                {
+                  /* Some other register was pushed.  */
+                  if (push_srp_found)
+                    {    
+                      sp += 4;
+                    }
+                  else
+                    {
+                      sp_add_later += 4;
+                    }
+                }
+            }
+          else if (cris_get_operand2 (insn) == SP_REGNUM 
+                   && cris_get_mode (insn) == 0x0000
+                   && cris_get_opcode (insn) == 0x000A)
+            {
+              /* subq <val>,sp */
+              val = cris_get_quick_value (insn);
+
+              if (push_srp_found)
+                {
+                  sp += val;
+                }
+              else
+                {
+                  sp_add_later += val;
+                }
+              
+            }
+          else if (cris_get_operand2 (insn) == SP_REGNUM
+                   /* Autoincrement addressing mode.  */
+                   && cris_get_mode (insn) == 0x0003
+                   /* Opcode.  */
+                   && ((insn) & 0x03E0) >> 5 == 0x0004)
+            {
+              /* subu <val>,sp */
+              val = get_data_from_address (&insn, tmp_pc);
+
+              if (push_srp_found)
+                {
+                  sp += val;
+                }
+              else
+                {
+                  sp_add_later += val;
+                }
+            }
+          else if (cris_get_operand2 (insn) == SP_REGNUM
+                   && ((insn & 0x0F00) >> 8) == 0x0001
+                   && (cris_get_signed_offset (insn) < 0))
+            {
+              /* Immediate byte offset addressing prefix word with sp as base 
+                 register.  Used for CRIS v8 i.e. ETRAX 100 and newer if <val> 
+                 is between 64 and 128. 
+                 movem r<regsave>,[sp=sp-<val>] */
+              val = -cris_get_signed_offset (insn);
+              insn_next = read_memory_unsigned_integer (tmp_pc, 
+                                                        sizeof (short));
+              tmp_pc += sizeof (short);
+              
+              if (cris_get_mode (insn_next) == PREFIX_ASSIGN_MODE
+                  && cris_get_opcode (insn_next) == 0x000F
+                  && cris_get_size (insn_next) == 0x0003
+                  && cris_get_operand1 (insn_next) == SP_REGNUM)
+                {             
+                  if (push_srp_found)
+                    {
+                      sp += val;
+                    }
+                  else
+                    {
+                      sp_add_later += val;
+                    }
+                }
+            }
+        }
+      
+      if (push_srp_found)
+        {
+          /* Reset flag.  */
+          push_srp_found = 0;
+
+          /* sp should now point at where srp is stored on the stack.  Update
+             the pc to the srp.  */
+          pc = read_memory_unsigned_integer (sp, 4);
+        }
+      else if (innermost_frame)
+        {
+          /* We couldn't find a push srp in the prologue, so this must be
+             a leaf function, and thus we use the srp register directly.
+             This should happen at most once, for the innermost function.  */
+          deprecated_read_register_gen (SRP_REGNUM, (char *) &pc);
+        }
+      else
+        {
+          /* Couldn't find an outer frame.  */
+          return;
+        }
+
+      /* Reset flag.  (In case the innermost frame wasn't a leaf, we don't
+         want to look at the srp register later either).  */
+      innermost_frame = 0;
+
+      /* Now, add the offset for everything up to, and including push srp,
+         that was held back during the prologue parsing.  */ 
+      sp += sp_add_later;
+      sp_add_later = 0;
+    }
+}
+
 void
 _initialize_cris_tdep (void)
 {
@@ -3569,20 +3881,28 @@ _initialize_cris_tdep (void)
   c = add_set_cmd ("cris-version", class_support, var_integer, 
                    (char *) &usr_cmd_cris_version, 
                    "Set the current CRIS version.", &setlist);
-  c->function.sfunc = cris_version_update;
+  set_cmd_sfunc (c, cris_version_update);
   add_show_from_set (c, &showlist);
   
   c = add_set_enum_cmd ("cris-mode", class_support, cris_mode_enums, 
                         &usr_cmd_cris_mode, 
                         "Set the current CRIS mode.", &setlist);
-  c->function.sfunc = cris_mode_update;
+  set_cmd_sfunc (c, cris_mode_update);
   add_show_from_set (c, &showlist);
 
   c = add_set_enum_cmd ("cris-abi", class_support, cris_abi_enums, 
                         &usr_cmd_cris_abi, 
                         "Set the current CRIS ABI version.", &setlist);
-  c->function.sfunc = cris_abi_update;
+  set_cmd_sfunc (c, cris_abi_update);
   add_show_from_set (c, &showlist);
+
+  c = add_cmd ("cris-fpless-backtrace", class_support, cris_fpless_backtrace, 
+               "Display call chain using the subroutine return pointer.\n"
+               "Note that this displays the address after the jump to the "
+               "subroutine.", &cmdlist);
+  
+  add_core_fns (&cris_elf_core_fns);
+  
 }
 
 /* Prints out all target specific values.  */
@@ -3609,13 +3929,22 @@ cris_version_update (char *ignore_args, int from_tty,
 {
   struct gdbarch_info info;
 
+  /* NOTE: cagney/2002-03-17: The add_show_from_set() function clones
+     the set command passed as a parameter.  The clone operation will
+     include (BUG?) any ``set'' command callback, if present.
+     Commands like ``info set'' call all the ``show'' command
+     callbacks.  Unfortunatly, for ``show'' commands cloned from
+     ``set'', this includes callbacks belonging to ``set'' commands.
+     Making this worse, this only occures if add_show_from_set() is
+     called after add_cmd_sfunc() (BUG?).  */
+
   /* From here on, trust the user's CRIS version setting.  */
-  if (c->type == set_cmd)
+  if (cmd_type (c) == set_cmd)
     {
       usr_cmd_cris_version_valid = 1;
   
       /* Update the current architecture, if needed.  */
-      memset (&info, 0, sizeof info);
+      gdbarch_info_init (&info);
       if (!gdbarch_update_p (info))
         internal_error (__FILE__, __LINE__, "cris_gdbarch_update: failed to update architecture.");
     }  
@@ -3627,13 +3956,22 @@ cris_mode_update (char *ignore_args, int from_tty,
 {
   struct gdbarch_info info;
   
+  /* NOTE: cagney/2002-03-17: The add_show_from_set() function clones
+     the set command passed as a parameter.  The clone operation will
+     include (BUG?) any ``set'' command callback, if present.
+     Commands like ``info set'' call all the ``show'' command
+     callbacks.  Unfortunatly, for ``show'' commands cloned from
+     ``set'', this includes callbacks belonging to ``set'' commands.
+     Making this worse, this only occures if add_show_from_set() is
+     called after add_cmd_sfunc() (BUG?).  */
+
   /* From here on, trust the user's CRIS mode setting.  */
-  if (c->type == set_cmd)
+  if (cmd_type (c) == set_cmd)
     {
       usr_cmd_cris_mode_valid = 1;
   
       /* Update the current architecture, if needed.  */
-      memset (&info, 0, sizeof info);
+      gdbarch_info_init (&info);
       if (!gdbarch_update_p (info))
         internal_error (__FILE__, __LINE__, "cris_gdbarch_update: failed to update architecture.");
     }
@@ -3645,13 +3983,22 @@ cris_abi_update (char *ignore_args, int from_tty,
 {
   struct gdbarch_info info;
   
+  /* NOTE: cagney/2002-03-17: The add_show_from_set() function clones
+     the set command passed as a parameter.  The clone operation will
+     include (BUG?) any ``set'' command callback, if present.
+     Commands like ``info set'' call all the ``show'' command
+     callbacks.  Unfortunatly, for ``show'' commands cloned from
+     ``set'', this includes callbacks belonging to ``set'' commands.
+     Making this worse, this only occures if add_show_from_set() is
+     called after add_cmd_sfunc() (BUG?).  */
+
   /* From here on, trust the user's CRIS ABI setting.  */
-  if (c->type == set_cmd)
+  if (cmd_type (c) == set_cmd)
     {
       usr_cmd_cris_abi_valid = 1;
   
       /* Update the current architecture, if needed.  */
-      memset (&info, 0, sizeof info);
+      gdbarch_info_init (&info);
       if (!gdbarch_update_p (info))
         internal_error (__FILE__, __LINE__, "cris_gdbarch_update: failed to update architecture.");
     }
@@ -3757,17 +4104,19 @@ cris_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
           cris_abi = CRIS_ABI_V2;
         }
     }
-  else if (gdbarch_tdep (current_gdbarch))
+  else if (arches != NULL)
     {
-      /* No bfd available.  Stick with whatever ABI we're currently using.  
-         (This is to avoid changing the ABI when the user updates the 
-         architecture with the 'set cris-version' command.)  */
-      cris_abi = gdbarch_tdep (current_gdbarch)->cris_abi;
+      /* No bfd available.  Stick with the ABI from the most recently
+         selected architecture of this same family (the head of arches
+         always points to this).  (This is to avoid changing the ABI
+         when the user updates the architecture with the 'set
+         cris-version' command.)  */
+      cris_abi = gdbarch_tdep (arches->gdbarch)->cris_abi;
     }
   else
     {
-      /* No bfd, and no current architecture available.  Assume it's the 
-         new ABI.  */
+      /* No bfd, and no previously selected architecture available.
+         Assume it's the new ABI.  */
       cris_abi = CRIS_ABI_V2;
     }
 
@@ -3803,7 +4152,7 @@ cris_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
       /* Ok.  */
       break;
 
-    case BIG_ENDIAN:
+    case BFD_ENDIAN_BIG:
       internal_error (__FILE__, __LINE__, "cris_gdbarch_init: big endian byte order in info");
       break;
     
@@ -3816,9 +4165,9 @@ cris_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
     {
       set_gdbarch_double_bit (gdbarch, 32);
       set_gdbarch_push_arguments (gdbarch, cris_abi_original_push_arguments);
-      set_gdbarch_store_return_value (gdbarch, 
+      set_gdbarch_deprecated_store_return_value (gdbarch, 
                                       cris_abi_original_store_return_value);
-      set_gdbarch_extract_return_value 
+      set_gdbarch_deprecated_extract_return_value 
         (gdbarch, cris_abi_original_extract_return_value);
       set_gdbarch_reg_struct_has_addr 
         (gdbarch, cris_abi_original_reg_struct_has_addr);
@@ -3827,9 +4176,9 @@ cris_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
     {
       set_gdbarch_double_bit (gdbarch, 64);
       set_gdbarch_push_arguments (gdbarch, cris_abi_v2_push_arguments);
-      set_gdbarch_store_return_value (gdbarch, cris_abi_v2_store_return_value);
-      set_gdbarch_extract_return_value (gdbarch, 
-                                        cris_abi_v2_extract_return_value);
+      set_gdbarch_deprecated_store_return_value (gdbarch, cris_abi_v2_store_return_value);
+      set_gdbarch_deprecated_extract_return_value
+       (gdbarch, cris_abi_v2_extract_return_value);
       set_gdbarch_reg_struct_has_addr (gdbarch, 
                                        cris_abi_v2_reg_struct_has_addr);
     }
@@ -3840,9 +4189,6 @@ cris_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
      which means we have to set this explicitly.  */
   set_gdbarch_long_double_bit (gdbarch, 64);
     
-  /* Floating point is IEEE compatible.  */
-  set_gdbarch_ieee_float (gdbarch, 1);
-
   /* There are 32 registers (some of which may not be implemented).  */
   set_gdbarch_num_regs (gdbarch, 32);
   set_gdbarch_sp_regnum (gdbarch, 14);
@@ -3945,7 +4291,7 @@ cris_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   set_gdbarch_call_dummy_stack_adjust_p (gdbarch, 0);
   set_gdbarch_fix_call_dummy (gdbarch, generic_fix_call_dummy);
 
-  set_gdbarch_get_saved_register (gdbarch, generic_get_saved_register);
+  set_gdbarch_get_saved_register (gdbarch, deprecated_generic_get_saved_register);
   
   /* No register requires conversion from raw format to virtual format.  */
   set_gdbarch_register_convertible (gdbarch, generic_register_convertible_not);
@@ -3955,8 +4301,8 @@ cris_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   set_gdbarch_pop_frame (gdbarch, cris_pop_frame);
 
   set_gdbarch_store_struct_return (gdbarch, cris_store_struct_return);
-  set_gdbarch_extract_struct_value_address (gdbarch, 
-                                            cris_extract_struct_value_address);
+  set_gdbarch_deprecated_extract_struct_value_address
+    (gdbarch, cris_extract_struct_value_address);
   set_gdbarch_use_struct_convention (gdbarch, cris_use_struct_convention);
 
   set_gdbarch_frame_init_saved_regs (gdbarch, cris_frame_init_saved_regs);
@@ -3997,5 +4343,9 @@ cris_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   /* Helpful for backtracing and returning in a call dummy.  */
   set_gdbarch_save_dummy_frame_tos (gdbarch, generic_save_dummy_frame_tos);
 
+  /* Use target_specific function to define link map offsets.  */
+  set_solib_svr4_fetch_link_map_offsets 
+    (gdbarch, cris_linux_svr4_fetch_link_map_offsets);
+  
   return gdbarch;
 }
This page took 0.037825 seconds and 4 git commands to generate.