mirror of
https://github.com/Zenithsiz/ftmemsim-valgrind.git
synced 2026-02-04 02:18:37 +00:00
Merge r6123:
Extensions for unwinding stacks on ppc32-aix5 and ppc64-aix5. Also, extend the mechanism developed for ppc64-linux for fishing return addresses out of the thread's redirection-stack when needed. git-svn-id: svn://svn.valgrind.org/valgrind/trunk@6261
This commit is contained in:
parent
11f205dc50
commit
fa62ba20cb
@ -60,9 +60,17 @@ UInt VG_(get_StackTrace2) ( ThreadId tid_if_known,
|
||||
Addr ip, Addr sp, Addr fp, Addr lr,
|
||||
Addr fp_min, Addr fp_max_orig )
|
||||
{
|
||||
#if defined(VGP_ppc32_linux) || defined(VGP_ppc64_linux)
|
||||
Bool lr_is_first_RA = False; /* ppc only */
|
||||
#endif
|
||||
# if defined(VGP_ppc32_linux) || defined(VGP_ppc64_linux) \
|
||||
|| defined(VGP_ppc32_aix5) \
|
||||
|| defined(VGP_ppc64_aix5)
|
||||
Bool lr_is_first_RA = False;
|
||||
# endif
|
||||
# if defined(VGP_ppc64_linux) || defined(VGP_ppc64_aix5) \
|
||||
|| defined(VGP_ppc32_aix5)
|
||||
Word redir_stack_size = 0;
|
||||
Word redirs_used = 0;
|
||||
# endif
|
||||
|
||||
Bool debug = False;
|
||||
Int i;
|
||||
Addr fp_max;
|
||||
@ -154,7 +162,7 @@ UInt VG_(get_StackTrace2) ( ThreadId tid_if_known,
|
||||
continue;
|
||||
}
|
||||
|
||||
/* That didn't work out, so see if there is any CFI info to hand
|
||||
/* That didn't work out, so see if there is any CF info to hand
|
||||
which can be used. */
|
||||
if ( VG_(use_CF_info)( &ip, &sp, &fp, fp_min, fp_max ) ) {
|
||||
ips[i++] = ip;
|
||||
@ -235,26 +243,45 @@ UInt VG_(get_StackTrace2) ( ThreadId tid_if_known,
|
||||
break;
|
||||
}
|
||||
|
||||
# elif defined(VGP_ppc32_linux) || defined(VGP_ppc64_linux)
|
||||
# elif defined(VGP_ppc32_linux) || defined(VGP_ppc64_linux) \
|
||||
|| defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5)
|
||||
|
||||
/*--------------------- ppc32/64 ---------------------*/
|
||||
|
||||
/* fp is %r1. ip is %cia. Note, ppc uses r1 as both the stack and
|
||||
frame pointers. */
|
||||
|
||||
# if defined(VGP_ppc64_linux)
|
||||
# if defined(VGP_ppc64_linux) || defined(VGP_ppc64_aix5)
|
||||
redir_stack_size = VEX_GUEST_PPC64_REDIR_STACK_SIZE;
|
||||
redirs_used = 0;
|
||||
# elif defined(VGP_ppc32_aix5)
|
||||
redir_stack_size = VEX_GUEST_PPC32_REDIR_STACK_SIZE;
|
||||
redirs_used = 0;
|
||||
# endif
|
||||
|
||||
# if defined(VG_PLAT_USES_PPCTOC)
|
||||
/* Deal with bogus LR values caused by function
|
||||
interception/wrapping; see comment on similar code a few lines
|
||||
further down. */
|
||||
if (lr == (Addr)&VG_(ppc64_linux_magic_redirect_return_stub)
|
||||
interception/wrapping on ppc-TOC platforms; see comment on
|
||||
similar code a few lines further down. */
|
||||
if (ULong_to_Ptr(lr) == (void*)&VG_(ppctoc_magic_redirect_return_stub)
|
||||
&& VG_(is_valid_tid)(tid_if_known)) {
|
||||
Long hsp = VG_(threads)[tid_if_known].arch.vex.guest_REDIR_SP;
|
||||
if (hsp >= 1 && hsp < VEX_GUEST_PPC64_REDIR_STACK_SIZE)
|
||||
Word hsp = VG_(threads)[tid_if_known].arch.vex.guest_REDIR_SP;
|
||||
redirs_used++;
|
||||
if (hsp >= 1 && hsp < redir_stack_size)
|
||||
lr = VG_(threads)[tid_if_known]
|
||||
.arch.vex.guest_REDIR_STACK[hsp-1];
|
||||
}
|
||||
# endif
|
||||
|
||||
/* We have to determine whether or not LR currently holds this fn
|
||||
(call it F)'s return address. It might not if F has previously
|
||||
called some other function, hence overwriting LR with a pointer
|
||||
to some part of F. Hence if LR and IP point to the same
|
||||
function then we conclude LR does not hold this function's
|
||||
return address; instead the LR at entry must have been saved in
|
||||
the stack by F's prologue and so we must get it from there
|
||||
instead. Note all this guff only applies to the innermost
|
||||
frame. */
|
||||
lr_is_first_RA = False;
|
||||
{
|
||||
# define M_VG_ERRTXT 1000
|
||||
@ -276,10 +303,11 @@ UInt VG_(get_StackTrace2) ( ThreadId tid_if_known,
|
||||
|
||||
while (True) {
|
||||
|
||||
/* on ppc64-linux (ppc64-elf, really), the lr save slot is 2
|
||||
words back from sp, whereas on ppc32-elf(?) it's only one
|
||||
word back. */
|
||||
# if defined(VGP_ppc64_linux)
|
||||
/* On ppc64-linux (ppc64-elf, really), and on AIX, the lr save
|
||||
slot is 2 words back from sp, whereas on ppc32-elf(?) it's
|
||||
only one word back. */
|
||||
# if defined(VGP_ppc64_linux) \
|
||||
|| defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5)
|
||||
const Int lr_offset = 2;
|
||||
# else
|
||||
const Int lr_offset = 1;
|
||||
@ -298,19 +326,23 @@ UInt VG_(get_StackTrace2) ( ThreadId tid_if_known,
|
||||
else
|
||||
ip = (((UWord*)fp)[lr_offset]);
|
||||
|
||||
# if defined(VGP_ppc64_linux)
|
||||
# if defined(VG_PLAT_USES_PPCTOC)
|
||||
/* Nasty hack to do with function replacement/wrapping on
|
||||
ppc64-linux. If LR points to our magic return stub,
|
||||
then we are in a wrapped or intercepted function, in
|
||||
which LR has been messed with. The original LR will
|
||||
have been pushed onto the thread's hidden REDIR stack
|
||||
one down from the top (top element is the saved R2) and
|
||||
so we should restore the value from there instead. */
|
||||
if (i == 1
|
||||
&& ip == (Addr)&VG_(ppc64_linux_magic_redirect_return_stub)
|
||||
ppc64-linux/ppc64-aix/ppc32-aix. If LR points to our
|
||||
magic return stub, then we are in a wrapped or
|
||||
intercepted function, in which LR has been messed with.
|
||||
The original LR will have been pushed onto the thread's
|
||||
hidden REDIR stack one down from the top (top element
|
||||
is the saved R2) and so we should restore the value
|
||||
from there instead. Since nested redirections can and
|
||||
do happen, we keep track of the number of nested LRs
|
||||
used by the unwinding so far with 'redirs_used'. */
|
||||
if (ip == (Addr)&VG_(ppctoc_magic_redirect_return_stub)
|
||||
&& VG_(is_valid_tid)(tid_if_known)) {
|
||||
Long hsp = VG_(threads)[tid_if_known].arch.vex.guest_REDIR_SP;
|
||||
if (hsp >= 1 && hsp < VEX_GUEST_PPC64_REDIR_STACK_SIZE)
|
||||
Word hsp = VG_(threads)[tid_if_known].arch.vex.guest_REDIR_SP;
|
||||
hsp -= 2 * redirs_used;
|
||||
redirs_used ++;
|
||||
if (hsp >= 1 && hsp < redir_stack_size)
|
||||
ip = VG_(threads)[tid_if_known]
|
||||
.arch.vex.guest_REDIR_STACK[hsp-1];
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user