From 87cb0c0cdbb3387a7964950751ef2dbab33254aa Mon Sep 17 00:00:00 2001 From: Ulrich Weigand Date: Wed, 30 Jul 2014 16:26:15 +0000 Subject: [PATCH] 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 * 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 * config/s390/tpf-unwind.h: Include . (__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 --- gcc/ChangeLog | 5 +++ gcc/config/s390/s390.c | 5 ++- libgcc/ChangeLog | 7 ++++ libgcc/config/s390/tpf-unwind.h | 65 ++++++++++++++++++++++----------- 4 files changed, 59 insertions(+), 23 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 1bb3d336076..04b0d3cf187 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2014-07-30 Ulrich Weigand + + * 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 * config/arm/arm.c (arm_get_frame_offsets): Adjust condition for diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c index bc6206e779f..03b85ff2ee1 100644 --- a/gcc/config/s390/s390.c +++ b/gcc/config/s390/s390.c @@ -10850,17 +10850,20 @@ static GTY(()) rtx s390_tpf_eh_return_symbol; void s390_emit_tpf_eh_return (rtx target) { - rtx insn, reg; + rtx insn, reg, orig_ra; if (!s390_tpf_eh_return_symbol) s390_tpf_eh_return_symbol = gen_rtx_SYMBOL_REF (Pmode, "__tpf_eh_return"); reg = gen_rtx_REG (Pmode, 2); + orig_ra = gen_rtx_REG (Pmode, 3); 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, gen_rtx_REG (Pmode, RETURN_REGNUM)); 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); } diff --git a/libgcc/ChangeLog b/libgcc/ChangeLog index 88fb09f25cc..4795414d166 100644 --- a/libgcc/ChangeLog +++ b/libgcc/ChangeLog @@ -1,3 +1,10 @@ +2014-07-30 J. D. Johnston + + * config/s390/tpf-unwind.h: Include . + (__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 * libgcov.h: Move renaming of entry points to lib gcov specific diff --git a/libgcc/config/s390/tpf-unwind.h b/libgcc/config/s390/tpf-unwind.h index 5fa177b5078..efffda5d434 100644 --- a/libgcc/config/s390/tpf-unwind.h +++ b/libgcc/config/s390/tpf-unwind.h @@ -24,6 +24,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see . */ #include +#include /* Function Name: __isPATrange Parameters passed into it: address to check @@ -139,29 +140,38 @@ s390_fallback_frame_state (struct _Unwind_Context *context, #define TPFAREA_SIZE STACK_POINTER_OFFSET-TPFAREA_OFFSET #define INVALID_RETURN 0 -void * __tpf_eh_return (void *target); +void * __tpf_eh_return (void *target, void *origRA); void * -__tpf_eh_return (void *target) +__tpf_eh_return (void *target, void *origRA) { Dl_info targetcodeInfo, currentcodeInfo; int retval; 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. */ 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). */ if (retval != INVALID_RETURN) { - - /* Get the stack pointer of the stack frame to be modified by - the exception unwinder. So that we can begin our climb - there. */ - stackptr = (void *) *((unsigned long int *) (*(PREVIOUS_STACK_PTR()))); + /* Get the stack pointer of the first stack frame beyond the + unwinder or if exists the calling C++ runtime function (e.g., + __cxa_throw). */ + if (!frameDepth2) + stackptr = (void *) *((unsigned long int *) (*(PREVIOUS_STACK_PTR()))); + else + stackptr = (void *) *(PREVIOUS_STACK_PTR()); /* Begin looping through stack frames. Stop if invalid code information is retrieved or if a match between the @@ -169,18 +179,26 @@ __tpf_eh_return (void *target) matches that of the target, calculated above. */ do { - /* Get return address based on our stackptr iterator. */ - current = (void *) *((unsigned long int *) - (stackptr+RA_OFFSET)); - - /* Is it a Pat Stub? */ - if (__isPATrange (current)) + if (!frameDepth2 || (frameDepth2 && !firstIteration)) + { + /* Get return address based on our stackptr iterator. */ + current = (void *) *((unsigned long int *) + (stackptr + RA_OFFSET)); + + /* Is it a Pat Stub? */ + if (__isPATrange (current)) + { + /* Yes it was, get real return address in TPF stack area. */ + current = (void *) *((unsigned long int *) + (stackptr + TPFRA_OFFSET)) + is_a_stub = true; + } + } + else { - /* Yes it was, get real return address - in TPF stack area. */ current = (void *) *((unsigned long int *) - (stackptr+TPFRA_OFFSET)); - is_a_stub = 1; + (stackptr + TPFRA_OFFSET)); + is_a_stub = true; } /* Get codeinfo on RA so that we can figure out @@ -219,8 +237,10 @@ __tpf_eh_return (void *target) This is necessary for CTOA stubs. Otherwise we leap one byte past where we want to go to in the TPF pat stub linkage code. */ - shifter = *((unsigned long int *) - (stackptr + RA_OFFSET)); + if (!frameDepth2 || (frameDepth2 && !firstIteration)) + shifter = *((unsigned long int *) (stackptr + RA_OFFSET)); + else + shifter = (unsigned long int) origRA; shifter &= ~1ul; @@ -239,7 +259,8 @@ __tpf_eh_return (void *target) Bump stack frame iterator. */ stackptr = (void *) *(unsigned long int *) stackptr; - is_a_stub = 0; + is_a_stub = false; + firstIteration = false; } while (stackptr && retval != INVALID_RETURN && targetcodeInfo.dli_fbase != currentcodeInfo.dli_fbase); -- 2.30.2