[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [libunwind] filling in unw_dyn_region_info_t
From: |
David Mosberger |
Subject: |
Re: [libunwind] filling in unw_dyn_region_info_t |
Date: |
Tue, 2 Mar 2004 17:03:21 -0800 |
Hi Todd,
>>>>> On Tue, 2 Mar 2004 17:43:58 -0600 (CST), Todd L Miller <address@hidden>
>>>>> said:
Todd> I'm dynamically generating code for instrumentation of the form
Todd> alloc r43=ar.pfs,27,19,8;;
Todd> mov.m r43=ar.unat;;
Todd> adds r12=-8,r12;;
Todd> st8 [r12]=r43,-8;;
Todd> st8.spill [r12]=r1,-8;;
Todd> st8.spill [r12]=r2,-8;;
Todd> followed by more integer register spills. I'm guessing that
Todd> the proper sequence of unwind operations would be something
Todd> like
Todd> _U_dyn_op_add( region->op[0], _U_QP_TRUE, 6, UNW_REG_SP, -8 );
This looks fine, assuming the "adds" is the sixth instruction in the
code (the exact location depends on the bundling, which you don't
show).
However, note that Section 7 of the Software COnventions & Runtime
Architecture Guide [1] ("SCRA") requires that the stack-pointer always
be 16-byte aligned, so even though the unwind-directive itself looks
reasonable, the code itself is incorrect.
Todd> _U_dyn_op_spill_sp_rel( region->op[1], _U_QP_TRUE, 12, UNW_IA64_GR + 1,
0 );
r1 is the global-pointer, which has special usage conventions. It doesn't
need an unwind directive.
Todd> _U_dyn_op_add( region->op[2], _UQ_TRUE, 15, UNW_REG_SP, -8 );
Plausible, except the instruction number (15) seems rather high.
Todd> _U_dyn_op_spill_sp_rel( region->op[3], _U_QP_TRUE, 12, UNW_IA64_GR + 2,
0 );
Not needed: scratch registers do not need unwind-directives.
Todd> _U_dyn_op_add( region->op[2], _UQ_TRUE, 15, UNW_REG_SP, -8 );
Plausible, except that the instruction number (15) seems off.
Todd> and so on, but I can't find documentation discussing what
Todd> libunwind expects.
The expectations of libunwind come from the underlying platform, which
in the case of ia64 are defined by the SCRA.
Todd> I'm looking for a pointer to documentation about this, or
Todd> insight into what and how much to tell libunwind.
Chapter 11 of the SCRA should answer most if not all your questions.
The most important thing though is that unwind directives are needed
only for "preserved" (callee-saved) registers and for "frame
registers" (such as the stack-pointer). "Scratch" (caller-saved)
registers never need unwind directives on ia64. Also, there are
default conventions that take effect in the absence of specific unwind
info. For example, if a procedure does not save ar.pfs, then the
unwinder will assume that the current contents of ar.pfs is still
valid. Thus, in leaf-routines, you generally don't need a directive
describing ar.pfs.
Todd> For instance, does it need to know where I'm stashing R2?
Nope. R2 is a scratch register.
Todd> If I spilled R12 to the stack first, how could I tell
Todd> libunwind that the stack pointer is on the stack? (Would it
Todd> infer that from an op_spill() of register 12?)
Yup, op_spill() should automatically do the right thing.
Todd> Would it be easier to tell libunwind what's going on if I
Todd> generated code that used some register other than 12? (If,
Todd> for instance, I started using r2 as the stack once I'd spilled
Todd> it.)
Yes, it generally is a good idea to update the stack pointer only once
per procedure (that's not a requirement, but it will reduce the amount
and complexity of unwind directives needed).
Todd> I also can't find information about the
Todd> UNW_INFO_FORMAT_TABLE[_REMOTE] types. Is this something a library user
Todd> should worry about?
No, you don't need to worry about that. UNW_INFO_FORMAT_TABLE is
intended for code-generators which patch existing code and then update
an existing unwind-table. The "_REMOTE" variant is mostly a hack for
gdb so it can manage unwind-tables more efficiently (and has nothing
to do with dynamically generated code; it's just defined in
libunwind-dynamic.h because there isn't a better place so far).
Todd> I'm particularly concerned because I need to tell libunwind
Todd> about code generated in _remote_ processes, and I can't find
Todd> examples of how to do that.
Aah, that's a good point: it's the _remote_ processes responsibility
to register the unwind info (via _U_dyn_register()). That is, the
process that generates the code is the one that must call _U_dyn_register().
Let me know if this isn't clear.
Thanks,
--david
[1] http://www.intel.com/design/itanium/downloads/245358.htm