unwind-ia64.c: Handle copy_state and label_state descriptors correctly.

* config/ia64/unwind-ia64.c: Handle copy_state and label_state
	  descriptors correctly.

From-SVN: r50789
This commit is contained in:
David Mosberger 2002-03-15 01:55:49 +00:00 committed by Hans Boehm
parent 03e9dbc91c
commit 5025a549a1
2 changed files with 77 additions and 23 deletions

View File

@ -1,3 +1,8 @@
2002-03-14 David Mosberger <davidm@hpl.hp.com>, Hans Boehm <Hans_Boehm@hp.com>
* config/ia64/unwind-ia64.c: Handle copy_state and label_state
descriptors correctly.
2002-03-14 Michael Meissner <meissner@redhat.com>
* params.def (PARAM_MAX_UNROLLED_INSNS): New macro, default to

View File

@ -121,6 +121,17 @@ struct unw_reg_info
int when; /* when the register gets saved */
};
struct unw_reg_state {
struct unw_reg_state *next; /* next (outer) element on state stack */
struct unw_reg_info reg[UNW_NUM_REGS]; /* register save locations */
};
struct unw_labeled_state {
struct unw_labeled_state *next; /* next labeled state (or NULL) */
unsigned long label; /* label for this state */
struct unw_reg_state saved_state;
};
typedef struct unw_state_record
{
unsigned int first_region : 1; /* is this the first region? */
@ -141,11 +152,8 @@ typedef struct unw_state_record
unsigned char gr_save_loc; /* next general register to use for saving */
unsigned char return_link_reg; /* branch register for return link */
struct unw_reg_state {
struct unw_reg_state *next;
unsigned long label; /* label of this state record */
struct unw_reg_info reg[UNW_NUM_REGS];
} curr, *stack, *reg_state_list;
struct unw_labeled_state *labeled_states; /* list of all labeled states */
struct unw_reg_state curr; /* current state */
_Unwind_Personality_Fn personality;
@ -226,7 +234,7 @@ static unsigned char const save_order[] =
#define MIN(X, Y) ((X) < (Y) ? (X) : (Y))
/* Unwind decoder routines */
/* Routines to manipulate the state stack. */
static void
push (struct unw_state_record *sr)
@ -235,20 +243,56 @@ push (struct unw_state_record *sr)
rs = malloc (sizeof (struct unw_reg_state));
memcpy (rs, &sr->curr, sizeof (*rs));
rs->next = sr->stack;
sr->stack = rs;
sr->curr.next = rs;
}
static void
pop (struct unw_state_record *sr)
{
struct unw_reg_state *rs;
struct unw_reg_state *rs = sr->curr.next;
rs = sr->stack;
sr->stack = rs->next;
if (!rs)
abort();
memcpy(&sr->curr, rs, sizeof(*rs));
free (rs);
}
/* Make a copy of the state stack. Non-recursive to avoid stack overflows. */
static struct unw_reg_state *
dup_state_stack (struct unw_reg_state *rs)
{
struct unw_reg_state *copy, *prev = NULL, *first = NULL;
while (rs)
{
copy = malloc(sizeof(struct unw_state_record));
memcpy(copy, rs, sizeof(*copy));
if (first)
prev->next = copy;
else
first = copy;
rs = rs->next;
prev = copy;
}
return first;
}
/* Free all stacked register states (but not RS itself). */
static void
free_state_stack (struct unw_reg_state *rs)
{
struct unw_reg_state *p, *next;
for (p = rs->next; p != NULL; p = next)
{
next = p->next;
free(p);
}
rs->next = NULL;
}
/* Unwind decoder routines */
static enum unw_register_index __attribute__((const))
decode_abreg (unsigned char abreg, int memory)
{
@ -396,7 +440,7 @@ desc_prologue (int body, unw_word rlen, unsigned char mask,
sr->first_region = 0;
/* Check if we're done. */
if (body && sr->when_target < sr->region_start + sr->region_len)
if (sr->when_target < sr->region_start + sr->region_len)
{
sr->done = 1;
return;
@ -631,13 +675,15 @@ desc_epilogue (unw_word t, unw_word ecount, struct unw_state_record *sr)
static inline void
desc_copy_state (unw_word label, struct unw_state_record *sr)
{
struct unw_reg_state *rs;
struct unw_labeled_state *ls;
for (rs = sr->reg_state_list; rs; rs = rs->next)
for (ls = sr->labeled_states; ls; ls = ls->next)
{
if (rs->label == label)
{
memcpy (&sr->curr, rs, sizeof(sr->curr));
if (ls->label == label)
{
free_state_stack(&sr->curr);
memcpy(&sr->curr, &ls->saved_state, sizeof(sr->curr));
sr->curr.next = dup_state_stack(ls->saved_state.next);
return;
}
}
@ -647,13 +693,16 @@ desc_copy_state (unw_word label, struct unw_state_record *sr)
static inline void
desc_label_state (unw_word label, struct unw_state_record *sr)
{
struct unw_reg_state *rs;
struct unw_labeled_state *ls;
rs = malloc (sizeof (struct unw_reg_state));
memcpy (rs, &sr->curr, sizeof (*rs));
rs->label = label;
rs->next = sr->reg_state_list;
sr->reg_state_list = rs;
ls = malloc(sizeof(struct unw_labeled_state));
ls->label = label;
memcpy(&ls->saved_state, &sr->curr, sizeof(ls->saved_state));
ls->saved_state.next = dup_state_stack(sr->curr.next);
/* insert into list of labeled states: */
ls->next = sr->labeled_states;
sr->labeled_states = ls;
}
/*