__sparc_utrap_install - install a SPARC V9 user trap handler


     #include <sys/utrap.h>

     int        __sparc_utrap_install(utrap_entry_t         type,
     utrap_handler_t  new_precise,  utrap_handler_t new_deferred,
     utrap_handler_t        *old_precise,         utrap_handler_t


     The __sparc_utrap_install() function establishes new_precise
     and  new_deferred  user  trap handlers as the new values for
     the specified  type  and  returns  the  existing  user  trap
     handler values in *old_precise and *old_deferred in a single
     atomic operation. A new handler address  of  NULL  means  no
     user  handler  of that type will be installed. A new handler
     address of UTH_NOCHANGE means that the user handler for that
     type  should  not be changed. An old handler pointer of NULL
     means that the user is not interested  in  the  old  handler

     A precise trap is  caused  by  a  specific  instruction  and
     occurs  before any program-visible state has been changed by
     this instruction. When a precise trap  occurs,  the  program
     counter  (PC) saved in the Trap Program Counter (TPC) regis-
     ter points to the instruction that  induced  the  trap;  all
     instructions  prior  to  this trapping instruction have been
     executed.  The next program counter (nPC) saved in the  Trap
     Next  Program  Counter  (TnPC)  register  points to the next
     instruction following the trapping  instruction,  which  has
     not  yet been executed.  A deferred trap is also caused by a
     particular  instruction,  but  unlike  a  precise  trap,   a
     deferred  trap may occur after the program-visible state has
     been changed.  See the SPARC Architecture Manual, Version  9
     for further information on precise and deferred traps.

     The list that follows  contains  hardware  traps  and  their
     corresponding user trap types. User trap types marked with a
     plus-sign (+) are required and must be provided by all  ABI-
     conforming  implementations.   The others may not be present
     on every implementation; an attempt to install a  user  trap
     handler  for  those conditions will return EINVAL. User trap
     types marked with an asterisk (*) are implemented as precise
     traps only.

    |          Trap Name          |  User Trap Type (utrap_entry_t)|
    | illegal_instruction         |  UT_ILLTRAP_INSTRUCTION  +*  or|
    |                             |  UT_ILLEGAL_INSTRUCTION        |
    | fp_disabled                 |  UT_FP_DISABLED +*             |
    | fp_exception_ieee_754       |  UT_FP_EXCEPTION_IEEE_754 +    |
    | fp_exception_other          |  UT_FP_EXCEPTION_OTHER         |
    | tag_overflow                |  UT_TAG_OVERFLOW +*            |
    | division_by_zero            |  UT_DIVISION_BY_ZERO +         |
    | mem_address_not_aligned     |  UT_MEM_ADDRESS_NOT_ALIGNED +  |
    | privileged_action           |  UT_PRIVILEGED_ACTION +        |
    | privileged_opcode           |  UT_PRIVILEGED_OPCODE          |
    | async_data_error            |  UT_ASYNC_DATA_ERROR           |
    | trap_instruction            |  UT_TRAP_INSTRUCTION_16 through|
    |                             |  UT_TRAP_INSTRUCTION_31 +*     |
    | instruction_access_exception|  UT_INSTRUCTION_EXCEPTION    or|
    | instruction_access_MMU_miss |  UT_INSTRUCTION_PROTECTION   or|
    | instruction_access_error    |  UT_INSTRUCTION_ERROR          |
    | data_access_exception       |  UT_DATA_EXCEPTION           or|
    | data_access_MMU_miss        |  UT_DATA_PROTECTION          or|
    | data_access_error           |  UT_DATA_ERROR                 |
    | data_access_protection      |                                |

     The following explanations are provided for those user  trap
     types that are not self-explanatory.

           This trap is raised by user execution of  the  ILLTRAP
           INSTRUCTION. It is always precise.

           This trap will be raised by the execution of otherwise
           undefined  opcodes.  It is implementation-dependent as
           to what opcodes raise this trap; the ABI  only  speci-
           fies  the  interface.  The  trap  may  be  precise  or

           All opcodes declared to be privileged in SPARC V9 will
           raise   this   trap.  It  is  implementation-dependent
           whether other opcodes will raise it as well;  the  ABI
           only specifies the interface.

           No valid user mapping can be made to this address, for
           a data or instruction access, respectively.

           A valid mapping  exists,  and  user  privilege  to  it
           exists,  but  the type of access (read, write, or exe-
           cute) is denied, for a  data  or  instruction  access,

           A valid mapping exists, and both  user  privilege  and
           the  type  of access are allowed, but an unrecoverable
           error occurred in attempting the access, for a data or
           instruction  access,  respectively.  %l1  will contain
           either BUS_ADDRERR or BUS_OBJERR.

           This trap is  raised  when  an  application  issues  a
           floating  point  instruction (including load or store)
           and the SPARC V9 Floating Point Registers State (FPRS)
           FEF  bit is 0. If a user handler is installed for this
           trap, it will be given control. Otherwise  the  system
           will set FEF to one and retry the instruction.

     For all traps, the handler executes in a new  register  win-
     dow,  where  the  in  registers are the out registers of the
     previous frame and have the value they contained at the time
     of  the  trap, similar to a normal subroutine call after the
     save instruction. The global registers (including  the  spe-
     cial  registers  %ccr,  %asi, and %y) and the floating-point
     registers have their values from the time of the  trap.  The
     stack  pointer  register  %sp  plus the BIAS will point to a
     properly-aligned 128-byte register save area; if the handler
     needs  scratch  space, it should decrement the stack pointer
     to obtain it. If the handler needs access  to  the  previous
     frame's in registers or local registers, it should execute a
     FLUSHW instruction, and then access them off  of  the  frame
     pointer. If the handler calls an ABI-conforming function, it
     must set the %asi register to ASI_PRIMARY_NOFAULT before the

     On entry to a precise user trap handler   %l6  contains  the
     %pc  and  %l7 contains the %npc at the time of the trap.  To
     return from a handler and reexecute the trapped instruction,
     the handler would execute:
     jmpl %l6, %g0 ! Trapped PC supplied to user trap handler
     return %l7    ! Trapped nPC supplied to user trap handler

     To return from a handler and skip the  trapped  instruction,
     the handler would execute:

     jmpl %l7, %g0 ! Trapped nPC supplied to user trap handler
     return %l7 + 4 ! Trapped nPC + 4

     On entry to a deferred trap handler %o0 contains the address
     of the instruction that caused the trap and %o1 contains the
     actual instruction (right-justified, zero-extended), if  the
     information  is  available. Otherwise %o0 contains the value
     -1 and %o1 is undefined.  Additional information may be made
     available  for certain cases of deferred traps, as indicated
     in the following table.

    |       Instructions       |         Additional Information        |
    | LD-type (LDSTUB)         |  %o2 contains  the  effective  address|
    |                          |  (rs1 + rs2 | simm13).                |
    | ST-type (CAS, SWAP)      |  %o2 contains the effective address  (|
    |                          |  rs1 + rs2 |simm13).                  |
    | Integer arithmetic       |  %o2 contains the rs1 value. %o3  con-|
    |                          |  tains  the  rs2  |  simm13 value. %o4|
    |                          |  contains  the  contents  of  the   %y|
    |                          |  register.                            |
    | Floating-point arithmetic|  %o2  contains  the  address  of   rs1|
    |                          |  value.  %o3  contains  the address of|
    |                          |  rs2 value.                           |
    | Control-transfer         |  %o2 contains the target address  (rs1|
    |                          |  + rs2 | simm13).                     |
    | Asynchronous data errors |  %o2 contains the address that  caused|
    |                          |  the error. %o3 contains the effective|
    |                          |  ASI, if available, else -1.          |

     To return from a deferred trap, the trap handler issues:

          ta    68    ! ST_RETURN_FROM_DEFERRED_TRAP

     The following pseudo-code explains how the operating  system
     dispatches traps:

     if (precise trap) {
           if (precise_handler) {
                /* not reached */
           } else {
      } else if (deferred_trap) {
                /* not reached */
           } else {
      if (signal)

     User trap handlers must preserve all  registers  except  the
     locals  (%l0-7) and the outs (%o0-7), that is, %i0-7, %g1-7,
     %d0-d62, %asi, %fsr, %fprs, %ccr,  and  %y,  except  to  the
     extent  that  modifying the registers is part of the desired
     functionality of the handler. For example, the  handler  for
     UT_FP_DISABLED may load floating-point registers.


     Upon successful completion,  0  is  returned.  Otherwise,  a
     non-zero  value is returned and errno is set to indicate the


     The __sparc_utrap_install() function will fail if:

           The type argument is not a supported user  trap  type;
           the new user trap handler address is not word aligned;
           the old user trap handler address cannot be  returned;
           or the user program is not a 64-bit executable.


     Example    1:     A     sample     program     using     the
     __sparc_utrap_install() function.

     The __sparc_utrap_install() function  is  normally  used  by
     user programs that wish to provide their own tailored excep-
     tion handlers as a faster alternative to signal(3C),  or  to
     handle  exceptions  that  are  not directly supported by the
     signal() interface, such as fp_disabled.

     extern void *fpdis_trap_handler();
     utrap_handler_t new_precise = (utrap_handler_t)fpdis_trap_handler;
     double d;
     int err;
     err = __sparc_utrap_install(UT_FP_DISABLED, new_precise,
     if (err == EINVAL) {
             /* unexpected error, do something */
             exit (1);
     d = 1.0e-300;
     wr      %g0, FPRS_FEF, %fprs
     jmpl    %l6, %g0
     return  %l7

     This example turns on bit  2,  FEF,  in  the  Floating-Point
     Registers  State  (FPRS)  Register,  after  a floating-point
     instruction causes an  fp_disabled  trap.  (Note  that  this
     example  simulates part of the default system behavior; pro-
     grams do not need such a handler. The example is for  illus-
     trative purposes only.)


     See attributes(5) for descriptions of the  following  attri-

    |       ATTRIBUTE TYPE        |       ATTRIBUTE VALUE       |
    | MT-Level                    | MT-Safe                     |


     signal(3C), attributes(5)

     SPARC Architecture Manual, Version 9

     Manufacturer's processor chip user manuals


     The Exceptions and Interrupt  Descriptions  section  of  the
     SPARC V9 manual documents which hardware traps are mandatory
     or optional, and whether they can be implemented as  precise
     or  deferred  traps,  or both.  The manufacturer's processor
     chip user manuals describe the details  of  the  traps  sup-
     ported for the specific processor implementation.

Man(1) output converted with man2html