libunwind-devel
[Top][All Lists]
Advanced

[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


reply via email to

[Prev in Thread] Current Thread [Next in Thread]