[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
This commit is contained in:
Louis Dionne 2018-10-25 12:13:43 +00:00
parent 77c26aebda
commit 9b3222f613
15 changed files with 75 additions and 32 deletions

View File

@ -22,11 +22,11 @@ Visibility Macros
Mark a symbol as being exported by the libc++ library. This attribute must
be applied to the declaration of all functions exported by the libc++ dylib.
**_LIBCPP_EXTERN_VIS**
**_LIBCPP_EXPORTED_FROM_ABI**
Mark a symbol as being exported by the libc++ library. This attribute may
only be applied to objects defined in the libc++ library. On Windows this
macro applies `dllimport`/`dllexport` to the symbol. On all other platforms
this macro has no effect.
only be applied to objects defined in the libc++ runtime library. On Windows,
this macro applies `dllimport`/`dllexport` to the symbol, and on other
platforms it gives the symbol default visibility.
**_LIBCPP_OVERRIDABLE_FUNC_VIS**
Mark a symbol as being exported by the libc++ library, but allow it to be

View File

@ -675,21 +675,23 @@ _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD
# define _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS
# define _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS
# define _LIBCPP_OVERRIDABLE_FUNC_VIS
# define _LIBCPP_EXPORTED_FROM_ABI
#elif defined(_LIBCPP_BUILDING_LIBRARY)
# define _LIBCPP_DLL_VIS __declspec(dllexport)
# define _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS
# define _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS _LIBCPP_DLL_VIS
# define _LIBCPP_OVERRIDABLE_FUNC_VIS _LIBCPP_DLL_VIS
# define _LIBCPP_EXPORTED_FROM_ABI __declspec(dllexport)
#else
# define _LIBCPP_DLL_VIS __declspec(dllimport)
# define _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS _LIBCPP_DLL_VIS
# define _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS
# define _LIBCPP_OVERRIDABLE_FUNC_VIS
# define _LIBCPP_EXPORTED_FROM_ABI __declspec(dllimport)
#endif
#define _LIBCPP_TYPE_VIS _LIBCPP_DLL_VIS
#define _LIBCPP_FUNC_VIS _LIBCPP_DLL_VIS
#define _LIBCPP_EXTERN_VIS _LIBCPP_DLL_VIS
#define _LIBCPP_EXCEPTION_ABI _LIBCPP_DLL_VIS
#define _LIBCPP_HIDDEN
#define _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
@ -743,8 +745,8 @@ _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD
# endif
#endif
#ifndef _LIBCPP_EXTERN_VIS
#define _LIBCPP_EXTERN_VIS
#ifndef _LIBCPP_EXPORTED_FROM_ABI
# define _LIBCPP_EXPORTED_FROM_ABI __attribute__((__visibility__("default")))
#endif
#ifndef _LIBCPP_OVERRIDABLE_FUNC_VIS

View File

@ -74,7 +74,7 @@ typedef void(*__libcpp_debug_function_type)(__libcpp_debug_info const&);
/// __libcpp_debug_function - The handler function called when a _LIBCPP_ASSERT
/// fails.
extern _LIBCPP_EXTERN_VIS __libcpp_debug_function_type __libcpp_debug_function;
extern _LIBCPP_EXPORTED_FROM_ABI __libcpp_debug_function_type __libcpp_debug_function;
/// __libcpp_abort_debug_function - A debug handler that aborts when called.
_LIBCPP_NORETURN _LIBCPP_FUNC_VIS

View File

@ -562,7 +562,7 @@ struct __is_transparent<_Tp, _Up,
struct _LIBCPP_TEMPLATE_VIS allocator_arg_t { };
#if defined(_LIBCPP_CXX03_LANG) || defined(_LIBCPP_BUILDING_LIBRARY)
extern const allocator_arg_t allocator_arg;
extern _LIBCPP_EXPORTED_FROM_ABI const allocator_arg_t allocator_arg;
#else
/* _LIBCPP_INLINE_VAR */ constexpr allocator_arg_t allocator_arg = allocator_arg_t();
#endif

View File

@ -1255,13 +1255,13 @@ struct __narrow_to_utf8<8>
};
template <>
struct __narrow_to_utf8<16>
struct _LIBCPP_TEMPLATE_VIS __narrow_to_utf8<16>
: public codecvt<char16_t, char, mbstate_t>
{
_LIBCPP_INLINE_VISIBILITY
__narrow_to_utf8() : codecvt<char16_t, char, mbstate_t>(1) {}
~__narrow_to_utf8();
_LIBCPP_EXPORTED_FROM_ABI ~__narrow_to_utf8();
template <class _OutputIterator, class _CharT>
_LIBCPP_INLINE_VISIBILITY
@ -1289,13 +1289,13 @@ struct __narrow_to_utf8<16>
};
template <>
struct __narrow_to_utf8<32>
struct _LIBCPP_TEMPLATE_VIS __narrow_to_utf8<32>
: public codecvt<char32_t, char, mbstate_t>
{
_LIBCPP_INLINE_VISIBILITY
__narrow_to_utf8() : codecvt<char32_t, char, mbstate_t>(1) {}
~__narrow_to_utf8();
_LIBCPP_EXPORTED_FROM_ABI ~__narrow_to_utf8();
template <class _OutputIterator, class _CharT>
_LIBCPP_INLINE_VISIBILITY
@ -1345,13 +1345,13 @@ struct __widen_from_utf8<8>
};
template <>
struct __widen_from_utf8<16>
struct _LIBCPP_TEMPLATE_VIS __widen_from_utf8<16>
: public codecvt<char16_t, char, mbstate_t>
{
_LIBCPP_INLINE_VISIBILITY
__widen_from_utf8() : codecvt<char16_t, char, mbstate_t>(1) {}
~__widen_from_utf8();
_LIBCPP_EXPORTED_FROM_ABI ~__widen_from_utf8();
template <class _OutputIterator>
_LIBCPP_INLINE_VISIBILITY
@ -1379,13 +1379,13 @@ struct __widen_from_utf8<16>
};
template <>
struct __widen_from_utf8<32>
struct _LIBCPP_TEMPLATE_VIS __widen_from_utf8<32>
: public codecvt<char32_t, char, mbstate_t>
{
_LIBCPP_INLINE_VISIBILITY
__widen_from_utf8() : codecvt<char32_t, char, mbstate_t>(1) {}
~__widen_from_utf8();
_LIBCPP_EXPORTED_FROM_ABI ~__widen_from_utf8();
template <class _OutputIterator>
_LIBCPP_INLINE_VISIBILITY

View File

@ -76,9 +76,9 @@ struct _LIBCPP_TYPE_VIS adopt_lock_t {};
#if defined(_LIBCPP_CXX03_LANG) || defined(_LIBCPP_BUILDING_LIBRARY)
extern const defer_lock_t defer_lock;
extern const try_to_lock_t try_to_lock;
extern const adopt_lock_t adopt_lock;
extern _LIBCPP_EXPORTED_FROM_ABI const defer_lock_t defer_lock;
extern _LIBCPP_EXPORTED_FROM_ABI const try_to_lock_t try_to_lock;
extern _LIBCPP_EXPORTED_FROM_ABI const adopt_lock_t adopt_lock;
#else

View File

@ -89,6 +89,11 @@ namespace std {
_LIBCPP_BEGIN_NAMESPACE_STD
namespace __itoa {
_LIBCPP_FUNC_VIS char* __u64toa(uint64_t __value, char* __buffer);
_LIBCPP_FUNC_VIS char* __u32toa(uint32_t __value, char* __buffer);
}
#if _LIBCPP_STD_VER > 11
enum class _LIBCPP_ENUM_VIS chars_format
@ -147,9 +152,6 @@ static constexpr uint32_t __pow10_32[] = {
UINT32_C(1000000000),
};
_LIBCPP_FUNC_VIS char* __u64toa(uint64_t __value, char* __buffer);
_LIBCPP_FUNC_VIS char* __u32toa(uint32_t __value, char* __buffer);
template <typename _Tp, typename = void>
struct _LIBCPP_HIDDEN __traits_base
{

View File

@ -2408,6 +2408,23 @@ private:
string_type __analyze(char __fmt, const ctype<_CharT>&);
};
#define _LIBCPP_TIME_GET_STORAGE_EXPLICIT_INSTANTIATION(_CharT) \
template <> _LIBCPP_FUNC_VIS time_base::dateorder __time_get_storage<_CharT>::__do_date_order() const; \
template <> _LIBCPP_FUNC_VIS __time_get_storage<_CharT>::__time_get_storage(const char*); \
template <> _LIBCPP_FUNC_VIS __time_get_storage<_CharT>::__time_get_storage(const string&); \
template <> _LIBCPP_FUNC_VIS void __time_get_storage<_CharT>::init(const ctype<_CharT>&); \
template <> _LIBCPP_FUNC_VIS __time_get_storage<_CharT>::string_type __time_get_storage<_CharT>::__analyze(char, const ctype<_CharT>&); \
extern template _LIBCPP_FUNC_VIS time_base::dateorder __time_get_storage<_CharT>::__do_date_order() const; \
extern template _LIBCPP_FUNC_VIS __time_get_storage<_CharT>::__time_get_storage(const char*); \
extern template _LIBCPP_FUNC_VIS __time_get_storage<_CharT>::__time_get_storage(const string&); \
extern template _LIBCPP_FUNC_VIS void __time_get_storage<_CharT>::init(const ctype<_CharT>&); \
extern template _LIBCPP_FUNC_VIS __time_get_storage<_CharT>::string_type __time_get_storage<_CharT>::__analyze(char, const ctype<_CharT>&); \
/**/
_LIBCPP_TIME_GET_STORAGE_EXPLICIT_INSTANTIATION(char)
_LIBCPP_TIME_GET_STORAGE_EXPLICIT_INSTANTIATION(wchar_t)
#undef _LIBCPP_TIME_GET_STORAGE_EXPLICIT_INSTANTIATION
template <class _CharT, class _InputIterator = istreambuf_iterator<_CharT> >
class _LIBCPP_TEMPLATE_VIS time_get_byname
: public time_get<_CharT, _InputIterator>,

View File

@ -151,7 +151,7 @@ class __thread_specific_ptr
__thread_specific_ptr(const __thread_specific_ptr&);
__thread_specific_ptr& operator=(const __thread_specific_ptr&);
static void _LIBCPP_TLS_DESTRUCTOR_CC __at_thread_exit(void*);
_LIBCPP_HIDDEN static void _LIBCPP_TLS_DESTRUCTOR_CC __at_thread_exit(void*);
public:
typedef _Tp* pointer;

View File

@ -297,7 +297,7 @@ template <class _Tp> void as_const(const _Tp&&) = delete;
struct _LIBCPP_TEMPLATE_VIS piecewise_construct_t { };
#if defined(_LIBCPP_CXX03_LANG) || defined(_LIBCPP_BUILDING_LIBRARY)
extern const piecewise_construct_t piecewise_construct;// = piecewise_construct_t();
extern _LIBCPP_EXPORTED_FROM_ABI const piecewise_construct_t piecewise_construct;// = piecewise_construct_t();
#else
/* _LIBCPP_INLINE_VAR */ constexpr piecewise_construct_t piecewise_construct = piecewise_construct_t();
#endif

View File

@ -16,6 +16,34 @@ New entries should be added directly below the "Version" header.
Version 7.0
-----------
* rXXXXX - Making libc++ build under -fvisibility=hidden
The change marks __thread_specific_ptr<__thread_struct>::__at_thread_exit(void*)
with hidden visibility. This removes a symbol from the shared libraries,
however this is not an ABI break because it's impossible for programs linking
against libc++.dylib to actually depend on that symbol. The reason is that
the symbol is exported from the shared library through an implicit
instantiation present in the dylib itself only. Furthermore, if a user's
dylib was implicitly instantiating __thread_specific_ptr<T>::__at_thread_exit
(because it's defined in the headers), marking that symbol as hidden would
not be an ABI break for them because none of their users could actually be
using the symbol in their dylib (because it's an implicit instantiation).
This change also marks __start_std_streams as hidden -- this variable is
only required to initialize the streams, and nobody should depend on it
from outside the dylib.
x86_64-linux-gnu
----------------
Symbol removed: _ZNSt3__121__thread_specific_ptrINS_15__thread_structEE16__at_thread_exitEPv
Symbol removed: _ZNSt3__119__start_std_streamsE
x86_64-apple-darwin16.0
-----------------------
Symbol removed: __ZNSt3__221__thread_specific_ptrINS_15__thread_structEE16__at_thread_exitEPv
Symbol removed: __ZNSt3__119__start_std_streamsE
* r338479 - Elementary string conversions for integral types
The change emits __u64toa and __u32toa under std::__1::__itoa.

View File

@ -1197,13 +1197,11 @@
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__119__shared_weak_countD0Ev'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__119__shared_weak_countD1Ev'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__119__shared_weak_countD2Ev'}
{'type': 'OBJECT', 'is_defined': True, 'name': '__ZNSt3__119__start_std_streamsE', 'size': 0}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__119__thread_local_dataEv'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__119declare_no_pointersEPcm'}
{'type': 'OBJECT', 'is_defined': True, 'name': '__ZNSt3__119piecewise_constructE', 'size': 0}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__120__get_collation_nameEPKc'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__120__throw_system_errorEiPKc'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__121__thread_specific_ptrINS_15__thread_structEE16__at_thread_exitEPv'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__121__throw_runtime_errorEPKc'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__121__undeclare_reachableEPv'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__121recursive_timed_mutex4lockEv'}

View File

@ -1119,13 +1119,11 @@
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__219__shared_weak_countD0Ev'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__219__shared_weak_countD1Ev'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__219__shared_weak_countD2Ev'}
{'type': 'OBJECT', 'is_defined': True, 'name': '__ZNSt3__219__start_std_streamsE', 'size': 0}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__219__thread_local_dataEv'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__219declare_no_pointersEPcm'}
{'type': 'OBJECT', 'is_defined': True, 'name': '__ZNSt3__219piecewise_constructE', 'size': 0}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__220__get_collation_nameEPKc'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__220__throw_system_errorEiPKc'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__221__thread_specific_ptrINS_15__thread_structEE16__at_thread_exitEPv'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__221__throw_runtime_errorEPKc'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__221__undeclare_reachableEPv'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__221recursive_timed_mutex4lockEv'}

