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

Hide cbits symbols via visibility attribute or compiler flag? #9991

Open
endgame opened this issue May 9, 2024 · 1 comment
Open

Hide cbits symbols via visibility attribute or compiler flag? #9991

endgame opened this issue May 9, 2024 · 1 comment

Comments

@endgame
Copy link

endgame commented May 9, 2024

Describe the feature request
When compiling cbits-style code (code that's designed for foreign import only by its containing library), it would be nice if there was some official/automatic way to restrict the symbol visibility of the compiled bundled C code.

AIUI, there are a couple of ways to do this:

  1. Set an attribute on the definitions. This is __attribute__((visibility)) on GCC >=4. I think Clang supports the same syntax and has done so for a long time. Still, it would be nice if we could signal (via #define?) that it's supported, so the code could still work with older compilers (assuming they're supported by GHC). GCC >=5 and at least Clang >=3.6 support the preprocessor symbol __has_attribute(foo), but I don't know if MSVC does, or if GHC even supports MSVC.
  2. Pass -fvisibility=hidden on the command line to set the default visibility and then change it where needed via __attribute__.

In my own C library projects, I only do "visibility stuff" if both №1 and №2 are available (i.e., most of the time on modern systems). When it's available, I set -fvisibility=hidden and then put (a macro that expands to) __attribute__((visibility("default"))) on the public interface. For cbits-type stuff, there shouldn't be a public interface, so we should just be able to hide everything that's foreign imported, as it would only be referenced by the Haskell functions in the same Dynamic Shared Object (DSO).

Note that this isn't a complete solution to the problem, as AIUI static libraries can't do visibility stuff. So you do still risk symbol clashes there (or the linker just picking one, maybe?).

Additional context
crypton-0.30 renamed some of its foreign imports to prevent a symbol clash during linking. This is exactly the "old woe" mentioned by the linked GCC wiki page.

I saw someone on irc://irc.libera.chat/reflex-frp just yesterday having problems with cryptonite (I have advised him to switch to crypton) and libsodium using the same symbols:

7:04 AM  Oh no!  I almost had my iOS build, but in the very last build step - frontend-static-aarch64-ios-0.1 - I get 'ld: 6 duplicate symbols for architecture arm64'
7:07 AM  Via different dependencies, I have two cryptography libraries, 'cryptonite' for Haskell and 'libsodium' for C.  Linking them together statically clashes.
7:14 AM  All 6 duplicates stem from 'blake2b-ref.o'
9:04 AM  I don't think we use blake anywhere in our app.  Going to local-fork either cryptonite or libsodium and rip blake2-ref out.  Or does anyone here know like, a linker option to make them coexist?
9:04 AM  or so?
@hacklschorsch
Copy link

Thanks @endgame !

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