gdb/doc/
[binutils-gdb.git] / gdb / mips-linux-tdep.c
index 242196ac790b4ddec2db307d7c9fc44401b8cfb6..5924b30984db3d95f2219f18082da3c3b1de7c98 100644 (file)
@@ -1,6 +1,6 @@
 /* Target-dependent code for GNU/Linux on MIPS processors.
 
 /* Target-dependent code for GNU/Linux on MIPS processors.
 
-   Copyright (C) 2001, 2002, 2004, 2005, 2006, 2007, 2008, 2009
+   Copyright (C) 2001, 2002, 2004, 2005, 2006, 2007, 2008, 2009, 2010
    Free Software Foundation, Inc.
 
    This file is part of GDB.
    Free Software Foundation, Inc.
 
    This file is part of GDB.
@@ -55,6 +55,7 @@ mips_linux_get_longjmp_target (struct frame_info *frame, CORE_ADDR *pc)
 {
   CORE_ADDR jb_addr;
   struct gdbarch *gdbarch = get_frame_arch (frame);
 {
   CORE_ADDR jb_addr;
   struct gdbarch *gdbarch = get_frame_arch (frame);
+  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
   char buf[gdbarch_ptr_bit (gdbarch) / TARGET_CHAR_BIT];
 
   jb_addr = get_frame_register_unsigned (frame, MIPS_A0_REGNUM);
   char buf[gdbarch_ptr_bit (gdbarch) / TARGET_CHAR_BIT];
 
   jb_addr = get_frame_register_unsigned (frame, MIPS_A0_REGNUM);
@@ -65,7 +66,8 @@ mips_linux_get_longjmp_target (struct frame_info *frame, CORE_ADDR *pc)
     return 0;
 
   *pc = extract_unsigned_integer (buf,
     return 0;
 
   *pc = extract_unsigned_integer (buf,
-                                 gdbarch_ptr_bit (gdbarch) / TARGET_CHAR_BIT);
+                                 gdbarch_ptr_bit (gdbarch) / TARGET_CHAR_BIT,
+                                 byte_order);
 
   return 1;
 }
 
   return 1;
 }
@@ -77,10 +79,11 @@ mips_linux_get_longjmp_target (struct frame_info *frame, CORE_ADDR *pc)
 static void
 supply_32bit_reg (struct regcache *regcache, int regnum, const void *addr)
 {
 static void
 supply_32bit_reg (struct regcache *regcache, int regnum, const void *addr)
 {
+  struct gdbarch *gdbarch = get_regcache_arch (regcache);
+  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
   gdb_byte buf[MAX_REGISTER_SIZE];
   gdb_byte buf[MAX_REGISTER_SIZE];
-  store_signed_integer (buf,
-                       register_size (get_regcache_arch (regcache), regnum),
-                        extract_signed_integer (addr, 4));
+  store_signed_integer (buf, register_size (gdbarch, regnum), byte_order,
+                        extract_signed_integer (addr, 4, byte_order));
   regcache_raw_supply (regcache, regnum, buf);
 }
 
   regcache_raw_supply (regcache, regnum, buf);
 }
 
@@ -258,6 +261,7 @@ mips64_linux_get_longjmp_target (struct frame_info *frame, CORE_ADDR *pc)
 {
   CORE_ADDR jb_addr;
   struct gdbarch *gdbarch = get_frame_arch (frame);
 {
   CORE_ADDR jb_addr;
   struct gdbarch *gdbarch = get_frame_arch (frame);
+  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
   void *buf = alloca (gdbarch_ptr_bit (gdbarch) / TARGET_CHAR_BIT);
   int element_size = gdbarch_ptr_bit (gdbarch) == 32 ? 4 : 8;
 
   void *buf = alloca (gdbarch_ptr_bit (gdbarch) / TARGET_CHAR_BIT);
   int element_size = gdbarch_ptr_bit (gdbarch) == 32 ? 4 : 8;
 
@@ -269,7 +273,8 @@ mips64_linux_get_longjmp_target (struct frame_info *frame, CORE_ADDR *pc)
     return 0;
 
   *pc = extract_unsigned_integer (buf,
     return 0;
 
   *pc = extract_unsigned_integer (buf,
-                                 gdbarch_ptr_bit (gdbarch) / TARGET_CHAR_BIT);
+                                 gdbarch_ptr_bit (gdbarch) / TARGET_CHAR_BIT,
+                                 byte_order);
 
   return 1;
 }
 
   return 1;
 }
@@ -343,6 +348,7 @@ mips64_fill_gregset (const struct regcache *regcache,
                     mips64_elf_gregset_t *gregsetp, int regno)
 {
   struct gdbarch *gdbarch = get_regcache_arch (regcache);
                     mips64_elf_gregset_t *gregsetp, int regno)
 {
   struct gdbarch *gdbarch = get_regcache_arch (regcache);
+  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
   int regaddr, regi;
   mips64_elf_greg_t *regp = *gregsetp;
   void *dst;
   int regaddr, regi;
   mips64_elf_greg_t *regp = *gregsetp;
   void *dst;
@@ -388,9 +394,10 @@ mips64_fill_gregset (const struct regcache *regcache,
       LONGEST val;
 
       regcache_raw_collect (regcache, regno, buf);
       LONGEST val;
 
       regcache_raw_collect (regcache, regno, buf);
-      val = extract_signed_integer (buf, register_size (gdbarch, regno));
+      val = extract_signed_integer (buf, register_size (gdbarch, regno),
+                                   byte_order);
       dst = regp + regaddr;
       dst = regp + regaddr;
-      store_signed_integer (dst, 8, val);
+      store_signed_integer (dst, 8, byte_order, val);
     }
 }
 
     }
 }
 
@@ -440,6 +447,7 @@ mips64_fill_fpregset (const struct regcache *regcache,
                      mips64_elf_fpregset_t *fpregsetp, int regno)
 {
   struct gdbarch *gdbarch = get_regcache_arch (regcache);
                      mips64_elf_fpregset_t *fpregsetp, int regno)
 {
   struct gdbarch *gdbarch = get_regcache_arch (regcache);
+  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
   gdb_byte *to;
 
   if ((regno >= gdbarch_fp0_regnum (gdbarch))
   gdb_byte *to;
 
   if ((regno >= gdbarch_fp0_regnum (gdbarch))
@@ -468,9 +476,10 @@ mips64_fill_fpregset (const struct regcache *regcache,
       LONGEST val;
 
       regcache_raw_collect (regcache, regno, buf);
       LONGEST val;
 
       regcache_raw_collect (regcache, regno, buf);
-      val = extract_signed_integer (buf, register_size (gdbarch, regno));
+      val = extract_signed_integer (buf, register_size (gdbarch, regno),
+                                   byte_order);
       to = (gdb_byte *) (*fpregsetp + 32);
       to = (gdb_byte *) (*fpregsetp + 32);
-      store_signed_integer (to, 4, val);
+      store_signed_integer (to, 4, byte_order, val);
     }
   else if (regno == mips_regnum (gdbarch)->fp_implementation_revision)
     {
     }
   else if (regno == mips_regnum (gdbarch)->fp_implementation_revision)
     {
@@ -478,9 +487,10 @@ mips64_fill_fpregset (const struct regcache *regcache,
       LONGEST val;
 
       regcache_raw_collect (regcache, regno, buf);
       LONGEST val;
 
       regcache_raw_collect (regcache, regno, buf);
-      val = extract_signed_integer (buf, register_size (gdbarch, regno));
+      val = extract_signed_integer (buf, register_size (gdbarch, regno),
+                                   byte_order);
       to = (gdb_byte *) (*fpregsetp + 32) + 4;
       to = (gdb_byte *) (*fpregsetp + 32) + 4;
-      store_signed_integer (to, 4, val);
+      store_signed_integer (to, 4, byte_order, val);
     }
   else if (regno == -1)
     {
     }
   else if (regno == -1)
     {
@@ -605,6 +615,7 @@ mips_linux_in_dynsym_stub (CORE_ADDR pc, char *name)
   unsigned char buf[28], *p;
   ULONGEST insn, insn1;
   int n64 = (mips_abi (target_gdbarch) == MIPS_ABI_N64);
   unsigned char buf[28], *p;
   ULONGEST insn, insn1;
   int n64 = (mips_abi (target_gdbarch) == MIPS_ABI_N64);
+  enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch);
 
   read_memory (pc - 12, buf, 28);
 
 
   read_memory (pc - 12, buf, 28);
 
@@ -622,7 +633,7 @@ mips_linux_in_dynsym_stub (CORE_ADDR pc, char *name)
   p = buf + 12;
   while (p >= buf)
     {
   p = buf + 12;
   while (p >= buf)
     {
-      insn = extract_unsigned_integer (p, 4);
+      insn = extract_unsigned_integer (p, 4, byte_order);
       if (insn == insn1)
        break;
       p -= 4;
       if (insn == insn1)
        break;
       p -= 4;
@@ -630,7 +641,7 @@ mips_linux_in_dynsym_stub (CORE_ADDR pc, char *name)
   if (p < buf)
     return 0;
 
   if (p < buf)
     return 0;
 
-  insn = extract_unsigned_integer (p + 4, 4);
+  insn = extract_unsigned_integer (p + 4, 4, byte_order);
   if (n64)
     {
       /* daddu t7,ra */
   if (n64)
     {
       /* daddu t7,ra */
@@ -644,12 +655,12 @@ mips_linux_in_dynsym_stub (CORE_ADDR pc, char *name)
        return 0;
     }
 
        return 0;
     }
 
-  insn = extract_unsigned_integer (p + 8, 4);
+  insn = extract_unsigned_integer (p + 8, 4, byte_order);
   /* jalr t9,ra */
   if (insn != 0x0320f809)
     return 0;
 
   /* jalr t9,ra */
   if (insn != 0x0320f809)
     return 0;
 
-  insn = extract_unsigned_integer (p + 12, 4);
+  insn = extract_unsigned_integer (p + 12, 4, byte_order);
   if (n64)
     {
       /* daddiu t8,zero,0 */
   if (n64)
     {
       /* daddiu t8,zero,0 */
@@ -702,7 +713,7 @@ mips_linux_skip_resolver (struct gdbarch *gdbarch, CORE_ADDR pc)
   resolver = lookup_minimal_symbol ("__dl_runtime_resolve", NULL, NULL);
 
   if (resolver && SYMBOL_VALUE_ADDRESS (resolver) == pc)
   resolver = lookup_minimal_symbol ("__dl_runtime_resolve", NULL, NULL);
 
   if (resolver && SYMBOL_VALUE_ADDRESS (resolver) == pc)
-    return frame_pc_unwind (get_current_frame ());
+    return frame_unwind_caller_pc (get_current_frame ());
 
   return glibc_skip_solib_resolver (gdbarch, pc);
 }
 
   return glibc_skip_solib_resolver (gdbarch, pc);
 }
