Skip to content

Commit 9b3222f

Browse files
committed
[libc++] Make sure we can build libc++ with -fvisibility=hidden
Summary: When building with -fvisibility=hidden, some symbols do not get exported from libc++.dylib. This means that some entities are not explicitly given default visibility in the source code, and that we rely on the fact -fvisibility=default is the default. This commit explicitly gives default visibility to those symbols to avoid being dependent on the command line flags used. The commit also remove symbols from the dylib -- those symbols do not actually need to be exported from the dylib and this should not be an ABI break. Finally, in the future, we may want to mark the whole std:: namespace as having hidden visibility (to switch from opt-out to opt-in), in which case the changes done in this commit will be required. Reviewers: EricWF Subscribers: mgorny, christof, dexonsmith, libcxx-commits Differential Revision: https://reviews.llvm.org/D52662 llvm-svn: 345260
1 parent 77c26ae commit 9b3222f

15 files changed

+75
-32
lines changed

libcxx/docs/DesignDocs/VisibilityMacros.rst

+4-4
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,11 @@ Visibility Macros
2222
Mark a symbol as being exported by the libc++ library. This attribute must
2323
be applied to the declaration of all functions exported by the libc++ dylib.
2424

25-
**_LIBCPP_EXTERN_VIS**
25+
**_LIBCPP_EXPORTED_FROM_ABI**
2626
Mark a symbol as being exported by the libc++ library. This attribute may
27-
only be applied to objects defined in the libc++ library. On Windows this
28-
macro applies `dllimport`/`dllexport` to the symbol. On all other platforms
29-
this macro has no effect.
27+
only be applied to objects defined in the libc++ runtime library. On Windows,
28+
this macro applies `dllimport`/`dllexport` to the symbol, and on other
29+
platforms it gives the symbol default visibility.
3030

3131
**_LIBCPP_OVERRIDABLE_FUNC_VIS**
3232
Mark a symbol as being exported by the libc++ library, but allow it to be

libcxx/include/__config

+5-3
Original file line numberDiff line numberDiff line change
@@ -675,21 +675,23 @@ _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD
675675
# define _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS
676676
# define _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS
677677
# define _LIBCPP_OVERRIDABLE_FUNC_VIS
678+
# define _LIBCPP_EXPORTED_FROM_ABI
678679
#elif defined(_LIBCPP_BUILDING_LIBRARY)
679680
# define _LIBCPP_DLL_VIS __declspec(dllexport)
680681
# define _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS
681682
# define _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS _LIBCPP_DLL_VIS
682683
# define _LIBCPP_OVERRIDABLE_FUNC_VIS _LIBCPP_DLL_VIS
684+
# define _LIBCPP_EXPORTED_FROM_ABI __declspec(dllexport)
683685
#else
684686
# define _LIBCPP_DLL_VIS __declspec(dllimport)
685687
# define _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS _LIBCPP_DLL_VIS
686688
# define _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS
687689
# define _LIBCPP_OVERRIDABLE_FUNC_VIS
690+
# define _LIBCPP_EXPORTED_FROM_ABI __declspec(dllimport)
688691
#endif
689692

690693
#define _LIBCPP_TYPE_VIS _LIBCPP_DLL_VIS
691694
#define _LIBCPP_FUNC_VIS _LIBCPP_DLL_VIS
692-
#define _LIBCPP_EXTERN_VIS _LIBCPP_DLL_VIS
693695
#define _LIBCPP_EXCEPTION_ABI _LIBCPP_DLL_VIS
694696
#define _LIBCPP_HIDDEN
695697
#define _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
@@ -743,8 +745,8 @@ _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD
743745
# endif
744746
#endif
745747

746-
#ifndef _LIBCPP_EXTERN_VIS
747-
#define _LIBCPP_EXTERN_VIS
748+
#ifndef _LIBCPP_EXPORTED_FROM_ABI
749+
# define _LIBCPP_EXPORTED_FROM_ABI __attribute__((__visibility__("default")))
748750
#endif
749751

750752
#ifndef _LIBCPP_OVERRIDABLE_FUNC_VIS

libcxx/include/__debug

+1-1
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ typedef void(*__libcpp_debug_function_type)(__libcpp_debug_info const&);
7474

