public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* Re: IA64 HP-UX Unwind patch
@ 2002-08-14 12:34 Steve Ellcey
  2002-08-14 12:55 ` Richard Henderson
  0 siblings, 1 reply; 9+ messages in thread
From: Steve Ellcey @ 2002-08-14 12:34 UTC (permalink / raw)
  To: rth; +Cc: gcc-patches, libstdc++

> Anyway, it's not worth adding macros for this.  Instead, modify
> the two places to expect *both* _URC_FOREIGN_EXCEPTION_CAUGHT
> and _URC_NO_REASON, with a comment about the different behaviour
> of the hpux library.

Actually the modification would only be needed in one place, 
in eh_throw.cc (__gxx_exception_cleanup) so that should be
simple to do.

> > The second problem is with _Unwind_SetIP.  Even in ILP32 mode, the HP-UX
> > Unwind library expects you to pass in a 64 bit pointer on IA64.  So, I
> > created a macro in os_defines.h called UNWIND_SETIP to use instead of
> > calling _Unwind_SetIP if it is defined.  I also ifdef'ed the
> > _Unwind_SetIP declaration in unwind.h so I could have my own version in
> > os_defines.h with different arg types.
> 
> Good lord.
> 
> How does the function call ABI work?  If we changed the prototype
> to a void* would it work?  I really dislike this part of the patch.

I am not sure what you mean by "How does the function call ABI work?"
so I don't know how to answer that.  Just changing the prototype by
itself is not enough since we also need to explicitly extend the pointer
with the addp4 (extend_ptr) instruction.  In HP C++, in ILP32 mode, they
take advantage of the fact that _Unwind_GetIP still returns 64 bits and
they save all 64 bits in the LSDA and then pass it back in to
_Unwind_GetIP as a 64 bit address.

For GCC to use the HP Unwind library there seem to be two options;
change GCC/libstdc++ to save all 64 bits that it gets from _Unwind_GetIP
and store it as 64 bits in the LSDA and pass it back into _Unwind_SetIP
as 64 bits or get and save only 32 bits and then extend it before
calling _Unwind_SetIP.  Just changing the _Unwind_SetIP call seemed like
a less intrusive (if still ugly) change.

I did it the other way for a time by defining _Unwind_Ptr to be 64 bits
in unwind.h when on IA64 in ILP32 mode.  I think there were some issues
with some of the casts in eh_personality.cc but other then that it
seemed to work.

Do you think that change (changing the typedef of _Unwind_Ptr) would be
cleaner then doing the extend_ptr on the _Unwind_SetIP call?

> > + extern void _Unwind_SetIP (struct _Unwind_Context *, unsigned __attribute__((__mode__(__word__))));
> 
> In any case, this is _Unwind_Word.

Yes, I did it this way so that libstdc++-v3/config/os/hpux/os_defines.h
wouldn't have to include unwind.h.  I could change os_defines.h to
include unwind.h or just put the declaration in unwind.h.

Steve Ellcey
sje@cup.hp.com

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: IA64 HP-UX Unwind patch
  2002-08-14 12:34 IA64 HP-UX Unwind patch Steve Ellcey
@ 2002-08-14 12:55 ` Richard Henderson
  0 siblings, 0 replies; 9+ messages in thread
From: Richard Henderson @ 2002-08-14 12:55 UTC (permalink / raw)
  To: Steve Ellcey; +Cc: gcc-patches, libstdc++

On Wed, Aug 14, 2002 at 12:34:17PM -0700, Steve Ellcey wrote:
> Actually the modification would only be needed in one place, 
> in eh_throw.cc (__gxx_exception_cleanup) so that should be
> simple to do.

You keep forgetting about libjava.

> I am not sure what you mean by "How does the function call ABI work?"
> so I don't know how to answer that.

Does void* get expanded to DImode in a register for the call?



r~

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: IA64 HP-UX Unwind patch
  2002-08-15  9:47 Steve Ellcey
@ 2002-08-15 10:37 ` Richard Henderson
  0 siblings, 0 replies; 9+ messages in thread
From: Richard Henderson @ 2002-08-15 10:37 UTC (permalink / raw)
  To: Steve Ellcey; +Cc: gcc-patches, libstdc++

On Thu, Aug 15, 2002 at 09:47:04AM -0700, Steve Ellcey wrote:
> The main concern I have is whether or not
> changing catchTemp in the __cxa_exception structure from void* to
> _Unwind_Ptr would have any effect on other platforms.

I can't think of anything off-hand.

> 	* gcc/unwind.h (_Unwind_Ptr): Make 64 bits on IA64 HP-UX.
> 	(_Unwind_Internal_Ptr): 32 bit version for use in
> 	read_encoded_value_with_base.
> 	* gcc/unwind-pe.h (read_encoded_value_with_base): Use
> 	_Unwind_Internal_Ptr instead of _Unwind_Ptr in order to get the
> 	right size.
> 	* libstdc++-v3/libsupc++/unwind-cxx.h (__cxa_exception):
> 	Change catchTemp type from void* to _Unwind_Ptr.
> 	* libstdc++-v3/libsupc++/eh_personality.cc (PERSONALITY_FUNCTION):
> 	Do not cast landing_pad or base_of_encoded_value to (void *).
> 	* libstdc++-v3/libsupc++/eh_throw.cc (__gxx_exception_cleanup):
> 	Accept _URC_NO_REASON as a valid reason code.

Ok.


r~

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: IA64 HP-UX Unwind patch
@ 2002-08-15  9:47 Steve Ellcey
  2002-08-15 10:37 ` Richard Henderson
  0 siblings, 1 reply; 9+ messages in thread
From: Steve Ellcey @ 2002-08-15  9:47 UTC (permalink / raw)
  To: rth; +Cc: gcc-patches, libstdc++

> > The other changes that would be needed to make this work would be to
> > modify catchTemp in the __cxa_exception in cxx-unwind.h to be
> > _Unwind_Ptr instead of void* and get rid of the void* casts when
> > assigning to catchTemp.  Does this look like a better approach?
> 
> Dunno.  Probably better, but I'm not sure how many warnings you'll
> get for casting between pointer and integer of different size.

It looks like I can do it with only one warning.  It comes from the
first call to _Unwind_SetGR in PERSONALITY_FUNCTION.  &xh->unwindHeader
is 32 bits and we cast it to a 64 bit value.  While I do get this
warning and the conversion is not getting done with addp4 (extend_ptr)
everything seems to work fine, here is a patch that might be considered
cleaner then the last one.  The main concern I have is whether or not
changing catchTemp in the __cxa_exception structure from void* to
_Unwind_Ptr would have any effect on other platforms.

Steve Ellcey
sje@cup.hp.com


2002-08-15  Steve Ellcey  <sje@cup.hp.com>

	* gcc/unwind.h (_Unwind_Ptr): Make 64 bits on IA64 HP-UX.
	(_Unwind_Internal_Ptr): 32 bit version for use in
	read_encoded_value_with_base.
	* gcc/unwind-pe.h (read_encoded_value_with_base): Use
	_Unwind_Internal_Ptr instead of _Unwind_Ptr in order to get the
	right size.
	* libstdc++-v3/libsupc++/unwind-cxx.h (__cxa_exception):
	Change catchTemp type from void* to _Unwind_Ptr.
	* libstdc++-v3/libsupc++/eh_personality.cc (PERSONALITY_FUNCTION):
	Do not cast landing_pad or base_of_encoded_value to (void *).
	* libstdc++-v3/libsupc++/eh_throw.cc (__gxx_exception_cleanup):
	Accept _URC_NO_REASON as a valid reason code.