@@ -786,7 +797,7 @@ static const struct tramp_frame mips_linux_n64_rt_sigframe = {
 
    struct sigframe {
      u32 sf_ass[4];            [argument save space for o32]
 
    struct sigframe {
      u32 sf_ass[4];            [argument save space for o32]
-     u32 sf_code[2];           [signal trampoline]
+     u32 sf_code[2];           [signal trampoline or fill]
      struct sigcontext sf_sc;
      sigset_t sf_mask;
    };
      struct sigcontext sf_sc;
      sigset_t sf_mask;
    };
@@ -816,7 +827,7 @@ static const struct tramp_frame mips_linux_n64_rt_sigframe = {
 
    struct rt_sigframe {
      u32 rs_ass[4];            [argument save space for o32]
 
    struct rt_sigframe {
      u32 rs_ass[4];            [argument save space for o32]
-     u32 rs_code[2]            [signal trampoline]
+     u32 rs_code[2]            [signal trampoline or fill]
      struct siginfo rs_info;
      struct ucontext rs_uc;
    };
      struct siginfo rs_info;
      struct ucontext rs_uc;
    };
@@ -831,7 +842,6 @@ static const struct tramp_frame mips_linux_n64_rt_sigframe = {
    };  */
 /* *INDENT-ON* */
 
    };  */
 /* *INDENT-ON* */
 
-#define SIGFRAME_CODE_OFFSET         (4 * 4)
 #define SIGFRAME_SIGCONTEXT_OFFSET   (6 * 4)
 
 #define RTSIGFRAME_SIGINFO_SIZE      128
 #define SIGFRAME_SIGCONTEXT_OFFSET   (6 * 4)
 
 #define RTSIGFRAME_SIGINFO_SIZE      128
@@ -860,14 +870,15 @@ mips_linux_o32_sigframe_init (const struct tramp_frame *self,
 {
   struct gdbarch *gdbarch = get_frame_arch (this_frame);
   int ireg, reg_position;
 {
   struct gdbarch *gdbarch = get_frame_arch (this_frame);
   int ireg, reg_position;
-  CORE_ADDR sigcontext_base = func - SIGFRAME_CODE_OFFSET;
+  CORE_ADDR frame_sp = get_frame_sp (this_frame);
+  CORE_ADDR sigcontext_base;
   const struct mips_regnum *regs = mips_regnum (gdbarch);
   CORE_ADDR regs_base;
 
   if (self == &mips_linux_o32_sigframe)
   const struct mips_regnum *regs = mips_regnum (gdbarch);
   CORE_ADDR regs_base;
 
   if (self == &mips_linux_o32_sigframe)
-    sigcontext_base += SIGFRAME_SIGCONTEXT_OFFSET;
+    sigcontext_base = frame_sp + SIGFRAME_SIGCONTEXT_OFFSET;
   else
   else
-    sigcontext_base += RTSIGFRAME_SIGCONTEXT_OFFSET;
+    sigcontext_base = frame_sp + RTSIGFRAME_SIGCONTEXT_OFFSET;
 
   /* I'm not proud of this hack.  Eventually we will have the
      infrastructure to indicate the size of saved registers on a
 
   /* I'm not proud of this hack.  Eventually we will have the
      infrastructure to indicate the size of saved registers on a
@@ -936,9 +947,7 @@ mips_linux_o32_sigframe_init (const struct tramp_frame *self,
                           sigcontext_base + SIGCONTEXT_BADVADDR);
 
   /* Choice of the bottom of the sigframe is somewhat arbitrary.  */
                           sigcontext_base + SIGCONTEXT_BADVADDR);
 
   /* Choice of the bottom of the sigframe is somewhat arbitrary.  */
-  trad_frame_set_id (this_cache,
-                    frame_id_build (func - SIGFRAME_CODE_OFFSET,
-                                    func));
+  trad_frame_set_id (this_cache, frame_id_build (frame_sp, func));
 }
 
 /* *INDENT-OFF* */
 }
 
 /* *INDENT-OFF* */
@@ -946,7 +955,7 @@ mips_linux_o32_sigframe_init (const struct tramp_frame *self,
 
   struct rt_sigframe_n32 {
     u32 rs_ass[4];                  [ argument save space for o32 ]
 
   struct rt_sigframe_n32 {
     u32 rs_ass[4];                  [ argument save space for o32 ]
-    u32 rs_code[2];                 [ signal trampoline ]
+    u32 rs_code[2];                 [ signal trampoline or fill ]
     struct siginfo rs_info;
     struct ucontextn32 rs_uc;
   };
     struct siginfo rs_info;
     struct ucontextn32 rs_uc;
   };
@@ -1027,13 +1036,14 @@ mips_linux_n32n64_sigframe_init (const struct tramp_frame *self,
 {
   struct gdbarch *gdbarch = get_frame_arch (this_frame);
   int ireg, reg_position;
 {
   struct gdbarch *gdbarch = get_frame_arch (this_frame);
   int ireg, reg_position;
-  CORE_ADDR sigcontext_base = func - SIGFRAME_CODE_OFFSET;
+  CORE_ADDR frame_sp = get_frame_sp (this_frame);
+  CORE_ADDR sigcontext_base;
   const struct mips_regnum *regs = mips_regnum (gdbarch);
 
   if (self == &mips_linux_n32_rt_sigframe)
   const struct mips_regnum *regs = mips_regnum (gdbarch);
 
   if (self == &mips_linux_n32_rt_sigframe)
-    sigcontext_base += N32_SIGFRAME_SIGCONTEXT_OFFSET;
+    sigcontext_base = frame_sp + N32_SIGFRAME_SIGCONTEXT_OFFSET;
   else
   else
-    sigcontext_base += N64_SIGFRAME_SIGCONTEXT_OFFSET;
+    sigcontext_base = frame_sp + N64_SIGFRAME_SIGCONTEXT_OFFSET;
 
   if (mips_linux_restart_reg_p (gdbarch))
     trad_frame_set_reg_addr (this_cache,
 
   if (mips_linux_restart_reg_p (gdbarch))
     trad_frame_set_reg_addr (this_cache,
@@ -1071,9 +1081,7 @@ mips_linux_n32n64_sigframe_init (const struct tramp_frame *self,
                           sigcontext_base + N64_SIGCONTEXT_LO);
 
   /* Choice of the bottom of the sigframe is somewhat arbitrary.  */
                           sigcontext_base + N64_SIGCONTEXT_LO);
 
   /* Choice of the bottom of the sigframe is somewhat arbitrary.  */
-  trad_frame_set_id (this_cache,
-                    frame_id_build (func - SIGFRAME_CODE_OFFSET,
-                                    func));
+  trad_frame_set_id (this_cache, frame_id_build (frame_sp, func));
 }
 
 static void
 }
 
 static void
@@ -1117,7 +1125,7 @@ mips_linux_syscall_next_pc (struct frame_info *frame)
       || v0 == MIPS_NR_rt_sigreturn
       || v0 == MIPS_NR_N64_rt_sigreturn
       || v0 == MIPS_NR_N32_rt_sigreturn)
       || v0 == MIPS_NR_rt_sigreturn
       || v0 == MIPS_NR_N64_rt_sigreturn
       || v0 == MIPS_NR_N32_rt_sigreturn)
-    return frame_pc_unwind (get_current_frame ());
+    return frame_unwind_caller_pc (get_current_frame ());
 
   return pc + 4;
 }
 
   return pc + 4;
 }