Adjust PC value in ARM stack trace.

-2 for Thumb BLX(2) or -4 for the rest.

Change-Id: I804fdabfa1db4709bede222d4b432e8d42d53167
This commit is contained in:
Ben Cheng 2013-05-07 14:22:43 -07:00
parent d541ba1719
commit 52171b9bdc

View File

@ -91,6 +91,27 @@ static _Unwind_Reason_Code trace_function(__unwind_context* context, void* arg)
return _URC_NO_REASON;
}
#ifdef __arm__
/*
* The instruction pointer is pointing at the instruction after the bl(x), and
* the _Unwind_Backtrace routine already masks the Thumb mode indicator (LSB
* in PC). So we need to do a quick check here to find out if the previous
* instruction is a Thumb-mode BLX(2). If so subtract 2 otherwise 4 from PC.
*/
if (ip != 0) {
short* ptr = reinterpret_cast<short*>(ip);
// Thumb BLX(2)
// FIXME - GCC 4.7 seems to have a bug as without the unnecessary cast to
// short the test will never pass.
if ((*(ptr-1) & 0xff80) == (short) 0x4780) {
ip -= 2;
} else {
ip -= 4;
}
}
#endif
state->frames[state->frame_count++] = ip;
return (state->frame_count >= state->max_depth) ? _URC_END_OF_STACK : _URC_NO_REASON;
}