This is the mail archive of the mailing list for the libstdc++ project.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

IA64 HP-UX Unwind patch

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++/
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.


Steve Ellcey

2002-07-24  Steve Ellcey  <>

	* 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++/ (__gxx_exception_cleanup):
	* libstdc++-v3/libsupc++/ (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 ----
  } _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.  */
+ #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;
+ /* HPUX IA64 _Unwind_DeleteException calls cleanup routine,
+    __gxx_exception_cleanup, with _URC_NO_REASON and not
+ #if defined(__ia64__)
+ #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
*** gcc.orig/libstdc++-v3/libsupc++/	Wed Jul 24 12:17:50 2002
--- gcc/libstdc++-v3/libsupc++/	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.
      __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++/	Wed Jul 24 12:17:55 2002
--- gcc/libstdc++-v3/libsupc++/	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),
+   UNWIND_SETIP (context, landing_pad);
+ #else
    _Unwind_SetIP (context, landing_pad);
+ #endif

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]