Skip to content

Commit 1819de0

Browse files
committed
[libc] Set default visibility to 'hidden' and make entrypoints default
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 #97109.
1 parent 594bc52 commit 1819de0

File tree

23 files changed

+105
-48
lines changed

23 files changed

+105
-48
lines changed

libc/cmake/modules/LLVMLibCCompileOptionRules.cmake

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ function(_get_common_compile_options output_var flags)
4141

4242
if(LLVM_COMPILER_IS_GCC_COMPATIBLE)
4343
list(APPEND compile_options "-fpie")
44+
list(APPEND compile_options "-fvisibility=hidden")
4445

4546
if(LLVM_LIBC_FULL_BUILD)
4647
list(APPEND compile_options "-DLIBC_FULL_BUILD")
@@ -78,6 +79,9 @@ function(_get_common_compile_options output_var flags)
7879
if (LIBC_CONF_ENABLE_STACK_PROTECTOR)
7980
list(APPEND compile_options "-fstack-protector-strong")
8081
endif()
82+
if(LIBC_CONF_VISIBILITY)
83+
list(APPEND compile_options "-DLIBC_VISIBILITY=${LIBC_CONF_VISIBILITY}")
84+
endif()
8185
list(APPEND compile_options "-Wall")
8286
list(APPEND compile_options "-Wextra")
8387
# -DLIBC_WNO_ERROR=ON if you can't build cleanly with -Werror.
@@ -102,7 +106,6 @@ function(_get_common_compile_options output_var flags)
102106
endif()
103107
if (LIBC_TARGET_OS_IS_GPU)
104108
list(APPEND compile_options "-nogpulib")
105-
list(APPEND compile_options "-fvisibility=hidden")
106109
list(APPEND compile_options "-fconvergent-functions")
107110
list(APPEND compile_options "-flto")
108111
list(APPEND compile_options "-Wno-multi-gpu")

libc/config/config.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,10 @@
3232
}
3333
},
3434
"codegen": {
35+
"LIBC_CONF_VISIBILITY": {
36+
"value": "default",
37+
"doc": "Visibility to use on all exported C library symbols."
38+
},
3539
"LIBC_CONF_KEEP_FRAME_POINTER": {
3640
"value": true,
3741
"doc": "Keep frame pointer in functions for better debugging experience."

libc/config/gpu/config.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,10 @@
1212
"LIBC_CONF_PRINTF_FLOAT_TO_STR_USE_MEGA_LONG_DOUBLE_TABLE": {
1313
"value": false
1414
}
15+
},
16+
"codegen": {
17+
"LIBC_CONF_VISIBILITY": {
18+
"value": "hidden"
19+
}
1520
}
1621
}

libc/docs/configure.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ to learn about the defaults for your platform and target.
2828
* **"codegen" options**
2929
- ``LIBC_CONF_ENABLE_STRONG_STACK_PROTECTOR``: Enable -fstack-protector-strong to defend against stack smashing attack.
3030
- ``LIBC_CONF_KEEP_FRAME_POINTER``: Keep frame pointer in functions for better debugging experience.
31+
- ``LIBC_CONF_VISIBILITY``: Visibility to use on all exported C library symbols.
3132
* **"malloc" options**
3233
- ``LIBC_CONF_FREELIST_MALLOC_BUFFER_SIZE``: Default size for the constinit freelist buffer used for the freelist malloc implementation (default 1o 1GB).
3334
* **"printf" options**

libc/docs/dev/entrypoints.rst

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,5 @@ Entrypoints in LLVM libc
55

66
A public function or a global variable provided by LLVM-libc is called an
77
entrypoint. The notion of entrypoints is ingrained in LLVM-libc's
8-
source layout, build system and source code.
8+
source layout, build system and source code. Entrypoints will be given the
9+
visibility defined in the ``LIBC_CONF_VISIBILITY`` configuration.

libc/src/__support/File/linux/stderr.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@
66
//
77
//===----------------------------------------------------------------------===//
88

9-
#include "file.h"
9+
#include "src/__support/File/linux/file.h"
10+
#include "src/__support/common.h"
11+
1012
#include <stdio.h>
1113

1214
namespace LIBC_NAMESPACE {
@@ -18,6 +20,5 @@ File *stderr = &StdErr;
1820

1921
} // namespace LIBC_NAMESPACE
2022

21-
extern "C" {
22-
FILE *stderr = reinterpret_cast<FILE *>(&LIBC_NAMESPACE::StdErr);
23-
}
23+
LLVM_LIBC_GLOBAL(FILE *,
24+
stderr) = reinterpret_cast<FILE *>(&LIBC_NAMESPACE::StdErr);

