I am working on assembly profiler for MIPS using EmulateInstruction.

I have set the ContextType to eContextPopRegisterOffStack in the function which 
emulates  "ld    ra,40(sp)"
(i.e. load/restore ra from stack) instruction.

0xffffffff802009a4 <bar>:
0xffffffff802009a4:  67bdffd0   daddiu     sp,sp,-48
0xffffffff802009a8:  ffbf0028   sd   ra,40(sp)    -----> store return address
0xffffffff802009ac:  ffbe0020   sd   s8,32(sp)
0xffffffff802009b0:  03a0f02d   move s8,sp
<..end of prologue...>
<..some other instructions...>
<..start of epilogue...>
0xffffffff802009f4:  03c0e82d   move sp,s8
0xffffffff802009f8:  dfbf0028   ld   ra,40(sp)    ------> restore return address
0xffffffff802009fc:  dfbe0020   ld   s8,32(sp)
0xffffffff80200a00:  67bd0030   daddiu     sp,sp,48
0xffffffff80200a04:  03e00008   jr   ra
0xffffffff80200a08:  00000000   nop

With this setting, the unwinder fails when we try to unwind from  
0xffffffff802009fc.
The call sequence is main()->foo()->bar() however,  backtrace displays only 
current frame.
----------------------------------------
(lldb) bt
* thread #1: tid = 0x0001, 0xffffffff802009fc a.out_64`bar(p=4) + 88 at a.c:30, 
stop reason = breakpoint 1.1
  * frame #0: 0xffffffff802009fc a.out_64`bar(p=4) + 88 at a.c:30
---------------------------------------

Below is a part of generated log:
--------------------------------------------------------------------------------------
th1/fr0 0xffffffff802009fc: CFA=sp+48 => fp=[CFA-16] ra= <same> pc=[CFA-8]

th1/fr0 CFA is 0xffffffff800fff60: Register sp (29) contents are 
0xffffffff800fff30, offset is 48
th1/fr0 initialized frame current pc is 0xffffffff802009fc cfa is 
0xffffffff800fff60 using EmulateInstructionMIPS64 UnwindPlan
th1/fr0 requested caller's saved PC but this UnwindPlan uses a RA reg; getting 
ra (31) instead
th1/fr0 supplying caller's saved ra (31)'s location using 
EmulateInstructionMIPS64 UnwindPlan
th1/fr0 could not supply caller's ra (31) location, IsSame
th1/fr1 could not get pc value
Frame 1 invalid RegisterContext for this frame, stopping stack walk
th1 Unwind of this thread is complete.
--------------------------------------------------------------------------------------

Here we just need to tell the unwinder that the register has been restored and 
take this register from live register context.
Which ContextType to use in such case?

1. There exists similar ContextType - eContextRegisterLoad, but it is 
unimplemented (just breaks out and does nothing) in 
UnwindAssemblyInstEmulation::WriteRegister().
   So will it be a good option to implement eContextRegisterLoad and set the 
register location to itself using SetRegisterLocationToRegister (reg_num, 
reg_num, true)
   OR
2. Add new ContextType say eContextRegisterRestore to EmulateInstruction class 
and implement it in UnwindAssemblyInstEmulation::WriteRegister().

Also, consider location of pc if we are restoring the return address register.
This is similar to how eContextPushRegisterOnStack handles return address 
register in UnwindAssemblyInstEmulation::WriteMemory().

Please let me know if I am missing something.

-Regards,
Bhushan
_______________________________________________
lldb-dev mailing list
lldb-dev@cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/lldb-dev

Reply via email to