[cfe-dev] RFC: Support x86 interrupt and exception handlers

H.J. Lu via cfe-dev cfe-dev at lists.llvm.org
Mon Sep 21 17:17:20 PDT 2015


On Mon, Sep 21, 2015 at 4:03 PM, Hal Finkel <hfinkel at anl.gov> wrote:
> ----- Original Message -----
>> From: "H.J. Lu" <hjl.tools at gmail.com>
>> To: "Hal Finkel" <hfinkel at anl.gov>
>> Cc: "GCC Development" <gcc at gcc.gnu.org>, cfe-dev at lists.llvm.org
>> Sent: Monday, September 21, 2015 5:57:36 PM
>> Subject: Re: [cfe-dev] RFC: Support x86 interrupt and exception handlers
>>
>> On Mon, Sep 21, 2015 at 3:40 PM, Hal Finkel <hfinkel at anl.gov> wrote:
>> > ----- 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);
>> >
>>
>> Since x86 interrupt/exception handlers don't conform to any x86
>> psABI,
>> you need to modify compiler to generate proper codes for
>>
>> void handler(void *);
>>
>> Please take a look at interrupt/exception handlers section in Intel
>> SDM
>> vol 3.
>
> Yes, I understand that. But we already would need to customize the call-frame-lowering code for these functions, and since this already requires customization, what's the advantage of the builtins over adding special logic to make these parameters correspond to the appropriate stack locations and/or registers?
>

Interrupt data and exception error code are always passed
on stack in both 32-bit and 64-bit modes.  For exception
data and error code, they locations are different from any
calling conventions. You need to do

1. Define types for those parameters in compiler for both 32-bit
and 64-bit,  and check them against user provided types.
2. Make special cases for parameters of exception data and
exception error code.

With builtin functions, you only need to check if handler
takes any parameters and you don't need check parameter
types since there is none.

-- 
H.J.



More information about the cfe-dev mailing list