This is an archive of the discontinued LLVM Phabricator instance.

Improve instruction emulation based stack unwinding on ARM
ClosedPublic

Authored by tberghammer on Jun 15 2015, 10:36 AM.

Details

Summary

Improve instruction emulation based stack unwinding on ARM

  • Add and fix the emulation of several instruction.
  • Disable frame pointer usage on Android.
  • Specify return address register for the unwind plan instead of explicit tracking the value of RA.
  • Replace prologue detection heuristics (unreliable in several cases) with a logic to follow the branch instructions and restore the CFI value based on them. The target address for a branch should have the same CFI as the source address (if they are in the same function).
  • Handle symbols in ELF files where the symbol size is not specified with calculating their size based on the next symbol (already done in MachO files).
  • Fix architecture in FuncUnwinders with filling up the information missing from the object file with the architecture of the target.
  • Add code to read register when the value is set to "IsSame" as it means the value of a register in the parent frame is the same as the value in the current frame.

Diff Detail

Repository
rL LLVM

Event Timeline

tberghammer retitled this revision from to Improve instruction emulation based stack unwinding on ARM.
tberghammer updated this object.
tberghammer edited the test plan for this revision. (Show Details)
tberghammer added a reviewer: jasonmolenda.
tberghammer added a subscriber: Unknown Object (MLST).
emaste added a subscriber: emaste.Jun 15 2015, 10:52 AM

Hi Jason,

Can you take a look for it? I plan to continue my work on ARM (and AARCH64) stack unwinding based on this patch but prefer to wait for your opinion first about the approach I am using.

On android this patch achieves a significant improvement (tested based on D10454) but it can have negative effect in some special case on other environments.

Thanks,
Tamas

jasonmolenda accepted this revision.Jun 22 2015, 9:14 PM
jasonmolenda edited edge metadata.

Tamas, I apologize for taking so long to get to this patch. I meant to do it over the weekend but didn't have the time - I need to think hard about changes in the unwinder before I feel comfortable with them and it took me a couple hours of staring at the patch and thinking things over.

I much prefer your approach in EmulateInstruction of saving the unwind register state so that we can re-establish it after an epilogue. Mine was not very elegant and I'm sure there are more complicated functions where mine could do the wrong thing. In practice with the armv7/arm64 code that we were supporting, it worked fine. But your approach is better.

One problem with the patch is that we're going to lose the mid-function epilogue correctness with the ARM64 instruction emulation plugin - it doesn't tag eContextAbsoluteBranchRegister / eContextRelativeBranchImmediate instructions which is the only way the m_forward_branch_offset ivar in EmulateInstruction is set. I think it's reasonable to accept the patch knowing that we're regressing arm64 until someone (who supports arm64, like myself or Greg) adds the instruction support for recognizing branch instructions and correctly identifying the target offset of those branches.

source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp
175 ↗(On Diff #27686)

I think you mean "current CFI information" here. The "I" in CFI stands for information, but it's one of those annoying aspects of english where it looks weird without "information" after it. :)

188 ↗(On Diff #27686)

CFI. Call Frame Information.

This revision is now accepted and ready to land.Jun 22 2015, 9:14 PM
This revision was automatically updated to reflect the committed changes.