diff --git a/doc/libunwind-dynamic.tex b/doc/libunwind-dynamic.tex index 16c4e01a..5b1bd0f1 100644 --- a/doc/libunwind-dynamic.tex +++ b/doc/libunwind-dynamic.tex @@ -1,5 +1,88 @@ -unw\_dyn\_region\_info\_t: +\documentclass{article} +\usepackage[fancyhdr,pdf]{latex2man} +\input{common.tex} + +\begin{document} + +\begin{Name}{3}{libunwind-dynamic}{David Mosberger-Tang}{Programming Library}{Introduction to dynamic unwind-info}libunwind-dynamic -- libunwind-support for runtime-generated code +\end{Name} + +\section{Introduction} + +For \Prog{libunwind} to do its work, it needs to be able to +reconstruct the \emph{frame state} of each frame in a call-chain. The +frame state consists of some frame registers (such as the +instruction-pointer and the stack-pointer) and the locations at which +the current values of every callee-saved (``preserved'') resides. + +The purpose of the dynamic unwind-info is therefore to provide +\Prog{libunwind} the minimal information it needs about each +dynamically generated procedure such that it can reconstruct the +procedure's frame state. + +For the purpose of the following discussion, a \emph{procedure} is any +contiguous piece of code. Normally, each procedure directly +corresponds to a function in the source-language but this is not +strictly required. For example, a runtime code-generator could +translate a given function into two separate (discontiguous) +procedures: one for frequently-executed (hot) code and one for +rarely-executed (cold) code. Similarly, simple source-language +functions (usually leaf functions) may get translated into code for +which the default unwind-conventions apply and for such code, no +dynamic unwind info needs to be registered. + +Within a procedure, the code can be thought of as being divided into a +sequence of \emph{regions}. Each region logically consists of an +optional \emph{prologue}, a \emph{body}, and an optional +\emph{epilogue}. If present, the prologue sets up the frame state for +the body, which does the actual work of the procedure. For example, +the prologue may need to allocate a stack-frame and save some +callee-saved registers before the body can start executing. +Correspondingly, the epilogue, if present, restores the previous frame +state and thereby undoes the effect of the prologue. Regions are +nested in the sense that the frame state at the end of a region serves +as the entry-state of the next region. At the end of several nested +regions, there may be a single epilogue which undoes the effect of all +the prologues in the nested regions. + +Even though logically we think of the prologue, body, and epilogue as +separate entities, optimizing code-generators will generally +interleave instructions from all three entities to achieve higher +performance. In fact, as far as the dynamic unwind-info is concerned, +there is no distinction at all between prologue and body. Similarly, +the exact set of instructions that make up an epilogue is also +irrelevant. The only point in the epilogue that needs to be described +explicitly is the point at which the stack-pointer gets restored. The +reason this point needs to be described is that once the stack-pointer +is restored, all values saved in the deallocated portion of the stack +become invalid. All other locations that store the values of +callee-saved register are assumed to remain valid throughout the end +of the region. + +Within a region, each instruction that affects the frame state in some +fashion needs to be described with an operation descriptor. For this +purpose, each instruction in the region is assigned a unique index. +Exactly how this index is derived depends on the architecture. For +example, on RISC and EPIC-style architecture, instructions have a +fixed size so it's possible to simply number the instructions. In +contrast, most CISC use variable-length instruction encodings, so it +is usually necessary to use a byte-offset as the index. Given the +instruction index, the operation descriptor specifies the effect of +the instruction in an abstract manner. For example, it might express +that the instruction stores calle-saved register \Var{r1} at offset 16 +in the stack frame. + +\section{Procedures} + +unw\_dyn\_info\_t +unw\_dyn\_proc\_info\_t +unw\_dyn\_table\_info\_t +unw\_dyn\_remote\_table\_info\_t + +\section{Regions} + +unw\_dyn\_region\_info\_t: - insn_count can be negative to indicate that the region is at the end of the procedure; in such a case, the negated insn_count value specifies the length of the final region @@ -7,3 +90,49 @@ unw\_dyn\_region\_info\_t: with a negative insn_count and only the last region in a procedure's region list may be negative. Furthermore, both di->start\_ip and di->end\_ip must be valid. + +\section{Operations} + +unw\_dyn\_operation\_t +unw\_dyn\_op\_t + \_U\_QP\_TRUE + +unw\_dyn\_info\_format\_t + +- instructions don't have to be sorted in increasing order of ``when'' + values: In general, if you can generate the sorted order easily + (e.g., without an explicit sorting step), I'd recommend doing so + because in that case, should some version of libunwind ever require + sorted order, libunwind can verify in O(N) that the list is sorted + already. In the particular case of the ia64-version of libunwind, a + sorted order won't help, since it always scans the instructions up + to UNW_DYN_STOP. + +\_U\_dyn\_region\_info\_size(opcount); +\_U\_dyn\_op\_save\_reg(); +\_U\_dyn\_op\_spill\_fp\_rel(); +\_U\_dyn\_op\_spill\_sp\_rel(); +\_U\_dyn\_op\_add(); +\_U\_dyn\_op\_pop\_frames(); +\_U\_dyn\_op\_label\_state(); +\_U\_dyn\_op\_copy\_state(); +\_U\_dyn\_op\_alias(); +\_U\_dyn\_op\_stop(); + +\section{See Also} + +\SeeAlso{libunwind(3)}, +\SeeAlso{\_U\_dyn\_register(3)}, +\SeeAlso{\_U\_dyn\_cancel(3)} + +\section{Author} + +\noindent +David Mosberger-Tang\\ +Hewlett-Packard Labs\\ +Palo-Alto, CA 94304\\ +Email: \Email{davidm@hpl.hp.com}\\ +WWW: \URL{http://www.hpl.hp.com/research/linux/libunwind/}. +\LatexManEnd + +\end{document}