libc/src/__support/File/linux/stdin.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@
66
//
77
//===----------------------------------------------------------------------===//
88

9-
#include "file.h"
9+
#include "src/__support/File/linux/file.h"
10+
#include "src/__support/common.h"
11+
1012
#include <stdio.h>
1113

1214
namespace LIBC_NAMESPACE {
@@ -19,6 +21,5 @@ File *stdin = &StdIn;
1921

2022
} // namespace LIBC_NAMESPACE
2123

22-
extern "C" {
23-
FILE *stdin = reinterpret_cast<FILE *>(&LIBC_NAMESPACE::StdIn);
24-
} // extern "C"
24+
LLVM_LIBC_GLOBAL(FILE *,
25+
stdin) = reinterpret_cast<FILE *>(&LIBC_NAMESPACE::StdIn);

libc/src/__support/File/linux/stdout.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@
66
//
77
//===----------------------------------------------------------------------===//
88

9-
#include "file.h"
9+
#include "src/__support/File/linux/file.h"
10+
#include "src/__support/common.h"
11+
1012
#include <stdio.h>
1113

1214
namespace LIBC_NAMESPACE {
@@ -19,6 +21,5 @@ File *stdout = &StdOut;
1921

2022
} // namespace LIBC_NAMESPACE
2123

22-
extern "C" {
23-
FILE *stdout = reinterpret_cast<FILE *>(&LIBC_NAMESPACE::StdOut);
24-
} // extern "C"
24+
LLVM_LIBC_GLOBAL(FILE *,
25+
stdout) = reinterpret_cast<FILE *>(&LIBC_NAMESPACE::StdOut);

libc/src/__support/common.h

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,26 @@
1616
#include "src/__support/macros/attributes.h"
1717
#include "src/__support/macros/properties/architectures.h"
1818

19+
#define __LIBC_MACRO_TO_STRING(str) #str
20+
#define LIBC_MACRO_TO_STRING(str) __LIBC_MACRO_TO_STRING(str)
21+
1922
#ifndef LLVM_LIBC_FUNCTION_ATTR
2023
#define LLVM_LIBC_FUNCTION_ATTR
2124
#endif
2225

