Purpose
The
__dsa_prev() function returns the address of the DSA prior to dsa_p on
the Language Environment® stack.
Two types of backchaining request are supported -- logical and physical.
The req_type parameter is used to select
either logical or physical backchaining. For physical backchaining,
the address of the DSA immediately prior to dsa_p is
always returned. That DSA can be a transition or overflow DSA, or
the DSA of a normal routine. For logical backchaining, __dsa_prev()
keeps looking backward on the Language Environment stack
until a normal DSA is found, skipping over any transition or overflow
DSAs.
If the dummy Language Environment DSA is
reached while backchaining, a NULL pointer is returned, and errno
is set to ESRCH.
__dsa_prev() can
be used when the Language Environment stack
of interest is not in the current address space. To access storage
outside the current address space, the user must provide the callback_p parameter. callback_p is
a pointer to a user-written function that fetches all required data
for __dsa_prev(). Generally, the (*callback_p)()
function would obtain the data using some application-dependent method
(like BPX1PTR) and move it into the current address space, where __dsa_prev()
can access it directly. If the Language Environment stack
of interest is in the same address space and is directly accessible
to __dsa_prev(), callback_p can be NULL.
Syntax
#include <edcwccwi.h>
void __dsa_prev(const void
* dsa_p, int req_type,
int dsa_fmt, void * (*callback_p)(void
*data_p, size_t data_l),
const void *caa_p, int *prev_fmt,
void **ph_callee_dsa_p, int *ph_callee_dsa_fmt);
- const void *dsa_p
- Pointer to the current DSA. __dsa_prev() returns a pointer to
the DSA logically or physically previous to dsa_p,
depending on the value of the req_type parameter.
dsa_p may point to a DSA in another address
space or in some other place not directly accessible by __dsa_prev().
If this address is not directly accessible, the callback_p parameter
must be non-NULL. The callback function will be used to access dsa_p indirectly.
- int req_type
- Controls if transition DSAs are returned. The allowed values for req_type are:
- __EDCWCCWI_PHYSICAL
- Physical backchaining causes __dsa_prev() to return the address
of the DSA immediately prior to dsa_p. The
returned DSA can be either a transition or normal DSA.
- __EDCWCCWI_LOGICAL
- Logical backchaining causes __dsa_prev() to skip over any transition
DSAs that it finds while backchaining, and not pass them back. The
address of the most recent normal DSA previous to dsa_p is
returned. Doing logical backchaining is the same as doing physical
backchaining one or more times, stopping when a normal DSA is found.
- int dsa_fmt
- The format of the DSA pointed to by dsa_p.
The allowed value for dsa_fmt is:
- __EDCWCCWI_DOWN
- This value indicates that dsa_p points
to a 64–bit DSA.
- void * (*callback_p)()
- Pointer to a user-provided function that fetches data not normally
accessible by __dsa_prev(). If callback_p is
NULL, __dsa_prev() accesses dsa_p and any
other required Language Environment data
areas directly in the current address space. The Language Environment stack
and all other data needed for backchaining must be directly accessible
to __dsa_prev() in this case.
The user-provided (*callback_p)()
function is passed the address and length of data to access. It must
fetch the data in some application-dependent manner, and make the
data available in the current address space in a place accessible
to __dsa_prev(). (*callback_p )() must return
a pointer to the copied data. This data must remain available to
__dsa_prev() until the next call to (*callback_p)(),
or until __dsa_prev() returns to its caller, whichever happens first.
On subsequent calls, (*callback_p)() is
allowed to reuse the same data passback area.
There is no provision
for (*
callback_p)() to pass back an error
return code, indicating that the requested data could not be obtained.
If (*
callback_p)() cannot return the requested
data, it must not return to __dsa_prev(). When an error occurs, (*
callback_p)()
may:
- longjmp() back to some error return point in the user code that
called __dsa_prev().
- ABEND or otherwise terminate abnormally.
- exit(), pthread_exit(), etc.
- Raise a caught signal where the catcher does longjmp() so as not
to return to __dsa_prev().
- Use Language Environment condition
management to bypass __dsa_prev() after the error and resume in user
code.
- Recover in some other way that does not involve returning to __dsa_prev().
__dsa_prev() calls (*
callback_p)()
with two parameters:
- void *data_p
- Pointer to the start of the required data. This address might
not be in the current address space.
- size_t data_l
- The number of bytes of data required. data_l will
never exceed 16 bytes. If (*callback_p)() cannot
pass back the complete data requested, it must not return to __dsa_prev().
- const void *caa_p
- Pointer to the Language Environment CAA for
the thread owning the dsa_p DSA. This parameter
must be non-NULL whenever callback_p is
non-NULL, and it may point to a CAA in some other address space.
If callback_p is NULL, caa_p may
also be NULL. If caa_p is NULL, the current
CAA (of the thread where __dsa_prev() is running) is used. In this
case, it is assumed that dsa_p points to
a DSA on the Language Environment stack
for the caller's thread.
- int *prev_fmt
- Pointer to an optional passback area where __dsa_prev() will return
the DSA format of the prior DSA. The possible values passed back in
this field are the same as the values for dsa_fmt.
If prev_fmt is NULL, the DSA format
for the previous DSA is not passed back. If __dsa_prev() cannot find
the previous DSA and returns a NULL value, the field pointed to by prev_fmt is
not altered.
- void **ph_callee_dsa_p
- Pointer to an optional passback area where __dsa_prev() will return
the address of the DSA of the physical callee. The physical callee
is the function called by the function owning the returned DSA. The
physical callee can be a Language Environment overflow
or stack expansion routine, or it can be a normal user or Language Environment function.
If physical backchaining is requested, *ph_callee_dsa_p will
be the same as dsa_p after __dsa_fmt() returns.
If ph_callee_dsa_p is NULL, the address
of the physical callee DSA is not passed back.
If __dsa_prev()
cannot find the previous DSA and returns a NULL value, the field pointed
to by ph_callee_dsa_p is not altered.
- int *ph_callee_dsa_fmt
- ph_callee_dsa_fmt is a pointer to an
optional passback area where __dsa_prev() will return the DSA format
of the physical callee's DSA. The possible values passed back in this
field are the same as the values for dsa_fmt.
If ph_callee_dsa_fmt is NULL, the format
of the physical callee DSA is not passed back. If __dsa_prev() cannot
find the previous DSA and returns a NULL value, the field pointed
to by ph_callee_dsa_fmt is not altered.
Return values
- If successful, __dsa_prev() returns the address of the previous
DSA. In addition, if errno is zero when __dsa_prev() is called, one
of the following errno values may be set to pass back additional information:
- EACCES
- TIndicates that the returned DSA pointer is for the Language Environment dummy
DSA (pointed to by the CAA ceecaaddsa field). This is not an error,
and all returned or passed-back information is valid.
- EALREADY
- Indicates that the input DSA pointer (dsa_p)
is for the Language Environment dummy
DSA (pointed to by the CAA CEECAADDSA field). This is not an error,
and all returned or passed-back information is valid.
- If unsuccessful, __dsa_prev() returns a NULL pointer, and sets
errno to one of the following values:
- ESRCH
- Indicates that there was no DSA previous to dsa_p that
could satisfy the physical or logical backchaining request. This error
also occurs if dsa_p is NULL when __dsa_prev()
is called.
- EINVAL
- This error can occur if:
- caa_p was NULL and callback_p was
not NULL.
- req_type was not __EDCWCCWI_PHYSICAL or __EDCWCCWI_LOGICAL.
- dsa_fmt was not __EDCWCCWI_DOWN.
Usage notes
- If the return code from __dsa_prev() is NULL, the listed errno
values are set even if errno was non-zero when __dsa_pr() was called.
When the return code from __dsa_pr() is not NULL, errno is not changed
if it was not zero when __dsa_prev() was called.
- __dsa_prev() may cause program checks if it accesses invalid addresses.
This is especially likely to happen if callback_p is
NULL and the Language Environment stack
being looked at is corrupted. For this reason, the caller should consider
having a signal catcher set up to handle SIGSEGV with appropriate
error recovery.
- The Vendor Interfaces header file, <edcwccwi.h>, is located
in member EDCWCCWI of the SCEESAMP data set. In order to include <edcwccwi.h>
in an application, the header file must be copied into a PDS or into
a directory in the z/OS® UNIX file
system where the C/C++ compiler will find it.