Skip to content
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

calypso should be usable with libc++ on OSX (clang on OSX should use that instead of libstdc++) #82

Closed
timotheecour opened this issue Jan 18, 2018 · 4 comments

Comments

@timotheecour
Copy link
Collaborator

timotheecour commented Jan 18, 2018

Calypso/runtime/calypso/cpp/eh/unwind-cxx.h uses #include <bits/atomic_word.h>

that's a libstdc++ file, but clang on OSX should use libc++ instead of libstdc++ (eg: https://discuss.codechef.com/questions/81564/bitsstdch-does-not-work-in-mac-os )

This is why we get errors such as:

ccmake -D LLVM_CONFIG=$homebrew_D/Cellar/llvm@3.9/3.9.1_1/bin/llvm-config -D D_FLAGS="-cpp-args=-I$homebrew_D/opt/llvm/include/c++/v1/" ..

Calypso/runtime/calypso/cpp/eh/unwind-cxx.h:38:10: fatal error: 'bits/atomic_word.h' file not found

NOTE: a workaround is to use gcc includes, eg: https://github.com/Syniurge/Calypso#installing-on-osx

related issues:

unwind-cxx.h should be updated to be more portable, and on OSX not depend on bits/atomic_word.h

EDIT

with the following patch:

--- a/runtime/calypso/cpp/eh/unwind-cxx.h
+++ b/runtime/calypso/cpp/eh/unwind-cxx.h
@@ -35,7 +35,20 @@
 #include <exception>
 #include <cstddef>
 #include "unwind.h"
-#include <bits/atomic_word.h>
+
+// PRTEMP
+// #include <bits/atomic_word.h>
+typedef int _Atomic_word;
+// This is a memory order acquire fence.
+#define _GLIBCXX_READ_MEM_BARRIER __atomic_thread_fence (__ATOMIC_ACQUIRE)
+// This is a memory order release fence.
+#define _GLIBCXX_WRITE_MEM_BARRIER __atomic_thread_fence (__ATOMIC_RELEASE)
+#define _GLIBCXX_CDTOR_CALLABI
+// #if defined(__ia64__) && defined(__hpux__)
+typedef unsigned _Unwind_Ptr __attribute__((__mode__(__word__)));
+typedef unsigned _Unwind_Exception_Class __attribute__((__mode__(__DI__)));

I can build most of calypso via:

ccmake -D LLVM_CONFIG=$homebrew_D/Cellar/llvm@3.9/3.9.1_1/bin/llvm-config -D D_FLAGS="-cpp-args=-nostdinc;-cpp-args=-I/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1;-cpp-args=-I/usr/include" ..

except for __is_pointer_p and __do_catch missing from type_info ; indeed, this is used:

/usr/include/c++/4.2.1/typeinfo

and that file contains modifications by APPLE to remove __do_catch, __is_pointer_p.

EDIT

indeed this was mentioned in https://syniurgeblog.wordpress.com/tag/c/ :

What’s essentially left to implement in Calypso:
libc++ doesn’t offer __do_catch(), an alternative is needed

@timotheecour
Copy link
Collaborator Author

also related: https://itanium-cxx-abi.github.io/cxx-abi/cxx-closed.html

[001012 all -- Jim] The issue here, raised originally by Martin, I will open as A-30. Implementations will generally need additional virtual functions associated with the type_info hierarchy to implement such functionality as dynamic cast. Gcc for instance has functions __is_function_p, __do_catch, __pointer_catch, ...

@timotheecour
Copy link
Collaborator Author

timotheecour commented Jan 18, 2018

