| Index: src/arm/assembler-arm-inl.h
|
| ===================================================================
|
| --- src/arm/assembler-arm-inl.h (revision 3577)
|
| +++ src/arm/assembler-arm-inl.h (working copy)
|
| @@ -229,14 +229,23 @@
|
|
|
|
|
| Address Assembler::target_address_address_at(Address pc) {
|
| - Instr instr = Memory::int32_at(pc);
|
| - // Verify that the instruction at pc is a ldr<cond> <Rd>, [pc +/- offset_12].
|
| + Address target_pc = pc;
|
| + Instr instr = Memory::int32_at(target_pc);
|
| + // If we have a bx instruction, the instruction before the bx is
|
| + // what we need to patch.
|
| + static const int32_t kBxInstMask = 0x0ffffff0;
|
| + static const int32_t kBxInstPattern = 0x012fff10;
|
| + if ((instr & kBxInstMask) == kBxInstPattern) {
|
| + target_pc -= kInstrSize;
|
| + instr = Memory::int32_at(target_pc);
|
| + }
|
| + // Verify that the instruction to patch is a ldr<cond> <Rd>, [pc +/- offset_12].
|
| ASSERT((instr & 0x0f7f0000) == 0x051f0000);
|
| int offset = instr & 0xfff; // offset_12 is unsigned
|
| if ((instr & (1 << 23)) == 0) offset = -offset; // U bit defines offset sign
|
| // Verify that the constant pool comes after the instruction referencing it.
|
| ASSERT(offset >= -4);
|
| - return pc + offset + 8;
|
| + return target_pc + offset + 8;
|
| }
|
|
|
|
|
|
|