| Index: src/arm/assembler-arm-inl.h
|
| ===================================================================
|
| --- src/arm/assembler-arm-inl.h (revision 4189)
|
| +++ src/arm/assembler-arm-inl.h (working copy)
|
| @@ -144,12 +144,21 @@
|
|
|
|
|
| bool RelocInfo::IsPatchedReturnSequence() {
|
| - // On ARM a "call instruction" is actually two instructions.
|
| - // mov lr, pc
|
| - // ldr pc, [pc, #XXX]
|
| - return (Assembler::instr_at(pc_) == kMovLrPc)
|
| - && ((Assembler::instr_at(pc_ + Assembler::kInstrSize) & kLdrPCPattern)
|
| - == kLdrPCPattern);
|
| + Instr current_instr = Assembler::instr_at(pc_);
|
| + Instr next_instr = Assembler::instr_at(pc_ + Assembler::kInstrSize);
|
| +#ifdef USE_BLX
|
| + // A patched return sequence is:
|
| + // ldr ip, [pc, #0]
|
| + // blx ip
|
| + return ((current_instr & kLdrPCMask) == kLdrPCPattern)
|
| + && ((next_instr & kBlxRegMask) == kBlxRegPattern);
|
| +#else
|
| + // A patched return sequence is:
|
| + // mov lr, pc
|
| + // ldr pc, [pc, #-4]
|
| + return (current_instr == kMovLrPc)
|
| + && ((next_instr & kLdrPCMask) == kLdrPCPattern);
|
| +#endif
|
| }
|
|
|
|
|
| @@ -225,6 +234,16 @@
|
| target_pc -= kInstrSize;
|
| instr = Memory::int32_at(target_pc);
|
| }
|
| +
|
| +#ifdef USE_BLX
|
| + // If we have a blx instruction, the instruction before it is
|
| + // what needs to be patched.
|
| + if ((instr & kBlxRegMask) == kBlxRegPattern) {
|
| + target_pc -= kInstrSize;
|
| + instr = Memory::int32_at(target_pc);
|
| + }
|
| +#endif
|
| +
|
| // Verify that the instruction to patch is a
|
| // ldr<cond> <Rd>, [pc +/- offset_12].
|
| ASSERT((instr & 0x0f7f0000) == 0x051f0000);
|
|
|