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

H.J. Lu via cfe-dev cfe-dev at lists.llvm.org
Tue Sep 22 04:39:19 PDT 2015


On Tue, Sep 22, 2015 at 1:11 AM, 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 7:17:20 PM
>> Subject: Re: [cfe-dev] RFC: Support x86 interrupt and exception handlers
>>
>> 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.
>
> I understand why you feel that the implementation is simpler with the builtin functions, but it also provides an inferior interface. Yes, you need to override the calling-convention code for these interrupt/exception handler functions, and do some more checking during semantic analysis to make sure the signature is correct. This is not necessarily a bad thing, and I believe, provides a much better user experience. If we're going to bother implementing this in the compiler, we should do it the right way. These things are semantically function parameters, and there's no runtime overhead in treating them as such, so we should.

The center piece of my proposal is not to change how parameters
are passed in compiler.  As for user experience, the feedbacks on
my proposal from our users are very positive.


-- 
H.J.



More information about the cfe-dev mailing list