View File

@ -1098,13 +1098,11 @@
{'name': '_ZNSt3__119__shared_weak_countD0Ev', 'is_defined': True, 'type': 'FUNC'}
{'name': '_ZNSt3__119__shared_weak_countD1Ev', 'is_defined': True, 'type': 'FUNC'}
{'name': '_ZNSt3__119__shared_weak_countD2Ev', 'is_defined': True, 'type': 'FUNC'}
{'name': '_ZNSt3__119__start_std_streamsE', 'is_defined': True, 'type': 'OBJECT', 'size': 1}
{'name': '_ZNSt3__119__thread_local_dataEv', 'is_defined': True, 'type': 'FUNC'}
{'name': '_ZNSt3__119declare_no_pointersEPcm', 'is_defined': True, 'type': 'FUNC'}
{'name': '_ZNSt3__119piecewise_constructE', 'is_defined': True, 'type': 'OBJECT', 'size': 1}
{'name': '_ZNSt3__120__get_collation_nameEPKc', 'is_defined': True, 'type': 'FUNC'}
{'name': '_ZNSt3__120__throw_system_errorEiPKc', 'is_defined': True, 'type': 'FUNC'}
{'name': '_ZNSt3__121__thread_specific_ptrINS_15__thread_structEE16__at_thread_exitEPv', 'is_defined': True, 'type': 'FUNC'}
{'name': '_ZNSt3__121__throw_runtime_errorEPKc', 'is_defined': True, 'type': 'FUNC'}
{'name': '_ZNSt3__121__undeclare_reachableEPv', 'is_defined': True, 'type': 'FUNC'}
{'name': '_ZNSt3__121recursive_timed_mutex4lockEv', 'is_defined': True, 'type': 'FUNC'}

View File

@ -77,7 +77,7 @@ __asm__("?wclog@" _LIBCPP_NAMESPACE_STR "@std@@3V?$basic_ostream@_WU?$char_trait
#endif
;
ios_base::Init __start_std_streams;
_LIBCPP_HIDDEN ios_base::Init __start_std_streams;
ios_base::Init::Init()
{