*** gcc.orig/gcc/unwind.h	Thu Aug 15 08:40:06 2002
--- gcc/gcc/unwind.h	Thu Aug 15 08:48:06 2002
*************** extern "C" {
*** 31,37 ****
--- 31,42 ----
     inefficient for 32-bit and smaller machines.  */
  typedef unsigned _Unwind_Word __attribute__((__mode__(__word__)));
  typedef signed _Unwind_Sword __attribute__((__mode__(__word__)));
+ #if defined(__ia64__) && defined(__hpux__)
+ typedef unsigned _Unwind_Ptr __attribute__((__mode__(__word__)));
+ #else
  typedef unsigned _Unwind_Ptr __attribute__((__mode__(__pointer__)));
+ #endif
+ typedef unsigned _Unwind_Internal_Ptr __attribute__((__mode__(__pointer__)));
  
  /* @@@ The IA-64 ABI uses a 64-bit word to identify the producer and
     consumer of an exception.  We'll go along with this for now even on
*** gcc.orig/gcc/unwind-pe.h	Thu Aug 15 08:39:56 2002
--- gcc/gcc/unwind-pe.h	Thu Aug 15 08:50:40 2002
*************** read_encoded_value_with_base (unsigned c
*** 179,191 ****
      } __attribute__((__packed__));
  
    union unaligned *u = (union unaligned *) p;
!   _Unwind_Ptr result;
  
    if (encoding == DW_EH_PE_aligned)
      {
!       _Unwind_Ptr a = (_Unwind_Ptr) p;
        a = (a + sizeof (void *) - 1) & - sizeof(void *);
!       result = *(_Unwind_Ptr *) a;
        p = (const unsigned char *) (a + sizeof (void *));
      }
    else
--- 179,191 ----
      } __attribute__((__packed__));
  
    union unaligned *u = (union unaligned *) p;
!   _Unwind_Internal_Ptr result;
  
    if (encoding == DW_EH_PE_aligned)
      {
!       _Unwind_Internal_Ptr a = (_Unwind_Internal_Ptr) p;
        a = (a + sizeof (void *) - 1) & - sizeof(void *);
!       result = *(_Unwind_Internal_Ptr *) a;
        p = (const unsigned char *) (a + sizeof (void *));
      }
    else
*************** read_encoded_value_with_base (unsigned c
*** 193,199 ****
        switch (encoding & 0x0f)
  	{
  	case DW_EH_PE_absptr:
! 	  result = (_Unwind_Ptr) u->ptr;
  	  p += sizeof (void *);
  	  break;
  
--- 193,199 ----
        switch (encoding & 0x0f)
  	{
  	case DW_EH_PE_absptr:
! 	  result = (_Unwind_Internal_Ptr) u->ptr;
  	  p += sizeof (void *);
  	  break;
  
*************** read_encoded_value_with_base (unsigned c
*** 201,207 ****
  	  {
  	    _Unwind_Word tmp;
  	    p = read_uleb128 (p, &tmp);
! 	    result = (_Unwind_Ptr) tmp;
  	  }
  	  break;
  
--- 201,207 ----
  	  {
  	    _Unwind_Word tmp;
  	    p = read_uleb128 (p, &tmp);
! 	    result = (_Unwind_Internal_Ptr) tmp;
  	  }
  	  break;
  
*************** read_encoded_value_with_base (unsigned c
*** 209,215 ****
  	  {
  	    _Unwind_Sword tmp;
  	    p = read_sleb128 (p, &tmp);
! 	    result = (_Unwind_Ptr) tmp;
  	  }
  	  break;
  
--- 209,215 ----
  	  {
  	    _Unwind_Sword tmp;
  	    p = read_sleb128 (p, &tmp);
! 	    result = (_Unwind_Internal_Ptr) tmp;
  	  }
  	  break;
  
*************** read_encoded_value_with_base (unsigned c
*** 246,254 ****
        if (result != 0)
  	{
  	  result += ((encoding & 0x70) == DW_EH_PE_pcrel
! 		     ? (_Unwind_Ptr) u : base);
  	  if (encoding & DW_EH_PE_indirect)
! 	    result = *(_Unwind_Ptr *) result;
  	}
      }
  
--- 246,254 ----
        if (result != 0)
  	{
  	  result += ((encoding & 0x70) == DW_EH_PE_pcrel
! 		     ? (_Unwind_Internal_Ptr) u : base);
  	  if (encoding & DW_EH_PE_indirect)
! 	    result = *(_Unwind_Internal_Ptr *) result;
  	}
      }
  
*** gcc.orig/libstdc++-v3/libsupc++/unwind-cxx.h	Thu Aug 15 08:41:04 2002
--- gcc/libstdc++-v3/libsupc++/unwind-cxx.h	Thu Aug 15 08:41:44 2002
*************** struct __cxa_exception
*** 70,76 ****
    int handlerSwitchValue;
    const unsigned char *actionRecord;
    const unsigned char *languageSpecificData;
!   void *catchTemp;
    void *adjustedPtr;
  
    // The generic exception header.  Must be last.
--- 70,76 ----
    int handlerSwitchValue;
    const unsigned char *actionRecord;
    const unsigned char *languageSpecificData;
!   _Unwind_Ptr catchTemp;
    void *adjustedPtr;
  
    // The generic exception header.  Must be last.
*** gcc.orig/libstdc++-v3/libsupc++/eh_personality.cc	Thu Aug 15 08:40:45 2002
--- gcc/libstdc++-v3/libsupc++/eh_personality.cc	Thu Aug 15 08:46:43 2002
*************** PERSONALITY_FUNCTION (int version,
*** 394,400 ****
  
            // ??? Completely unknown what this field is supposed to be for.
            // ??? Need to cache TType encoding base for call_unexpected.
!           xh->catchTemp = (void *) (_Unwind_Ptr) landing_pad;
  	}
        return _URC_HANDLER_FOUND;
      }
--- 394,400 ----
  
            // ??? Completely unknown what this field is supposed to be for.
            // ??? Need to cache TType encoding base for call_unexpected.
!           xh->catchTemp = landing_pad;
  	}
        return _URC_HANDLER_FOUND;
      }
*************** PERSONALITY_FUNCTION (int version,
*** 411,417 ****
    if (handler_switch_value < 0)
      {
        parse_lsda_header (context, xh->languageSpecificData, &info);
!       xh->catchTemp = (void *) base_of_encoded_value (info.ttype_encoding,
  						      context);
      }
  
--- 411,417 ----
    if (handler_switch_value < 0)
      {
        parse_lsda_header (context, xh->languageSpecificData, &info);
!       xh->catchTemp = base_of_encoded_value (info.ttype_encoding,
  						      context);
      }
  
*** gcc.orig/libstdc++-v3/libsupc++/eh_throw.cc	Thu Aug 15 08:40:58 2002
--- gcc/libstdc++-v3/libsupc++/eh_throw.cc	Thu Aug 15 08:44:47 2002
*************** __gxx_exception_cleanup (_Unwind_Reason_
*** 42,48 ****
  
    // If we haven't been caught by a foreign handler, then this is
    // some sort of unwind error.  In that case just die immediately.
!   if (code != _URC_FOREIGN_EXCEPTION_CAUGHT)
      __terminate (header->terminateHandler);
  
    if (header->exceptionDestructor)
--- 42,51 ----
  
    // If we haven't been caught by a foreign handler, then this is
    // some sort of unwind error.  In that case just die immediately.
!   // _Unwind_DeleteException in the HP-UX IA64 libunwind library
!   //  returns _URC_NO_REASON and not _URC_FOREIGN_EXCEPTION_CAUGHT
!   // like the GCC _Unwind_DeleteException function does.
!   if (code != _URC_FOREIGN_EXCEPTION_CAUGHT && code != _URC_NO_REASON)
      __terminate (header->terminateHandler);
  
    if (header->exceptionDestructor)

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: IA64 HP-UX Unwind patch
  2002-08-14 13:34 Steve Ellcey
@ 2002-08-14 14:29 ` Richard Henderson
  0 siblings, 0 replies; 9+ messages in thread
From: Richard Henderson @ 2002-08-14 14:29 UTC (permalink / raw)
  To: Steve Ellcey; +Cc: gcc-patches, libstdc++

On Wed, Aug 14, 2002 at 01:34:50PM -0700, Steve Ellcey wrote:
> I do keep forgetting about libjava but I just looked and I don't see a
> use of _URC_FOREIGN_EXCEPTION in it anywhere so I don't think I have to
> change anything there for the _URC_NO_REASON problem.  The _Unwind_SetIP
> part may require libjava work.

Oh, right, cause there's no exception object destructor for Java.

> 	#if defined(__ia64__) && defined(__hpux__)
> 	typedef unsigned _Unwind_Ptr __attribute__((__mode__(__word__)));
> 	#else
> 	typedef unsigned _Unwind_Ptr __attribute__((__mode__(__pointer__)));
> 	#endif
> 
> The other changes that would be needed to make this work would be to
> modify catchTemp in the __cxa_exception in cxx-unwind.h to be
> _Unwind_Ptr instead of void* and get rid of the void* casts when
> assigning to catchTemp.  Does this look like a better approach?

Dunno.  Probably better, but I'm not sure how many warnings you'll
get for casting between pointer and integer of different size.



r~

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: IA64 HP-UX Unwind patch
@ 2002-08-14 13:34 Steve Ellcey
  2002-08-14 14:29 ` Richard Henderson
  0 siblings, 1 reply; 9+ messages in thread
From: Steve Ellcey @ 2002-08-14 13:34 UTC (permalink / raw)
  To: rth; +Cc: gcc-patches, libstdc++

> On Wed, Aug 14, 2002 at 12:34:17PM -0700, Steve Ellcey wrote:
> > Actually the modification would only be needed in one place, 
> > in eh_throw.cc (__gxx_exception_cleanup) so that should be
> > simple to do.
> 
> You keep forgetting about libjava.

I do keep forgetting about libjava but I just looked and I don't see a
use of _URC_FOREIGN_EXCEPTION in it anywhere so I don't think I have to
change anything there for the _URC_NO_REASON problem.  The _Unwind_SetIP
part may require libjava work.

> > I am not sure what you mean by "How does the function call ABI work?"
> > so I don't know how to answer that.
> 
> Does void* get expanded to DImode in a register for the call?

No, void* would just be SImode (in ILP32 mode) when passed and would not
be expanded.

I am experimenting with the idea of the following change in unwind.h:

	#if defined(__ia64__) && defined(__hpux__)
	typedef unsigned _Unwind_Ptr __attribute__((__mode__(__word__)));
	#else
	typedef unsigned _Unwind_Ptr __attribute__((__mode__(__pointer__)));
	#endif

The other changes that would be needed to make this work would be to
modify catchTemp in the __cxa_exception in cxx-unwind.h to be
_Unwind_Ptr instead of void* and get rid of the void* casts when
assigning to catchTemp.  Does this look like a better approach?  I am
still testing it to see if it actually works.  This might also make
libjava changes unnecessary since the Java LSDA uses _Unwind_Ptr's in
its LSDA but I don't see any void* types like catchTemp in the Java
code.

Steve Ellcey
sje@cup.hp.com

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: IA64 HP-UX Unwind patch
  2002-08-14 10:45 Steve Ellcey
@ 2002-08-14 11:02 ` Richard Henderson
  0 siblings, 0 replies; 9+ messages in thread
From: Richard Henderson @ 2002-08-14 11:02 UTC (permalink / raw)
  To: Steve Ellcey; +Cc: gcc-patches, libstdc++

On Wed, Aug 14, 2002 at 10:45:00AM -0700, Steve Ellcey wrote:
> The first is what _URC_ code does _Unwind_DeleteException call the
> cleanup routine with.  HP uses _URC_NO_REASON and GCC uses
> _URC_FOREIGN_EXCEPTION_CAUGHT.  My fix for this was to create
> _URC_EXPECTED_BY_CLEANUP in unwind.h and define it to
> _URC_FOREIGN_EXCEPTION_CAUGHT if it was not already defined and then use
> that in __gxx_exception_cleanup (libstdc++-v3/libsupc++/eh_throw.cc).
> Then I put my own definition of _URC_EXPECTED_BY_CLEANUP in
> libstdc++-v3/config/os/hpux/os_defines.h for HP-UX.

This, IMO, is a bug in the HPUX library.  Section 1.4

  "If a given runtime resumes normal execution after catching a
   foreign exception..."

Anyway, it's not worth adding macros for this.  Instead, modify
the two places to expect *both* _URC_FOREIGN_EXCEPTION_CAUGHT
and _URC_NO_REASON, with a comment about the different behaviour
of the hpux library.

> The second problem is with _Unwind_SetIP.  Even in ILP32 mode, the HP-UX
> Unwind library expects you to pass in a 64 bit pointer on IA64.  So, I
> created a macro in os_defines.h called UNWIND_SETIP to use instead of
> calling _Unwind_SetIP if it is defined.  I also ifdef'ed the
> _Unwind_SetIP declaration in unwind.h so I could have my own version in
> os_defines.h with different arg types.

Good lord.

How does the function call ABI work?  If we changed the prototype
to a void* would it work?  I really dislike this part of the patch.

> + extern void _Unwind_SetIP (struct _Unwind_Context *, unsigned __attribute__((__mode__(__word__))));

In any case, this is _Unwind_Word.



r~

^ permalink raw reply	[flat|nested] 9+ messages in thread

* IA64 HP-UX Unwind patch
@ 2002-08-14 10:45 Steve Ellcey
  2002-08-14 11:02 ` Richard Henderson
  0 siblings, 1 reply; 9+ messages in thread
From: Steve Ellcey @ 2002-08-14 10:45 UTC (permalink / raw)
  To: gcc-patches, libstdc++


I sent this out a while back but just realised I sent it to gcc-patches
and forgot to also send it to libstdc++.

This patch is the final patch for using HP-UX's libunwind instead of the
GCC unwind code on IA64.  The problem I have run into is two ABI
differences between the HP Unwind and the GCC Unwind.

The first is what _URC_ code does _Unwind_DeleteException call the
cleanup routine with.  HP uses _URC_NO_REASON and GCC uses
_URC_FOREIGN_EXCEPTION_CAUGHT.  My fix for this was to create
_URC_EXPECTED_BY_CLEANUP in unwind.h and define it to
_URC_FOREIGN_EXCEPTION_CAUGHT if it was not already defined and then use
that in __gxx_exception_cleanup (libstdc++-v3/libsupc++/eh_throw.cc).
Then I put my own definition of _URC_EXPECTED_BY_CLEANUP in
libstdc++-v3/config/os/hpux/os_defines.h for HP-UX.

The second problem is with _Unwind_SetIP.  Even in ILP32 mode, the HP-UX
Unwind library expects you to pass in a 64 bit pointer on IA64.  So, I
created a macro in os_defines.h called UNWIND_SETIP to use instead of
calling _Unwind_SetIP if it is defined.  I also ifdef'ed the
_Unwind_SetIP declaration in unwind.h so I could have my own version in
os_defines.h with different arg types.

My definition of UNWIND_SETIP uses a builtin called __extend_ptr to turn
the 32 bit pointer in landing_pad into a 64 bit pointer.  I did not
include the implementation of this builtin in this patch but thought I
would do that seperately.

One possible change that I considered but was not able to manage was to
use the system unwind.h instead of the one in GCC when building
libstdc++-v3 but since they are both called unwind.h I couldn't figure
out how to tell unwind-cxx.h to use a system header instead of the GCC
one.  Brackets instead of quotes had no effect.  If I did this I
wouldn't have to include my own _Unwind_SetIP declaration and I could
put the default _URC_EXPECTED_BY_CLEANUP in eh_throw.c instead of
unwind.h and not mess with any GCC code but only with libstdc++-v3.

I can't think of any way to avoid the ifdef around _Unwind_SetIP though.

Comments?

Steve Ellcey
sje@cup.hp.com


2002-07-24  Steve Ellcey  <sje@cup.hp.com>

	* gcc/unwind.h (_URC_EXPECTED_BY_CLEANUP): New Macro with
	default definition.
	(_Unwind_SetIP): Prototype only if UNWIND_SETIP is not set.
	* libstdc++-v3/config/os/hpux/os_defines.h (_URC_EXPECTED_BY_CLEANUP):
	Define to match HP libunwind.
	(UNWIND_SETIP) Define with new modified arguments.
	* libstdc++-v3/libsupc++/eh_throw.cc (__gxx_exception_cleanup):
	Use _URC_EXPECTED_BY_CLEANUP instead of _URC_FOREIGN_EXCEPTION_CAUGHT.
	* libstdc++-v3/libsupc++/eh_personality.cc (PERSONALITY_FUNCTION):
	Call UNWIND_SETIP instead of _Unwind_SetIP if defined.


*** gcc.orig/gcc/unwind.h	Wed Jul 24 12:16:30 2002
--- gcc/gcc/unwind.h	Wed Jul 24 12:42:25 2002
*************** typedef enum
*** 54,59 ****
--- 54,66 ----
    _URC_CONTINUE_UNWIND = 8
  } _Unwind_Reason_Code;
  
+ /* G++ _Unwind_DeleteException calls __gxx_exception_cleanup with
+    _URC_FOREIGN_EXCEPTION_CAUGHT, the HP libunwind library version
+    of _Unwind_DeleteException calls it with _URC_NO_REASON.  */
+ 
+ #ifndef _URC_EXPECTED_BY_CLEANUP
+ #define _URC_EXPECTED_BY_CLEANUP _URC_FOREIGN_EXCEPTION_CAUGHT
+ #endif
  
  /* The unwind interface uses a pointer to an exception header object
     as its representation of an exception being thrown. In general, the
*************** extern _Unwind_Word _Unwind_GetGR (struc
*** 124,130 ****
--- 131,144 ----
  extern void _Unwind_SetGR (struct _Unwind_Context *, int, _Unwind_Word);
  
  extern _Unwind_Ptr _Unwind_GetIP (struct _Unwind_Context *);
+ 
+ /* HP IA64 ILP32 _Unwind_SetIP requires a 64 bit address, there is
+    a private extern and calling sequence in
+    libstdc++-v3/config/os/hpux/os_defines.h.  */
+ 
+ #ifndef UNWIND_SETIP
  extern void _Unwind_SetIP (struct _Unwind_Context *, _Unwind_Ptr);
+ #endif
  
  extern void *_Unwind_GetLanguageSpecificData (struct _Unwind_Context *);
  
*** gcc.orig/libstdc++-v3/config/os/hpux/os_defines.h	Wed Jul 24 12:16:57 2002
--- gcc/libstdc++-v3/config/os/hpux/os_defines.h	Wed Jul 24 14:00:28 2002
*************** namespace std 
*** 86,89 ****
--- 86,105 ----
  typedef long int __padding_type;
  #endif
  
+ /* HPUX IA64 _Unwind_DeleteException calls cleanup routine,
+    __gxx_exception_cleanup, with _URC_NO_REASON and not
+    _URC_FOREIGN_EXCEPTION_CAUGHT.  */
+ 
+ #if defined(__ia64__)
+ #undef _URC_EXPECTED_BY_CLEANUP
+ #define _URC_EXPECTED_BY_CLEANUP _URC_NO_REASON
+ #endif
+ 
+ /* HPUX IA64 ILP32 Unwind_SetIP needs to be passed a 64 bit pointer.  */
+ 
+ #if !defined(_LP64) && defined (__ia64__)
+ extern void _Unwind_SetIP (struct _Unwind_Context *, unsigned __attribute__((__mode__(__word__))));
+ #define UNWIND_SETIP(CONTEXT,LANDING_PAD) _Unwind_SetIP (CONTEXT, __extend_ptr ((void *) LANDING_PAD))
+ #endif
+ 
  #endif
*** gcc.orig/libstdc++-v3/libsupc++/eh_throw.cc	Wed Jul 24 12:17:50 2002
--- gcc/libstdc++-v3/libsupc++/eh_throw.cc	Wed Jul 24 12:29:14 2002
*************** __gxx_exception_cleanup (_Unwind_Reason_
*** 42,48 ****
  
    // If we haven't been caught by a foreign handler, then this is
    // some sort of unwind error.  In that case just die immediately.
!   if (code != _URC_FOREIGN_EXCEPTION_CAUGHT)
      __terminate (header->terminateHandler);
  
    if (header->exceptionDestructor)
--- 42,48 ----
  
    // If we haven't been caught by a foreign handler, then this is
    // some sort of unwind error.  In that case just die immediately.
!   if (code != _URC_EXPECTED_BY_CLEANUP)
      __terminate (header->terminateHandler);
  
    if (header->exceptionDestructor)
*** gcc.orig/libstdc++-v3/libsupc++/eh_personality.cc	Wed Jul 24 12:17:55 2002
--- gcc/libstdc++-v3/libsupc++/eh_personality.cc	Wed Jul 24 12:30:17 2002
*************** PERSONALITY_FUNCTION (int version,
*** 419,425 ****
--- 419,429 ----
  		 (_Unwind_Ptr) &xh->unwindHeader);
    _Unwind_SetGR (context, __builtin_eh_return_data_regno (1),
  		 handler_switch_value);
+ #ifdef UNWIND_SETIP
+   UNWIND_SETIP (context, landing_pad);
+ #else
    _Unwind_SetIP (context, landing_pad);
+ #endif
    return _URC_INSTALL_CONTEXT;
  }
  

^ permalink raw reply	[flat|nested] 9+ messages in thread

* IA64 HP-UX Unwind patch
@ 2002-07-24 15:23 Steve Ellcey
  0 siblings, 0 replies; 9+ messages in thread
From: Steve Ellcey @ 2002-07-24 15:23 UTC (permalink / raw)
  To: gcc-patches

This patch is, I hope, the final patch for using HP-UX's libunwind
instead of the GCC unwind code, though I expect changes will be required
before it is approved.  The problem I have run into is two ABI
differences between the HP Unwind and the GCC Unwind.

The first is what _URC_ code does _Unwind_DeleteException call the
cleanup routine with.  HP uses _URC_NO_REASON and GCC uses
_URC_FOREIGN_EXCEPTION_CAUGHT.  My fix for this was to create
_URC_EXPECTED_BY_CLEANUP in unwind.h and define it to
_URC_FOREIGN_EXCEPTION_CAUGHT if it was not already defined and then use
that in __gxx_exception_cleanup (libstdc++-v3/libsupc++/eh_throw.cc).
Then I put my own definition of _URC_EXPECTED_BY_CLEANUP in
libstdc++-v3/config/os/hpux/os_defines.h for HP-UX.

The second problem is with _Unwind_SetIP.  Even in ILP32 mode, the HP-UX
Unwind library expects you to pass in a 64 bit pointer on IA64.  So, I
created a macro in os_defines.h UNWIND_SETIP to use instead of calling
_Unwind_SetIP if it is defined.  I also ifdef'ed the _Unwind_SetIP
declaration in unwind.h so I could have my own version in os_defines.h
with different arg types.

My definition of UNWIND_SETIP uses a builtin called __extend_ptr to turn
the 32 bit pointer in landing_pad into a 64 bit pointer.  I did not
include the implementation of this builtin in this patch but thought I
would do that seperately.

One possible change that I considered but was not able to manage was to
use the system unwind.h instead of the one in GCC when building
libstdc++-v3 but since they are both called unwind.h I couldn't figure
out how to tell unwind-cxx.h to use a system header instead of the GCC
one.  Brackets instead of quotes had no effect.  If I did this I
wouldn't have to include my own _Unwind_SetIP declaration and I could
put the default _URC_EXPECTED_BY_CLEANUP in eh_throw.c instead of
unwind.h and not mess with any GCC code but only with libstdc++-v3.

I can't think of any way to avoid the ifdef around _Unwind_SetIP.

Comments?

Steve Ellcey
sje@cup.hp.com


2002-07-24  Steve Ellcey  <sje@cup.hp.com>

	* gcc/unwind.h (_URC_EXPECTED_BY_CLEANUP): New Macro with
	default definition.
	(_Unwind_SetIP): Prototype only if UNWIND_SETIP is not set.
	* libstdc++-v3/config/os/hpux/os_defines.h (_URC_EXPECTED_BY_CLEANUP):
	Define to match HP libunwind.
	(UNWIND_SETIP) Define with new modified arguments.
	* libstdc++-v3/libsupc++/eh_throw.cc (__gxx_exception_cleanup):
	Use _URC_EXPECTED_BY_CLEANUP instead of _URC_FOREIGN_EXCEPTION_CAUGHT.
	* libstdc++-v3/libsupc++/eh_personality.cc (PERSONALITY_FUNCTION):
	Call UNWIND_SETIP instead of _Unwind_SetIP if defined.


*** gcc.orig/gcc/unwind.h	Wed Jul 24 12:16:30 2002
--- gcc/gcc/unwind.h	Wed Jul 24 12:42:25 2002
*************** typedef enum
*** 54,59 ****
--- 54,66 ----
    _URC_CONTINUE_UNWIND = 8
  } _Unwind_Reason_Code;
  
+ /* G++ _Unwind_DeleteException calls __gxx_exception_cleanup with
+    _URC_FOREIGN_EXCEPTION_CAUGHT, the HP libunwind library version
+    of _Unwind_DeleteException calls it with _URC_NO_REASON.  */
+ 
+ #ifndef _URC_EXPECTED_BY_CLEANUP
+ #define _URC_EXPECTED_BY_CLEANUP _URC_FOREIGN_EXCEPTION_CAUGHT
+ #endif
  
  /* The unwind interface uses a pointer to an exception header object
     as its representation of an exception being thrown. In general, the
*************** extern _Unwind_Word _Unwind_GetGR (struc
*** 124,130 ****
--- 131,144 ----
  extern void _Unwind_SetGR (struct _Unwind_Context *, int, _Unwind_Word);
  
  extern _Unwind_Ptr _Unwind_GetIP (struct _Unwind_Context *);
+ 
+ /* HP IA64 ILP32 _Unwind_SetIP requires a 64 bit address, there is
+    a private extern and calling sequence in
+    libstdc++-v3/config/os/hpux/os_defines.h.  */
+ 
+ #ifndef UNWIND_SETIP
  extern void _Unwind_SetIP (struct _Unwind_Context *, _Unwind_Ptr);
+ #endif
  
  extern void *_Unwind_GetLanguageSpecificData (struct _Unwind_Context *);
  
*** gcc.orig/libstdc++-v3/config/os/hpux/os_defines.h	Wed Jul 24 12:16:57 2002
--- gcc/libstdc++-v3/config/os/hpux/os_defines.h	Wed Jul 24 14:00:28 2002
*************** namespace std 
*** 86,89 ****
--- 86,105 ----
  typedef long int __padding_type;
  #endif
  
+ /* HPUX IA64 _Unwind_DeleteException calls cleanup routine,
+    __gxx_exception_cleanup, with _URC_NO_REASON and not
+    _URC_FOREIGN_EXCEPTION_CAUGHT.  */
+ 
+ #if defined(__ia64__)
+ #undef _URC_EXPECTED_BY_CLEANUP
+ #define _URC_EXPECTED_BY_CLEANUP _URC_NO_REASON
+ #endif
+ 
+ /* HPUX IA64 ILP32 Unwind_SetIP needs to be passed a 64 bit pointer.  */
+ 
+ #if !defined(_LP64) && defined (__ia64__)
+ extern void _Unwind_SetIP (struct _Unwind_Context *, unsigned __attribute__((__mode__(__word__))));
+ #define UNWIND_SETIP(CONTEXT,LANDING_PAD) _Unwind_SetIP (CONTEXT, __extend_ptr ((void *) LANDING_PAD))
+ #endif
+ 
  #endif
