-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[libc] Add LIBC_NAMESPACE_DECL macro #97109
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
Conversation
@llvm/pr-subscribers-libc Author: None (PiJoules) ChangesThis defines to LIBC_NAMESPACE with Full diff: https://github.com/llvm/llvm-project/pull/97109.diff 3 Files Affected:
diff --git a/libc/src/__support/macros/config.h b/libc/src/__support/macros/config.h
index 6390c7992325d..0380c8d6c8b89 100644
--- a/libc/src/__support/macros/config.h
+++ b/libc/src/__support/macros/config.h
@@ -27,4 +27,8 @@
#define LIBC_HAS_FEATURE(f) 0
#endif
+// Declare a LIBC_NAMESPACE with hidden visibility. This can be used on a
+// case-by-case basis where sets of symbols within this declaration are hidden.
+#define LIBC_NAMESPACE_HIDDEN_DECL [[gnu::visibility("hidden")]] LIBC_NAMESPACE
+
#endif // LLVM_LIBC_SRC___SUPPORT_MACROS_CONFIG_H
diff --git a/libc/src/stdlib/rand_util.cpp b/libc/src/stdlib/rand_util.cpp
index ff3478db70003..1f3e03679ba19 100644
--- a/libc/src/stdlib/rand_util.cpp
+++ b/libc/src/stdlib/rand_util.cpp
@@ -9,11 +9,12 @@
#include "src/stdlib/rand_util.h"
#include "src/__support/CPP/atomic.h"
#include "src/__support/macros/attributes.h"
+#include "src/__support/macros/config.h"
-namespace LIBC_NAMESPACE {
+namespace LIBC_NAMESPACE_HIDDEN_DECL {
// C standard 7.10p2: If 'rand' is called before 'srand' it is to
// proceed as if the 'srand' function was called with a value of '1'.
cpp::Atomic<unsigned long> rand_next = 1;
-} // namespace LIBC_NAMESPACE
+} // namespace LIBC_NAMESPACE_HIDDEN_DECL
diff --git a/libc/src/stdlib/rand_util.h b/libc/src/stdlib/rand_util.h
index 5d7febf8248d8..2de48f035d784 100644
--- a/libc/src/stdlib/rand_util.h
+++ b/libc/src/stdlib/rand_util.h
@@ -11,14 +11,15 @@
#include "src/__support/CPP/atomic.h"
#include "src/__support/macros/attributes.h"
+#include "src/__support/macros/config.h"
-namespace LIBC_NAMESPACE {
+namespace LIBC_NAMESPACE_HIDDEN_DECL {
// The ISO C standard does not explicitly require thread-safe behavior for the
// generic `rand()` function. Some implementations expect it however, so we
// provide it here.
extern cpp::Atomic<unsigned long> rand_next;
-} // namespace LIBC_NAMESPACE
+} // namespace LIBC_NAMESPACE_HIDDEN_DECL
#endif // LLVM_LIBC_SRC_STDLIB_RAND_UTIL_H
|
So, the GPU build just compiles with |
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.
Okay, I'm thinking that we should just compile everything with -fvisibility=hidden
. This prevents exposing our internal symbols, as noted in this patch. The public option macro should then carry something like this in common.h
#ifdef LIBC_TARGET_IS_GPU
#define LLVM_LIBC_FUNCTION_ATTR [[gnu::visibility("hidden")]]
#else
#define LLVM_LIBC_FUNCTION_ATTR [[gnu::visibility("default")]]
#endif
Is this reasonable? I can make a patch for this, or we can update this one.
Alternatively I think we can put that attr in the config.json. |
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.
I'm thinking about moving all of our internal implementation to something like #define LIBC_NAMESPACE_INTERNAL LIBC_NAMESPACE::internal
and make that has hidden visibility by default. We will only leave entry point functions in LIBC_NAMESPACE
. WDYT?
tagging @frobtech @brooksmoses
I don't think we need to bother, since we already have a macro that marks all of our "API" functions right? (Maybe errno would need something special?). Figured it's sufficient to make everything hidden except our API functions. |
I would also +1 for hidden by default if it doesn't break anyone downstream. |
Summary: See for visibility: https://llvm.org/docs/LangRef.html#visibility-styles Currently we build everything with default visibility, meaning that all internal symbols are preemptable and visible to any `.so` they're linked into. What we want is hidden visibility for all the internal parts, and default visibility for the API functions / exposed globals. This patch is based on llvm#97109.
|
Summary: See for visibility: https://llvm.org/docs/LangRef.html#visibility-styles Currently we build everything with default visibility, meaning that all internal symbols are preemptable and visible to any `.so` they're linked into. What we want is hidden visibility for all the internal parts, and default visibility for the API functions / exposed globals. This patch is based on llvm#97109.
That's correct. Using It's a good normal practice to use |
libc/src/__support/macros/config.h
Outdated
@@ -27,4 +27,8 @@ | |||
#define LIBC_HAS_FEATURE(f) 0 | |||
#endif | |||
|
|||
// Declare a LIBC_NAMESPACE with hidden visibility. This can be used on a | |||
// case-by-case basis where sets of symbols within this declaration are hidden. | |||
#define LIBC_NAMESPACE_HIDDEN_DECL [[gnu::visibility("hidden")]] LIBC_NAMESPACE |
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.
Let's just call it LIBC_NAMESPACE_DECL
. There is no case-by-case.
We also need some updates to various docs/ files to clearly explain that namespace LIBC_NAMESPACE_DECL {
and only that formulation must be used around all declarations and definitions. We then need to update the existing clang-tidy checks to require and enforce that.
I think the natural order of operations is:
- Define new macro and update docs to say how to use it correctly. That can land without other blockers.
- Update clang-tidy checks to enforce the new standard, making sure they have full fixit implementation. That shouldn't land quite yet because then the libc linter bot will start complaining anew.
- Use clang-tidy to apply fixups to all libc code so it now conforms. No manual edits should be needed, but manual audit is needed to be sure it caught everything and the fixit edits were correct.
- Land 2. & 3. either in quick succession or as one commit, not sure how much it matters if everybody who would look at the libc linter bot knows what's being done.
So, the patch where I prefer |
#97123 only addresses the issue for the CMake build though and we have other users that build LLVM libc with their own build system and want to make that they always get the right behavior. I don't think it's either or, we really want both of these changes since they're addressing different use cases. |
So, this is pretty much how we export our symbols https://godbolt.org/z/4bdoeq5oh. Since it's in a namespace, if we put the visibility on everything it will still apply to the C symbols. So we need specific attributes on the entrypoints. We could potentially |
Yeah, I think the solution is to take #97123 and then modify the |
Okay, so I think the solution here is to land #97123 to make all the entrypoints have visibility set correctly, and to allow the user to configure the visibility on the entrypoints. (default is default). Then we can modify this one to basically just do
|
0fe1259
to
f49c5c4
Compare
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.
I think every namespace should be hidden, and only the entrypoints get different visibility. I don't think there's a case where we'd want one namespace hidden and another default.
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.
git grep LIBC_NAMESPACE -- 'libc*.rst'
shows other example snippets that are violating the new style requirement, so those should be updated too. Many are in libc/docs/dev/clang_tidy_checks.rst, so for there let's just add a big TODO comment pointing to an issue we file to track morphing the clang-tidy check/fixit into enforcing the new style. We can fix that up when we land the changes to the clang-tidy check's implementation. But the other places in libc/docs should be updated in this change.
libc/src/__support/macros/config.h
Outdated
// Declare a LIBC_NAMESPACE with hidden visibility. `namespace | ||
// LIBC_NAMESPACE_DECL {` should be used around all declarations and definitions | ||
// for libc internals as opposed to just `namespace LIBC_NAMESPACE {`. This | ||
// ensures that all internal implementations within this namespace have hidden |
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.
There are other ways that would achieve that "implementations have hidden visibility". I think it's more important to emphasize that all the declarations indicate hidden visibility, which optimizes codegen for uses of symbols defined in other TUs in ways that can be necessary for correctness by avoiding dynamic relocation.
This defines to LIBC_NAMESPACE with `__attribute__((visibility("hidden")))` so all the symbols under it have hidden visibility. This new macro should be used when declaring a new namespace that will have internal functions/globals and LIBC_NAMESPACE should be used as a means of accessing functions/globals declared within LIBC_NAMESPACE_DECL.
f49c5c4
to
afb5d2f
Compare
This defines to LIBC_NAMESPACE with `__attribute__((visibility("hidden")))` so all the symbols under it have hidden visibility. This new macro should be used when declaring a new namespace that will have internal functions/globals and LIBC_NAMESPACE should be used as a means of accessing functions/globals declared within LIBC_NAMESPACE_DECL.
Namespace macro that should be used to declare a new namespace is updated from LIBC_NAMESPACE to LIBC_NAMESPACE_DECL which by default has hidden visibility (llvm#97109). This commit updates the clang-tidy checks to match the new policy.
Namespace macro that should be used to declare a new namespace is updated from LIBC_NAMESPACE to LIBC_NAMESPACE_DECL which by default has hidden visibility (llvm#97109). This commit updates the clang-tidy checks to match the new policy.
Namespace macro that should be used to declare a new namespace is updated from LIBC_NAMESPACE to LIBC_NAMESPACE_DECL which by default has hidden visibility (llvm#97109). This commit updates the clang-tidy checks to match the new policy.
This defines to LIBC_NAMESPACE with
__attribute__((visibility("hidden")))
so all the symbols under it have hidden visibility. This new macro should be used when declaring a new namespace that will have internal functions/globals and LIBC_NAMESPACE should be used as a means of accessing functions/globals declared within LIBC_NAMESPACE_DECL.