-
Notifications
You must be signed in to change notification settings - Fork 120
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
MSYS2: Export forwarders for __cxa_begin_catch
, __cxa_end_catch
, __cxa_rethrow
and __gxx_personality_seh0
#279
Conversation
…`__cxa_rethrow` and `__gxx_personality_seh0` libobjc2 uses native C++ exceptions on MinGW. The clang compiler will emit references to `__cxa_begin_catch`, `__cxa_end_catch`, `__cxa_rethrow` and `__gxx_personality_seh0` for Objective C code which uses Objective C exceptions. These symbols are defined in the C++ runtime, not in libobjc2. As a result, merely linking with libobjc2 is not sufficient. Objective C code such as GNUstep must be compiled with the `LDFLAGS="-lgcc_s -lstdc++"` or `LDFLAGS="-lc++"`, depending on the environment. This is tedious. Additionally, specifying `-lc++` on the msys/clang64 environment causes linker errors: ``` Linking library libgnustep-base ... ld.lld: error: libc++.dll.a(libc++.dll): .idata$4 should not refer to special section 0 ``` A [similar error has been observed for other libraries](msys2/MINGW-packages#18589) A solution for this is to define forwarding exports for `__cxa_begin_catch`, `__cxa_end_catch`, `__cxa_rethrow` and `__gxx_personality_seh0`. This is implemented by adding a `eh_forwards.def` file to the list of libobjc2 source files, which forwards the symbols to the actual C++ runtime. On MSYS2, the libstdc++ and libc++ runtimes are supported, which covers all MinGW environments: https://www.msys2.org/docs/environments/. Forwarding exports are discussed here: - https://learn.microsoft.com/en-us/cpp/build/reference/exports?view=msvc-170 - https://devblogs.microsoft.com/oldnewthing/20060719-24/?p=30473 - https://devblogs.microsoft.com/oldnewthing/20121116-00/?p=6073
21e5314
to
6ef33e5
Compare
@MehdiChinoune - FYI. This is my best attempt at removing the need to set @davidchisnall It's a bit clunky, but it does work. The root problem this PR is trying to address is that ObjC code will generate calls to |
Option 2 might be better for modularity. Unfortunately, LLVM 18 has now branched and so we will have to support both options unless you can get the change in before it ships. |
Getting those changes in LLVM 18 while they have already declared release candidates feels like a stretch. What if I amend this PR so that it declares those functions, and we can work to get an update in the next release of LLVM? We'll have to be hybrid for a while, but MSYS2 is a fast-moving rolling release so the forwarders could be deprecated in the next 6 months or so. I assume the API shape would look like this:
The rethrow method is named |
Backport two patches from libobjc2: - Fix uncaught exception handling (gnustep/libobjc2#278) - Export forwarders for C++ methods, so that we no longer need to link with the C++ runtime (gnustep/libobjc2#279)
@@ -23,32 +29,33 @@ void *__cxa_allocate_exception(size_t thrown_size) CXA_ALLOCATE_EXCEPTION_SPECIF | |||
* _Unwind_Exception structure within this structure, and should be passed to | |||
* the C++ personality function. | |||
*/ | |||
__attribute__((weak)) | |||
OBJC_WEAK |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These don't actually need to be weak anymore. We don't support a separate libobjcxx.so anymore, so we know at compile time whether these are present. We should remove the weak attribute here and make sure we're not doing dynamic checks for their existence anywhere.
|
||
if (HAVE_LIBSTDCXX) | ||
find_library(CXX_RUNTIME "stdc++" REQUIRED) | ||
set(CXX_RUNTIME_NAME "libstdc++-6") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hard coding the libstdc++ version seems very fragile.
find_library(CXX_RUNTIME "c++" REQUIRED) | ||
get_filename_component(CXX_RUNTIME_NAME ${CXX_RUNTIME} NAME_WE CACHE) | ||
else () | ||
message(WARNING "Could not determine the C++ runtime.") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is detecting the C++ standard library, not the runtime. Does MinGW guarantee that the latter is always accessed via the former? This is not true on FreeBSD, for example, where libc++.so is a linker script that links libc++ and libcxxrt, so that we could ship libstdc++ and libc++ with a common runtime.
Let's do it properly - #280 |
libobjc2 uses native C++ exceptions on MinGW. The clang compiler will emit references to
__cxa_begin_catch
,__cxa_end_catch
,__cxa_rethrow
and__gxx_personality_seh0
for Objective C code which uses Objective C exceptions.These symbols are defined in the C++ runtime, not in libobjc2. As a result, merely linking with libobjc2 is not sufficient. Objective C code such as GNUstep must be compiled with the
LDFLAGS="-lgcc_s -lstdc++"
orLDFLAGS="-lc++"
, depending on the environment.This is tedious. Additionally, specifying
-lc++
on the msys/clang64 environment causes linker errors:A similar error has been observed for other libraries
A solution for this is to define forwarding exports for
__cxa_begin_catch
,__cxa_end_catch
,__cxa_rethrow
and__gxx_personality_seh0
. This is implemented by adding aeh_forwards.def
file to the list of libobjc2 source files, which forwards the symbols to the actual C++ runtime. On MSYS2, the libstdc++ and libc++ runtimes are supported, which covers all MinGW environments: https://www.msys2.org/docs/environments/.Forwarding exports are discussed here: