mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-03-19 03:40:26 +08:00
* init.c: Remove obsolete dwarf2 frame.h section.
From-SVN: r47445
This commit is contained in:
parent
2db1ab2d04
commit
c87222f074
@ -1,3 +1,7 @@
|
||||
2001-11-29 Richard Henderson <rth@redhat.com>
|
||||
|
||||
* init.c: Remove obsolete dwarf2 frame.h section.
|
||||
|
||||
2001-11-29 Joseph S. Myers <jsm28@cam.ac.uk>
|
||||
|
||||
* Make-lang.in (ada.generated-manpages): New dummy target.
|
||||
|
323
gcc/ada/init.c
323
gcc/ada/init.c
@ -4,7 +4,7 @@
|
||||
* *
|
||||
* I N I T *
|
||||
* *
|
||||
* $Revision$
|
||||
* $Revision: 1.6 $
|
||||
* *
|
||||
* C Implementation File *
|
||||
* *
|
||||
@ -1640,327 +1640,6 @@ __gnat_initialize ()
|
||||
#endif
|
||||
}
|
||||
|
||||
/***************************************/
|
||||
/* __gnat_initialize (default version) */
|
||||
/***************************************/
|
||||
|
||||
/* Get the stack unwinding mechanism when available and when compiling
|
||||
a-init.c for the run time. Except in the case of a restricted run-time,
|
||||
such as RT-Linux modules (__RT__ is defined). */
|
||||
|
||||
#elif defined (IN_RTS) && !defined (__RT__)
|
||||
|
||||
/* If we have a definition of INCOMING_RETURN_ADDR_RTX, assume that
|
||||
the rest of the DWARF 2 frame unwind support is also provided. */
|
||||
#if !defined (DWARF2_UNWIND_INFO) && defined (INCOMING_RETURN_ADDR_RTX)
|
||||
#define DWARF2_UNWIND_INFO 1
|
||||
#endif
|
||||
|
||||
#ifdef DWARF2_UNWIND_INFO
|
||||
#include "frame.h"
|
||||
|
||||
struct machine_state
|
||||
{
|
||||
frame_state f1, f2, f3;
|
||||
frame_state *udata, *udata_start, *sub_udata;
|
||||
void *pc, *pc_start, *new_pc;
|
||||
};
|
||||
|
||||
typedef int word_type __attribute__ ((mode (__word__)));
|
||||
|
||||
/* This type is used in get_reg and put_reg to deal with ABIs where a void*
|
||||
is smaller than a word, such as the Irix 6 n32 ABI. We cast twice to
|
||||
avoid a warning about casting between int and pointer of different
|
||||
sizes. */
|
||||
|
||||
typedef int ptr_type __attribute__ ((mode (pointer)));
|
||||
|
||||
static void get_reg PARAMS ((unsigned int, frame_state *,
|
||||
frame_state *));
|
||||
static void put_reg PARAMS ((unsigned int, void *,
|
||||
frame_state *));
|
||||
static void copy_reg PARAMS ((unsigned int, frame_state *,
|
||||
frame_state *));
|
||||
static inline void put_return_addr PARAMS ((void *, frame_state *));
|
||||
static inline void *get_return_addr PARAMS ((frame_state *,
|
||||
frame_state *));
|
||||
static frame_state *__frame_state_for_r PARAMS ((void *, frame_state *));
|
||||
|
||||
#ifdef INCOMING_REGNO
|
||||
static int in_reg_window PARAMS ((unsigned int, frame_state *));
|
||||
#endif
|
||||
|
||||
extern void __gnat_pop_frame PARAMS ((struct machine_state *));
|
||||
extern void __gnat_set_machine_state PARAMS ((struct machine_state *));
|
||||
extern void __gnat_enter_handler PARAMS ((struct machine_state *,
|
||||
void *));
|
||||
extern __SIZE_TYPE__ __gnat_machine_state_length PARAMS ((void));
|
||||
extern void *__gnat_get_code_loc PARAMS ((struct machine_state *));
|
||||
|
||||
/* Get the value of register REG as saved in UDATA, where SUB_UDATA is a
|
||||
frame called by UDATA or 0. */
|
||||
|
||||
static void *
|
||||
get_reg (reg, udata, sub_udata)
|
||||
unsigned int reg;
|
||||
frame_state *udata, *sub_udata;
|
||||
{
|
||||
if (udata->saved[reg] == REG_SAVED_OFFSET)
|
||||
return
|
||||
(void *) (ptr_type) *(word_type *) (udata->cfa
|
||||
+ udata->reg_or_offset[reg]);
|
||||
else if (udata->saved[reg] == REG_SAVED_REG && sub_udata)
|
||||
return get_reg (udata->reg_or_offset[reg], sub_udata, 0);
|
||||
else
|
||||
abort ();
|
||||
}
|
||||
|
||||
/* Overwrite the saved value for register REG in frame UDATA with VAL. */
|
||||
|
||||
static void
|
||||
put_reg (reg, val, udata)
|
||||
unsigned int reg;
|
||||
void *val;
|
||||
frame_state *udate;
|
||||
{
|
||||
if (udata->saved[reg] == REG_SAVED_OFFSET)
|
||||
*(word_type *) (udata->cfa + udata->reg_or_offset[reg])
|
||||
= (word_type) (ptr_type) val;
|
||||
else
|
||||
abort ();
|
||||
}
|
||||
|
||||
/* Copy the saved value for register REG from frame UDATA to frame
|
||||
TARGET_UDATA. Unlike the previous two functions, this can handle
|
||||
registers that are not one word large. */
|
||||
|
||||
static void
|
||||
copy_reg (reg, udata, target_udata)
|
||||
unsigned int reg;
|
||||
frame_state *udate, *target_udata;
|
||||
{
|
||||
if (udata->saved[reg] == REG_SAVED_OFFSET
|
||||
&& target_udata->saved[reg] == REG_SAVED_OFFSET)
|
||||
memcpy (target_udata->cfa + target_udata->reg_or_offset[reg],
|
||||
udata->cfa + udata->reg_or_offset[reg],
|
||||
__builtin_dwarf_reg_size (reg));
|
||||
else
|
||||
abort ();
|
||||
}
|
||||
|
||||
/* Overwrite the return address for frame UDATA with VAL. */
|
||||
|
||||
static inline void
|
||||
put_return_addr (val, udata)
|
||||
void *val;
|
||||
frame_state *udata;
|
||||
{
|
||||
val = __builtin_frob_return_addr (val);
|
||||
put_reg (udata->retaddr_column, val, udata);
|
||||
}
|
||||
|
||||
#ifdef INCOMING_REGNO
|
||||
|
||||
/* Is the saved value for register REG in frame UDATA stored in a register
|
||||
window in the previous frame? */
|
||||
|
||||
static int
|
||||
in_reg_window (reg, udata)
|
||||
unsigned int reg;
|
||||
frame_state *udata;
|
||||
{
|
||||
if (udata->saved[reg] != REG_SAVED_OFFSET)
|
||||
return 0;
|
||||
|
||||
#ifdef STACK_GROWS_DOWNWARD
|
||||
return udata->reg_or_offset[reg] > 0;
|
||||
#else
|
||||
return udata->reg_or_offset[reg] < 0;
|
||||
#endif
|
||||
}
|
||||
#endif /* INCOMING_REGNO */
|
||||
|
||||
/* Retrieve the return address for frame UDATA, where SUB_UDATA is a
|
||||
frame called by UDATA or 0. */
|
||||
|
||||
static inline void *
|
||||
get_return_addr (udata, sub_udata)
|
||||
frame_state *udate, *sub_udata;
|
||||
{
|
||||
return __builtin_extract_return_addr (get_reg (udata->retaddr_column,
|
||||
udata, sub_udata));
|
||||
}
|
||||
|
||||
/* Thread-safe version of __frame_state_for */
|
||||
|
||||
static frame_state *
|
||||
__frame_state_for_r (void *pc_target, frame_state *state_in)
|
||||
void *pc_target;
|
||||
frame_state *state_in;
|
||||
{
|
||||
frame_state *f;
|
||||
|
||||
(*Lock_Task) ();
|
||||
f = __frame_state_for (pc_target, state_in);
|
||||
(*Unlock_Task) ();
|
||||
return f;
|
||||
}
|
||||
|
||||
/* Given the current frame UDATA and its return address PC, return the
|
||||
information about the calling frame in CALLER_UDATA. */
|
||||
|
||||
void
|
||||
__gnat_pop_frame (m)
|
||||
struct machine_state *m;
|
||||
{
|
||||
frame_state *p;
|
||||
|
||||
int i;
|
||||
|
||||
m->pc = m->new_pc;
|
||||
p = m->udata;
|
||||
if (! __frame_state_for_r (m->pc, m->sub_udata))
|
||||
{
|
||||
m->new_pc = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Now go back to our caller's stack frame. If our caller's CFA register
|
||||
was saved in our stack frame, restore it; otherwise, assume the CFA
|
||||
register is SP and restore it to our CFA value. */
|
||||
if (m->udata->saved[m->sub_udata->cfa_reg])
|
||||
m->sub_udata->cfa = get_reg (m->sub_udata->cfa_reg, m->udata, 0);
|
||||
else
|
||||
m->sub_udata->cfa = m->udata->cfa;
|
||||
m->sub_udata->cfa += m->sub_udata->cfa_offset;
|
||||
|
||||
m->udata = m->sub_udata;
|
||||
m->sub_udata = p;
|
||||
m->new_pc = get_return_addr (m->udata, m->sub_udata) - 1;
|
||||
|
||||
return;
|
||||
|
||||
/* ??? disable this code for now since it doesn't work properly */
|
||||
#if 0
|
||||
if (m->pc == m->pc_start)
|
||||
return;
|
||||
|
||||
/* Copy the frame's saved register values into our register save slots. */
|
||||
|
||||
for (i = 0; i < FIRST_PSEUDO_REGISTER; ++i)
|
||||
if (i != m->udata->retaddr_column && m->udata->saved[i])
|
||||
{
|
||||
#ifdef INCOMING_REGNO
|
||||
/* If you modify the saved value of the return address
|
||||
register on the SPARC, you modify the return address for
|
||||
your caller's frame. Don't do that here, as it will
|
||||
confuse get_return_addr. */
|
||||
if (in_reg_window (i, m->udata)
|
||||
&& m->udata->saved[m->udata->retaddr_column] == REG_SAVED_REG
|
||||
&& m->udata->reg_or_offset[m->udata->retaddr_column] == i)
|
||||
continue;
|
||||
#endif
|
||||
copy_reg (i, m->udata, m->udata_start);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
__gnat_set_machine_state (machine_state)
|
||||
struct machine_state *machine_state;
|
||||
{
|
||||
frame_state sub_udata;
|
||||
|
||||
/* Start at our stack frame. */
|
||||
label:
|
||||
machine_state->udata = &machine_state->f1;
|
||||
machine_state->sub_udata = &machine_state->f2;
|
||||
machine_state->udata_start = &machine_state->f3;
|
||||
|
||||
if (! __frame_state_for_r (&&label, machine_state->udata))
|
||||
return;
|
||||
|
||||
/* We need to get the value from the CFA register. At this point in
|
||||
compiling libgnat.a we don't know whether or not we will use the frame
|
||||
pointer register for the CFA, so we check our unwind info. */
|
||||
if (machine_state->udata->cfa_reg == __builtin_dwarf_fp_regnum ())
|
||||
machine_state->udata->cfa = __builtin_fp ();
|
||||
else
|
||||
machine_state->udata->cfa = __builtin_sp ();
|
||||
machine_state->udata->cfa += machine_state->udata->cfa_offset;
|
||||
|
||||
memcpy (machine_state->udata_start, machine_state->udata,
|
||||
sizeof (frame_state));
|
||||
machine_state->new_pc =
|
||||
machine_state->pc_start =
|
||||
machine_state->pc = &&label;
|
||||
|
||||
/* Do any necessary initialization to access arbitrary stack frames.
|
||||
On the SPARC, this means flushing the register windows. */
|
||||
__builtin_unwind_init ();
|
||||
|
||||
/* go up one frame */
|
||||
__gnat_pop_frame (machine_state);
|
||||
}
|
||||
|
||||
void
|
||||
__gnat_enter_handler (m, handler)
|
||||
struct machine_state *m;
|
||||
void *handler;
|
||||
{
|
||||
void *retaddr;
|
||||
|
||||
#ifdef INCOMING_REGNO
|
||||
/* we need to update the saved return address register from
|
||||
the last frame we unwind, or the handler frame will have the wrong
|
||||
return address. */
|
||||
if (m->udata->saved[m->udata->retaddr_column] == REG_SAVED_REG)
|
||||
{
|
||||
int i = m->udata->reg_or_offset[m->udata->retaddr_column];
|
||||
if (in_reg_window (i, m->udata))
|
||||
copy_reg (i, m->udata, m->udata_start);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Emit the stub to adjust sp and jump to the handler. */
|
||||
retaddr = __builtin_eh_stub ();
|
||||
|
||||
/* And then set our return address to point to the stub. */
|
||||
if (m->udata_start->saved[m->udata_start->retaddr_column] ==
|
||||
REG_SAVED_OFFSET)
|
||||
put_return_addr (retaddr, m->udata_start);
|
||||
else
|
||||
__builtin_set_return_addr_reg (retaddr);
|
||||
|
||||
/* Set up the registers we use to communicate with the stub.
|
||||
We check STACK_GROWS_DOWNWARD so the stub can use adjust_stack. */
|
||||
__builtin_set_eh_regs
|
||||
(handler,
|
||||
#ifdef STACK_GROWS_DOWNWARD
|
||||
m->udata->cfa - m->udata_start->cfa
|
||||
#else
|
||||
m->udata_start->cfa - m->udata->cfa
|
||||
#endif
|
||||
+ m->udata->args_size);
|
||||
|
||||
/* Epilogue: restore the handler frame's register values and return
|
||||
to the stub. */
|
||||
}
|
||||
|
||||
__SIZE_TYPE__
|
||||
__gnat_machine_state_length ()
|
||||
{
|
||||
return sizeof (struct machine_state);
|
||||
}
|
||||
|
||||
void *
|
||||
__gnat_get_code_loc (m)
|
||||
struct machine_state *m;
|
||||
{
|
||||
return m->pc;
|
||||
}
|
||||
#endif /* DWARF2_UNWIND_INFO */
|
||||
|
||||
#else
|
||||
|
||||
/* For all other versions of GNAT, the initialize routine and handler
|
||||
|
Loading…
x
Reference in New Issue
Block a user