Commit 5025a549 by David Mosberger Committed by Hans Boehm

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
parent 03e9dbc9
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> 2002-03-14 Michael Meissner <meissner@redhat.com>
* params.def (PARAM_MAX_UNROLLED_INSNS): New macro, default to * params.def (PARAM_MAX_UNROLLED_INSNS): New macro, default to
......
...@@ -121,6 +121,17 @@ struct unw_reg_info ...@@ -121,6 +121,17 @@ struct unw_reg_info
int when; /* when the register gets saved */ 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 typedef struct unw_state_record
{ {
unsigned int first_region : 1; /* is this the first region? */ unsigned int first_region : 1; /* is this the first region? */
...@@ -141,11 +152,8 @@ typedef struct unw_state_record ...@@ -141,11 +152,8 @@ typedef struct unw_state_record
unsigned char gr_save_loc; /* next general register to use for saving */ unsigned char gr_save_loc; /* next general register to use for saving */
unsigned char return_link_reg; /* branch register for return link */ unsigned char return_link_reg; /* branch register for return link */
struct unw_reg_state { struct unw_labeled_state *labeled_states; /* list of all labeled states */
struct unw_reg_state *next; struct unw_reg_state curr; /* current state */
unsigned long label; /* label of this state record */
struct unw_reg_info reg[UNW_NUM_REGS];
} curr, *stack, *reg_state_list;
_Unwind_Personality_Fn personality; _Unwind_Personality_Fn personality;
...@@ -226,7 +234,7 @@ static unsigned char const save_order[] = ...@@ -226,7 +234,7 @@ static unsigned char const save_order[] =
#define MIN(X, Y) ((X) < (Y) ? (X) : (Y)) #define MIN(X, Y) ((X) < (Y) ? (X) : (Y))
/* Unwind decoder routines */ /* Routines to manipulate the state stack. */
static void static void
push (struct unw_state_record *sr) push (struct unw_state_record *sr)
...@@ -235,20 +243,56 @@ push (struct unw_state_record *sr) ...@@ -235,20 +243,56 @@ push (struct unw_state_record *sr)
rs = malloc (sizeof (struct unw_reg_state)); rs = malloc (sizeof (struct unw_reg_state));
memcpy (rs, &sr->curr, sizeof (*rs)); memcpy (rs, &sr->curr, sizeof (*rs));
rs->next = sr->stack; sr->curr.next = rs;
sr->stack = rs;
} }
static void static void
pop (struct unw_state_record *sr) pop (struct unw_state_record *sr)
{ {
struct unw_reg_state *rs; struct unw_reg_state *rs = sr->curr.next;
rs = sr->stack; if (!rs)
sr->stack = rs->next; abort();
memcpy(&sr->curr, rs, sizeof(*rs));
free (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)) static enum unw_register_index __attribute__((const))
decode_abreg (unsigned char abreg, int memory) decode_abreg (unsigned char abreg, int memory)
{ {
...@@ -396,7 +440,7 @@ desc_prologue (int body, unw_word rlen, unsigned char mask, ...@@ -396,7 +440,7 @@ desc_prologue (int body, unw_word rlen, unsigned char mask,
sr->first_region = 0; sr->first_region = 0;
/* Check if we're done. */ /* 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; sr->done = 1;
return; return;
...@@ -631,13 +675,15 @@ desc_epilogue (unw_word t, unw_word ecount, struct unw_state_record *sr) ...@@ -631,13 +675,15 @@ desc_epilogue (unw_word t, unw_word ecount, struct unw_state_record *sr)
static inline void static inline void
desc_copy_state (unw_word label, struct unw_state_record *sr) 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) if (ls->label == label)
{ {
memcpy (&sr->curr, rs, sizeof(sr->curr)); 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; return;
} }
} }
...@@ -647,13 +693,16 @@ desc_copy_state (unw_word label, struct unw_state_record *sr) ...@@ -647,13 +693,16 @@ desc_copy_state (unw_word label, struct unw_state_record *sr)
static inline void static inline void
desc_label_state (unw_word label, struct unw_state_record *sr) 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)); ls = malloc(sizeof(struct unw_labeled_state));
memcpy (rs, &sr->curr, sizeof (*rs)); ls->label = label;
rs->label = label; memcpy(&ls->saved_state, &sr->curr, sizeof(ls->saved_state));
rs->next = sr->reg_state_list; ls->saved_state.next = dup_state_stack(sr->curr.next);
sr->reg_state_list = rs;
/* insert into list of labeled states: */
ls->next = sr->labeled_states;
sr->labeled_states = ls;
} }
/* /*
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment