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.
This commit is contained in:
Michal Ludvig 2002-10-24 01:27:43 +00:00
parent c38da1aff1
commit baed091b2b
6 changed files with 145 additions and 53 deletions

View 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".

View 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;

View File

@ -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_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

View File

@ -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 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);
}

View 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;
}

View 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