[cfe-dev] RFC: Support x86 interrupt and exception handlers
Hal Finkel via cfe-dev
cfe-dev at lists.llvm.org
Mon Sep 21 15:40:58 PDT 2015
----- Original Message -----
> From: "H.J. Lu via cfe-dev" <cfe-dev at lists.llvm.org>
> To: "GCC Development" <gcc at gcc.gnu.org>, cfe-dev at lists.llvm.org
> Sent: Monday, September 21, 2015 11:27:18 AM
> Subject: Re: [cfe-dev] RFC: Support x86 interrupt and exception handlers
>
> On Thu, Sep 17, 2015 at 12:26 PM, H.J. Lu <hjl.tools at gmail.com>
> wrote:
> > On Tue, Sep 15, 2015 at 1:11 PM, H.J. Lu <hjl.tools at gmail.com>
> > wrote:
> >>> To implement interrupt and exception handlers for x86 processors,
> >>> a
> >>> compiler should support:
> >>>
> >>> 1. void * __builtin_ia32_interrupt_data (void)
> >>
> >> I got a feedback on the name of this builtin function. Since
> >> it also works for 64-bit, we should avoid ia32 in its name.
> >> We'd like to change it to
> >>
> >> void * __builtin_interrupt_data (void)
> >>
> >
> > Here is the updated spec.
> >
>
> This updated spec adds
>
> unsigned int __builtin_exception_error (void)
> unsigned long long int __builtin_exception_error (void)
>
> This function returns the exception error code pushed onto the stack
> by
> processor. Its return value is 64 bits in 64-bit mode and 32 bits in
> 32-bit mode. This function can only be used in exception handler.
>
> It also changes the definition of
>
> void * __builtin_interrupt_data (void)
>
> so that it returns a pointer to the data layout pushed onto stack
> by processor for both interrupt and exception handlers.
>
>
> --
> H.J.
> ---
> The interrupt and exception handlers are called by x86 processors.
> X86
> hardware pushes information onto stack and calls the handler. The
> requirements are
>
> 1. Both interrupt and exception handlers must use the 'IRET'
> instruction,
> instead of the 'RET' instruction, to return from the handlers.
> 2. All registers are callee-saved in interrupt and exception
> handlers.
> 3. The difference between interrupt and exception handlers is the
> exception handler must pop 'ERROR_CODE' off the stack before the
> 'IRET'
> instruction.
>
> The design goals of interrupt and exception handlers for x86
> processors
> are:
>
> 1. No new calling convention in compiler.
> 2. Support both 32-bit and 64-bit modes.
> 3. Flexible for compilers to optimize.
> 4. Easy to use by programmers.
>
> To implement interrupt and exception handlers for x86 processors, a
> compiler should support:
>
> 1. void * __builtin_interrupt_data (void)
>
> This function returns a pointer to the return address pushed onto the
> stack by processor.
>
> The __builtin_frame_address builtin isn't suitable for interrupt and
> exception handlers since it returns the stack frame address on the
> callee side and compiler may generate a new stack frame for stack
> alignment.
>
> 2. unsigned int __builtin_exception_error (void)
> unsigned long long int __builtin_exception_error (void)
>
> This function returns the exception error code pushed onto the stack
> by
> processor. Its return value is 64 bits in 64-bit mode and 32 bits in
> 32-bit mode. This function can only be used in exception handler.
Instead of adding more builtins for these, why not simply model this by giving the handler function a non-trivial signature? So, for example, the interrupt handler would be:
void handler(void *);
and the exception handler would be:
void handler(size_t);
-Hal
>
> 3. 'interrupt' attribute
>
> Use this attribute to indicate that the specified void function
> without
> arguments is an interrupt handler. The compiler generates function
> entry
> and exit sequences suitable for use in an interrupt handler when this
> attribute is present. The 'IRET' instruction, instead of the
> 'RET' instruction, is used to return from interrupt handlers. All
> registers, except for the EFLAGS register which is restored by the
> 'IRET' instruction, are preserved by the compiler. The red zone
> isn't supported in the interrupted function; that is an interrupt
> handler may access stack within 128 bytes of the current stack
> pointer.
>
> You can use the builtin '__builtin_interrupt_data' function to access
> the interrupt data pushed onto the stack by processor:
>
> void
> f () __attribute__ ((interrupt))
> {
> void *p = __builtin_interrupt_data ();
> ...
> }
>
> 4. 'exception' attribute
>
> Use 'exception' instead of 'interrupt' for handlers intended to be
> used for 'exception' (i.e. those that must pop 'ERROR_CODE' off the
> stack before the 'IRET' instruction).
>
> You can use the builtin '__builtin_exception_error' function to
> access the exception error code pushed onto the stack by processor
> as well as the builtin '__builtin_interrupt_data' function to
> access the exception data on stack:
>
> void
> f () __attribute__ ((exception))
> {
> unsigned int error = __builtin_exception_error ();
> void *p = __builtin_interrupt_data ();
> ...
> }
> _______________________________________________
> cfe-dev mailing list
> cfe-dev at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
>
--
Hal Finkel
Assistant Computational Scientist
Leadership Computing Facility
Argonne National Laboratory
More information about the cfe-dev
mailing list