2002-10-24 Michal Ludvig <mludvig@suse.cz>
authorMichal Ludvig <mludvig@suse.cz>
Thu, 24 Oct 2002 01:27:43 +0000 (01:27 +0000)
committerMichal Ludvig <mludvig@suse.cz>
Thu, 24 Oct 2002 01:27:43 +0000 (01:27 +0000)
* dwarf2cfi.c (struct context)
(struct context_reg): Moved to dwarf2cfi.h
(context_alloc, frame_state_alloc, context_cpy):
Made extern instead of static, removed prototypes.
* dwarf2cfi.h (struct context)
(struct context_reg): New, moved from dwarf2cfi.c
(context_alloc, frame_state_alloc, context_cpy):
New prototypes.
* x86-64-linux-tdep.c (x86_64_linux_sigtramp_saved_pc):
Changed from static to extern.
(LINUX_SIGINFO_SIZE, LINUX_SIGCONTEXT_PC_OFFSET)
(LINUX_SIGCONTEXT_FP_OFFSET)
(LINUX_UCONTEXT_SIGCONTEXT_OFFSET): Adjusted.
(x86_64_linux_in_sigtramp, x86_64_linux_frame_chain)
(x86_64_init_frame_pc, x86_64_init_extra_frame_info): New.
* x86-64-tdep.c (x86_64_gdbarch_init): Several
set_gdbarch_*() calls now use x86-64 specific functions
instead of DWARF2 CFI ones.
* x86-64-tdep.h (x86_64_linux_in_sigtramp)
(x86_64_linux_frame_chain, x86_64_init_frame_pc)
(x86_64_init_extra_frame_info): New prototypes.

gdb/ChangeLog
gdb/dwarf2cfi.c
gdb/dwarf2cfi.h
gdb/x86-64-linux-tdep.c
gdb/x86-64-tdep.c
gdb/x86-64-tdep.h

index 985d12176b6f380d00ffabe82af4527089cad5d5..daa56c480f3657b79a4d6eed7bad4d81e261a87b 100644 (file)
@@ -1,3 +1,27 @@
+2002-10-24  Michal Ludvig  <mludvig@suse.cz>
+
+       * dwarf2cfi.c (struct context)
+       (struct context_reg): Moved to dwarf2cfi.h
+       (context_alloc, frame_state_alloc, context_cpy):
+       Made extern instead of static, removed prototypes.
+       * dwarf2cfi.h (struct context)
+       (struct context_reg): New, moved from dwarf2cfi.c
+       (context_alloc, frame_state_alloc, context_cpy):
+       New prototypes.
+       * x86-64-linux-tdep.c (x86_64_linux_sigtramp_saved_pc):
+       Changed from static to extern.
+       (LINUX_SIGINFO_SIZE, LINUX_SIGCONTEXT_PC_OFFSET)
+       (LINUX_SIGCONTEXT_FP_OFFSET)
+       (LINUX_UCONTEXT_SIGCONTEXT_OFFSET): Adjusted.
+       (x86_64_linux_in_sigtramp, x86_64_linux_frame_chain)
+       (x86_64_init_frame_pc, x86_64_init_extra_frame_info): New.
+       * x86-64-tdep.c (x86_64_gdbarch_init): Several
+       set_gdbarch_*() calls now use x86-64 specific functions 
+       instead of DWARF2 CFI ones.
+       * x86-64-tdep.h (x86_64_linux_in_sigtramp)
+       (x86_64_linux_frame_chain, x86_64_init_frame_pc)
+       (x86_64_init_extra_frame_info): New prototypes.
+       
 2002-10-23  David Carlton  <carlton@math.stanford.edu>
 
        * linespec.c: #include "parser-defs.h".
index 18782b16dc87b0b83195064de0c891bc3507ea06..41e645b88660e37694d55a295ef4a6cb87795443 100644 (file)
@@ -90,37 +90,6 @@ struct fde_array
   int array_size;
 };
 
-struct context_reg
-{
-  union
-  {
-    unsigned int reg;
-    long offset;
-    CORE_ADDR addr;
-  }
-  loc;
-  enum
-  {
-    REG_CTX_UNSAVED,
-    REG_CTX_SAVED_OFFSET,
-    REG_CTX_SAVED_REG,
-    REG_CTX_SAVED_ADDR,
-    REG_CTX_VALUE,
-  }
-  how;
-};
-
-/* This is the register and unwind state for a particular frame.  */
-struct context
-{
-  struct context_reg *reg;
-
-  CORE_ADDR cfa;
-  CORE_ADDR ra;
-  void *lsda;
-  int args_size;
-};
-
 struct frame_state_reg
 {
   union
@@ -208,11 +177,8 @@ static struct fde_unit *fde_unit_alloc (void);
 static struct cie_unit *cie_unit_alloc (void);
 static void fde_chunks_need_space ();
 
-static struct context *context_alloc ();
-static struct frame_state *frame_state_alloc ();
 static void unwind_tmp_obstack_init ();
 static void unwind_tmp_obstack_free ();
-static void context_cpy (struct context *dst, struct context *src);
 
 static unsigned int read_1u (bfd * abfd, char **p);
 static int read_1s (bfd * abfd, char **p);
@@ -286,7 +252,7 @@ fde_chunks_need_space (void)
 }
 
 /* Alocate a new `struct context' on temporary obstack.  */
-static struct context *
+struct context *
 context_alloc (void)
 {
   struct context *context;
@@ -303,7 +269,7 @@ context_alloc (void)
 }
 
 /* Alocate a new `struct frame_state' on temporary obstack.  */
-static struct frame_state *
+struct frame_state *
 frame_state_alloc (void)
 {
   struct frame_state *fs;
@@ -332,7 +298,7 @@ unwind_tmp_obstack_free (void)
   unwind_tmp_obstack_init ();
 }
 
-static void
+void
 context_cpy (struct context *dst, struct context *src)
 {
   int regs_size = sizeof (struct context_reg) * NUM_REGS;
index f4c675aca7be1d2bfb235aba76e6a3c695db78f6..b6abbdeebe6bc33555c32e7fbf3f26254b12a46e 100644 (file)
 #ifndef DWARF2CFI_H
 #define DWARF2CFI_H
 
+struct context_reg
+{
+  union
+  {
+    unsigned int reg;
+    long offset;
+    CORE_ADDR addr;
+  }
+  loc;
+  enum
+  {
+    REG_CTX_UNSAVED,
+    REG_CTX_SAVED_OFFSET,
+    REG_CTX_SAVED_REG,
+    REG_CTX_SAVED_ADDR,
+    REG_CTX_VALUE,
+  }
+  how;
+};
+
+/* This is the register and unwind state for a particular frame.  */
+struct context
+{
+  struct context_reg *reg;
+
+  CORE_ADDR cfa;
+  CORE_ADDR ra;
+  void *lsda;
+  int args_size;
+};
+
 /* Return the frame address.  */
 CORE_ADDR cfi_read_fp ();
 
@@ -63,4 +94,7 @@ void cfi_get_saved_register (char *raw_buffer,
 void cfi_virtual_frame_pointer (CORE_ADDR pc, int *frame_regnum,
                                LONGEST * frame_offset);
 
+struct context *context_alloc ();
+void context_cpy (struct context *dst, struct context *src);
+struct frame_state *frame_state_alloc ();
 #endif
index ac41daa88493787eea8df1ffe74977f3df5f7b59..71e3276c8a26dcc91d475578bd9f70c6a993b21f 100644 (file)
 #define LINUX_SIGTRAMP_OFFSET1 (7)
 
 static const unsigned char linux_sigtramp_code[] = {
-  LINUX_SIGTRAMP_INSN0, 0xc7, 0xc0, 0x89, 0x00, 0x00, 0x00,    /*  mov $0x89,%rax */
-  LINUX_SIGTRAMP_INSN1, 0x05   /* syscall */
+  /*  mov $__NR_rt_sigreturn,%rax */   
+  LINUX_SIGTRAMP_INSN0, 0xc7, 0xc0, 0x0f, 0x00, 0x00, 0x00,
+  /* syscall */
+  LINUX_SIGTRAMP_INSN1, 0x05
 };
 
 #define LINUX_SIGTRAMP_LEN (sizeof linux_sigtramp_code)
@@ -68,17 +70,22 @@ x86_64_linux_sigtramp_start (CORE_ADDR pc)
   return pc;
 }
 
-#define LINUX_SIGINFO_SIZE 128
+#define LINUX_SIGINFO_SIZE 0
 
 /* Offset to struct sigcontext in ucontext, from <asm/ucontext.h>.  */
-#define LINUX_UCONTEXT_SIGCONTEXT_OFFSET (36)
+#define LINUX_UCONTEXT_SIGCONTEXT_OFFSET 40
+
+/* Offset to saved PC in sigcontext, from <asm/sigcontext.h>.  */
+#define LINUX_SIGCONTEXT_PC_OFFSET 128
+#define LINUX_SIGCONTEXT_FP_OFFSET 120
 
 /* Assuming FRAME is for a GNU/Linux sigtramp routine, return the
    address of the associated sigcontext structure.  */
-CORE_ADDR
+static CORE_ADDR
 x86_64_linux_sigcontext_addr (struct frame_info *frame)
 {
   CORE_ADDR pc;
+  ULONGEST rsp;
 
   pc = x86_64_linux_sigtramp_start (frame->pc);
   if (pc)
@@ -92,7 +99,8 @@ x86_64_linux_sigcontext_addr (struct frame_info *frame)
 
 
       /* This is the top frame. */
-      return read_register (SP_REGNUM) + LINUX_SIGINFO_SIZE +
+      rsp = read_register (SP_REGNUM);
+      return rsp + LINUX_SIGINFO_SIZE +
        LINUX_UCONTEXT_SIGCONTEXT_OFFSET;
 
     }
@@ -101,13 +109,10 @@ x86_64_linux_sigcontext_addr (struct frame_info *frame)
   return 0;
 }
 
-/* Offset to saved PC in sigcontext, from <asm/sigcontext.h>.  */
-#define LINUX_SIGCONTEXT_PC_OFFSET (136)
-
 /* Assuming FRAME is for a GNU/Linux sigtramp routine, return the
    saved program counter.  */
 
-CORE_ADDR
+static CORE_ADDR
 x86_64_linux_sigtramp_saved_pc (struct frame_info *frame)
 {
   CORE_ADDR addr;
@@ -135,3 +140,61 @@ x86_64_linux_frame_saved_pc (struct frame_info *frame)
     return x86_64_linux_sigtramp_saved_pc (frame);
   return cfi_get_ra (frame);
 }
+
+/* Return whether PC is in a GNU/Linux sigtramp routine.  */
+
+int
+x86_64_linux_in_sigtramp (CORE_ADDR pc, char *name)
+{
+  if (name)
+    return STREQ ("__restore_rt", name);
+  
+  return (x86_64_linux_sigtramp_start (pc) != 0);
+}
+
+CORE_ADDR
+x86_64_linux_frame_chain (struct frame_info *fi)
+{
+       ULONGEST addr;
+       CORE_ADDR fp, pc;
+       
+       if (! fi->signal_handler_caller)
+       {
+               fp = cfi_frame_chain (fi);
+               if(fp)
+                       return fp;
+               else
+                       addr = fi->frame;
+       }
+       else
+               addr = fi->next->frame;
+
+       addr += LINUX_SIGINFO_SIZE + LINUX_UCONTEXT_SIGCONTEXT_OFFSET;
+       
+       fp = read_memory_integer (addr + LINUX_SIGCONTEXT_FP_OFFSET, 8)+8;
+       
+       return fp;
+}
+
+void
+x86_64_init_frame_pc (int fromleaf, struct frame_info *fi)
+{
+       CORE_ADDR addr;
+
+       if(fi->next && fi->next->signal_handler_caller)
+       {
+               addr = fi->next->next->frame 
+                       + LINUX_SIGINFO_SIZE 
+                       + LINUX_UCONTEXT_SIGCONTEXT_OFFSET;
+               fi->pc = read_memory_integer (addr 
+                               + LINUX_SIGCONTEXT_PC_OFFSET, 8);
+       }
+       else
+               cfi_init_frame_pc (fromleaf, fi);
+}
+
+void
+x86_64_init_extra_frame_info (int fromleaf, struct frame_info *fi)
+{
+       cfi_init_extra_frame_info (fromleaf, fi);
+}
index 31f32f189cd9b34eba3a2c1aa6f60030ef5d6660..5d92a99b140e7b637ed85b5d650a5b129dc4f2a9 100644 (file)
@@ -1026,7 +1026,7 @@ x86_64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 
   /* FRAME_CHAIN takes a frame's nominal address and produces the frame's
      chain-pointer.  */
-  set_gdbarch_frame_chain (gdbarch, cfi_frame_chain);
+  set_gdbarch_frame_chain (gdbarch, x86_64_linux_frame_chain);
 
   set_gdbarch_frameless_function_invocation (gdbarch,
                                             x86_64_frameless_function_invocation);
@@ -1041,10 +1041,10 @@ x86_64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   set_gdbarch_frame_init_saved_regs (gdbarch, x86_64_frame_init_saved_regs);
 
 /* Frame pc initialization is handled by unwind informations.  */
-  set_gdbarch_init_frame_pc (gdbarch, cfi_init_frame_pc);
+  set_gdbarch_init_frame_pc (gdbarch, x86_64_init_frame_pc);
 
 /* Initialization of unwind informations.  */
-  set_gdbarch_init_extra_frame_info (gdbarch, cfi_init_extra_frame_info);
+  set_gdbarch_init_extra_frame_info (gdbarch, x86_64_init_extra_frame_info);
 
 /* Getting saved registers is handled by unwind informations.  */
   set_gdbarch_get_saved_register (gdbarch, cfi_get_saved_register);
@@ -1054,8 +1054,7 @@ x86_64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 /* Cons up virtual frame pointer for trace */
   set_gdbarch_virtual_frame_pointer (gdbarch, cfi_virtual_frame_pointer);
 
-
-  set_gdbarch_frame_chain_valid (gdbarch, generic_file_frame_chain_valid);
+  set_gdbarch_frame_chain_valid (gdbarch, file_frame_chain_valid);
 
   set_gdbarch_use_generic_dummy_frames (gdbarch, 1);
   set_gdbarch_call_dummy_location (gdbarch, AT_ENTRY_POINT);
@@ -1122,6 +1121,8 @@ x86_64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   set_gdbarch_dwarf2_build_frame_info (gdbarch, dwarf2_build_frame_info);
   set_gdbarch_dwarf2_reg_to_regnum (gdbarch, x86_64_dwarf2_reg_to_regnum);
 
+  set_gdbarch_pc_in_sigtramp (gdbarch, x86_64_linux_in_sigtramp);
+
   return gdbarch;
 }
 
index 711486077fb2ac650f98ced31f818ad568e900be..fd23a7a7f318d2a95813f86ffaa892d8b5c4cdce 100644 (file)
@@ -31,8 +31,12 @@ extern int x86_64_num_gregs;
 int x86_64_register_number (const char *name);
 const char *x86_64_register_name (int reg_nr);
        
-
 gdbarch_frame_saved_pc_ftype x86_64_linux_frame_saved_pc;
 gdbarch_saved_pc_after_call_ftype x86_64_linux_saved_pc_after_call;
+gdbarch_pc_in_sigtramp_ftype x86_64_linux_in_sigtramp;
+CORE_ADDR x86_64_linux_frame_chain (struct frame_info *fi);
+void x86_64_init_frame_pc (int fromleaf, struct frame_info *fi);
+void x86_64_init_extra_frame_info (int fromleaf, struct frame_info *fi);
+
 
 #endif