*** gcc.orig/libstdc++-v3/libsupc++/eh_throw.cc	Wed Jul 24 12:17:50 2002
--- gcc/libstdc++-v3/libsupc++/eh_throw.cc	Wed Jul 24 12:29:14 2002
*************** __gxx_exception_cleanup (_Unwind_Reason_
*** 42,48 ****
  
    // If we haven't been caught by a foreign handler, then this is
    // some sort of unwind error.  In that case just die immediately.
!   if (code != _URC_FOREIGN_EXCEPTION_CAUGHT)
      __terminate (header->terminateHandler);
  
    if (header->exceptionDestructor)
--- 42,48 ----
  
    // If we haven't been caught by a foreign handler, then this is
    // some sort of unwind error.  In that case just die immediately.
!   if (code != _URC_EXPECTED_BY_CLEANUP)
      __terminate (header->terminateHandler);
  
    if (header->exceptionDestructor)
*** gcc.orig/libstdc++-v3/libsupc++/eh_personality.cc	Wed Jul 24 12:17:55 2002
--- gcc/libstdc++-v3/libsupc++/eh_personality.cc	Wed Jul 24 12:30:17 2002
*************** PERSONALITY_FUNCTION (int version,
*** 419,425 ****
--- 419,429 ----
  		 (_Unwind_Ptr) &xh->unwindHeader);
    _Unwind_SetGR (context, __builtin_eh_return_data_regno (1),
  		 handler_switch_value);
+ #ifdef UNWIND_SETIP
+   UNWIND_SETIP (context, landing_pad);
+ #else
    _Unwind_SetIP (context, landing_pad);
+ #endif
    return _URC_INSTALL_CONTEXT;
  }
  

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2002-08-15 17:37 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2002-08-14 12:34 IA64 HP-UX Unwind patch Steve Ellcey
2002-08-14 12:55 ` Richard Henderson
  -- strict thread matches above, loose matches on Subject: below --
2002-08-15  9:47 Steve Ellcey
2002-08-15 10:37 ` Richard Henderson
2002-08-14 13:34 Steve Ellcey
2002-08-14 14:29 ` Richard Henderson
2002-08-14 10:45 Steve Ellcey
2002-08-14 11:02 ` Richard Henderson
2002-07-24 15:23 Steve Ellcey

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).