26+
#ifndef LIBC_VISIBILITY
27+
#define LIBC_VISIBILITY default
28+
#endif
29+
30+
#ifndef LLVM_LIBC_VISIBILITY
31+
#define LLVM_LIBC_VISIBILITY \
32+
[[gnu::visibility(LIBC_MACRO_TO_STRING(LIBC_VISIBILITY))]]
33+
#endif
34+
2335
// MacOS needs to be excluded because it does not support aliasing.
2436
#if defined(LIBC_COPT_PUBLIC_PACKAGING) && (!defined(__APPLE__))
2537
#define LLVM_LIBC_FUNCTION_IMPL(type, name, arglist) \
26-
LLVM_LIBC_FUNCTION_ATTR decltype(LIBC_NAMESPACE::name) \
38+
LLVM_LIBC_FUNCTION_ATTR LLVM_LIBC_VISIBILITY decltype(LIBC_NAMESPACE::name) \
2739
__##name##_impl__ __asm__(#name); \
2840
decltype(LIBC_NAMESPACE::name) name [[gnu::alias(#name)]]; \
2941
type __##name##_impl__ arglist
@@ -35,6 +47,10 @@
3547
#define LLVM_LIBC_FUNCTION(type, name, arglist) \
3648
LLVM_LIBC_FUNCTION_IMPL(type, name, arglist)
3749

50+
// Defines a global variable meant to be exported by the C library.
51+
#define LLVM_LIBC_GLOBAL(type, name) \
52+
LLVM_LIBC_VISIBILITY type name __asm__(#name)
53+
3854
namespace LIBC_NAMESPACE {
3955
namespace internal {
4056
LIBC_INLINE constexpr bool same_string(char const *lhs, char const *rhs) {
@@ -46,9 +62,6 @@ LIBC_INLINE constexpr bool same_string(char const *lhs, char const *rhs) {
4662
} // namespace internal
4763
} // namespace LIBC_NAMESPACE
4864

49-
#define __LIBC_MACRO_TO_STRING(str) #str
50-
#define LIBC_MACRO_TO_STRING(str) __LIBC_MACRO_TO_STRING(str)
51-
5265
// LLVM_LIBC_IS_DEFINED checks whether a particular macro is defined.
5366
// Usage: constexpr bool kUseAvx = LLVM_LIBC_IS_DEFINED(__AVX__);
5467
//

libc/src/errno/libc_errno.cpp

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,12 @@
88

99
#include "libc_errno.h"
1010
#include "src/__support/CPP/atomic.h"
11+
#include "src/__support/common.h"
1112

1213
#ifdef LIBC_TARGET_ARCH_IS_GPU
1314
// LIBC_THREAD_LOCAL on GPU currently does nothing. So essentially this is just
1415
// a global errno for gpu to use for now.
15-
extern "C" {
16-
LIBC_THREAD_LOCAL LIBC_NAMESPACE::cpp::Atomic<int> __llvmlibc_errno;
17-
}
16+
LLVM_LIBC_GLOBAL(LIBC_NAMESPACE::cpp::Atomic<int>, __llvmlibc_errno);
1817

1918
void LIBC_NAMESPACE::Errno::operator=(int a) {
2019
__llvmlibc_errno.store(a, cpp::MemoryOrder::RELAXED);
@@ -33,9 +32,7 @@ LIBC_NAMESPACE::Errno::operator int() { return __llvmlibc_internal_errno; }
3332
#elif defined(LIBC_FULL_BUILD)
3433
// This mode is for public libc archive, hermetic, and integration tests.
3534
// In full build mode, we provide the errno storage ourselves.
36-
extern "C" {
37-
LIBC_THREAD_LOCAL int __llvmlibc_errno;
38-
}
35+
LLVM_LIBC_GLOBAL(LIBC_THREAD_LOCAL int, __llvmlibc_errno);
3936

4037
void LIBC_NAMESPACE::Errno::operator=(int a) { __llvmlibc_errno = a; }
4138
LIBC_NAMESPACE::Errno::operator int() { return __llvmlibc_errno; }

libc/src/stdio/generic/stderr.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@
77
//===----------------------------------------------------------------------===//
88

99
#include "src/__support/File/file.h"
10+
#include "src/__support/common.h"
1011

1112
#include <stdio.h>
1213

13-
extern "C" FILE *stderr;
14+
LLVM_LIBC_GLOBAL(FILE *, stderr);

libc/src/stdio/generic/stdin.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@
77
//===----------------------------------------------------------------------===//
88

99
#include "src/__support/File/file.h"
10+
#include "src/__support/common.h"
1011

1112
#include <stdio.h>
1213

13-
extern "C" FILE *stdin;
14+
LLVM_LIBC_GLOBAL(FILE *, stdin);

libc/src/stdio/generic/stdout.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@
77
//===----------------------------------------------------------------------===//
88

99
#include "src/__support/File/file.h"
10+
#include "src/__support/common.h"
1011

1112
#include <stdio.h>
1213

13-
extern "C" FILE *stdout;
14+
LLVM_LIBC_GLOBAL(FILE *, stdout);

libc/src/stdio/gpu/stderr.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,14 @@
66
//
77
//===----------------------------------------------------------------------===//
88

9+
#include "src/__support/common.h"
10+
911
#include <stdio.h>
1012

1113
namespace LIBC_NAMESPACE {
1214
static struct {
1315
} stub;
1416
FILE *stderr = reinterpret_cast<FILE *>(&stub);
1517
} // namespace LIBC_NAMESPACE
16-
extern "C" FILE *stderr = reinterpret_cast<FILE *>(&LIBC_NAMESPACE::stub);
18+
LLVM_LIBC_GLOBAL(FILE *,
19+
stderr) = reinterpret_cast<FILE *>(&LIBC_NAMESPACE::stub);

libc/src/stdio/gpu/stdin.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,14 @@
66
//
77
//===----------------------------------------------------------------------===//
88

9+
#include "src/__support/common.h"
10+
911
#include <stdio.h>
1012

1113
namespace LIBC_NAMESPACE {
1214
static struct {
1315
} stub;
1416
FILE *stdin = reinterpret_cast<FILE *>(&stub);
1517
} // namespace LIBC_NAMESPACE
16-
extern "C" FILE *stdin = reinterpret_cast<FILE *>(&LIBC_NAMESPACE::stub);
18+
LLVM_LIBC_GLOBAL(FILE *,
19+
stdin) = reinterpret_cast<FILE *>(&LIBC_NAMESPACE::stub);

libc/src/stdio/gpu/stdout.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,14 @@
66
//
77
//===----------------------------------------------------------------------===//
88

9+
#include "src/__support/common.h"
10+
911
#include <stdio.h>
1012

1113
namespace LIBC_NAMESPACE {
1214
static struct {
1315
} stub;
1416
FILE *stdout = reinterpret_cast<FILE *>(&stub);
1517
} // namespace LIBC_NAMESPACE
16-
extern "C" FILE *stdout = reinterpret_cast<FILE *>(&LIBC_NAMESPACE::stub);
18+
LLVM_LIBC_GLOBAL(FILE *,
19+
stdout) = reinterpret_cast<FILE *>(&LIBC_NAMESPACE::stub);

libc/src/stdlib/atexit.cpp

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,19 +13,16 @@
1313

1414
namespace LIBC_NAMESPACE {
1515

16-
extern "C" {
17-
18-
int __cxa_atexit(AtExitCallback *callback, void *payload, void *) {
16+
LLVM_LIBC_FUNCTION(int, __cxa_atexit,
17+
(AtExitCallback * callback, void *payload, void *)) {
1918
return add_atexit_unit(atexit_callbacks, {callback, payload});
2019
}
2120

22-
void __cxa_finalize(void *dso) {
21+
LLVM_LIBC_FUNCTION(void, __cxa_finalize, (void *dso)) {
2322
if (!dso)
2423
call_exit_callbacks(atexit_callbacks);
2524
}
2625

27-
} // extern "C"
28-
2926
LLVM_LIBC_FUNCTION(int, atexit, (__atexithandler_t callback)) {
3027
return add_atexit_unit(
3128
atexit_callbacks,

libc/src/stdlib/atexit.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,14 @@
1010
#define LLVM_LIBC_SRC_STDLIB_ATEXIT_H
1111

1212
#include "hdr/types/atexithandler_t.h"
13+
#include "src/stdlib/exit_handler.h"
14+
1315
namespace LIBC_NAMESPACE {
1416

17+
int __cxa_atexit(AtExitCallback *callback, void *payload, void *);
18+
19+
void __cxa_finalize(void *dso);
20+
1521
int atexit(__atexithandler_t);
1622

1723
} // namespace LIBC_NAMESPACE

libc/src/stdlib/exit.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,7 @@
99
#include "src/stdlib/exit.h"
1010
#include "src/__support/OSUtil/exit.h"
1111
#include "src/__support/common.h"
12-
13-
extern "C" void __cxa_finalize(void *);
12+
#include "src/stdlib/atexit.h"
1413

1514
namespace LIBC_NAMESPACE {
1615

libc/src/unistd/environ.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,12 @@
66
//
77
//===----------------------------------------------------------------------===//
88

9+
#include "src/unistd/environ.h"
10+
#include "src/__support/common.h"
11+
912
namespace LIBC_NAMESPACE {
1013

1114
// This is initialized to the correct value by the statup code.
12-
extern "C" {
13-
char **environ = nullptr;
14-
}
15+
LLVM_LIBC_GLOBAL(char **, environ) = nullptr;
1516

1617
} // namespace LIBC_NAMESPACE

libc/src/unistd/getopt.cpp

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -175,12 +175,10 @@ int getopt_r(int argc, char *const argv[], const char *optstring,
175175

176176
namespace impl {
177177

178-
extern "C" {
179-
char *optarg = nullptr;
180-
int optind = 1;
181-
int optopt = 0;
182-
int opterr = 0;
183-
}
178+
LLVM_LIBC_GLOBAL(char, *optarg) = nullptr;
179+
LLVM_LIBC_GLOBAL(int, optind) = 1;
180+
LLVM_LIBC_GLOBAL(int, optopt) = 0;
181+
LLVM_LIBC_GLOBAL(int, opterr) = 0;
184182

185183
static unsigned optpos;
186184

libc/test/IntegrationTest/test.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ void *memcpy(void *__restrict, const void *__restrict, size_t);
2828
void *memmove(void *dst, const void *src, size_t count);
2929
void *memset(void *ptr, int value, size_t count);
3030
int atexit(void (*func)(void));
31+
int __cxa_atexit(void (*func)(void *), void *payload, void *dso);
32+
void __cxa_finalize(void *dso);
3133

3234
} // namespace LIBC_NAMESPACE
3335

@@ -53,6 +55,12 @@ void *memset(void *ptr, int value, size_t count) {
5355
// This is needed if the test was compiled with '-fno-use-cxa-atexit'.
5456
int atexit(void (*func)(void)) { return LIBC_NAMESPACE::atexit(func); }
5557

58+
int __cxa_atexit(void (*callback)(void *), void *payload, void *dso) {
59+
return LIBC_NAMESPACE::__cxa_atexit(callback, payload, dso);
60+
}
61+
62+
void __cxa_finalize(void *dso) { LIBC_NAMESPACE::__cxa_finalize(dso); }
63+
5664
} // extern "C"
5765

5866
// Integration tests cannot use the SCUDO standalone allocator as SCUDO pulls

0 commit comments

Comments
 (0)