* dwarf2-frame.h (dwarf2_frame_set_init_reg): New prototype.

* dwarf2-frame.c (dwarf2_frame_data): New variable.
(struct dwarf2_frame_ops): New.
(dwarf2_frame_default_init_reg): New function, based on
dwarf2_frame_init_reg.
(dwarf2_frame_init, dwarf2_frame_set_init_reg): New function.
(dwarf2_frame_init_reg): Call architecture-specific function.
(dwarf2_frame_objfile_data): Renamed from dwarf2_frame_data.
(dwarf2_frame_find_fde, add_fde): Use dwarf2_frame_objfile_data
instead of dwarf2_frame_data.
(_initialize_dwarf2_frame): Initailize new dwarf2_frame_data.
Initialize dwarf2_frame_objfile instead of old dwarf2_frame_data.
This commit is contained in:
Mark Kettenis 2004-02-15 21:29:26 +00:00
parent 046a4708e4
commit 8f22cb9068
3 changed files with 118 additions and 42 deletions

View File

@ -1,3 +1,18 @@
2004-02-15 Mark Kettenis <kettenis@gnu.org>
* dwarf2-frame.h (dwarf2_frame_set_init_reg): New prototype.
* dwarf2-frame.c (dwarf2_frame_data): New variable.
(struct dwarf2_frame_ops): New.
(dwarf2_frame_default_init_reg): New function, based on
dwarf2_frame_init_reg.
(dwarf2_frame_init, dwarf2_frame_set_init_reg): New function.
(dwarf2_frame_init_reg): Call architecture-specific function.
(dwarf2_frame_objfile_data): Renamed from dwarf2_frame_data.
(dwarf2_frame_find_fde, add_fde): Use dwarf2_frame_objfile_data
instead of dwarf2_frame_data.
(_initialize_dwarf2_frame): Initailize new dwarf2_frame_data.
Initialize dwarf2_frame_objfile instead of old dwarf2_frame_data.
2004-02-15 Andrew Cagney <cagney@redhat.com>
* gdbarch.sh (deprecated_register_gdbarch_swap): Rename

View File