maybe something like this:
(inspired from https://github.com/llvm-mirror/libcxxabi/blob/master/src/cxa_default_handlers.cpp)
problem : private_typeinfo.h is not accessible directly, it's in https://github.com/llvm-mirror/libcxxabi/blob/master/src/private_typeinfo.h


+    bool doCatch(void* address, ubyte encoding)
+    {
+        void *__thr_obj = __get_object_from_ue(&_cpp_exception.unwindHeader);
+        const __shim_type_info* thrown_type = cast(const __shim_type_info*)(_cpp_exception.exceptionType);
+
+        auto catchTypeInfo = getCatchTypeInfo(address, encoding);
+        if(!catchTypeInfo) return false;
+        const __shim_type_info* catch_type = cast(const __shim_type_info*)(catchTypeInfo);
+        if (catch_type.can_catch(thrown_type, __thr_obj))
+        {
+            // NOTE: __cxa_begin_catch returns adjustedPtr, which in C++ EH is set by __gxx_personality_v0 if the search phase is successful
+            _cpp_exception.adjustedPtr = __thr_obj;
+            return true;
+        }
+
+        return false;
+    }

also requires:

--- a/runtime/CMakeLists.txt
+++ b/runtime/CMakeLists.txt
@@ -479,9 +479,10 @@ macro(build_runtime_libs druntime_o druntime_bc phobos2_o phobos2_bc calypsort_o
         LIBRARY_OUTPUT_DIRECTORY    ${output_path}
         RUNTIME_OUTPUT_DIRECTORY    ${output_path}
         COMPILE_FLAGS               "${c_flags}"
-        # fix for OSX
+        # fix for OSX PRTEMP
         #LINK_FLAGS                  "${ld_flags}"
-        LINK_FLAGS                  "${ld_flags} -L../lib -ldruntime-ldc${lib_suffix}"
+        #LINK_FLAGS                  "${ld_flags} -L../lib -ldruntime-ldc${lib_suffix}"
+        LINK_FLAGS                  "${ld_flags} -L../lib -ldruntime-ldc${lib_suffix} -lc++abi"
         LINKER_LANGUAGE             CXX
     )

to avoid link error:

Undefined symbols for architecture x86_64:
  "typeinfo for __cxxabiv1::__shim_type_info", referenced from:
      __D3cpp2eh3gnu10CppHandler7doCatchMFPvhZb in gnu-debug.o

as well as adding:
modmap (C++) "private_typeinfo.h";
and passing an addition -cpp-args=-I=path/libcxxabi/src/

EDIT: exception handling doesn't work though (same error as #87)

@Syniurge
Copy link
Owner

Good finds! This will ease fixing the OS X support.

(I vaguely remember quickly looking for an alternative to std::type_info::__do_catch in libc++ and didn't find it at that time)

Syniurge added a commit that referenced this issue Jan 31, 2018
There are slight vtable and layout differences with libstdc++:
 - std::type_info::can_catch has one less parameter
 - __cxa_exception/__cxa_dependent_exception have an extra referenceCount/primaryException field
 - caught pointer objects aren't expected to be deferenced i.e passed by value

Parts of libcxxabi were copied, and libstdc++'s unwind-cxx.h file was also trimmed down to from now on have a self-contained C++ header file which only depends on unwind.h. Hence Calypso doesn't depend on neither systemtap-sdt-dev nor libstdc++ anymore.

(SHOULD FIX, OS X build in progress, results tomorrow)
Fixes issues #87, #82, #34.

Thanks to @timotheecour for pointing out the existence of __shim_type_info.
Syniurge added a commit that referenced this issue Feb 11, 2018
Compared to libstdc++, there are slight vtable and layout differences in the libc++ ABI:
    - std::type_info::can_catch has one less parameter
    - __cxa_exception/__cxa_dependent_exception have an extra referenceCount/primaryException field
    - caught pointer objects aren't expected to be deferenced i.e passed by value

Parts of libc++abi were copied, and libstdc++'s unwind-cxx.h file was also trimmed down. From now on the C++ header only depends on unwind.h, hence Calypso doesn't have to be built anymore against systemtap-sdt-dev and libstdc++.

Although it works on Linux, this doesn't fix issues #87 and #82 on MacOS yet, which seems to be due to ABI differences.

Thanks to @timotheecour for pointing out the existence of __shim_type_info.
Syniurge added a commit that referenced this issue Feb 12, 2018
Apple's unwind.h header doesn't specify any special alignment for _Unwind_Exception, resulting in a different layout for __cxa_exception with libc++abi libraries that come with Apple OSes.

Issues #87 and #82 should definitively be fixed now.
Syniurge added a commit that referenced this issue Feb 12, 2018
Apple's unwind.h header doesn't specify any special alignment for _Unwind_Exception, resulting in a different layout for __cxa_exception with libc++abi shared libraries that come with Apple OSes.

Issues #87 and #82 are definitively fixed now.
@timotheecour
Copy link
Collaborator Author

fixed via 5aa7849 and 55de259 ; thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants