Commit 783d2650 by J. D. Johnston Committed by Ulrich Weigand

tpf-unwind.h (s390_fallback_frame_state): Correct end-of-stack check.

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.

From-SVN: r93643
parent b12a00f1
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> 2005-01-14 Richard Earnshaw <rearnsha@arm.com>
PR target/7525 PR target/7525
......
...@@ -52,8 +52,8 @@ __isPATrange (void *addr) ...@@ -52,8 +52,8 @@ __isPATrange (void *addr)
return 0; return 0;
} }
/* TPF stack placeholder offset. */ /* TPF return address offset from start of stack frame. */
#define TPF_LOC_DIFF_OFFSET 168 #define TPFRA_OFFSET 168
/* Exceptions macro defined for TPF so that functions without /* Exceptions macro defined for TPF so that functions without
dwarf frame information can be used with exceptions. */ dwarf frame information can be used with exceptions. */
...@@ -67,12 +67,18 @@ s390_fallback_frame_state (struct _Unwind_Context *context, ...@@ -67,12 +67,18 @@ s390_fallback_frame_state (struct _Unwind_Context *context,
unsigned long int new_cfa; unsigned long int new_cfa;
int i; int i;
if (context->cfa == NULL) regs = *((unsigned long int *)
return _URC_END_OF_STACK; (((unsigned long int) context->cfa) - STACK_POINTER_OFFSET));
/* Are we going through special linkage code? */ /* Are we going through special linkage code? */
if (__isPATrange (context->ra)) 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. */ /* No stack frame. */
fs->cfa_how = CFA_REG_OFFSET; fs->cfa_how = CFA_REG_OFFSET;
fs->cfa_reg = 15; fs->cfa_reg = 15;
...@@ -88,7 +94,7 @@ s390_fallback_frame_state (struct _Unwind_Context *context, ...@@ -88,7 +94,7 @@ s390_fallback_frame_state (struct _Unwind_Context *context,
/* ... except for %r14, which is stored at CFA-112 /* ... except for %r14, which is stored at CFA-112
and used as return address. */ and used as return address. */
fs->regs.reg[14].how = REG_SAVED_OFFSET; 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; fs->retaddr_column = 14;
return _URC_NO_REASON; return _URC_NO_REASON;
...@@ -136,9 +142,10 @@ s390_fallback_frame_state (struct _Unwind_Context *context, ...@@ -136,9 +142,10 @@ s390_fallback_frame_state (struct _Unwind_Context *context,
#define PREVIOUS_STACK_PTR() \ #define PREVIOUS_STACK_PTR() \
((unsigned long int *)(*(CURRENT_STACK_PTR()))) ((unsigned long int *)(*(CURRENT_STACK_PTR())))
#define RA_OFFSET_FROM_START_OF_STACK_FRAME 112 #define RA_OFFSET 112
#define CURRENT_STACK_PTR_OFFSET 120 #define R15_OFFSET 120
#define TPFRA_OFFSET_FROM_START_OF_STACK_FRAME 168 #define TPFAREA_OFFSET 160
#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);
...@@ -148,105 +155,103 @@ __tpf_eh_return (void *target) ...@@ -148,105 +155,103 @@ __tpf_eh_return (void *target)
{ {
Dl_info targetcodeInfo, currentcodeInfo; Dl_info targetcodeInfo, currentcodeInfo;
int retval; int retval;
void *current, *stackptr; void *current, *stackptr, *destination_frame;
unsigned long int shifter; unsigned long int shifter, is_a_stub;
is_a_stub = 0;
/* Get code info for target return's address. */ /* Get code info for target return's address. */
retval = dladdr (target, &targetcodeInfo); 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). */ /* 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. */ /* Get the stack pointer of the stack frame to be modified by
retval = dladdr (current, &currentcodeInfo); 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). */ /* Begin looping through stack frames. Stop if invalid
if (retval != INVALID_RETURN) 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 /* Get return address based on our stackptr iterator. */
the exception unwinder. So that we can begin our climb current = (void *) *((unsigned long int *)
there. */ (stackptr+RA_OFFSET));
stackptr = (void *) (*((unsigned long int *)
(*((unsigned long int *)(*(PREVIOUS_STACK_PTR())))))); /* Is it a Pat Stub? */
if (__isPATrange (current))
/* 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. */ /* Yes it was, get real return address
in TPF stack area. */
current = (void *) *((unsigned long int *) current = (void *) *((unsigned long int *)
(stackptr+RA_OFFSET_FROM_START_OF_STACK_FRAME)); (stackptr+TPFRA_OFFSET));
is_a_stub = 1;
/* 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;
} }
}
/* 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 /* No pat stub found, could be a problem? Simply return unmodified
...@@ -254,4 +259,3 @@ __tpf_eh_return (void *target) ...@@ -254,4 +259,3 @@ __tpf_eh_return (void *target)
return target; return target;
} }
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