7575
/// __libcpp_debug_function - The handler function called when a _LIBCPP_ASSERT
7676
/// fails.
77-
extern _LIBCPP_EXTERN_VIS __libcpp_debug_function_type __libcpp_debug_function;
77+
extern _LIBCPP_EXPORTED_FROM_ABI __libcpp_debug_function_type __libcpp_debug_function;
7878

7979
/// __libcpp_abort_debug_function - A debug handler that aborts when called.
8080
_LIBCPP_NORETURN _LIBCPP_FUNC_VIS

libcxx/include/__functional_base

+1-1
Original file line numberDiff line numberDiff line change
@@ -562,7 +562,7 @@ struct __is_transparent<_Tp, _Up,
562562
struct _LIBCPP_TEMPLATE_VIS allocator_arg_t { };
563563

564564
#if defined(_LIBCPP_CXX03_LANG) || defined(_LIBCPP_BUILDING_LIBRARY)
565-
extern const allocator_arg_t allocator_arg;
565+
extern _LIBCPP_EXPORTED_FROM_ABI const allocator_arg_t allocator_arg;
566566
#else
567567
/* _LIBCPP_INLINE_VAR */ constexpr allocator_arg_t allocator_arg = allocator_arg_t();
568568
#endif

libcxx/include/__locale

+8-8
Original file line numberDiff line numberDiff line change
@@ -1255,13 +1255,13 @@ struct __narrow_to_utf8<8>
12551255
};
12561256

12571257
template <>
1258-
struct __narrow_to_utf8<16>
1258+
struct _LIBCPP_TEMPLATE_VIS __narrow_to_utf8<16>
12591259
: public codecvt<char16_t, char, mbstate_t>
12601260
{
12611261
_LIBCPP_INLINE_VISIBILITY
12621262
__narrow_to_utf8() : codecvt<char16_t, char, mbstate_t>(1) {}
12631263

1264-
~__narrow_to_utf8();
1264+
_LIBCPP_EXPORTED_FROM_ABI ~__narrow_to_utf8();
12651265

12661266
template <class _OutputIterator, class _CharT>
12671267
_LIBCPP_INLINE_VISIBILITY
@@ -1289,13 +1289,13 @@ struct __narrow_to_utf8<16>
12891289
};
12901290

12911291
template <>
1292-
struct __narrow_to_utf8<32>
1292+
struct _LIBCPP_TEMPLATE_VIS __narrow_to_utf8<32>
12931293
: public codecvt<char32_t, char, mbstate_t>
12941294
{
12951295
_LIBCPP_INLINE_VISIBILITY
12961296
__narrow_to_utf8() : codecvt<char32_t, char, mbstate_t>(1) {}
12971297

1298-
~__narrow_to_utf8();
1298+
_LIBCPP_EXPORTED_FROM_ABI ~__narrow_to_utf8();
12991299

13001300
template <class _OutputIterator, class _CharT>
13011301
_LIBCPP_INLINE_VISIBILITY
@@ -1345,13 +1345,13 @@ struct __widen_from_utf8<8>
13451345
};
13461346

13471347
template <>
1348-
struct __widen_from_utf8<16>
1348+
struct _LIBCPP_TEMPLATE_VIS __widen_from_utf8<16>
13491349
: public codecvt<char16_t, char, mbstate_t>
13501350
{
13511351
_LIBCPP_INLINE_VISIBILITY
13521352
__widen_from_utf8() : codecvt<char16_t, char, mbstate_t>(1) {}
13531353

1354-
~__widen_from_utf8();
1354+
_LIBCPP_EXPORTED_FROM_ABI ~__widen_from_utf8();
13551355

13561356
template <class _OutputIterator>
13571357
_LIBCPP_INLINE_VISIBILITY
@@ -1379,13 +1379,13 @@ struct __widen_from_utf8<16>
13791379
};
13801380

