use link register to determine return address when appropriate in getStackTrace

On PowerPC and ARM, we can't rely on the return address having already
been saved on the stack on entry to a thunk, so we must look for it in
the link register instead.
This commit is contained in:
Joel Dice 2011-02-21 15:25:52 -07:00
parent 20f4510122
commit e20daca297
5 changed files with 24 additions and 2 deletions

View File

@ -1838,7 +1838,11 @@ class MyArchitecture: public Assembler::Architecture {
return index;
}
virtual bool hasLinkRegister() {
return true;
}
virtual unsigned stackAlignmentInWords() {
return StackAlignmentInWords;
}

View File

@ -333,6 +333,8 @@ class Assembler {
virtual unsigned argumentRegisterCount() = 0;
virtual int argumentRegister(unsigned index) = 0;
virtual bool hasLinkRegister() = 0;
virtual unsigned stackAlignmentInWords() = 0;
virtual bool matchCall(void* returnAddress, void* target) = 0;

View File

@ -7706,7 +7706,15 @@ class MyProcessor: public Processor {
} else if (isThunk(t, ip) or isVirtualThunk(t, ip)) {
// we caught the thread in a thunk where the stack register
// indicates the most recent Java frame on the stack
c.ip = getIp(t, link, stack);
// On e.g. x86, the return address will have already been
// pushed onto the stack, in which case we use getIp to
// retrieve it. On e.g. PowerPC and ARM, it will be in the
// link register. Note that we can't just check if the link
// argument is null here, since we use ecx/rcx as a
// pseudo-link register on x86 for the purpose of tail
// calls.
c.ip = t->arch->hasLinkRegister() ? link : getIp(t, link, stack);
c.stack = stack;
} else {
// we caught the thread in native code, and the most recent

View File

@ -1952,6 +1952,10 @@ class MyArchitecture: public Assembler::Architecture {
return index + 3;
}
virtual bool hasLinkRegister() {
return true;
}
virtual unsigned stackAlignmentInWords() {
return StackAlignmentInWords;

View File

@ -2846,6 +2846,10 @@ class MyArchitecture: public Assembler::Architecture {
}
}
virtual bool hasLinkRegister() {
return false;
}
virtual unsigned stackAlignmentInWords() {
return StackAlignmentInWords;
}