Merge "Fix the 16 bit/32 bit instruction check for arm."
This commit is contained in:
commit
d518a6d3bc
|
@ -90,15 +90,22 @@ static _Unwind_Reason_Code trace_function(__unwind_context* context, void* arg)
|
||||||
// Modify the pc to point at the real function.
|
// Modify the pc to point at the real function.
|
||||||
if (ip != 0) {
|
if (ip != 0) {
|
||||||
#if defined(__arm__)
|
#if defined(__arm__)
|
||||||
// We need to do a quick check here to find out if the previous
|
// If the ip is suspiciously low, do nothing to avoid a segfault trying
|
||||||
// instruction is a Thumb-mode BLX(2). If so subtract 2 otherwise
|
// to access this memory.
|
||||||
// 4 from PC.
|
if (ip >= 4096) {
|
||||||
short* ptr = reinterpret_cast<short*>(ip);
|
// Check bits [15:11] of the first halfword assuming the instruction
|
||||||
// Thumb BLX(2)
|
// is 32 bits long. If the bits are any of these values, then our
|
||||||
if ((*(ptr-1) & 0xff80) == 0x4780) {
|
// assumption was correct:
|
||||||
ip -= 2;
|
// b11101
|
||||||
} else {
|
// b11110
|
||||||
ip -= 4;
|
// b11111
|
||||||
|
// Otherwise, this is a 16 bit instruction.
|
||||||
|
uint16_t value = (*reinterpret_cast<uint16_t*>(ip - 2)) >> 11;
|
||||||
|
if (value == 0x1f || value == 0x1e || value == 0x1d) {
|
||||||
|
ip -= 4;
|
||||||
|
} else {
|
||||||
|
ip -= 2;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#elif defined(__aarch64__)
|
#elif defined(__aarch64__)
|
||||||
// All instructions are 4 bytes long, skip back one instruction.
|
// All instructions are 4 bytes long, skip back one instruction.
|
||||||
|
|
Loading…
Reference in New Issue