-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[libc] Set default visibility to 'hidden' and make entrypoints default #97123
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
base: main
Are you sure you want to change the base?
Conversation
@llvm/pr-subscribers-libc Author: Joseph Huber (jhuber6) ChangesSummary: Currently we build everything with default visibility, meaning that all This patch is based on #97109. Full diff: https://github.com/llvm/llvm-project/pull/97123.diff 2 Files Affected:
diff --git a/libc/cmake/modules/LLVMLibCCompileOptionRules.cmake b/libc/cmake/modules/LLVMLibCCompileOptionRules.cmake
index 3bf429381d4af..73950f9dc1ce9 100644
--- a/libc/cmake/modules/LLVMLibCCompileOptionRules.cmake
+++ b/libc/cmake/modules/LLVMLibCCompileOptionRules.cmake
@@ -41,6 +41,7 @@ function(_get_common_compile_options output_var flags)
if(LLVM_COMPILER_IS_GCC_COMPATIBLE)
list(APPEND compile_options "-fpie")
+ list(APPEND compile_options "-fvisibility=hidden")
if(LLVM_LIBC_FULL_BUILD)
list(APPEND compile_options "-DLIBC_FULL_BUILD")
@@ -94,7 +95,6 @@ function(_get_common_compile_options output_var flags)
endif()
if (LIBC_TARGET_OS_IS_GPU)
list(APPEND compile_options "-nogpulib")
- list(APPEND compile_options "-fvisibility=hidden")
list(APPEND compile_options "-fconvergent-functions")
list(APPEND compile_options "-flto")
list(APPEND compile_options "-Wno-multi-gpu")
diff --git a/libc/src/__support/common.h b/libc/src/__support/common.h
index 53951dc131c28..5b26a5a19f7c2 100644
--- a/libc/src/__support/common.h
+++ b/libc/src/__support/common.h
@@ -16,6 +16,10 @@
#include "src/__support/macros/attributes.h"
#include "src/__support/macros/properties/architectures.h"
+#ifndef LIBC_TARGET_ARCH_IS_GPU
+#define LLVM_LIBC_FUNCTION_ATTR [[gnu::visibility("default")]]
+#endif
+
#ifndef LLVM_LIBC_FUNCTION_ATTR
#define LLVM_LIBC_FUNCTION_ATTR
#endif
|
Please check__getauxval and cxa_atexit. they are not declared as entrypoints. Stack guards and startup routines may also need changes. |
Yep, along with |
Okay, I updated this to add a new I added a |
✅ With the latest revision this PR passed the C/C++ code formatter. |
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.
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 doing a lot more than what the top line says. I don't think we should roll all these things into one change. I also don't think we should be doing all of these things.
As discussed in #97109, once that lands then using -fvisibility=hidden
will be moot, but it's certainly harmless enough to add. It should be unconditional and uniform if it's there. There's no configuration that wants anything different.
We don't need new cmake config AFAIK. The existing LLVM_LIBC_FUNCTION_ATTR
macro will be defined by cases that actually want non-hidden visibility for the public C linkage symbols, and there is no cmake-based build that wants different. Embedders building shared libraries already use that to cause the public C linkage symbols (aliases) for functions to have STV_DEFAULT
.
What we do need is an equivalent to LLVM_LIBC_FUNCTION
for variables with public C ABI linkage. (I think all the embedders doing shared library builds just are not yet using any of the llvm-libc code that defines exported variables.) However, that can be a much simpler macro API because there's always a prior declaration and that suffices for the type. So I think it can be something like:
#define LLVM_LIBC_VAR(name) \
extern decltype(LIBC_NAMESPACE::name) name [[gnu::alias(#name)]]; \
LLVM_LIBC_PUBLIC_ATTR decltype(LIBC_NAMESPACE::name) \
__##name##__impl __asm__(#name)
This is used inside the namespace:
LLVM_LIBC_VAR(foo);
LLVM_LIBC_VAR(bar) = 1;
LLVM_LIBC_VAR(baz){fancy,constructor,args};
Of course, the header file has previously done plain extern int bar;
et al inside the namespace.
The above assumes we rename LLVM_LIBC_FUNCTION_ATTR
to LLVM_LIBC_PUBLIC_ATTR
and use the same macro for both public linkage functions and public linkage variables. We could add a separate LLVM_LIBC_VAR_ATTR
if there's reason to. But for my embedding I'll be using the same definition for both anyway and I think a single macro probably makes sense.
We can soup that up to:
#define LLVM_LIBC_VAR(name, ...) \
extern __VA_ARGS__ decltype(LIBC_NAMESPACE::name) \
name [[gnu::alias(#name)]]; \
LLVM_LIBC_PUBLIC_ATTR __VA_ARGS__ decltype(LIBC_NAMESPACE::name) \
__##name##__impl __asm__(#name)
so that one day we can do:
LLVM_LIBC_VAR(errno, thread_local);
when we want that in the public ABI.
So I think we should have some separate changes here:
- (optional)
-fvisibility=hidden
across the board in cmake, if you want to bother. I don't care either way since [libc] Add LIBC_NAMESPACE_DECL macro #97109 and related need to land anyway and that makes it moot. - Define and document new
LLVM_LIBC_VAR
usage norm (bikeshed on macro names, etc.) - Update existing public ABI variable defns to use that.
- Update clang-tidy checks to enforce the new norm.
AFAIK there isn't really any hurry for any of these, since we don't yet have embedders who a) care about visibility (i.e. dynamic linking) and b) are using llvm-libc bits that define public ABI variable symbols.
The other changes here such as what's going on the __cxa_*
symbols are unclear to me. I think they should be done separately with more comments and discussion about what they're for.
I figured that we needed a new one because this now needs to apply to globals and functions. I could definitely define it to be default depending on the target though if we don't want a new config.
Yeah, I guess the most pertinent thing here is setting the visibility manually so that the entrypoints have the proper visibility even if we make everything hidden.
I originally tried to do this, but it's not possible on NVPTX because their aliases only apply to functions. Also, it crashes the AMDGPU compiler. I had code that worked fine in LLVM-IR, it just broke everything else.
The GPU target wants everything to be hidden, but I already do that, so it's not a blocker on my side. It's definitely reasonable to split this stuff out. I think #97109 should just put hidden in front of every namespace honestly, but you need to first set the visibility manually like is done here so that it doesn't break the current behavior. |
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 linkedinto. 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 #97109.