1
0
Fork 0
mirror of https://github.com/tobast/libunwind-eh_elf.git synced 2024-06-02 01:12:37 +02:00

Partial draft.

(Logical change 1.139)
This commit is contained in:
mostang.com!davidm 2003-12-10 07:14:38 +00:00
parent f18f14e2f5
commit e91ef29727

View file

@ -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}