summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoruweigand <uweigand@138bc75d-0d04-0410-961f-82ee72b054a4>2005-01-14 14:27:42 +0000
committeruweigand <uweigand@138bc75d-0d04-0410-961f-82ee72b054a4>2005-01-14 14:27:42 +0000
commitc2443017ee2181ceb48226f3b947a7695d7b52bc (patch)
tree61ecb3ca4252d06c4a059d3c7d9610b9162fb1bb
parentafe27f3bd875ba812e294cc77b01777b654a03f4 (diff)
downloadgcc-c2443017ee2181ceb48226f3b947a7695d7b52bc.tar.gz
2005-01-14 J. D. Johnston <jjohnst@us.ibm.com>
* config/s390/tpf-unwind.h (s390_fallback_frame_state): Correct end-of-stack check. (__tpf_eh_return): Copy TPF private stack area from the module boundary stack frame. Add check for when module addresses are equal, but no stub address is found. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@93643 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog8
-rw-r--r--gcc/config/s390/tpf-unwind.h196
2 files changed, 108 insertions, 96 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 7233c29222b..5626607baf0 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,11 @@
+2005-01-14 J. D. Johnston <jjohnst@us.ibm.com>
+
+ * config/s390/tpf-unwind.h (s390_fallback_frame_state): Correct
+ end-of-stack check.
+ (__tpf_eh_return): Copy TPF private stack area from the module
+ boundary stack frame. Add check for when module addresses are
+ equal, but no stub address is found.
+
2005-01-14 Richard Earnshaw <rearnsha@arm.com>
PR target/7525
diff --git a/gcc/config/s390/tpf-unwind.h b/gcc/config/s390/tpf-unwind.h
index 6c584ac60aa..3289df98ea7 100644
--- a/gcc/config/s390/tpf-unwind.h
+++ b/gcc/config/s390/tpf-unwind.h
@@ -52,8 +52,8 @@ __isPATrange (void *addr)
return 0;
}
-/* TPF stack placeholder offset. */
-#define TPF_LOC_DIFF_OFFSET 168
+/* TPF return address offset from start of stack frame. */
+#define TPFRA_OFFSET 168
/* Exceptions macro defined for TPF so that functions without
dwarf frame information can be used with exceptions. */
@@ -67,12 +67,18 @@ s390_fallback_frame_state (struct _Unwind_Context *context,
unsigned long int new_cfa;
int i;
- if (context->cfa == NULL)
- return _URC_END_OF_STACK;
+ regs = *((unsigned long int *)
+ (((unsigned long int) context->cfa) - STACK_POINTER_OFFSET));
/* Are we going through special linkage code? */
if (__isPATrange (context->ra))
{
+
+ /* Our return register isn't zero for end of stack, so
+ check backward stackpointer to see if it is zero. */
+ if (regs == NULL)
+ return _URC_END_OF_STACK;
+
/* No stack frame. */
fs->cfa_how = CFA_REG_OFFSET;
fs->cfa_reg = 15;
@@ -88,7 +94,7 @@ s390_fallback_frame_state (struct _Unwind_Context *context,
/* ... except for %r14, which is stored at CFA-112
and used as return address. */
fs->regs.reg[14].how = REG_SAVED_OFFSET;
- fs->regs.reg[14].loc.offset = TPF_LOC_DIFF_OFFSET - STACK_POINTER_OFFSET;
+ fs->regs.reg[14].loc.offset = TPFRA_OFFSET - STACK_POINTER_OFFSET;
fs->retaddr_column = 14;
return _URC_NO_REASON;
@@ -136,9 +142,10 @@ s390_fallback_frame_state (struct _Unwind_Context *context,
#define PREVIOUS_STACK_PTR() \
((unsigned long int *)(*(CURRENT_STACK_PTR())))
-#define RA_OFFSET_FROM_START_OF_STACK_FRAME 112
-#define CURRENT_STACK_PTR_OFFSET 120
-#define TPFRA_OFFSET_FROM_START_OF_STACK_FRAME 168
+#define RA_OFFSET 112
+#define R15_OFFSET 120
+#define TPFAREA_OFFSET 160
+#define TPFAREA_SIZE STACK_POINTER_OFFSET-TPFAREA_OFFSET
#define INVALID_RETURN 0
void * __tpf_eh_return (void *target);
@@ -148,105 +155,103 @@ __tpf_eh_return (void *target)
{
Dl_info targetcodeInfo, currentcodeInfo;
int retval;
- void *current, *stackptr;
- unsigned long int shifter;
+ void *current, *stackptr, *destination_frame;
+ unsigned long int shifter, is_a_stub;
+
+ is_a_stub = 0;
/* Get code info for target return's address. */
retval = dladdr (target, &targetcodeInfo);
- /* Get the return address of the stack frame to be replaced by
- the exception unwinder. So that the __cxa_throw return is
- replaced by the target return. */
- current = (void *) *((unsigned long int *)
- ((*((unsigned long int *)*(PREVIOUS_STACK_PTR())))
- + RA_OFFSET_FROM_START_OF_STACK_FRAME));
-
/* Ensure the code info is valid (for target). */
- if (retval != INVALID_RETURN)
+ if (retval != INVALID_RETURN)
{
- /* Now check to see if the current RA is a PAT
- stub return address. */
- if ( __isPATrange(current))
- {
- /* It was! Then go into the TPF private stack area and fetch
- the real address. */
- current = (void *) *((unsigned long int *)
- ((unsigned long int)*((unsigned long int *)
- *(PREVIOUS_STACK_PTR()))
- +TPFRA_OFFSET_FROM_START_OF_STACK_FRAME));
- }
- /* Get code info for current return address. */
- retval = dladdr (current, &currentcodeInfo);
+ /* 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())));
- /* Ensure the code info is valid (for current frame). */
- if (retval != INVALID_RETURN)
+ /* Begin looping through stack frames. Stop if invalid
+ code information is retrieved or if a match between the
+ current stack frame iteration shared object's address
+ matches that of the target, calculated above. */
+ do
{
- /* Get the stack pointer of the stack frame to be replaced by
- the exception unwinder. So that we can begin our climb
- there. */
- stackptr = (void *) (*((unsigned long int *)
- (*((unsigned long int *)(*(PREVIOUS_STACK_PTR()))))));
-
- /* Begin looping through stack frames. Stop if invalid
- code information is retrieved or if a match between the
- current stack frame iteration shared object's address
- matches that of the target, calculated above. */
- while (retval != INVALID_RETURN
- && targetcodeInfo.dli_fbase != currentcodeInfo.dli_fbase)
+ /* Get return address based on our stackptr iterator. */
+ current = (void *) *((unsigned long int *)
+ (stackptr+RA_OFFSET));
+
+ /* Is it a Pat Stub? */
+ if (__isPATrange (current))
{
- /* Get return address based on our stackptr iterator. */
+ /* Yes it was, get real return address
+ in TPF stack area. */
current = (void *) *((unsigned long int *)
- (stackptr+RA_OFFSET_FROM_START_OF_STACK_FRAME));
-
- /* 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_FROM_START_OF_STACK_FRAME));
- }
-
- /* Get codeinfo on RA so that we can figure out
- the module address. */
- retval = dladdr (current, &currentcodeInfo);
-
- /* Check that codeinfo for current stack frame is valid.
- Then compare the module address of current stack frame
- to target stack frame to determine if we have the pat
- stub address we want. */
- if (retval != INVALID_RETURN
- && targetcodeInfo.dli_fbase == currentcodeInfo.dli_fbase)
- {
- /* Yes! They are in the same module. Now store the
- real target address into the TPF stack area of
- the target frame we are jumping to. */
- *((unsigned long int *)(*((unsigned long int *)
- (*PREVIOUS_STACK_PTR() + CURRENT_STACK_PTR_OFFSET))
- + TPFRA_OFFSET_FROM_START_OF_STACK_FRAME))
- = (unsigned long int) target;
-
- /* Before returning the desired pat stub address to
- the exception handling unwinder so that it can
- actually do the "leap" shift out the low order
- bit designated to determine if we are in 64BIT mode.
- 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_FROM_START_OF_STACK_FRAME));
-
- shifter &= ~1ul;
-
- return (void *) shifter;
- }
-
- /* Desired module pat stub not found ...
- Bump stack frame iterator. */
- stackptr = (void *) *(unsigned long int *) stackptr;
+ (stackptr+TPFRA_OFFSET));
+ is_a_stub = 1;
}
- }
+
+ /* Get codeinfo on RA so that we can figure out
+ the module address. */
+ retval = dladdr (current, &currentcodeInfo);
+
+ /* Check that codeinfo for current stack frame is valid.
+ Then compare the module address of current stack frame
+ to target stack frame to determine if we have the pat
+ stub address we want. Also ensure we are dealing
+ with a module crossing, stub return address. */
+ if (is_a_stub && retval != INVALID_RETURN
+ && targetcodeInfo.dli_fbase == currentcodeInfo.dli_fbase)
+ {
+ /* Yes! They are in the same module.
+ Force copy of TPF private stack area to
+ destination stack frame TPF private area. */
+ destination_frame = (void *) *((unsigned long int *)
+ (*PREVIOUS_STACK_PTR() + R15_OFFSET));
+
+ /* Copy TPF linkage area from current frame to
+ destination frame. */
+ memcpy((void *) (destination_frame + TPFAREA_OFFSET),
+ (void *) (stackptr + TPFAREA_OFFSET), TPFAREA_SIZE);
+
+ /* Now overlay the
+ real target address into the TPF stack area of
+ the target frame we are jumping to. */
+ *((unsigned long int *) (destination_frame +
+ TPFRA_OFFSET)) = (unsigned long int) target;
+
+ /* Before returning the desired pat stub address to
+ the exception handling unwinder so that it can
+ actually do the "leap" shift out the low order
+ bit designated to determine if we are in 64BIT mode.
+ 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));
+
+ shifter &= ~1ul;
+
+ /* Store Pat Stub Address in destination Stack Frame. */
+ *((unsigned long int *) (destination_frame +
+ RA_OFFSET)) = shifter;
+
+ /* Re-adjust pat stub address to go to correct place
+ in linkage. */
+ shifter = shifter - 4;
+
+ return (void *) shifter;
+ }
+
+ /* Desired module pat stub not found ...
+ Bump stack frame iterator. */
+ stackptr = (void *) *(unsigned long int *) stackptr;
+
+ is_a_stub = 0;
+
+ } while (stackptr && retval != INVALID_RETURN
+ && targetcodeInfo.dli_fbase != currentcodeInfo.dli_fbase);
}
/* No pat stub found, could be a problem? Simply return unmodified
@@ -254,4 +259,3 @@ __tpf_eh_return (void *target)
return target;
}
-