diff options
author | mostang.com!davidm <mostang.com!davidm> | 2003-12-21 05:53:57 +0000 |
---|---|---|
committer | mostang.com!davidm <mostang.com!davidm> | 2003-12-21 05:53:57 +0000 |
commit | 3d24b59dbaa67b246d7b627a5f61e2b381d01838 (patch) | |
tree | 79380e4909c1c57dc9a23a5fc4d2ddb3c1e4f585 /doc | |
parent | 8365c7bc6034faa12786087e4c5679fc202a0437 (diff) | |
download | libunwind-3d24b59dbaa67b246d7b627a5f61e2b381d01838.tar.gz |
Update it some more.
(Logical change 1.147)
Diffstat (limited to 'doc')
-rw-r--r-- | doc/libunwind-dynamic.tex | 417 |
1 files changed, 341 insertions, 76 deletions
diff --git a/doc/libunwind-dynamic.tex b/doc/libunwind-dynamic.tex index 5b1bd0f1..43c86320 100644 --- a/doc/libunwind-dynamic.tex +++ b/doc/libunwind-dynamic.tex @@ -10,55 +10,63 @@ \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. +For \Prog{libunwind} to do its job, it needs to be able to reconstruct +the \emph{frame state} of each frame in a call-chain. The frame state +describes the subset of the machine-state that consists of the +\emph{frame registers} (typically the instruction-pointer and the +stack-pointer) and all callee-saved registers (preserved registers). +The frame state describes each register either by providing its +current value (for frame registers) or by providing the location at +which the current value is stored (callee-saved registers). + +For statically generated code, the compiler normally takes care of +emitting \emph{unwind-info} which provides the minimum amount of +information needed to reconstruct the frame-state for each instruction +in a procedure. For dynamically generated code, the runtime code +generator must use the dynamic unwind-info interface provided by +\Prog{libunwind} to supply the equivalent information. This manual +page describes the format of this information in detail. + +For the purpose of this discussion, a \emph{procedure} is defined to +be an arbitrary piece of \emph{contiguous} 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, it is not strictly necessary to register dynamic unwind-info. + +A procedure logically consists of a sequence of \emph{regions}. +Regions are nested in the sense that the frame state at the end of one +region is, by default, assumed to be the frame state for the next +region. Each region is thought of as being divided into a +\emph{prologue}, a \emph{body}, and an \emph{epilogue}. Each of them +can be empty. If non-empty, the prologue sets up the frame state for +the body. For example, the prologue may need to allocate some space +on the stack and save certain callee-saved registers. The body +performs the actual work of the procedure but does not change the +frame state in any way. If non-empty, the epilogue restores the +previous frame state and as such it undoes or cancels the effect of +the prologue. In fact, a single epilogue may undo the effect of the +prologues of several (nested) regions. + +We should point out that even though the prologue, body, and epilogue +are logically separate entities, optimizing code-generators will +generally interleave instructions from all three entities. For this +reason, the dynamic unwind-info interface of \Prog{libunwind} makes no +distinction whatsoever 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 +by the dynamic unwind-info 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 frame become invalid and hence +\Prog{libunwind} needs to know about it. The portion of the frame +state not saved on the stack is assume to remain valid through the end +of the region. For this reason, there is usually no need to describe +instructions which restore the contents of callee-saved registers. Within a region, each instruction that affects the frame state in some fashion needs to be described with an operation descriptor. For this @@ -75,40 +83,286 @@ 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 +A runtime code-generator registers the dynamic unwind-info of a +procedure by setting up a structure of type \Type{unw\_dyn\_info\_t} +and calling \Func{\_U\_dyn\_register}(), passing the address of the +structure as the sole argument. The members of the +\Type{unw\_dyn\_info\_t} structure are described below: +\begin{itemize} +\item[\Type{void~*}next] Private to \Prog{libunwind}. Must not be used + by the application. +\item[\Type{void~*}prev] Private to \Prog{libunwind}. Must not be used + by the application. +\item[\Type{unw\_word\_t} \Var{start\_ip}] The start-address of the + instructions of the procedure (remember: procedure are defined to be + contiguous pieces of code, so a single code-range is sufficient). +\item[\Type{unw\_word\_t} \Var{end\_ip}] The end-address of the + instructions of the procedure (non-inclusive, that is, + \Var{end\_ip}-\Var{start\_ip} is the size of the procedure in + bytes). +\item[\Type{unw\_word\_t} \Var{gp}] The global-pointer value in use + for this procedure. The exact meaing of the global-pointer is + architecture-specific and on some architecture, it is not used at + all. +\item[\Type{int32\_t} \Var{format}] The format of the unwind-info. + This member can be one of \Const{UNW\_INFO\_FORMAT\_DYNAMIC}, + \Const{UNW\_INFO\_FORMAT\_TABLE}, or + \Const{UNW\_INFO\_FORMAT\_REMOTE\_TABLE}. +\item[\Type{union} \Var{u}] This union contains one sub-member + structure for every possible unwind-info format: + \begin{description} + \item[\Type{unw\_dyn\_proc\_info\_t} \Var{pi}] This member is used + for format \Const{UNW\_INFO\_FORMAT\_DYNAMIC}. + \item[\Type{unw\_dyn\_table\_info\_t} \Var{ti}] This member is used + for format \Const{UNW\_INFO\_FORMAT\_TABLE}. + \item[\Type{unw\_dyn\_remote\_table\_info\_t} \Var{rti}] This member + is used for format \Const{UNW\_INFO\_FORMAT\_REMOTE\_TABLE}. + \end{description}\ + The format of these sub-members is described in detail below. +\end{itemize} -\section{Regions} +\subsection{Proc-info format} -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 - in number of instructions. There must be at most one region - 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. +This is the preferred dynamic unwind-info format and it is generally +the one used by full-blown runtime code-generators. In this format, +the details of a procedure are described by a structure of type +\Type{unw\_dyn\_proc\_info\_t}. This structure contains the following +members: +\begin{description} -\section{Operations} +\item[\Type{unw\_word\_t} \Var{name\_ptr}] The address of a + (human-readable) name of the procedure or 0 if no such name is + available. If non-zero, The string stored at this address must be + ASCII NUL terminated. For source languages that use name-mangling + (such as C++ or Java) the string stored at this address should be + the \emph{demangled} version of the name. -unw\_dyn\_operation\_t -unw\_dyn\_op\_t - \_U\_QP\_TRUE +\item[\Type{unw\_word\_t} \Var{handler}] The address of the + personality-routine for this procedure. Personality-routines are + used in conjunction with exception handling. See the C++ ABI draft + (http://www.codesourcery.com/cxx-abi/) for an overview and a + description of the personality routine. If the procedure has no + personality routine, \Var{handler} must be set to 0. + +\item[\Type{uint32\_t} \Var{flags}] A bitmask of flags. At the + moment, no flags have been defined and this member must be + set to 0. + +\item[\Type{unw\_dyn\_region\_info\_t~*}\Var{regions}] A NULL-terminated + linked list of region-descriptors. See section ``Region + descriptors'' below for more details. + +\end{description} + +\subsection{Table-info format} + +This format is generally used when the dynamically generated code was +derived from static code and the unwind-info for the dynamic and the +static versions is identical. For example, this format can be useful +when loading statically-generated code into an address-space in a +non-standard fashion (i.e., through some means other than +\Func{dlopen}()). In this format, the details of a group of procedures +is described by a structure of type \Type{unw\_dyn\_table\_info}. +This structure contains the following members: +\begin{description} + +\item[\Type{unw\_word\_t} \Var{name\_ptr}] The address of a + (human-readable) name of the procedure or 0 if no such name is + available. If non-zero, The string stored at this address must be + ASCII NUL terminated. For source languages that use name-mangling + (such as C++ or Java) the string stored at this address should be + the \emph{demangled} version of the name. + +\item[\Type{unw\_word\_t} \Var{segbase}] The segment-base value + that needs to be added to the segment-relative values stored in the + unwind-info. The exact meaning of this value is + architecture-specific. + +\item[\Type{unw\_word\_t} \Var{table\_len}] The length of the + unwind-info (\Var{table\_data}) counted in units of words + (\Type{unw\_word\_t}). + +\item[\Type{unw\_word\_t} \Var{table\_data}] A pointer to the actual + data encoding the unwind-info. The exact format is + architecture-specific (see architecture-specific sections below). + +\end{description} + +\subsection{Remote table-info format} + +The remote table-info format has the same basic purpose as the regular +table-info format. The only difference is that when \Prog{libunwind} +uses the unwind-info, it will keep the table data in the target +address-space (which may be remote). Consequently, the type of the +\Var{table\_data} member is \Type{unw\_word\_t} rather than a pointer. +This implies that \Prog{libunwind} will have to access the table-data +via the address-space's \Func{access\_mem}() call-back, rather than +through a direct memory reference. + +From the point of view of a runtime-code generator, the remote +table-info format offers no advantage and it is expected that such +generators will describe their procedures either with the proc-info +format or the normal table-info format. The main reason that the +remote table-info format exists is to enable the +address-space-specific \Func{find\_proc\_info}() callback (see +\SeeAlso{unw\_create\_addr\_space}(3)) to return unwind tables whose +data remains in remote memory. This can speed up unwinding (e.g., for +a debugger) because it reduces the amount of data that needs to be +loaded from remote memory. + +\section{Regions descriptors} + +A region descriptor is a variable length structure that describes how +each instruction in the region affects the frame state. Of course, +most instructions in a region usualy do not change the frame state and +for those, nothing needs to be recorded in the region descriptor. A +region descriptor is a structure of type +\Type{unw\_dyn\_region\_info\_t} and has the following members: +\begin{description} +\item[\Type{unw\_dyn\_region\_info\_t~*}\Var{next}] A pointer to the + next region. If this is the last region, \Var{next} is \Const{NULL}. +\item[\Type{int32\_t} \Var{insn\_count}] The length of the region in + instructions. Each instruction is assumed to have a fixed size (see + architecture-specific sections for details). The value of + \Var{insn\_count} may be negative in the last region of a procedure + (i.e., it may be negative only if \Var{next} is \Const{NULL}). A + negative value indicates that the region covers the last \emph{N} + instructions of the procedure, where \emph{N} is the absolute value + of \Var{insn\_count}. +\item[\Type{uint32\_t} \Var{op\_count}] The (allocated) length of + the \Var{op\_count} array. +\item[\Type{unw\_dyn\_op\_t} \Var{op}] An array of dynamic unwind + directives. See Section ``Dynamic unwind directives'' for a + description of the directives. +\end{description} +A region descriptor with an \Var{insn\_count} of zero is an +\emph{empty region} and such regions are perfectly legal. In fact, +empty regions can be useful to establish a particular frame state +before the start of another region. + +A single region list can be shared across multiple procedures provided +those procedures share a common prologue and epilogue (their bodies +may differ, of course). Normally, such procedures consist of a canned +prologue, the body, and a canned epilogue. This could be described by +two regions: one covering the prologue and one covering the epilogue. +Since the body length is variable, the latter region would need to +specify a negative value in \Var{insn\_count} such that +\Prog{libunwind} knows that the region covers the end of the procedure +(up to the address specified by \Var{end\_ip}). + +The region descriptor is a variable length structure to make it +possible to allocate all the necessary memory with a single +memory-allocation request. To facilitate the allocation of a region +descriptors \Prog{libunwind} provides a helper routine with the +following synopsis: -unw\_dyn\_info\_format\_t +\noindent +\Type{size\_t} \Func{\_U\_dyn\_region\_size}(\Type{int} \Var{op\_count}); + +This routine returns the number of bytes needed to hold a region +descriptor with space for \Var{op\_count} unwind directives. Note +that the length of the \Var{op} array does not have to match exactly +with the number of directives in a region. Instead, it is sufficient +if the \Var{op} array contains at least as many entries as there are +directives, since the end of the directives can always be indicated +with the \Const{UNW\_DYN\_STOP} directive. + +\section{Dynamic unwind directives} + +A dynamic unwind directive describes how the frame state changes +at a particular point within a region. The description is in +the form of a structure of type \Type{unw\_dyn\_op\_t}. This +structure has the following members: +\begin{description} +\item[\Type{int8\_t} \Var{tag}] The operation tag. Must be one + of the \Type{unw\_dyn\_operation\_t} values described below. +\item[\Type{int8\_t} \Var{qp}] The qualifying predicate that controls + whether or not this directive is active. This is useful for + predicated architecturs such as IA-64 or ARM, where the contents of + another (callee-saved) register determines whether or not an + instruction is executed (takes effect). If the directive is always + active, this member should be set to the manifest constant + \Const{\_U\_QP\_TRUE} (this constant is defined for all + architectures, predicated or not). +\item[\Type{int16\_t} \Var{reg}] The number of the register affected + by the instruction. +\item[\Type{int32\_t} \Var{when}] The region-relative number of + the instruction to which this directive applies. For example, + a value of 0 means that the effect described by this directive + has taken place once the first instruction in the region has + executed. +\item[\Type{unw\_word\_t} \Var{val}] The value to be applied by the + operation tag. The exact meaning of this value varies by tag. See + Section ``Operation tags'' below. +\end{description} +It is perfectly legitimate to specify multiple dynamic unwind +directives with the same \Var{when} value, if a particular instruction +has a complex effect on the frame state. + +Empty regions by definition contain no actual instructions and as such +the directives are not tied to a particular instruction. By +convention, the \Var{when} member should be set to 0, however. + +There is no need for the dynamic unwind directives to appear +in order of increasing \Var{when} values. If the directives happen to +be sorted in that order, it may result in slightly faster execution, +but a runtime code-generator should not go to extra lengths just to +ensure that the directives are sorted. + +IMPLEMENTATION NOTE: should \Prog{libunwind} implementations for +certain architectures prefer the list of unwind directives to be +sorted, it is recommended that such implementations first check +whether the list happens to be sorted already and, if not, sort the +directives explicitly before the first use. With this approach, the +overhead of explicit sorting is only paid when there is a real benefit +and if the runtime code-generator happens to generated sorted lists +naturally, the performance penalty is limited to a simple O(N) check. + +\subsection{Operations tags} + +The possible operation tags are defined by enumeration type +\Type{unw\_dyn\_operation\_t} which defines the following +values: +\begin{description} + +\item[\Const{UNW\_DYN\_STOP}] Marks the end of the dynamic unwind + directive list. All remaining entries in the \Var{op} array of the + region-descriptor are ignored. This tag is guaranteed to have a + value of 0. + +\item[\Const{UNW\_DYN\_SAVE\_REG}] Marks an instruction which saves + register \Var{reg} to register \Var{val}. -- 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. +\item[\Const{UNW\_DYN\_SPILL\_FP\_REL}] Marks an instruction which + spills register \Var{reg} to a frame-pointer-relative location. The + frame-pointer-relative offset is given by the value stored in member + \Var{val}. See the architecture-specific sections for a description + of the stack frame layout. + +\item[\Const{UNW\_DYN\_SPILL\_SP\_REL}] Marks an instruction which + spills register \Var{reg} to a stack-pointer-relative location. The + stack-pointer-relative offset is given by the value stored in member + \Var{val}. See the architecture-specific sections for a description + of the stack frame layout. + +\item[\Const{UNW\_DYN\_ADD}] Marks an instruction which adds + the constant value \Var{val} to register \Var{reg}. To add subtract + a constant value, store the two's-complement of the value in + \Var{val}. The set of registers that can be specified for this tag + is described in the architecture-specific sections below. + +\item[\Const{UNW\_DYN\_POP\_FRAMES}] + +\item[\Const{UNW\_DYN\_LABEL\_STATE}] + +\item[\Const{UNW\_DYN\_COPY\_STATE}] + +\item[\Const{UNW\_DYN\_ALIAS}] + +\end{description} + +unw\_dyn\_op\_t -\_U\_dyn\_region\_info\_size(opcount); \_U\_dyn\_op\_save\_reg(); \_U\_dyn\_op\_spill\_fp\_rel(); \_U\_dyn\_op\_spill\_sp\_rel(); @@ -119,6 +373,17 @@ unw\_dyn\_info\_format\_t \_U\_dyn\_op\_alias(); \_U\_dyn\_op\_stop(); +\section{IA-64 specifics} + +- meaning of segbase member in table-info/table-remote-info format +- format of table\_data in table-info/table-remote-info format +- instruction size: each bundle is counted as 3 instructions, regardless + of template (MLX) +- describe stack-frame layout, especially with regards to sp-relative + and fp-relative addressing +- UNW\_DYN\_ADD can only add to ``sp'' (always a negative value); use + POP\_FRAMES otherwise + \section{See Also} \SeeAlso{libunwind(3)}, |