mirror of
https://github.com/Zenithsiz/ftmemsim-valgrind.git
synced 2026-02-03 18:13:01 +00:00
Make VG_(get_StackTrace2) aware of bogus LR values in
replacement/wrapper functions on ppc64-linux, which otherwise mess up the backtraces. git-svn-id: svn://svn.valgrind.org/valgrind/trunk@5549
This commit is contained in:
parent
a9bbc3690b
commit
8a98207bcf
@ -138,7 +138,8 @@ static void report_and_quit ( const Char* report,
|
||||
|
||||
stacktop = tst->os_state.valgrind_stack_init_SP;
|
||||
|
||||
VG_(get_StackTrace2)(ips, BACKTRACE_DEPTH, ip, sp, fp, lr, sp, stacktop);
|
||||
VG_(get_StackTrace2)(0/*tid is unknown*/,
|
||||
ips, BACKTRACE_DEPTH, ip, sp, fp, lr, sp, stacktop);
|
||||
VG_(pp_StackTrace) (ips, BACKTRACE_DEPTH);
|
||||
|
||||
// Don't print this, as it's not terribly interesting and avoids a
|
||||
|
||||
@ -48,8 +48,13 @@
|
||||
IPs into 'ips'. In order to be thread-safe, we pass in the
|
||||
thread's IP SP, FP if that's meaningful, and LR if that's
|
||||
meaningful. Returns number of IPs put in 'ips'.
|
||||
|
||||
If you know what the thread ID for this stack is, send that as the
|
||||
first parameter, else send zero. This helps generate better stack
|
||||
traces on ppc64-linux and has no effect on other platforms.
|
||||
*/
|
||||
UInt VG_(get_StackTrace2) ( Addr* ips, UInt n_ips,
|
||||
UInt VG_(get_StackTrace2) ( ThreadId tid_if_known,
|
||||
Addr* ips, UInt n_ips,
|
||||
Addr ip, Addr sp, Addr fp, Addr lr,
|
||||
Addr fp_min, Addr fp_max_orig )
|
||||
{
|
||||
@ -230,7 +235,7 @@ UInt VG_(get_StackTrace2) ( Addr* ips, UInt n_ips,
|
||||
|
||||
# elif defined(VGP_ppc32_linux) || defined(VGP_ppc64_linux)
|
||||
|
||||
/*--------------------- ppc32 ---------------------*/
|
||||
/*--------------------- ppc32/64 ---------------------*/
|
||||
|
||||
/* fp is %r1. ip is %cia. Note, ppc uses r1 as both the stack and
|
||||
frame pointers. */
|
||||
@ -259,7 +264,11 @@ UInt VG_(get_StackTrace2) ( Addr* ips, UInt n_ips,
|
||||
/* 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. */
|
||||
const Int lr_offset = VG_WORDSIZE==8 ? 2 : 1;
|
||||
# if defined(VGP_ppc64_linux)
|
||||
const Int lr_offset = 2;
|
||||
# else
|
||||
const Int lr_offset = 1;
|
||||
# endif
|
||||
|
||||
if (i >= n_ips)
|
||||
break;
|
||||
@ -274,6 +283,24 @@ UInt VG_(get_StackTrace2) ( Addr* ips, UInt n_ips,
|
||||
else
|
||||
ip = (((UWord*)fp)[lr_offset]);
|
||||
|
||||
# if defined(VGP_ppc64_linux)
|
||||
/* 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)
|
||||
&& 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)
|
||||
ip = VG_(threads)[tid_if_known]
|
||||
.arch.vex.guest_REDIR_STACK[hsp-1];
|
||||
}
|
||||
# endif
|
||||
|
||||
fp = (((UWord*)fp)[0]);
|
||||
ips[i++] = ip;
|
||||
if (debug)
|
||||
@ -324,7 +351,8 @@ UInt VG_(get_StackTrace) ( ThreadId tid, StackTrace ips, UInt n_ips )
|
||||
VG_(printf)("tid %d: stack_highest=%p ip=%p sp=%p fp=%p\n",
|
||||
tid, stack_highest_word, ip, sp, fp);
|
||||
|
||||
return VG_(get_StackTrace2)(ips, n_ips, ip, sp, fp, lr, sp, stack_highest_word);
|
||||
return VG_(get_StackTrace2)(tid, ips, n_ips, ip, sp, fp, lr, sp,
|
||||
stack_highest_word);
|
||||
}
|
||||
|
||||
static void printIpDesc(UInt n, Addr ip)
|
||||
|
||||
@ -566,6 +566,8 @@ static Bool chase_into_ok ( void* closureV, Addr64 addr64 )
|
||||
}
|
||||
|
||||
|
||||
/* --------------- ppc64-linux specific helpers --------------- */
|
||||
|
||||
#if defined(VGP_ppc64_linux)
|
||||
static IRExpr* mkU64 ( ULong n )
|
||||
{
|
||||
@ -681,6 +683,7 @@ Bool mk_preamble__ppc64_magic_return_stub ( void* closureV, IRBB* bb )
|
||||
}
|
||||
#endif
|
||||
|
||||
/* --------------- END ppc64-linux specific helpers --------------- */
|
||||
|
||||
/* This is an the IR preamble generators used for replacement
|
||||
functions. It adds code to set the guest_NRADDR to zero
|
||||
@ -692,7 +695,11 @@ Bool mk_preamble__ppc64_magic_return_stub ( void* closureV, IRBB* bb )
|
||||
replacement function, and sets LR to point at the magic return-stub
|
||||
address. Setting LR causes the return of the wrapped/redirected
|
||||
function to lead to our magic return stub, which restores LR and R2
|
||||
from said stack and returns for real. */
|
||||
from said stack and returns for real.
|
||||
|
||||
VG_(get_StackTrace2) understands that the LR value may point to the
|
||||
return stub address, and that in that case it can get the real LR
|
||||
value from the hidden stack instead. */
|
||||
static
|
||||
Bool mk_preamble__set_NRADDR_to_zero ( void* closureV, IRBB* bb )
|
||||
{
|
||||
|
||||
@ -39,7 +39,12 @@
|
||||
#include "pub_tool_stacktrace.h"
|
||||
|
||||
// Variant that gives a little more control over the stack-walking.
|
||||
extern UInt VG_(get_StackTrace2) ( StackTrace ips, UInt n_ips,
|
||||
// If you know what the thread ID for this stack is, send that
|
||||
// as the first parameter, else send zero. This helps generate
|
||||
// better stack traces on ppc64-linux and has no effect on other
|
||||
// platforms.
|
||||
extern UInt VG_(get_StackTrace2) ( ThreadId tid_if_known,
|
||||
StackTrace ips, UInt n_ips,
|
||||
Addr ip, Addr sp, Addr fp, Addr lr,
|
||||
Addr fp_min, Addr fp_max );
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user