This is an archive of the discontinued LLVM Phabricator instance.

[MIPS] Avoid breakpoint in delay slot
ClosedPublic

Authored by bhushan on Aug 19 2015, 10:46 PM.

Details

Reviewers
clayborg
jingham
Summary

In MIPS, when a breakpoint is hit in a delay slot then the PC points to the previous branch/jump instruction. In this case, CAUSE.BD bit is set and we can correct the PC accordingly.
However doing a single step at this point will continue execution from the current PC and not from the target of previous branch/jump instruction.
Solution to this is to not allow breakpoint in a delay slot and move it to previous branch/jump instruction (which will have same effect).

When user tries to set breakpoint by address then this patch checks if the instruction at that address is a delay slot instruction and if it is then the breakpoint is moved to its previous instruction.

Diff Detail

Repository
rL LLVM

Event Timeline

bhushan updated this revision to Diff 32661.Aug 19 2015, 10:46 PM
bhushan retitled this revision from to [MIPS] Avoid breakpoint in delay slot.
bhushan updated this object.
bhushan added a reviewer: clayborg.
bhushan set the repository for this revision to rL LLVM.
bhushan added subscribers: lldb-commits, jaydeep, slthakur and 2 others.
jingham requested changes to this revision.Aug 20 2015, 11:52 AM
jingham added a reviewer: jingham.
jingham added a subscriber: jingham.

I wish we had a better abstraction for machine-specific behaviors than ArchSpec, since it seems sad to put this machine specific a bit of business in Target.cpp, but I don't think you should have to tackle that to get this fix in.

However, I think you came in at too low a level by making the interface about delay slots. Rather, there should be a function Target::GetBreakableLoadAddress (analogous to GetOpcodeLoadAddress & GetCallableLoadAddress) that encapsulated calculating the new breakpoint address and CreateBreakpoint should call that. After all, maybe there will be other reasons why "you want to set a breakpoint on address X but we know Y is a better address" might happen and it would be better to hide the specific reason away as much as possible.

Also, since this will get called for every breakpoint address we set, please don't do any work in this function till you've decided you are on a machine that would require it.

Also, for you own sanity, I would suggest putting some logging (under the breakpoint channel) summarizing what you did to the address. Someday, you'll get some weird bug report from somebody whose breakpoints are going wrong, and then you'll wish too late that you knew what you thought you were doing...

This revision now requires changes to proceed.Aug 20 2015, 11:52 AM
bhushan updated this revision to Diff 33063.Aug 25 2015, 5:02 AM
bhushan edited edge metadata.

Addressed review comments.

  1. Introduced Target::GetBreakableLoadAddress() instead of Target::AdjustBreakpointInDelaySlot() so that it should look more generic and targets can calculate the new breakpoint address based on whatever reason applicable to them (not restricting it to a delay-slot only).
  1. Target::GetBreakableLoadAddress() does not do any work unless a target requires it.
  1. Logging is enabled (under the breakpoint channel) and now mentions a reason why we changed the original breakpoint address. (In case of MIPS, the reason is a delay slot).
clayborg accepted this revision.Aug 25 2015, 9:41 AM
clayborg edited edge metadata.

Looks good.

jingham accepted this revision.Aug 25 2015, 10:51 AM
jingham edited edge metadata.

Thanks, that looks good to me too.

This revision is now accepted and ready to land.Aug 25 2015, 10:51 AM
bhushan closed this revision.Sep 30 2015, 3:39 AM

Closed by commit rL246015