summaryrefslogtreecommitdiff
path: root/libgcc
diff options
context:
space:
mode:
authoruweigand <uweigand@138bc75d-0d04-0410-961f-82ee72b054a4>2014-07-30 16:26:15 +0000
committeruweigand <uweigand@138bc75d-0d04-0410-961f-82ee72b054a4>2014-07-30 16:26:15 +0000
commitbcd3133e25678fdb2512cc4c9a7547ffe72abe99 (patch)
tree57f3cc9e5f416ad89cc5891a65172ed17a41e0eb /libgcc
parent7a5646aa828504895d9baf6d8f1bac3d35ba7ff6 (diff)
downloadgcc-bcd3133e25678fdb2512cc4c9a7547ffe72abe99.tar.gz
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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@213305 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libgcc')
-rw-r--r--libgcc/ChangeLog7
-rw-r--r--libgcc/config/s390/tpf-unwind.h65
2 files changed, 50 insertions, 22 deletions
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 <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>
* 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
<http://www.gnu.org/licenses/>. */
#include <dlfcn.h>
+#include <stdbool.h>
/* 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);