mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-11-25 02:53:48 +08:00
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:
parent
c38da1aff1
commit
baed091b2b
@ -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".
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user