@ -454,6 +454,96 @@ execute_cfa_program (unsigned char *insn_ptr, unsigned char *insn_end,
dwarf2_frame_state_free_regs (fs->regs.prev);
fs->regs.prev = NULL;
}
/* Architecture-specific operations. */
/* Per-architecture data key. */
static struct gdbarch_data *dwarf2_frame_data;
struct dwarf2_frame_ops
{
/* Pre-initialize the register state REG for register REGNUM. */
void (*init_reg) (struct gdbarch *, int, struct dwarf2_frame_state_reg *);
};
/* Default architecture-specific register state initialization
function. */
static void
dwarf2_frame_default_init_reg (struct gdbarch *gdbarch, int regnum,
struct dwarf2_frame_state_reg *reg)
{
/* If we have a register that acts as a program counter, mark it as
a destination for the return address. If we have a register that
serves as the stack pointer, arrange for it to be filled with the
call frame address (CFA). The other registers are marked as
unspecified.
We copy the return address to the program counter, since many
parts in GDB assume that it is possible to get the return address
by unwinding the program counter register. However, on ISA's
with a dedicated return address register, the CFI usually only
contains information to unwind that return address register.
The reason we're treating the stack pointer special here is
because in many cases GCC doesn't emit CFI for the stack pointer
and implicitly assumes that it is equal to the CFA. This makes
some sense since the DWARF specification (version 3, draft 8,
p. 102) says that:
"Typically, the CFA is defined to be the value of the stack
pointer at the call site in the previous frame (which may be
different from its value on entry to the current frame)."
However, this isn't true for all platforms supported by GCC
(e.g. IBM S/390 and zSeries). Those architectures should provide
their own architecture-specific initialization function. */
if (regnum == PC_REGNUM)
reg->how = DWARF2_FRAME_REG_RA;
else if (regnum == SP_REGNUM)
reg->how = DWARF2_FRAME_REG_CFA;
}
/* Return a default for the architecture-specific operations. */
static void *
dwarf2_frame_init (struct gdbarch *gdbarch)
{
struct dwarf2_frame_ops *ops;
ops = GDBARCH_OBSTACK_ZALLOC (gdbarch, struct dwarf2_frame_ops);
ops->init_reg = dwarf2_frame_default_init_reg;
return ops;
}
/* Set the architecture-specific register state initialization
function for GDBARCH to INIT_REG. */
void
dwarf2_frame_set_init_reg (struct gdbarch *gdbarch,
void (*init_reg) (struct gdbarch *, int,
struct dwarf2_frame_state_reg *))
{
struct dwarf2_frame_ops *ops;
ops = gdbarch_data (gdbarch, dwarf2_frame_data);
ops->init_reg = init_reg;
}
/* Pre-initialize the register state REG for register REGNUM. */
static void
dwarf2_frame_init_reg (struct gdbarch *gdbarch, int regnum,
struct dwarf2_frame_state_reg *reg)
{
struct dwarf2_frame_ops *ops;
ops = gdbarch_data (gdbarch, dwarf2_frame_data);
ops->init_reg (gdbarch, regnum, reg);
}
struct dwarf2_frame_cache
{
@ -465,42 +555,6 @@ struct dwarf2_frame_cache
struct dwarf2_frame_state_reg *reg;
};
/* Initialize the register state REG. If we have a register that acts
as a program counter, mark it as a destination for the return
address. If we have a register that serves as the stack pointer,
arrange for it to be filled with the call frame address (CFA). The
other registers are marked as unspecified.
We copy the return address to the program counter, since many parts
in GDB assume that it is possible to get the return address by
unwind the program counter register. However, on ISA's with a
dedicated return address register, the CFI usually only contains
information to unwind that return address register.
The reason we're treating the stack pointer special here is because
in many cases GCC doesn't emit CFI for the stack pointer and
implicitly assumes that it is equal to the CFA. This makes some
sense since the DWARF specification (version 3, draft 8, p. 102)
says that:
"Typically, the CFA is defined to be the value of the stack pointer
at the call site in the previous frame (which may be different from
its value on entry to the current frame)."
However, this isn't true for all platforms supported by GCC
(e.g. IBM S/390 and zSeries). For those targets we should override
the defaults given here. */
static void
dwarf2_frame_init_reg (struct gdbarch *gdbarch, int regnum,
struct dwarf2_frame_state_reg *reg)
{
if (regnum == PC_REGNUM)
reg->how = DWARF2_FRAME_REG_RA;
else if (regnum == SP_REGNUM)
reg->how = DWARF2_FRAME_REG_CFA;
}
static struct dwarf2_frame_cache *
dwarf2_frame_cache (struct frame_info *next_frame, void **this_cache)
{
@ -851,7 +905,7 @@ struct comp_unit
bfd_vma tbase;
};
const struct objfile_data *dwarf2_frame_data;
const struct objfile_data *dwarf2_frame_objfile_data;
static unsigned int
read_1_byte (bfd *bfd, char *buf)
@ -1111,7 +1165,7 @@ dwarf2_frame_find_fde (CORE_ADDR *pc)
struct dwarf2_fde *fde;
CORE_ADDR offset;
fde = objfile_data (objfile, dwarf2_frame_data);
fde = objfile_data (objfile, dwarf2_frame_objfile_data);
if (fde == NULL)
continue;
@ -1137,8 +1191,8 @@ dwarf2_frame_find_fde (CORE_ADDR *pc)
static void
add_fde (struct comp_unit *unit, struct dwarf2_fde *fde)
{
fde->next = objfile_data (unit->objfile, dwarf2_frame_data);
set_objfile_data (unit->objfile, dwarf2_frame_data, fde);
fde->next = objfile_data (unit->objfile, dwarf2_frame_objfile_data);
set_objfile_data (unit->objfile, dwarf2_frame_objfile_data, fde);
}
#ifdef CC_HAS_LONG_LONG
@ -1461,7 +1515,6 @@ decode_frame_entry (struct comp_unit *unit, char *start, int eh_frame_p)
return ret;
}
/* FIXME: kettenis/20030504: This still needs to be integrated with
@ -1541,5 +1594,6 @@ void _initialize_dwarf2_frame (void);
void
_initialize_dwarf2_frame (void)
{
dwarf2_frame_data = register_objfile_data ();
dwarf2_frame_data = register_gdbarch_data (dwarf2_frame_init);
dwarf2_frame_objfile_data = register_objfile_data ();
}

View File

@ -71,6 +71,13 @@ struct dwarf2_frame_state_reg
enum dwarf2_frame_reg_rule how;
};
/* Set the architecture-specific register state initialization
function for GDBARCH to INIT_REG. */
extern void dwarf2_frame_set_init_reg (struct gdbarch *gdbarch,
void (*init_reg) (struct gdbarch *, int,
struct dwarf2_frame_state_reg *));
/* Return the frame unwind methods for the function that contains PC,
or NULL if it can't be handled by DWARF CFI frame unwinder. */