Commit 87cb0c0c by Ulrich Weigand

s390.c (s390_emit_tpf_eh_return): Pass original return address as second…

s390.c (s390_emit_tpf_eh_return): Pass original return address as second parameter to __tpf_eh_return routine.

gcc/

2014-07-30  Ulrich Weigand  <Ulrich.Weigand@de.ibm.com>

	* config/s390/s390.c (s390_emit_tpf_eh_return): Pass original return
	address as second parameter to __tpf_eh_return routine.

libgcc/

2014-07-30  J. D. Johnston  <jjohnst@us.ibm.com>

	* config/s390/tpf-unwind.h: Include <stdbool.h>.
	(__tpf_eh_return): Add original return address as second parameter.
	Handle cases where unwinder routines were called directly, instead
	of from within the C++ library.

From-SVN: r213305
parent e58d3b41
2014-07-30 Ulrich Weigand <Ulrich.Weigand@de.ibm.com>
* config/s390/s390.c (s390_emit_tpf_eh_return): Pass original return
address as second parameter to __tpf_eh_return routine.
2014-07-30 Jiong Wang <jiong.wang@arm.com> 2014-07-30 Jiong Wang <jiong.wang@arm.com>
* config/arm/arm.c (arm_get_frame_offsets): Adjust condition for * config/arm/arm.c (arm_get_frame_offsets): Adjust condition for
......
...@@ -10850,17 +10850,20 @@ static GTY(()) rtx s390_tpf_eh_return_symbol; ...@@ -10850,17 +10850,20 @@ static GTY(()) rtx s390_tpf_eh_return_symbol;
void void
s390_emit_tpf_eh_return (rtx target) s390_emit_tpf_eh_return (rtx target)
{ {
rtx insn, reg; rtx insn, reg, orig_ra;
if (!s390_tpf_eh_return_symbol) if (!s390_tpf_eh_return_symbol)
s390_tpf_eh_return_symbol = gen_rtx_SYMBOL_REF (Pmode, "__tpf_eh_return"); s390_tpf_eh_return_symbol = gen_rtx_SYMBOL_REF (Pmode, "__tpf_eh_return");
reg = gen_rtx_REG (Pmode, 2); reg = gen_rtx_REG (Pmode, 2);
orig_ra = gen_rtx_REG (Pmode, 3);
emit_move_insn (reg, target); emit_move_insn (reg, target);
emit_move_insn (orig_ra, get_hard_reg_initial_val (Pmode, RETURN_REGNUM));
insn = s390_emit_call (s390_tpf_eh_return_symbol, NULL_RTX, reg, insn = s390_emit_call (s390_tpf_eh_return_symbol, NULL_RTX, reg,
gen_rtx_REG (Pmode, RETURN_REGNUM)); gen_rtx_REG (Pmode, RETURN_REGNUM));
use_reg (&CALL_INSN_FUNCTION_USAGE (insn), reg); use_reg (&CALL_INSN_FUNCTION_USAGE (insn), reg);
use_reg (&CALL_INSN_FUNCTION_USAGE (insn), orig_ra);
emit_move_insn (EH_RETURN_HANDLER_RTX, reg); emit_move_insn (EH_RETURN_HANDLER_RTX, reg);
} }
......
2014-07-30 J. D. Johnston <jjohnst@us.ibm.com>
* config/s390/tpf-unwind.h: Include <stdbool.h>.
(__tpf_eh_return): Add original return address as second parameter.
Handle cases where unwinder routines were called directly, instead
of from within the C++ library.
2014-07-29 Nathan Sidwell <nathan@acm.org> 2014-07-29 Nathan Sidwell <nathan@acm.org>
* libgcov.h: Move renaming of entry points to lib gcov specific * libgcov.h: Move renaming of entry points to lib gcov specific
......
...@@ -24,6 +24,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see ...@@ -24,6 +24,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
<http://www.gnu.org/licenses/>. */ <http://www.gnu.org/licenses/>. */
#include <dlfcn.h> #include <dlfcn.h>
#include <stdbool.h>
/* Function Name: __isPATrange /* Function Name: __isPATrange
Parameters passed into it: address to check Parameters passed into it: address to check
...@@ -139,29 +140,38 @@ s390_fallback_frame_state (struct _Unwind_Context *context, ...@@ -139,29 +140,38 @@ s390_fallback_frame_state (struct _Unwind_Context *context,
#define TPFAREA_SIZE STACK_POINTER_OFFSET-TPFAREA_OFFSET #define TPFAREA_SIZE STACK_POINTER_OFFSET-TPFAREA_OFFSET
#define INVALID_RETURN 0 #define INVALID_RETURN 0
void * __tpf_eh_return (void *target); void * __tpf_eh_return (void *target, void *origRA);
void * void *
__tpf_eh_return (void *target) __tpf_eh_return (void *target, void *origRA)
{ {
Dl_info targetcodeInfo, currentcodeInfo; Dl_info targetcodeInfo, currentcodeInfo;
int retval; int retval;
void *current, *stackptr, *destination_frame; void *current, *stackptr, *destination_frame;
unsigned long int shifter, is_a_stub; unsigned long int shifter;
bool is_a_stub, frameDepth2, firstIteration;
is_a_stub = 0; is_a_stub = false;
frameDepth2 = false;
firstIteration = true;
/* Get code info for target return's address. */ /* Get code info for target return's address. */
retval = dladdr (target, &targetcodeInfo); retval = dladdr (target, &targetcodeInfo);
/* Check if original RA is a Pat stub. If so set flag. */
if (__isPATrange (origRA))
frameDepth2 = true;
/* Ensure the code info is valid (for target). */ /* Ensure the code info is valid (for target). */
if (retval != INVALID_RETURN) if (retval != INVALID_RETURN)
{ {
/* Get the stack pointer of the first stack frame beyond the
/* Get the stack pointer of the stack frame to be modified by unwinder or if exists the calling C++ runtime function (e.g.,
the exception unwinder. So that we can begin our climb __cxa_throw). */
there. */ if (!frameDepth2)
stackptr = (void *) *((unsigned long int *) (*(PREVIOUS_STACK_PTR()))); stackptr = (void *) *((unsigned long int *) (*(PREVIOUS_STACK_PTR())));
else
stackptr = (void *) *(PREVIOUS_STACK_PTR());
/* Begin looping through stack frames. Stop if invalid /* Begin looping through stack frames. Stop if invalid
code information is retrieved or if a match between the code information is retrieved or if a match between the
...@@ -169,18 +179,26 @@ __tpf_eh_return (void *target) ...@@ -169,18 +179,26 @@ __tpf_eh_return (void *target)
matches that of the target, calculated above. */ matches that of the target, calculated above. */
do do
{ {
if (!frameDepth2 || (frameDepth2 && !firstIteration))
{
/* Get return address based on our stackptr iterator. */ /* Get return address based on our stackptr iterator. */
current = (void *) *((unsigned long int *) current = (void *) *((unsigned long int *)
(stackptr+RA_OFFSET)); (stackptr + RA_OFFSET));
/* Is it a Pat Stub? */ /* Is it a Pat Stub? */
if (__isPATrange (current)) if (__isPATrange (current))
{ {
/* Yes it was, get real return address /* Yes it was, get real return address in TPF stack area. */
in TPF stack area. */ current = (void *) *((unsigned long int *)
(stackptr + TPFRA_OFFSET))
is_a_stub = true;
}
}
else
{
current = (void *) *((unsigned long int *) current = (void *) *((unsigned long int *)
(stackptr+TPFRA_OFFSET)); (stackptr + TPFRA_OFFSET));
is_a_stub = 1; is_a_stub = true;
} }
/* Get codeinfo on RA so that we can figure out /* Get codeinfo on RA so that we can figure out
...@@ -219,8 +237,10 @@ __tpf_eh_return (void *target) ...@@ -219,8 +237,10 @@ __tpf_eh_return (void *target)
This is necessary for CTOA stubs. This is necessary for CTOA stubs.
Otherwise we leap one byte past where we want to Otherwise we leap one byte past where we want to
go to in the TPF pat stub linkage code. */ go to in the TPF pat stub linkage code. */
shifter = *((unsigned long int *) if (!frameDepth2 || (frameDepth2 && !firstIteration))
(stackptr + RA_OFFSET)); shifter = *((unsigned long int *) (stackptr + RA_OFFSET));
else
shifter = (unsigned long int) origRA;
shifter &= ~1ul; shifter &= ~1ul;
...@@ -239,7 +259,8 @@ __tpf_eh_return (void *target) ...@@ -239,7 +259,8 @@ __tpf_eh_return (void *target)
Bump stack frame iterator. */ Bump stack frame iterator. */
stackptr = (void *) *(unsigned long int *) stackptr; stackptr = (void *) *(unsigned long int *) stackptr;
is_a_stub = 0; is_a_stub = false;
firstIteration = false;
} while (stackptr && retval != INVALID_RETURN } while (stackptr && retval != INVALID_RETURN
&& targetcodeInfo.dli_fbase != currentcodeInfo.dli_fbase); && targetcodeInfo.dli_fbase != currentcodeInfo.dli_fbase);
......
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