* [RFA] sighandler backtrace on x86-64
@ 2002-09-18 5:56 Michal Ludvig
2002-09-19 9:00 ` Elena Zannoni
0 siblings, 1 reply; 5+ messages in thread
From: Michal Ludvig @ 2002-09-18 5:56 UTC (permalink / raw)
To: GDB Patches
[-- Attachment #1: Type: text/plain, Size: 268 bytes --]
Hi all,
the attached patch enables backtrace through signal handlers on x86-64.
It isn't yet complete, but this is the part that works.
Can someone approve it please?
Michal Ludvig
--
* SuSE CR, s.r.o * mludvig@suse.cz
* +420 2 9654 5373 * http://www.suse.cz
[-- Attachment #2: sig3.diff --]
[-- Type: text/plain, Size: 10654 bytes --]
2002-09-18 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.
Index: dwarf2cfi.c
===================================================================
RCS file: /cvs/src/src/gdb/dwarf2cfi.c,v
retrieving revision 1.16
diff -u -p -r1.16 dwarf2cfi.c
--- dwarf2cfi.c 19 Jul 2002 09:40:51 -0000 1.16
+++ dwarf2cfi.c 18 Sep 2002 11:11:02 -0000
@@ -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 (
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: dwarf2cfi.h
===================================================================
RCS file: /cvs/src/src/gdb/dwarf2cfi.h,v
retrieving revision 1.1
diff -u -p -r1.1 dwarf2cfi.h
--- dwarf2cfi.h 7 Dec 2001 12:10:15 -0000 1.1
+++ dwarf2cfi.h 18 Sep 2002 11:11:02 -0000
@@ -22,6 +22,37 @@
#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_b
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: x86-64-linux-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/x86-64-linux-tdep.c,v
retrieving revision 1.5
diff -u -p -r1.5 x86-64-linux-tdep.c
--- x86-64-linux-tdep.c 3 Sep 2002 13:06:33 -0000 1.5
+++ x86-64-linux-tdep.c 18 Sep 2002 11:11:02 -0000
@@ -35,8 +35,10 @@
#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 p
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 fra
/* 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 fra
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;
@@ -134,4 +139,62 @@ x86_64_linux_frame_saved_pc (struct fram
if (frame->signal_handler_caller)
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: x86-64-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/x86-64-tdep.c,v
retrieving revision 1.27
diff -u -p -r1.27 x86-64-tdep.c
--- x86-64-tdep.c 12 Sep 2002 08:39:26 -0000 1.27
+++ x86-64-tdep.c 18 Sep 2002 11:11:03 -0000
@@ -1026,7 +1026,7 @@ x86_64_gdbarch_init (struct gdbarch_info
/* 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
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
/* 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);
@@ -1121,6 +1120,8 @@ x86_64_gdbarch_init (struct gdbarch_info
/* Use dwarf2 debug frame informations. */
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: x86-64-tdep.h
===================================================================
RCS file: /cvs/src/src/gdb/x86-64-tdep.h,v
retrieving revision 1.5
diff -u -p -r1.5 x86-64-tdep.h
--- x86-64-tdep.h 20 Jun 2002 13:08:12 -0000 1.5
+++ x86-64-tdep.h 18 Sep 2002 11:11:03 -0000
@@ -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
^ permalink raw reply [flat|nested] 5+ messages in thread* Re: [RFA] sighandler backtrace on x86-64
2002-09-18 5:56 [RFA] sighandler backtrace on x86-64 Michal Ludvig
@ 2002-09-19 9:00 ` Elena Zannoni
2002-09-20 1:27 ` Michal Ludvig
0 siblings, 1 reply; 5+ messages in thread
From: Elena Zannoni @ 2002-09-19 9:00 UTC (permalink / raw)
To: Michal Ludvig; +Cc: GDB Patches
Michal Ludvig writes:
> Hi all,
> the attached patch enables backtrace through signal handlers on x86-64.
> It isn't yet complete, but this is the part that works.
> Can someone approve it please?
>
> Michal Ludvig
> --
> * SuSE CR, s.r.o * mludvig@suse.cz
> * +420 2 9654 5373 * http://www.suse.cz
> 2002-09-18 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.
I don't see any uses of the structures and functions you are exporting.
Could you postpone these changes until they are actually used?
I have some comments anyway, see below.
> * 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.
>
> Index: dwarf2cfi.c
> ===================================================================
> RCS file: /cvs/src/src/gdb/dwarf2cfi.c,v
> retrieving revision 1.16
> diff -u -p -r1.16 dwarf2cfi.c
> --- dwarf2cfi.c 19 Jul 2002 09:40:51 -0000 1.16
> +++ dwarf2cfi.c 18 Sep 2002 11:11:02 -0000
> @@ -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 (
> 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: dwarf2cfi.h
> ===================================================================
> RCS file: /cvs/src/src/gdb/dwarf2cfi.h,v
> retrieving revision 1.1
> diff -u -p -r1.1 dwarf2cfi.h
> --- dwarf2cfi.h 7 Dec 2001 12:10:15 -0000 1.1
> +++ dwarf2cfi.h 18 Sep 2002 11:11:02 -0000
> @@ -22,6 +22,37 @@
> #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;
> +};
> +
Do you need to make the whole structure accessible? would it be enough
for your purposes to just add
struct context;
struct context_reg;
to the .h file?
> /* Return the frame address. */
> CORE_ADDR cfi_read_fp ();
>
> @@ -63,4 +94,7 @@ void cfi_get_saved_register (char *raw_b
> 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 ();
'extern' keyword?
Elena
> #endif
> Index: x86-64-linux-tdep.c
> ===================================================================
> RCS file: /cvs/src/src/gdb/x86-64-linux-tdep.c,v
> retrieving revision 1.5
> diff -u -p -r1.5 x86-64-linux-tdep.c
> --- x86-64-linux-tdep.c 3 Sep 2002 13:06:33 -0000 1.5
> +++ x86-64-linux-tdep.c 18 Sep 2002 11:11:02 -0000
> @@ -35,8 +35,10 @@
> #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 p
> 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 fra
>
>
> /* 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 fra
> 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;
> @@ -134,4 +139,62 @@ x86_64_linux_frame_saved_pc (struct fram
> if (frame->signal_handler_caller)
> 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: x86-64-tdep.c
> ===================================================================
> RCS file: /cvs/src/src/gdb/x86-64-tdep.c,v
> retrieving revision 1.27
> diff -u -p -r1.27 x86-64-tdep.c
> --- x86-64-tdep.c 12 Sep 2002 08:39:26 -0000 1.27
> +++ x86-64-tdep.c 18 Sep 2002 11:11:03 -0000
> @@ -1026,7 +1026,7 @@ x86_64_gdbarch_init (struct gdbarch_info
>
> /* 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
> 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
> /* 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);
> @@ -1121,6 +1120,8 @@ x86_64_gdbarch_init (struct gdbarch_info
> /* Use dwarf2 debug frame informations. */
> 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: x86-64-tdep.h
> ===================================================================
> RCS file: /cvs/src/src/gdb/x86-64-tdep.h,v
> retrieving revision 1.5
> diff -u -p -r1.5 x86-64-tdep.h
> --- x86-64-tdep.h 20 Jun 2002 13:08:12 -0000 1.5
> +++ x86-64-tdep.h 18 Sep 2002 11:11:03 -0000
> @@ -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
^ permalink raw reply [flat|nested] 5+ messages in thread* Re: [RFA] sighandler backtrace on x86-64
2002-09-19 9:00 ` Elena Zannoni
@ 2002-09-20 1:27 ` Michal Ludvig
2002-10-21 5:45 ` Elena Zannoni
0 siblings, 1 reply; 5+ messages in thread
From: Michal Ludvig @ 2002-09-20 1:27 UTC (permalink / raw)
To: Elena Zannoni; +Cc: GDB Patches
Elena Zannoni wrote:
> Do you need to make the whole structure accessible? would it be enough
> for your purposes to just add
> struct context;
> struct context_reg;
> to the .h file?
Hmm, I don't think so. I'm afraid I'll have to artifically create the
content of context_reg for the sighandler caller frame.
> I don't see any uses of the structures and functions you are
> exporting.
> Could you postpone these changes until they are actually used?
Sure I can. Anyway having all structures in .h isn't a bad habit, is it?
> > +struct context *context_alloc ();
> > +void context_cpy (struct context *dst, struct context *src);
> > +struct frame_state *frame_state_alloc ();
>
> 'extern' keyword?
It is the default for function declarations, and AFAIK is never used for
them in gdb's headers.
Can I commit without the struct context movement?
Michal Ludvig
--
* SuSE CR, s.r.o * mludvig@suse.cz
* +420 2 9654 5373 * http://www.suse.cz
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [RFA] sighandler backtrace on x86-64
2002-09-20 1:27 ` Michal Ludvig
@ 2002-10-21 5:45 ` Elena Zannoni
2002-10-23 18:38 ` Michal Ludvig
0 siblings, 1 reply; 5+ messages in thread
From: Elena Zannoni @ 2002-10-21 5:45 UTC (permalink / raw)
To: Michal Ludvig; +Cc: Elena Zannoni, GDB Patches
Michal Ludvig writes:
> Elena Zannoni wrote:
> > Do you need to make the whole structure accessible? would it be enough
> > for your purposes to just add
> > struct context;
> > struct context_reg;
> > to the .h file?
>
> Hmm, I don't think so. I'm afraid I'll have to artifically create the
> content of context_reg for the sighandler caller frame.
>
If you need to access the fields of the structure later on, then it's fine.
> > I don't see any uses of the structures and functions you are
> > exporting.
> > Could you postpone these changes until they are actually used?
>
> Sure I can. Anyway having all structures in .h isn't a bad habit, is it?
>
No, having the whole structure is fine, if it is used. If you just
need it for passing paramters around, w/o accessing the internal
fields, then it's better not exporting the whole struct, to keep the
interface a bit tighter.
> > > +struct context *context_alloc ();
> > > +void context_cpy (struct context *dst, struct context *src);
> > > +struct frame_state *frame_state_alloc ();
> >
> > 'extern' keyword?
>
> It is the default for function declarations, and AFAIK is never used for
> them in gdb's headers.
>
Hmmm, it is customary to use it.
> Can I commit without the struct context movement?
>
Yes, but I have noticed a few non-gnu style problems in x86-64.c:
> + if(fp)
> + fp = read_memory_integer (addr + LINUX_SIGCONTEXT_FP_OFFSET, 8)+8;
> + if(fi->next && fi->next->signal_handler_caller)
Could you fix them before committing?
Thanks
Elena
> Michal Ludvig
> --
> * SuSE CR, s.r.o * mludvig@suse.cz
> * +420 2 9654 5373 * http://www.suse.cz
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2002-10-24 1:38 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2002-09-18 5:56 [RFA] sighandler backtrace on x86-64 Michal Ludvig
2002-09-19 9:00 ` Elena Zannoni
2002-09-20 1:27 ` Michal Ludvig
2002-10-21 5:45 ` Elena Zannoni
2002-10-23 18:38 ` Michal Ludvig
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox