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

2015-09-21 Thread Hal Finkel
- Original Message -
> From: "H.J. Lu via cfe-dev" 
> To: "GCC Development" , cfe-...@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 
> wrote:
> > On Tue, Sep 15, 2015 at 1:11 PM, H.J. Lu 
> > 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 'IR

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

2015-09-21 Thread Hal Finkel
- Original Message -
> From: "H.J. Lu" 
> To: "Hal Finkel" 
> Cc: "GCC Development" , cfe-...@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  wrote:
> > - Original Message -
> >> From: "H.J. Lu via cfe-dev" 
> >> To: "GCC Development" , cfe-...@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 
> >> wrote:
> >> > On Tue, Sep 15, 2015 at 1:11 PM, H.J. Lu 
> >> > 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?

 -Hal

> 
> --
> H.J.
> 

-- 
Hal Finkel
Assistant Computational Scientist
Leadership Computing Facility
Argonne National Laboratory


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

2015-09-22 Thread Hal Finkel
- Original Message -
> From: "H.J. Lu" 
> To: "Hal Finkel" 
> Cc: "GCC Development" , cfe-...@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  wrote:
> > - Original Message -
> >> From: "H.J. Lu" 
> >> To: "Hal Finkel" 
> >> Cc: "GCC Development" , cfe-...@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 
> >> wrote:
> >> > - Original Message -
> >> >> From: "H.J. Lu via cfe-dev" 
> >> >> To: "GCC Development" , cfe-...@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 
> >> >> wrote:
> >> >> > On Tue, Sep 15, 2015 at 1:11 PM, H.J. Lu
> >> >> > 
> >> >> > 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 handl

Re: LLVM collaboration?

2014-09-17 Thread Hal Finkel
Rafael,

As I mentioned earlier on IRC, the current trunk LLVM plugin requires get_view 
and get/release_input_file (which had not previously been the case). I've 
attached a version of the patch that also provides an implementation of those 
functions.

 -Hal

- Original Message -
> From: "Hal Finkel" 
> To: "Rafael Espíndola" 
> Cc: "Renato Golin" , "gcc" , "Jan 
> Hubicka" 
> Sent: Tuesday, February 11, 2014 4:35:59 PM
> Subject: Re: LLVM collaboration?
> 
> - Original Message -
> > From: "Rafael Espíndola" 
> > To: "Jan Hubicka" 
> > Cc: "Renato Golin" , "gcc"
> > , "Hal Finkel" 
> > Sent: Tuesday, February 11, 2014 3:38:40 PM
> > Subject: Re: Fwd: LLVM collaboration?
> > 
> > > My reading of bfd/plugin.c is that it basically walks the
> > > directory
> > > and looks
> > > for first plugin that returns OK for onload. (that is always the
> > > case for
> > > GCC/LLVM plugins).  So if I instlal GCC and llvm plugin there it
> > > will
> > > depend who will end up being first and only that plugin will be
> > > used.
> > >
> > > We need multiple plugin support as suggested by the directory
> > > name
> > > ;)
> > >
> > > Also it sems that currently plugin is not used if file is ELF for
> > > ar/nm/ranlib
> > > (as mentioned by Markus) and also GNU-ld seems to choke on LLVM
> > > object files
> > > even if it has plugin.
> > >
> > > This probably needs ot be sanitized.
> > 
> > CCing Hal Finkel. He got this to work some time ago. Not sure if he
> > ever ported the patches to bfd trunk.
> 
> I have a patch for binutils 2.24 (attached -- I think this works, I
> hand isolated it from my BG/Q patchset). I would not consider it to
> be of upstream quality, but I'd obviously appreciate any assistance
> on making everything clean and proper ;)
> 
>  -Hal
> 
> > 
> > >> For OS X the situation is a bit different. There instead of a
> > >> plugin
> > >> the linker loads a library: libLTO.dylib. When doing LTO with a
> > >> newer
> > >> llvm, one needs to set DYLD_LIBRARY_PATH. I think I proposed
> > >> setting
> > >> that from clang some time ago, but I don't remember the outcome.
> > >>
> > >> In theory GCC could implement a libLTO.dylib and set
> > >> DYLD_LIBRARY_PATH. The gold/bfd plugin that LLVM uses is
> > >> basically
> > >> a
> > >> API mapping the other way, so the job would be inverting it. The
> > >> LTO
> > >> model ld64 is a bit more strict about knowing all symbol
> > >> definitions
> > >> and uses (including inline asm), so there would be work to be
> > >> done
> > >> to
> > >> cover that, but the simple cases shouldn't be too hard.
> > >
> > > I would not care that much about symbols in asm definitions to
> > > start with.
> > > Even if we will force users to non-LTO those object files, it
> > > would
> > > be an
> > > improvement over what we have now.
> > >
> > > One problem is that we need a volunteer to implement the reverse
> > > glue
> > > (libLTO->plugin API), since I do not have an OS X box (well, have
> > > an old G5,
> > > but even that is quite far from me right now)
> > >
> > > Why complete symbol tables are required? Can't ld64 be changed to
> > > ignore
> > > unresolved symbols in the first stage just like gold/gnu-ld does?
> > 
> > I am not sure about this. My *guess* is that it does dead stripping
> > computation before asking libLTO for the object file. I noticed the
> > issue while trying to LTO firefox some time ago.
> > 
> > Cheers,
> > Rafael
> > 
> 
> --
> Hal Finkel
> Assistant Computational Scientist
> Leadership Computing Facility
> Argonne National Laboratory
> 

-- 
Hal Finkel
Assistant Computational Scientist
Leadership Computing Facility
Argonne National Laboratory
diff --git a/bfd/elflink.c b/bfd/elflink.c
index 99b7ca1..c2bf9c3 100644
--- a/bfd/elflink.c
+++ b/bfd/elflink.c
@@ -5054,7 +5054,9 @@ elf_link_add_archive_symbols (bfd *abfd, struct bfd_link_info *info)
 	goto error_return;
 
 	  if (! bfd_check_format (element, bfd_object))
-	goto error_return;
+	/* goto error_return; */
+/* this might be an object understood only by an LTO plugin */
+ 

Re: LLVM collaboration?

2014-02-11 Thread Hal Finkel
- Original Message -
> From: "Rafael Espíndola" 
> To: "Jan Hubicka" 
> Cc: "Renato Golin" , "gcc" , "Hal 
> Finkel" 
> Sent: Tuesday, February 11, 2014 3:38:40 PM
> Subject: Re: Fwd: LLVM collaboration?
> 
> > My reading of bfd/plugin.c is that it basically walks the directory
> > and looks
> > for first plugin that returns OK for onload. (that is always the
> > case for
> > GCC/LLVM plugins).  So if I instlal GCC and llvm plugin there it
> > will
> > depend who will end up being first and only that plugin will be
> > used.
> >
> > We need multiple plugin support as suggested by the directory name
> > ;)
> >
> > Also it sems that currently plugin is not used if file is ELF for
> > ar/nm/ranlib
> > (as mentioned by Markus) and also GNU-ld seems to choke on LLVM
> > object files
> > even if it has plugin.
> >
> > This probably needs ot be sanitized.
> 
> CCing Hal Finkel. He got this to work some time ago. Not sure if he
> ever ported the patches to bfd trunk.

I have a patch for binutils 2.24 (attached -- I think this works, I hand 
isolated it from my BG/Q patchset). I would not consider it to be of upstream 
quality, but I'd obviously appreciate any assistance on making everything clean 
and proper ;)

 -Hal

> 
> >> For OS X the situation is a bit different. There instead of a
> >> plugin
> >> the linker loads a library: libLTO.dylib. When doing LTO with a
> >> newer
> >> llvm, one needs to set DYLD_LIBRARY_PATH. I think I proposed
> >> setting
> >> that from clang some time ago, but I don't remember the outcome.
> >>
> >> In theory GCC could implement a libLTO.dylib and set
> >> DYLD_LIBRARY_PATH. The gold/bfd plugin that LLVM uses is basically
> >> a
> >> API mapping the other way, so the job would be inverting it. The
> >> LTO
> >> model ld64 is a bit more strict about knowing all symbol
> >> definitions
> >> and uses (including inline asm), so there would be work to be done
> >> to
> >> cover that, but the simple cases shouldn't be too hard.
> >
> > I would not care that much about symbols in asm definitions to
> > start with.
> > Even if we will force users to non-LTO those object files, it would
> > be an
> > improvement over what we have now.
> >
> > One problem is that we need a volunteer to implement the reverse
> > glue
> > (libLTO->plugin API), since I do not have an OS X box (well, have
> > an old G5,
> > but even that is quite far from me right now)
> >
> > Why complete symbol tables are required? Can't ld64 be changed to
> > ignore
> > unresolved symbols in the first stage just like gold/gnu-ld does?
> 
> I am not sure about this. My *guess* is that it does dead stripping
> computation before asking libLTO for the object file. I noticed the
> issue while trying to LTO firefox some time ago.
> 
> Cheers,
> Rafael
> 

-- 
Hal Finkel
Assistant Computational Scientist
Leadership Computing Facility
Argonne National Laboratory
diff --git a/bfd/elflink.c b/bfd/elflink.c
index 99b7ca1..c2bf9c3 100644
--- a/bfd/elflink.c
+++ b/bfd/elflink.c
@@ -5054,7 +5054,9 @@ elf_link_add_archive_symbols (bfd *abfd, struct bfd_link_info *info)
 	goto error_return;
 
 	  if (! bfd_check_format (element, bfd_object))
-	goto error_return;
+	/* goto error_return; */
+/* this might be an object understood only by an LTO plugin */
+bfd_elf_make_object (element);
 
 	  /* Doublecheck that we have not included this object
 	 already--it should be impossible, but there may be
diff --git a/ld/ldfile.c b/ld/ldfile.c
index 16baef8..159a60c 100644
--- a/ld/ldfile.c
+++ b/ld/ldfile.c
@@ -38,6 +38,7 @@
 #ifdef ENABLE_PLUGINS
 #include "plugin-api.h"
 #include "plugin.h"
+#include "elf-bfd.h"
 #endif /* ENABLE_PLUGINS */
 
 bfd_boolean  ldfile_assumed_script = FALSE;
@@ -124,6 +125,7 @@ bfd_boolean
 ldfile_try_open_bfd (const char *attempt,
 		 lang_input_statement_type *entry)
 {
+  int is_obj = 0;
   entry->the_bfd = bfd_openr (attempt, entry->target);
 
   if (verbose)
@@ -168,6 +170,34 @@ ldfile_try_open_bfd (const char *attempt,
 	{
 	  if (! bfd_check_format (check, bfd_object))
 	{
+#ifdef ENABLE_PLUGINS
+	  if (check == entry->the_bfd
+		  && bfd_get_error () == bfd_error_file_not_recognized
+		  && ! ldemul_unrecognized_file (entry))
+		{
+  if (plugin_active_plugins_p ()
+  && !no_more_claiming)
+{
+  int fd = open (attempt, O_RD