|
|
Unwind utility routines provide the core functionality of the stack unwind
mechanism. They can be used to create powerful unwind applications. These
routines are present and have identical functionality on all PA-RISC systems
running HP-UX or MPE XL.
U_get_unwind_table
struct utable {
unsigned unwind_table_start;
unsigned unwind_table_end;
};
struct utable U_get_unwind_table(unsigned int dp_value);
Returns the code offsets of the start and end of the unwind table of
a given object module. The unwind table is word-aligned. It takes the
DP value for the object module where the unwind table is stored. It
returns the offset of the start of the unwind table, and the offset
of the first word beyond the unwind table.
This is the interface for assembly programmers:
ARGO: DP value of routine being unwound to.
RETO: Offset (in space of routine being unwound to)
of start of unwind table.
RET1: Offset (in space of routine being unwound to)
of first word beyond end of unwind table.
U_get_unwind_entry
int U_get_unwind_entry(
unsigned int PC;
unsigned int Space_id;
unsigned int table_start;
unsigned int table_end);
Given the PC_offset value of interest and the start and end of
the associated unwind table, returns the code offset (in
PC_space) of the associated unwind table entry. If no unwind
table entry exists, -1 is returned. Typically the table_start
and table_end is found using the U_qet_unwind_table
routine.
This is the interface for assembly programmers:
ARG0: PC value to look up.
ARG1: Space id of table.
ARG2: Offset of start of unwind table.
ARG3: Offset of first word beyond end of unwind table.
RET0: Offset of unwind table entry associated with PC value;
-1 if none exists.
This routine requires that the unwind table is sorted in increasing
order of starting addresses. It does a binary search of the table to
get to the entry corresponding to the input PC value.
U_get_previous_frame
struct current_frame_def {
unsigned cur_frsize; /* Frame size of current routine. */
unsigned cursp; /* The current value of stack pointer. */
unsigned currls; /* PC_space of the calling routine. */
unsigned currlo; /* PC_offset of the calling routine. */
unsigned curdp; /* Data Pointer of the current routine. */
unsigned toprp; /* Initial value of RP. */
unsigned topmrp; /* Initial value of MRP. */
unsigned topsr0; /* Initial value of sr0. */
unsigned topsr4; /* Initial value of sr4 */
unsigned r3; /* Initial value of gr3 */
unsigned cur_r19; /* GR19 value of the calling routine. */
}; /* Used only in HP-UX. */
struct previous_frame_def {
unsigned prev_frsize; /* frame size of calling routine. */
unsigned prevSP; /* SP of calling routine. */
unsigned prevRLS; /* PC_space of calling routine's caller. */
unsigned prevRLO; /* PC_offset of calling routine's caller.*/
unsigned prevDP; /* DP of calling routine. */
unsigned udescr0; /* low word of calling routine's unwind */
/* descriptor. */
unsigned udescr1; /* high word of calling routine's */
/* unwind descriptor. */
unsigned ustart; /* start of the unwind region. */
unsigned uw_index; /* index into the unwind table. */
unsigned uend; /* end of the unwind region. */
unsigned prev_r19; /* GR19 value of the caller's caller. */
};
int U_get_previous_frame(
struct current_frame_def *curr.frame;
struct previous_frame_def *prev.frame);
Given a PC_space, a PC_offset value that is a return link to the
caller, the frame size, and the DP and SP values of the called routine, these
routines return the frame size, the DP and SP values of the caller's frame, and
the (PC_space, PC_offset) value that is a return link to the caller's
caller.
The routine returns:
0 | normal; |
|
-1 | if curRLS, curRLO is nil, indicating stack was fully
unwound; |
|
-4 | if error occurs during linker stub unwinding other negative
values less than -1 may be used in the future to indicate additional
unexpected (internal) errors. |
|
positive | if the frame is not unwindable for some reason.
Values currently used:
1 - no unwind_descriptor
0x7fffffff - cannot_unwind bit on in previous unwind descriptor |
This is the interface for assembly programmers:
ARG0: | Pointer to an eleven-word area of memory that contains
the current frame info. |
|
ARG1: | Pointer to an eleven-word area of memory defined on exit
as per definition of the previous_frame_info structure. |
|
RET0: | Return value defined on exit. |
This routine is designed to enable access to the previous frame on the stack
with input information about the current state. You may call this iteratively
by setting the cur fields to the appropriate machine state, and then
copying the first five prev values (and the prev_r19 value) into
the corresponding fields for successive calls, until end-of-stack is reached.
When a nonzero value is returned, the fields that would normally get defined
on exit are undefined.
If the frame of the called routine is the topmost frame on the stack when
unwinding commences, cur_frsize should be zero on the initial call.
|