Commit a1622f83 by Andrew MacLeod Committed by Andrew Macleod

[multiple changes]

Thu Jun  8 14:16:15 EDT 1998  Andrew MacLeod  <amacleod@cygnus.com>
	* eh-common.h: Remove NEW_EH_MODEL compile time flag, and replace with
	flag_new_exceptions runtime flag.
	(struct old_exception_table): New struct which represents what
	the exception table looks like without the new model.
	(NEW_EH_RUNTIME): New value used as a tag in the exception table to
	flag that this is a new style table.
	* except.h: Remove compile time flag NEW_EH_MODEL.
	(expand_builtin_eh_stub_old): New prototype.
	* tree.h (enum built_in_function): Add BUILT_IN_EH_STUB_OLD.
	* expr.c (expand_builtin): New builtin func BUILT_IN_EH_STUB_OLD.
	* c-decl.c (init_decl_processing): Add new builtin function
	__builtin_eh_stub_old.
	* final.c (final_scan_insn): Replace compile time flag NEW_EH_MODEL.
	* flags.h (flag_new_exceptions): New runtime flag.
	* toplev.c (flag_new_exceptions): Initialize default to 0,
	-fnew-exceptions sets to 1.
	* except.c (output_exception_table_entry): Output New style exception
	identifier into table, and replace compile time flag NEW_EH_MODEL
	with runtime flag flag_new_exceptions.
	(output_exception_table): Replace compile time flag NEW_EH_MODEL.
	(expand_builtin_eh_stub_old): Duplicates original functionality of
	expand_builtin_eh_stub.
	(expand_builtin_eh_stub): Replace compile time flag NEW_EH_MODEL.
	* libgcc2.c (find_exception_handler): Remove NEW_EH_MODEL #ifdefs.
	(old_find_exception_handler): New func, same as find_exception_handler
	except it works on the old style exception table.
	(__throw): Replace NEW_EH_MODEL. Detect new model based on presence
	of identifier in the exception table, and call appropriate routines.
1998-06-08  Andrew MacLeod  <amacleod@cygnus.com>
	* except.c (init_exception_processing): Remove NEW_EH_MODEL compile
	time flag.  Call __cp_eh_info instead of __cp_exception_info.
	* exception.cc (struct cp_eh_info): Remove NEW_EH_MODEL flag.
	(__cp_exception_info): Return offset into cp_eh_info structure to
	match what use to be the start of this structure.
	(__cp_eh_info): New function to return a pointer to cp_eh_info struct.
	(__cplus_type_matcher, __cp_push_exception): Remove NEW_EH_MODEL
	compile time flag.
	(__uncatch_exception, __check_eh_spec, std::uncaught_exception): Call
	__cp_eh_info instead of __cp_exception_info.

From-SVN: r20336
parent aeb302bb
Mon Jun 8 14:16:15 EDT 1998 Andrew MacLeod <amacleod@cygnus.com>
* eh-common.h: Remove NEW_EH_MODEL compile time flag, and replace with
flag_new_exceptions runtime flag.
(struct old_exception_table): New struct which represents what
the exception table looks like without the new model.
(NEW_EH_RUNTIME): New value used as a tag in the exception table to
flag that this is a new style table.
* except.h: Remove compile time flag NEW_EH_MODEL.
(expand_builtin_eh_stub_old): New prototype.
* tree.h (enum built_in_function): Add BUILT_IN_EH_STUB_OLD.
* expr.c (expand_builtin): New builtin func BUILT_IN_EH_STUB_OLD.
* c-decl.c (init_decl_processing): Add new builtin function
__builtin_eh_stub_old.
* final.c (final_scan_insn): Replace compile time flag NEW_EH_MODEL.
* flags.h (flag_new_exceptions): New runtime flag.
* toplev.c (flag_new_exceptions): Initialize default to 0,
-fnew-exceptions sets to 1.
* except.c (output_exception_table_entry): Output New style exception
identifier into table, and replace compile time flag NEW_EH_MODEL
with runtime flag flag_new_exceptions.
(output_exception_table): Replace compile time flag NEW_EH_MODEL.
(expand_builtin_eh_stub_old): Duplicates original functionality of
expand_builtin_eh_stub.
(expand_builtin_eh_stub): Replace compile time flag NEW_EH_MODEL.
* libgcc2.c (find_exception_handler): Remove NEW_EH_MODEL #ifdefs.
(old_find_exception_handler): New func, same as find_exception_handler
except it works on the old style exception table.
(__throw): Replace NEW_EH_MODEL. Detect new model based on presence
of identifier in the exception table, and call appropriate routines.
Mon Jun 8 01:21:13 1998 Jason Merrill <jason@yorick.cygnus.com>
* function.c: Define current_function_cannot_inline.
......
......@@ -3260,6 +3260,8 @@ init_decl_processing ()
ptr_type_node,
endlink)),
BUILT_IN_SET_RETURN_ADDR_REG, NULL_PTR);
builtin_function ("__builtin_eh_stub_old", ptr_ftype_void,
BUILT_IN_EH_STUB_OLD, NULL_PTR);
builtin_function ("__builtin_eh_stub", ptr_ftype_void,
BUILT_IN_EH_STUB, NULL_PTR);
builtin_function
......
1998-06-08 Andrew MacLeod <amacleod@cygnus.com>
* except.c (init_exception_processing): Remove NEW_EH_MODEL compile
time flag. Call __cp_eh_info instead of __cp_exception_info.
* exception.cc (struct cp_eh_info): Remove NEW_EH_MODEL flag.
(__cp_exception_info): Return offset into cp_eh_info structure to
match what use to be the start of this structure.
(__cp_eh_info): New function to return a pointer to cp_eh_info struct.
(__cplus_type_matcher, __cp_push_exception): Remove NEW_EH_MODEL
compile time flag.
(__uncatch_exception, __check_eh_spec, std::uncaught_exception): Call
__cp_eh_info instead of __cp_exception_info.
1998-06-08 Jason Merrill <jason@yorick.cygnus.com>
* decl.c (cp_finish_decl): Disable inlining of extern inlines
......
......@@ -203,10 +203,8 @@ init_exception_processing ()
push_lang_context (lang_name_c);
#ifdef NEW_EH_MODEL
set_exception_lang_code (EH_LANG_C_plus_plus);
set_exception_version_code (1);
#endif
CatchMatch
= builtin_function (flag_rtti
......@@ -245,25 +243,20 @@ call_eh_info ()
{
tree fn;
fn = get_identifier ("__cp_exception_info");
fn = get_identifier ("__cp_eh_info");
if (IDENTIFIER_GLOBAL_VALUE (fn))
fn = IDENTIFIER_GLOBAL_VALUE (fn);
else
{
#ifdef NEW_EH_MODEL
tree t1;
#endif
tree t, fields[7];
int fo = 0;
tree t1, t, fields[7];
/* Declare cp_eh_info * __cp_exception_info (void),
/* Declare cp_eh_info * __cp_eh_info (void),
as defined in exception.cc. */
push_obstacks_nochange ();
end_temporary_allocation ();
/* struct cp_eh_info. This must match exception.cc. Note that this
type is not pushed anywhere. */
#ifdef NEW_EH_MODEL
t1= make_lang_type (RECORD_TYPE);
fields[0] = build_lang_field_decl (FIELD_DECL,
get_identifier ("handler_label"), ptr_type_node);
......@@ -288,31 +281,27 @@ call_eh_info ()
/* N.B.: The fourth field LEN is expected to be
the number of fields - 1, not the total number of fields. */
finish_builtin_type (t1, "__eh_info", fields, 3, ptr_type_node);
fo = 1;
#endif
t = make_lang_type (RECORD_TYPE);
#ifdef NEW_EH_MODEL
fields[0] = build_lang_field_decl (FIELD_DECL, get_identifier ("eh_info"),
t1);
#endif
fields[0+fo] = build_lang_field_decl (FIELD_DECL, get_identifier ("value"),
fields[0] = build_lang_field_decl (FIELD_DECL,
get_identifier ("eh_info"), t1);
fields[1] = build_lang_field_decl (FIELD_DECL, get_identifier ("value"),
ptr_type_node);
fields[1+fo] = build_lang_field_decl (FIELD_DECL, get_identifier ("type"),
fields[2] = build_lang_field_decl (FIELD_DECL, get_identifier ("type"),
ptr_type_node);
fields[2+fo] = build_lang_field_decl
fields[3] = build_lang_field_decl
(FIELD_DECL, get_identifier ("cleanup"),
build_pointer_type (build_function_type
(ptr_type_node, tree_cons
(NULL_TREE, ptr_type_node, void_list_node))));
fields[3+fo] = build_lang_field_decl (FIELD_DECL, get_identifier ("caught"),
fields[4] = build_lang_field_decl (FIELD_DECL, get_identifier ("caught"),
boolean_type_node);
fields[4+fo] = build_lang_field_decl (FIELD_DECL, get_identifier ("next"),
fields[5] = build_lang_field_decl (FIELD_DECL, get_identifier ("next"),
build_pointer_type (t));
fields[5+fo] = build_lang_field_decl
fields[6] = build_lang_field_decl
(FIELD_DECL, get_identifier ("handlers"), long_integer_type_node);
/* N.B.: The fourth field LEN is expected to be
the number of fields - 1, not the total number of fields. */
finish_builtin_type (t, "cp_eh_info", fields, 5+fo, ptr_type_node);
finish_builtin_type (t, "cp_eh_info", fields, 6, ptr_type_node);
t = build_pointer_type (t);
/* And now the function. */
......
......@@ -86,9 +86,7 @@ std::unexpected ()
struct cp_eh_info
{
#ifdef NEW_EH_MODEL
__eh_info eh_info;
#endif
void *value;
void *type;
void (*cleanup)(void *, int);
......@@ -105,11 +103,23 @@ extern "C" cp_eh_info **__get_eh_info (); // actually void **
extern bool __is_pointer (void *);
/* OLD Compiler hook to return a pointer to the info for the current exception.
Used by get_eh_info (). This fudges the actualy returned value to
point to the beginning of what USE to be the cp_eh_info structure.
THis is so that old code that dereferences this pointer will find
things where it expects it to be.*/
extern "C" void *
__cp_exception_info (void)
{
return &((*__get_eh_info ())->value);
}
/* Compiler hook to return a pointer to the info for the current exception.
Used by get_eh_info (). */
extern "C" cp_eh_info *
__cp_exception_info (void)
__cp_eh_info (void)
{
return *__get_eh_info ();
}
......@@ -138,8 +148,6 @@ __eh_free (void *p)
}
#ifdef NEW_EH_MODEL
typedef void * (* rtimetype) (void);
extern "C" void *
......@@ -157,7 +165,6 @@ __cplus_type_matcher (cp_eh_info *info, exception_table *matching_info,
ret = __throw_type_match_rtti (match_type, info->type, info->value);
return ret;
}
#endif
/* Compiler hook to push a new exception onto the stack.
......@@ -174,12 +181,10 @@ __cp_push_exception (void *value, void *type, void (*cleanup)(void *, int))
p->handlers = 0;
p->caught = false;
#ifdef NEW_EH_MODEL
p->eh_info.match_function = __cplus_type_matcher;
p->eh_info.language = EH_LANG_C_plus_plus;
p->eh_info.version = 1;
p->eh_info.coerced_value = NULL;
#endif
cp_eh_info **q = __get_eh_info ();
......@@ -227,7 +232,7 @@ __cp_pop_exception (cp_eh_info *p)
extern "C" void
__uncatch_exception (void)
{
cp_eh_info *p = __cp_exception_info ();
cp_eh_info *p = __cp_eh_info ();
if (p == 0)
terminate ();
p->caught = false;
......@@ -248,7 +253,7 @@ __uncatch_exception (void)
extern "C" void
__check_eh_spec (int n, const void **spec)
{
cp_eh_info *p = __cp_exception_info ();
cp_eh_info *p = __cp_eh_info ();
for (int i = 0; i < n; ++i)
{
......@@ -301,7 +306,7 @@ __throw_bad_typeid (void)
bool
std::uncaught_exception ()
{
cp_eh_info *p = __cp_exception_info ();
cp_eh_info *p = __cp_eh_info ();
return p && ! p->caught;
}
......
......@@ -5,7 +5,7 @@
independant exception handling model. Both the static compiler and
the runtime library share this file. */
/* The compiler flag NEW_EH_MODEL is used to determine whether the
/* The runtime flag flag_new_exceptions is used to determine whether the
compiler supports the new runtime typechecking mechanism or not. Under
the new model, runtime info is contained in the exception table, and
the __throw() library routine determines which handler to call based
......@@ -18,17 +18,6 @@
#include "gansidecl.h"
#ifndef NEW_EH_MODEL
struct eh_context
{
void **dynamic_handler_chain;
/* This is language dependent part of the eh context. */
void *info;
};
#else
/* The handler_label field MUST be the first field in this structure. The
__throw() library routine expects uses __eh_stub() from except.c, which
simply dereferences the context pointer to get the handler */
......@@ -41,23 +30,14 @@ struct eh_context
void *info;
};
#endif
#ifndef EH_TABLE_LOOKUP
#ifndef NEW_EH_MODEL
typedef struct exception_table
typedef struct old_exception_table
{
void *start_region;
void *end_region;
void *exception_handler;
} exception_table;
typedef exception_table exception_descriptor;
#else
} old_exception_table;
typedef struct exception_table
{
......@@ -76,11 +56,18 @@ typedef struct exception_lang_info
short version;
} exception_lang_info;
/* This value in the first field of the exception descriptor
identifies the descriptor as the new model format. This value would never
be present in this location under the old model */
#define NEW_EH_RUNTIME ((void *) -2)
/* Each function has an exception_descriptor which contains the
language info, and a table of exception ranges and handlers */
typedef struct exception_descriptor
{
void *runtime_id_field;
exception_lang_info lang;
exception_table table[1];
} exception_descriptor;
......@@ -126,8 +113,6 @@ enum exception_source_language
EH_LANG_Mips_Assembler = 0x8001
};
#endif
#endif /* EH_TABLE_LOOKUP */
......@@ -1842,23 +1842,20 @@ output_exception_table_entry (file, n)
assemble_integer (handler->handler_label,
POINTER_SIZE / BITS_PER_UNIT, 1);
#ifdef NEW_EH_MODEL
/* for now make sure the sizes match */
if (handler->type_info == NULL)
assemble_integer (const0_rtx, POINTER_SIZE / BITS_PER_UNIT, 1);
else
output_constant ((tree)(handler->type_info),
if (flag_new_exceptions)
{
if (handler->type_info == NULL)
assemble_integer (const0_rtx, POINTER_SIZE / BITS_PER_UNIT, 1);
else
output_constant ((tree)(handler->type_info),
POINTER_SIZE / BITS_PER_UNIT);
#endif
}
putc ('\n', file); /* blank line */
}
}
/* Output the exception table if we have and need one. */
#ifdef NEW_EH_MODEL
static short language_code = 0;
static short version_code = 0;
......@@ -1876,7 +1873,6 @@ void set_exception_version_code (code)
version_code = code;
}
#endif
void
output_exception_table ()
......@@ -1893,17 +1889,20 @@ output_exception_table ()
assemble_align (GET_MODE_ALIGNMENT (ptr_mode));
assemble_label ("__EXCEPTION_TABLE__");
#ifdef NEW_EH_MODEL
assemble_integer (GEN_INT (language_code), 2 , 1);
assemble_integer (GEN_INT (version_code), 2 , 1);
/* Add enough padding to make sure table aligns on a pointer boundry. */
i = GET_MODE_ALIGNMENT (ptr_mode) / BITS_PER_UNIT - 4;
for ( ; i < 0; i = i + GET_MODE_ALIGNMENT (ptr_mode) / BITS_PER_UNIT)
;
if (i != 0)
assemble_integer (const0_rtx, i , 1);
#endif
if (flag_new_exceptions)
{
assemble_integer (GEN_INT (NEW_EH_RUNTIME),
POINTER_SIZE / BITS_PER_UNIT, 1);
assemble_integer (GEN_INT (language_code), 2 , 1);
assemble_integer (GEN_INT (version_code), 2 , 1);
/* Add enough padding to make sure table aligns on a pointer boundry. */
i = GET_MODE_ALIGNMENT (ptr_mode) / BITS_PER_UNIT - 4;
for ( ; i < 0; i = i + GET_MODE_ALIGNMENT (ptr_mode) / BITS_PER_UNIT)
;
if (i != 0)
assemble_integer (const0_rtx, i , 1);
}
for (i = 0; i < eh_table_size; ++i)
output_exception_table_entry (asm_out_file, eh_table[i]);
......@@ -1913,11 +1912,12 @@ output_exception_table ()
/* Ending marker for table. */
assemble_integer (constm1_rtx, POINTER_SIZE / BITS_PER_UNIT, 1);
#ifndef NEW_EH_MODEL
/* for binary compatability, the old __throw checked the second
position for a -1, so we should output at least 2 -1's */
assemble_integer (constm1_rtx, POINTER_SIZE / BITS_PER_UNIT, 1);
#endif
if (! flag_new_exceptions)
assemble_integer (constm1_rtx, POINTER_SIZE / BITS_PER_UNIT, 1);
putc ('\n', asm_out_file); /* blank line */
}
......@@ -2424,11 +2424,30 @@ get_reg_for_handler ()
and then return to the stub. */
rtx
expand_builtin_eh_stub_old ()
{
rtx stub_start = gen_label_rtx ();
rtx after_stub = gen_label_rtx ();
rtx handler, offset;
emit_jump (after_stub);
emit_label (stub_start);
eh_regs (&handler, &offset, 0);
adjust_stack (offset);
emit_indirect_jump (handler);
emit_label (after_stub);
return gen_rtx_LABEL_REF (Pmode, stub_start);
}
rtx
expand_builtin_eh_stub ()
{
rtx stub_start = gen_label_rtx ();
rtx after_stub = gen_label_rtx ();
rtx handler, offset;
rtx jump_to, temp;
emit_jump (after_stub);
emit_label (stub_start);
......@@ -2436,28 +2455,19 @@ expand_builtin_eh_stub ()
eh_regs (&handler, &offset, 0);
adjust_stack (offset);
#ifdef NEW_EH_MODEL
/* Handler is in fact a pointer to the _eh_context structure, we need
to pick out the handler field (first element), and jump to there,
leaving the pointer to _eh_conext in the same hardware register. */
{
rtx jump_to, temp;
temp = gen_rtx_MEM (Pmode, handler);
MEM_IN_STRUCT_P (temp) = 1;
RTX_UNCHANGING_P (temp) = 1;
emit_insn (gen_rtx_SET (Pmode, offset, temp));
emit_insn (gen_rtx_USE (Pmode, handler));
temp = gen_rtx_MEM (Pmode, handler);
MEM_IN_STRUCT_P (temp) = 1;
RTX_UNCHANGING_P (temp) = 1;
emit_insn (gen_rtx_SET (Pmode, offset, temp));
emit_insn (gen_rtx_USE (Pmode, handler));
emit_indirect_jump (offset);
emit_indirect_jump (offset);
}
#else
emit_indirect_jump (handler);
#endif
emit_label (after_stub);
return gen_rtx_LABEL_REF (Pmode, stub_start);
}
......
......@@ -149,13 +149,9 @@ extern int doing_eh PROTO ((int));
/* Toplevel initialization for EH. */
#ifdef NEW_EH_MODEL
void set_exception_lang_code PROTO((short));
void set_exception_version_code PROTO((short));
#endif
/* A list of handlers asocciated with an exception region. HANDLER_LABEL
is the the label that control should be transfered to if the data
in TYPE_INFO matches an exception. a value of NULL_TREE for TYPE_INFO
......@@ -381,6 +377,7 @@ extern void expand_fixup_region_end PROTO((tree));
void expand_builtin_unwind_init PROTO((void));
rtx expand_builtin_dwarf_fp_regnum PROTO((void));
rtx expand_builtin_eh_stub PROTO((void));
rtx expand_builtin_eh_stub_old PROTO((void));
#ifdef TREE_CODE
rtx expand_builtin_frob_return_addr PROTO((tree));
rtx expand_builtin_extract_return_addr PROTO((tree));
......
......@@ -8954,6 +8954,8 @@ expand_builtin (exp, target, subtarget, mode, ignore)
case BUILT_IN_SET_RETURN_ADDR_REG:
expand_builtin_set_return_addr_reg (TREE_VALUE (arglist));
return const0_rtx;
case BUILT_IN_EH_STUB_OLD:
return expand_builtin_eh_stub_old ();
case BUILT_IN_EH_STUB:
return expand_builtin_eh_stub ();
case BUILT_IN_SET_EH_REGS:
......
......@@ -2057,9 +2057,8 @@ final_scan_insn (insn, file, optimize, prescan, nopeepholes)
&& ! exceptions_via_longjmp)
{
ASM_OUTPUT_INTERNAL_LABEL (file, "LEHB", NOTE_BLOCK_NUMBER (insn));
#ifndef NEW_EH_MODEL
add_eh_table_entry (NOTE_BLOCK_NUMBER (insn));
#endif
if (! flag_new_exceptions)
add_eh_table_entry (NOTE_BLOCK_NUMBER (insn));
#ifdef ASM_OUTPUT_EH_REGION_BEG
ASM_OUTPUT_EH_REGION_BEG (file, NOTE_BLOCK_NUMBER (insn));
#endif
......@@ -2070,9 +2069,8 @@ final_scan_insn (insn, file, optimize, prescan, nopeepholes)
&& ! exceptions_via_longjmp)
{
ASM_OUTPUT_INTERNAL_LABEL (file, "LEHE", NOTE_BLOCK_NUMBER (insn));
#ifdef NEW_EH_MODEL
add_eh_table_entry (NOTE_BLOCK_NUMBER (insn));
#endif
if (flag_new_exceptions)
add_eh_table_entry (NOTE_BLOCK_NUMBER (insn));
#ifdef ASM_OUTPUT_EH_REGION_END
ASM_OUTPUT_EH_REGION_END (file, NOTE_BLOCK_NUMBER (insn));
#endif
......
......@@ -377,6 +377,11 @@ extern int flag_pic;
extern int flag_exceptions;
/* Nonzero means use the new model for exception handling. Replaces
-DNEW_EH_MODEL as a compile option. */
extern int flag_new_exceptions;
/* Nonzero means don't place uninitialized global data in common storage
by default. */
......
......@@ -3367,11 +3367,41 @@ EH_TABLE_LOOKUP
an inner block. */
static void *
old_find_exception_handler (void *pc, old_exception_table *table)
{
if (table)
{
int pos;
int best = -1;
/* We can't do a binary search because the table isn't guaranteed
to be sorted from function to function. */
for (pos = 0; table[pos].start_region != (void *) -1; ++pos)
{
if (table[pos].start_region <= pc && table[pos].end_region > pc)
{
/* This can apply. Make sure it is at least as small as
the previous best. */
if (best == -1 || (table[pos].end_region <= table[best].end_region
&& table[pos].start_region >= table[best].start_region))
best = pos;
}
/* But it is sorted by starting PC within a function. */
else if (best >= 0 && table[pos].start_region > pc)
break;
}
if (best != -1)
return table[best].exception_handler;
}
return (void *) 0;
}
static void *
find_exception_handler (void *pc, exception_descriptor *table, void *eh_info)
{
if (table)
{
#ifdef NEW_EH_MODEL
/* The new model assumed the table is sorted inner-most out so the
first region we find which matches is the correct one */
......@@ -3406,29 +3436,6 @@ find_exception_handler (void *pc, exception_descriptor *table, void *eh_info)
return tab[pos].exception_handler;
}
}
#else
int pos;
int best = -1;
/* We can't do a binary search because the table isn't guaranteed
to be sorted from function to function. */
for (pos = 0; table[pos].start_region != (void *) -1; ++pos)
{
if (table[pos].start_region <= pc && table[pos].end_region > pc)
{
/* This can apply. Make sure it is at least as small as
the previous best. */
if (best == -1 || (table[pos].end_region <= table[best].end_region
&& table[pos].start_region >= table[best].start_region))
best = pos;
}
/* But it is sorted by starting PC within a function. */
else if (best >= 0 && table[pos].start_region > pc)
break;
}
if (best != -1)
return table[best].exception_handler;
#endif
}
return (void *) 0;
......@@ -3568,6 +3575,7 @@ __throw ()
frame_state *sub_udata = &ustruct2;
frame_state my_ustruct, *my_udata = &my_ustruct;
long args_size;
int new_exception_model;
/* This is required for C++ semantics. We must call terminate if we
try and rethrow an exception, when there is no exception currently
......@@ -3611,7 +3619,16 @@ label:
if (! udata)
break;
handler = find_exception_handler (pc, udata->eh_ptr, eh->info);
if (udata->eh_ptr == NULL)
new_exception_model = 0;
else
new_exception_model = (((exception_descriptor *)(udata->eh_ptr))->
runtime_id_field == NEW_EH_RUNTIME);
if (new_exception_model)
handler = find_exception_handler (pc, udata->eh_ptr, eh->info);
else
handler = old_find_exception_handler (pc, udata->eh_ptr);
/* If we found one, we can stop searching. */
if (handler)
......@@ -3630,9 +3647,7 @@ label:
if (! handler)
__terminate ();
#ifdef NEW_EH_MODEL
eh->handler_label = handler;
#endif
if (pc == saved_pc)
/* We found a handler in the throw context, no need to unwind. */
......@@ -3691,7 +3706,10 @@ label:
/* udata now refers to the frame called by the handler frame. */
/* Emit the stub to adjust sp and jump to the handler. */
retaddr = __builtin_eh_stub ();
if (new_exception_model)
retaddr = __builtin_eh_stub ();
else
retaddr = __builtin_eh_stub_old ();
/* And then set our return address to point to the stub. */
if (my_udata->saved[my_udata->retaddr_column] == REG_SAVED_OFFSET)
......@@ -3702,19 +3720,23 @@ label:
/* Set up the registers we use to communicate with the stub.
We check STACK_GROWS_DOWNWARD so the stub can use adjust_stack. */
#ifdef NEW_EH_MODEL
__builtin_set_eh_regs ((void *)eh,
if (new_exception_model)
__builtin_set_eh_regs ((void *)eh,
#ifdef STACK_GROWS_DOWNWARD
udata->cfa - my_udata->cfa
#else
__builtin_set_eh_regs (handler,
my_udata->cfa - udata->cfa
#endif
+ args_size);
else
__builtin_set_eh_regs (handler,
#ifdef STACK_GROWS_DOWNWARD
udata->cfa - my_udata->cfa
#else
my_udata->cfa - udata->cfa
#endif
+ args_size
);
+ args_size);
/* Epilogue: restore the handler frame's register values and return
to the stub. */
......
......@@ -600,6 +600,11 @@ int flag_pic;
int flag_exceptions;
/* Nonzero means use the new model for exception handling. Replaces
-DNEW_EH_MODEL as a compile option. */
extern int flag_new_exceptions = 0;
/* Nonzero means don't place uninitialized global data in common storage
by default. */
......@@ -759,6 +764,7 @@ struct { char *string; int *variable; int on_value;} f_options[] =
{"pic", &flag_pic, 1},
{"PIC", &flag_pic, 2},
{"exceptions", &flag_exceptions, 1},
{"new-exceptions", &flag_new_exceptions, 1},
{"sjlj-exceptions", &exceptions_via_longjmp, 1},
{"asynchronous-exceptions", &asynchronous_exceptions, 1},
{"profile-arcs", &profile_arc_flag, 1},
......
......@@ -116,6 +116,7 @@ enum built_in_function
BUILT_IN_FROB_RETURN_ADDR,
BUILT_IN_EXTRACT_RETURN_ADDR,
BUILT_IN_SET_RETURN_ADDR_REG,
BUILT_IN_EH_STUB_OLD,
BUILT_IN_EH_STUB,
BUILT_IN_SET_EH_REGS,
......
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