13811381
template <>
1382-
struct __widen_from_utf8<32>
1382+
struct _LIBCPP_TEMPLATE_VIS __widen_from_utf8<32>
13831383
: public codecvt<char32_t, char, mbstate_t>
13841384
{
13851385
_LIBCPP_INLINE_VISIBILITY
13861386
__widen_from_utf8() : codecvt<char32_t, char, mbstate_t>(1) {}
13871387

1388-
~__widen_from_utf8();
1388+
_LIBCPP_EXPORTED_FROM_ABI ~__widen_from_utf8();
13891389

13901390
template <class _OutputIterator>
13911391
_LIBCPP_INLINE_VISIBILITY

libcxx/include/__mutex_base

+3-3
Original file line numberDiff line numberDiff line change
@@ -76,9 +76,9 @@ struct _LIBCPP_TYPE_VIS adopt_lock_t {};
7676

7777
#if defined(_LIBCPP_CXX03_LANG) || defined(_LIBCPP_BUILDING_LIBRARY)
7878

79-
extern const defer_lock_t defer_lock;
80-
extern const try_to_lock_t try_to_lock;
81-
extern const adopt_lock_t adopt_lock;
79+
extern _LIBCPP_EXPORTED_FROM_ABI const defer_lock_t defer_lock;
80+
extern _LIBCPP_EXPORTED_FROM_ABI const try_to_lock_t try_to_lock;
81+
extern _LIBCPP_EXPORTED_FROM_ABI const adopt_lock_t adopt_lock;
8282

8383
#else
8484

libcxx/include/charconv

+5-3
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,11 @@ namespace std {
8989

9090
_LIBCPP_BEGIN_NAMESPACE_STD
9191

92+
namespace __itoa {
93+
_LIBCPP_FUNC_VIS char* __u64toa(uint64_t __value, char* __buffer);
94+
_LIBCPP_FUNC_VIS char* __u32toa(uint32_t __value, char* __buffer);
95+
}
96+
9297
#if _LIBCPP_STD_VER > 11
9398

9499
enum class _LIBCPP_ENUM_VIS chars_format
@@ -147,9 +152,6 @@ static constexpr uint32_t __pow10_32[] = {
147152
UINT32_C(1000000000),
148153
};
149154

150-
_LIBCPP_FUNC_VIS char* __u64toa(uint64_t __value, char* __buffer);
151-
_LIBCPP_FUNC_VIS char* __u32toa(uint32_t __value, char* __buffer);
152-
153155
template <typename _Tp, typename = void>
154156
struct _LIBCPP_HIDDEN __traits_base
155157
{

libcxx/include/locale

+17
Original file line numberDiff line numberDiff line change
@@ -2408,6 +2408,23 @@ private:
24082408
string_type __analyze(char __fmt, const ctype<_CharT>&);
24092409
};
24102410

2411+
#define _LIBCPP_TIME_GET_STORAGE_EXPLICIT_INSTANTIATION(_CharT) \
2412+
template <> _LIBCPP_FUNC_VIS time_base::dateorder __time_get_storage<_CharT>::__do_date_order() const; \
2413+
template <> _LIBCPP_FUNC_VIS __time_get_storage<_CharT>::__time_get_storage(const char*); \
2414+
template <> _LIBCPP_FUNC_VIS __time_get_storage<_CharT>::__time_get_storage(const string&); \
2415+
template <> _LIBCPP_FUNC_VIS void __time_get_storage<_CharT>::init(const ctype<_CharT>&); \
2416+
template <> _LIBCPP_FUNC_VIS __time_get_storage<_CharT>::string_type __time_get_storage<_CharT>::__analyze(char, const ctype<_CharT>&); \
2417+
extern template _LIBCPP_FUNC_VIS time_base::dateorder __time_get_storage<_CharT>::__do_date_order() const; \
2418+
extern template _LIBCPP_FUNC_VIS __time_get_storage<_CharT>::__time_get_storage(const char*); \
2419+
extern template _LIBCPP_FUNC_VIS __time_get_storage<_CharT>::__time_get_storage(const string&); \
2420+
extern template _LIBCPP_FUNC_VIS void __time_get_storage<_CharT>::init(const ctype<_CharT>&); \
2421+
extern template _LIBCPP_FUNC_VIS __time_get_storage<_CharT>::string_type __time_get_storage<_CharT>::__analyze(char, const ctype<_CharT>&); \
2422+
/**/
2423+
2424+
_LIBCPP_TIME_GET_STORAGE_EXPLICIT_INSTANTIATION(char)
2425+
_LIBCPP_TIME_GET_STORAGE_EXPLICIT_INSTANTIATION(wchar_t)
2426+
#undef _LIBCPP_TIME_GET_STORAGE_EXPLICIT_INSTANTIATION
2427+
24112428
template <class _CharT, class _InputIterator = istreambuf_iterator<_CharT> >
24122429
class _LIBCPP_TEMPLATE_VIS time_get_byname
24132430
: public time_get<_CharT, _InputIterator>,

libcxx/include/thread

+1-1
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ class __thread_specific_ptr
151151
__thread_specific_ptr(const __thread_specific_ptr&);
152152
__thread_specific_ptr& operator=(const __thread_specific_ptr&);
153153

154-
static void _LIBCPP_TLS_DESTRUCTOR_CC __at_thread_exit(void*);
154+
_LIBCPP_HIDDEN static void _LIBCPP_TLS_DESTRUCTOR_CC __at_thread_exit(void*);
155155

156156
public:
157157
typedef _Tp* pointer;

libcxx/include/utility

+1-1
Original file line numberDiff line numberDiff line change
@@ -297,7 +297,7 @@ template <class _Tp> void as_const(const _Tp&&) = delete;
297297

298298
struct _LIBCPP_TEMPLATE_VIS piecewise_construct_t { };
299299
#if defined(_LIBCPP_CXX03_LANG) || defined(_LIBCPP_BUILDING_LIBRARY)
300-
extern const piecewise_construct_t piecewise_construct;// = piecewise_construct_t();
300+
extern _LIBCPP_EXPORTED_FROM_ABI const piecewise_construct_t piecewise_construct;// = piecewise_construct_t();
301301
#else
302302
/* _LIBCPP_INLINE_VAR */ constexpr piecewise_construct_t piecewise_construct = piecewise_construct_t();
303303
#endif

libcxx/lib/abi/CHANGELOG.TXT

+28
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,34 @@ New entries should be added directly below the "Version" header.
1616
Version 7.0
1717
-----------
1818

19+
* rXXXXX - Making libc++ build under -fvisibility=hidden
20+
21+
The change marks __thread_specific_ptr<__thread_struct>::__at_thread_exit(void*)
22+
with hidden visibility. This removes a symbol from the shared libraries,
23+
however this is not an ABI break because it's impossible for programs linking
24+
against libc++.dylib to actually depend on that symbol. The reason is that
25+
the symbol is exported from the shared library through an implicit
26+
instantiation present in the dylib itself only. Furthermore, if a user's
27+
dylib was implicitly instantiating __thread_specific_ptr<T>::__at_thread_exit
28+
(because it's defined in the headers), marking that symbol as hidden would
29+
not be an ABI break for them because none of their users could actually be
30+
using the symbol in their dylib (because it's an implicit instantiation).
31+
32+
This change also marks __start_std_streams as hidden -- this variable is
33+
only required to initialize the streams, and nobody should depend on it
34+
from outside the dylib.
35+
36+
x86_64-linux-gnu
37+
----------------
38+
Symbol removed: _ZNSt3__121__thread_specific_ptrINS_15__thread_structEE16__at_thread_exitEPv
39+
Symbol removed: _ZNSt3__119__start_std_streamsE
40+
41+
x86_64-apple-darwin16.0
42+
-----------------------
43+
Symbol removed: __ZNSt3__221__thread_specific_ptrINS_15__thread_structEE16__at_thread_exitEPv
44+
Symbol removed: __ZNSt3__119__start_std_streamsE
45+
46+
1947
* r338479 - Elementary string conversions for integral types
2048

2149
The change emits __u64toa and __u32toa under std::__1::__itoa.

libcxx/lib/abi/x86_64-apple-darwin.v1.abilist

-2
Original file line numberDiff line numberDiff line change
@@ -1197,13 +1197,11 @@
11971197
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__119__shared_weak_countD0Ev'}
11981198
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__119__shared_weak_countD1Ev'}
11991199
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__119__shared_weak_countD2Ev'}
1200-
{'type': 'OBJECT', 'is_defined': True, 'name': '__ZNSt3__119__start_std_streamsE', 'size': 0}
12011200
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__119__thread_local_dataEv'}
12021201
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__119declare_no_pointersEPcm'}
12031202
{'type': 'OBJECT', 'is_defined': True, 'name': '__ZNSt3__119piecewise_constructE', 'size': 0}
12041203
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__120__get_collation_nameEPKc'}
12051204
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__120__throw_system_errorEiPKc'}
1206-
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__121__thread_specific_ptrINS_15__thread_structEE16__at_thread_exitEPv'}
12071205
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__121__throw_runtime_errorEPKc'}
12081206
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__121__undeclare_reachableEPv'}
12091207
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__121recursive_timed_mutex4lockEv'}

libcxx/lib/abi/x86_64-apple-darwin.v2.abilist

-2
Original file line numberDiff line numberDiff line change
@@ -1119,13 +1119,11 @@
11191119
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__219__shared_weak_countD0Ev'}
11201120
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__219__shared_weak_countD1Ev'}
11211121
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__219__shared_weak_countD2Ev'}
1122-
{'type': 'OBJECT', 'is_defined': True, 'name': '__ZNSt3__219__start_std_streamsE', 'size': 0}
11231122
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__219__thread_local_dataEv'}
11241123
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__219declare_no_pointersEPcm'}
11251124
{'type': 'OBJECT', 'is_defined': True, 'name': '__ZNSt3__219piecewise_constructE', 'size': 0}
11261125
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__220__get_collation_nameEPKc'}
11271126
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__220__throw_system_errorEiPKc'}
1128-
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__221__thread_specific_ptrINS_15__thread_structEE16__at_thread_exitEPv'}
11291127
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__221__throw_runtime_errorEPKc'}
11301128
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__221__undeclare_reachableEPv'}
11311129
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__221recursive_timed_mutex4lockEv'}

libcxx/lib/abi/x86_64-unknown-linux-gnu.v1.abilist

-2
Original file line numberDiff line numberDiff line change
@@ -1098,13 +1098,11 @@
10981098
{'name': '_ZNSt3__119__shared_weak_countD0Ev', 'is_defined': True, 'type': 'FUNC'}
10991099
{'name': '_ZNSt3__119__shared_weak_countD1Ev', 'is_defined': True, 'type': 'FUNC'}
11001100
{'name': '_ZNSt3__119__shared_weak_countD2Ev', 'is_defined': True, 'type': 'FUNC'}
1101-
{'name': '_ZNSt3__119__start_std_streamsE', 'is_defined': True, 'type': 'OBJECT', 'size': 1}
11021101
{'name': '_ZNSt3__119__thread_local_dataEv', 'is_defined': True, 'type': 'FUNC'}
11031102
{'name': '_ZNSt3__119declare_no_pointersEPcm', 'is_defined': True, 'type': 'FUNC'}
11041103
{'name': '_ZNSt3__119piecewise_constructE', 'is_defined': True, 'type': 'OBJECT', 'size': 1}
11051104
{'name': '_ZNSt3__120__get_collation_nameEPKc', 'is_defined': True, 'type': 'FUNC'}
11061105
{'name': '_ZNSt3__120__throw_system_errorEiPKc', 'is_defined': True, 'type': 'FUNC'}
1107-
{'name': '_ZNSt3__121__thread_specific_ptrINS_15__thread_structEE16__at_thread_exitEPv', 'is_defined': True, 'type': 'FUNC'}
11081106
{'name': '_ZNSt3__121__throw_runtime_errorEPKc', 'is_defined': True, 'type': 'FUNC'}
11091107
{'name': '_ZNSt3__121__undeclare_reachableEPv', 'is_defined': True, 'type': 'FUNC'}
11101108
{'name': '_ZNSt3__121recursive_timed_mutex4lockEv', 'is_defined': True, 'type': 'FUNC'}

libcxx/src/iostream.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ __asm__("?wclog@" _LIBCPP_NAMESPACE_STR "@std@@3V?$basic_ostream@_WU?$char_trait
7777
#endif
7878
;
7979

80-
ios_base::Init __start_std_streams;
80+
_LIBCPP_HIDDEN ios_base::Init __start_std_streams;
8181

8282
ios_base::Init::Init()
8383
{

0 commit comments

Comments
 (0)