Skip to content

Commit

Permalink
Bug #25835560: SET DEFAULT SYMBOL VISIBILITY TO HIDDEN
Browse files Browse the repository at this point in the history
Hide all symbols by default and export only the ones that are supposed
to actually be visible. This primarily affects mysqld, but also plugins
and statically linked libraries of various sorts now stop polluting the
server's namespace. In addition, we export 297 “legacy” functions and
classes that were already in use by existing plugins; this is not meant
as an endorsement of the practice, and is likely to break in the future,
but fixing them all is a longer procedure that will take time.

A stripped mysqld binary (RelWithDebInfo) on Linux goes from 38 to 34 MB,
exporting 950 instead of 20854 symbols.

Windows builds can now skip the WScript step that goes through every
symbol and exports it manually through a .def file. On a 16-core Xeon
build server (vale31), this reduces the build time of a full debug
build by about 40 seconds (from 9 minutes 25 seconds to 8 minutes
45 seconds). The difference for an incremental build, ie., just touching
sql/main.cc and rebuilding, is even bigger; it goes from 1m42s to
just under 13 seconds, as the incrementality is significantly increased.

Change-Id: I2d1c39b6822502139e3286c7473db81c876b7bbc
  • Loading branch information
Steinar H. Gunderson committed Apr 7, 2017
1 parent e4103ba commit bc4eff8
Show file tree
Hide file tree
Showing 226 changed files with 1,686 additions and 1,529 deletions.
9 changes: 5 additions & 4 deletions cmake/build_configurations/compiler_options.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ IF(UNIX)

# Default GCC flags
IF(CMAKE_COMPILER_IS_GNUCC)
SET(COMMON_C_FLAGS "-g -fno-omit-frame-pointer")
SET(COMMON_C_FLAGS "-g -fno-omit-frame-pointer -fvisibility=hidden")
# Disable inline optimizations for valgrind testing to avoid false positives
IF(WITH_VALGRIND)
SET(COMMON_C_FLAGS "-fno-inline ${COMMON_C_FLAGS}")
Expand All @@ -46,7 +46,7 @@ IF(UNIX)
SET(CMAKE_C_FLAGS_RELWITHDEBINFO "-O3 ${COMMON_C_FLAGS}")
ENDIF()
IF(CMAKE_COMPILER_IS_GNUCXX)
SET(COMMON_CXX_FLAGS "-g -fno-omit-frame-pointer -std=c++11")
SET(COMMON_CXX_FLAGS "-g -fno-omit-frame-pointer -std=c++11 -fvisibility=hidden")
# Disable inline optimizations for valgrind testing to avoid false positives
IF(WITH_VALGRIND)
SET(COMMON_CXX_FLAGS "-fno-inline ${COMMON_CXX_FLAGS}")
Expand All @@ -66,15 +66,15 @@ IF(UNIX)

# Default Clang flags
IF(CMAKE_C_COMPILER_ID MATCHES "Clang")
SET(COMMON_C_FLAGS "-g -fno-omit-frame-pointer")
SET(COMMON_C_FLAGS "-g -fno-omit-frame-pointer -fvisibility=hidden")
IF(NOT DISABLE_SHARED)
SET(COMMON_C_FLAGS "-fPIC ${COMMON_C_FLAGS}")
ENDIF()
SET(CMAKE_C_FLAGS_DEBUG "${COMMON_C_FLAGS}")
SET(CMAKE_C_FLAGS_RELWITHDEBINFO "-O3 ${COMMON_C_FLAGS}")
ENDIF()
IF(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
SET(COMMON_CXX_FLAGS "-g -fno-omit-frame-pointer -std=c++11")
SET(COMMON_CXX_FLAGS "-g -fno-omit-frame-pointer -std=c++11 -fvisibility=hidden")
IF(NOT DISABLE_SHARED)
SET(COMMON_CXX_FLAGS "-fPIC ${COMMON_CXX_FLAGS}")
ENDIF()
Expand Down Expand Up @@ -109,6 +109,7 @@ IF(UNIX)
SET(SUNPRO_FLAGS "-xdebuginfo=no%decl")
SET(SUNPRO_FLAGS "${SUNPRO_FLAGS} -xbuiltin=%all")
SET(SUNPRO_FLAGS "${SUNPRO_FLAGS} -xlibmil")
SET(SUNPRO_FLAGS "${SUNPRO_FLAGS} -xldscope=symbolic")
IF(NOT DISABLE_SHARED)
SET(SUNPRO_FLAGS "${SUNPRO_FLAGS} -KPIC")
ENDIF()
Expand Down
8 changes: 8 additions & 0 deletions cmake/os/Windows.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,14 @@ IF(MSVC)
#TODO: update the code and remove the disabled warnings
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /wd4800 /wd4805 /wd4996")
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4800 /wd4805 /wd4996 /we4099")

# These are warnings about exported entry points not being complete,
# e.g. exporting "Baz *Foo::bar();" without Baz being exported.
# As most of these are for legacy export (MYSQL_PLUGIN_LEGACY_API),
# we deliberately keep the exported interface minimal, and thus,
# we suppress these warnings.
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /wd4251 /wd4275")
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4251 /wd4275")
ENDIF()

# Always link with socket library
Expand Down
26 changes: 17 additions & 9 deletions cmake/plugin.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -120,8 +120,16 @@ MACRO(MYSQL_ADD_PLUGIN)
# Build either static library or module
IF (WITH_${plugin} AND NOT ARG_MODULE_ONLY)
ADD_CONVENIENCE_LIBRARY(${target} STATIC ${SOURCES})

# Plugins are taken to be part of the server (so MYSQL_SERVER).
# However, also make sure that when building the plugin statically, we
# don't try to export any symbols pulled in from header files.
# This would be harmless in the server, but some of the statically linked
# plugins (like the performance schema plugin) are also linked into unit
# tests, which don't necessarily link in all the dependencies of such
# symbols.
SET_TARGET_PROPERTIES(${target}
PROPERTIES COMPILE_DEFINITIONS "MYSQL_SERVER")
PROPERTIES COMPILE_DEFINITIONS "MYSQL_SERVER;MYSQL_NO_PLUGIN_EXPORT")
SET_TARGET_PROPERTIES(${target}
PROPERTIES COMPILE_FLAGS ${SSL_DEFINES})

Expand All @@ -132,9 +140,9 @@ MACRO(MYSQL_ADD_PLUGIN)
OUTPUT_NAME ${ARG_STATIC_OUTPUT_NAME})
ENDIF()

# Update mysqld dependencies
SET (MYSQLD_STATIC_PLUGIN_LIBS ${MYSQLD_STATIC_PLUGIN_LIBS}
${target} ${ARG_LINK_LIBRARIES} CACHE INTERNAL "" FORCE)
# Link the plugin into mysqld.
SET (MYSQLD_STATIC_PLUGIN_LIBS ${MYSQLD_STATIC_PLUGIN_LIBS}
${target} CACHE INTERNAL "" FORCE)

IF(ARG_MANDATORY)
SET(${with_var} ON CACHE INTERNAL "Link ${plugin} statically to the server"
Expand Down Expand Up @@ -178,19 +186,19 @@ MACRO(MYSQL_ADD_PLUGIN)
# unresolved symbols. Others are less strict and allow unresolved symbols
# in shared libraries. On Linux for example, CMake does not even add
# executable to the linker command line (it would result into link error).
# Thus we skip TARGET_LINK_LIBRARIES on Linux, as it would only generate
# an additional dependency.
# Use MYSQL_PLUGIN_IMPORT for static data symbols to be exported.
# Use MYSQL_PLUGIN_API for symbols to be exported/imported.
IF(WIN32 OR APPLE)
TARGET_LINK_LIBRARIES (${target} mysqld ${ARG_LINK_LIBRARIES})
ELSE()
TARGET_LINK_LIBRARIES (${target} ${ARG_LINK_LIBRARIES})
ENDIF()
ADD_DEPENDENCIES(${target} GenError ${ARG_DEPENDENCIES})

IF(NOT ARG_MODULE_ONLY)
IF(NOT ARG_MODULE_ONLY)
# set cached variable, e.g with checkbox in GUI
SET(${with_var} OFF CACHE BOOL "Link ${plugin} statically to the server"
FORCE)
ENDIF()
ENDIF()
SET_TARGET_PROPERTIES(${target} PROPERTIES
OUTPUT_NAME "${ARG_MODULE_OUTPUT_NAME}")

Expand Down
2 changes: 1 addition & 1 deletion components/mysql_server/dynamic_loader_path_filter.cc
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02111-1307 USA */

typedef std::string my_string;

extern "C" MYSQL_PLUGIN_IMPORT CHARSET_INFO *system_charset_info;
extern "C" MYSQL_PLUGIN_API CHARSET_INFO *system_charset_info;
bool check_string_char_length(const LEX_CSTRING &str, const char *err_msg,
size_t max_char_length, const CHARSET_INFO *cs,
bool no_error);
Expand Down
3 changes: 0 additions & 3 deletions configure.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -519,9 +519,6 @@ ENDIF()

SET(CMAKE_EXTRA_INCLUDE_FILES)

# Support for tagging symbols with __attribute__((visibility("hidden")))
MY_CHECK_CXX_COMPILER_FLAG("-fvisibility=hidden" HAVE_VISIBILITY_HIDDEN)

#
# Code tests
#
Expand Down
47 changes: 25 additions & 22 deletions dbug/dbug.c
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@
#include "my_inttypes.h"
#include "my_io.h"
#include "my_macros.h"
#include "my_sharedlib.h"
#include "my_sys.h"
#include "my_thread_local.h"
#include "mysql/service_my_snprintf.h"
Expand Down Expand Up @@ -402,7 +403,7 @@ static void unlock_stack(CODE_STATE *cs)
*
*/

void _db_process_(const char *name)
void MYSQL_PLUGIN_API _db_process_(const char *name)
{
CODE_STATE *cs;

Expand Down Expand Up @@ -840,7 +841,7 @@ static void FixTraceFlags(uint old_fflags, CODE_STATE *cs)
*
*/

void _db_set_(const char *control)
MYSQL_PLUGIN_API void _db_set_(const char *control)
{
CODE_STATE *cs;
uint old_fflags;
Expand Down Expand Up @@ -879,7 +880,7 @@ void _db_set_(const char *control)
*
*/

void _db_push_(const char *control)
MYSQL_PLUGIN_API void _db_push_(const char *control)
{
CODE_STATE *cs;
uint old_fflags;
Expand All @@ -904,7 +905,7 @@ void _db_push_(const char *control)
Returns TRUE if session-local settings have been set.
*/

int _db_is_pushed_()
MYSQL_PLUGIN_API int _db_is_pushed_()
{
CODE_STATE *cs= NULL;
get_code_state_or_return FALSE;
Expand All @@ -926,7 +927,7 @@ int _db_is_pushed_()
*
*/

void _db_set_init_(const char *control)
MYSQL_PLUGIN_API void _db_set_init_(const char *control)
{
CODE_STATE tmp_cs;
memset(&tmp_cs, 0, sizeof(tmp_cs));
Expand All @@ -952,7 +953,7 @@ void _db_set_init_(const char *control)
*
*/

void _db_pop_()
MYSQL_PLUGIN_API void _db_pop_()
{
struct settings *discard;
uint old_fflags;
Expand Down Expand Up @@ -1068,7 +1069,7 @@ void _db_pop_()
} \
} while (0)

int _db_explain_ (CODE_STATE *cs, char *buf, size_t len)
MYSQL_PLUGIN_API int _db_explain_ (CODE_STATE *cs, char *buf, size_t len)
{
char *start=buf, *end=buf+len-4;

Expand Down Expand Up @@ -1172,8 +1173,9 @@ int _db_explain_init_(char *buf, size_t len)
*
*/

void _db_enter_(const char *_func_, const char *_file_,
uint _line_, struct _db_stack_frame_ *_stack_frame_)
MYSQL_PLUGIN_API void _db_enter_(
const char *_func_, const char *_file_,
uint _line_, struct _db_stack_frame_ *_stack_frame_)
{
int save_errno;
CODE_STATE *cs;
Expand Down Expand Up @@ -1242,7 +1244,8 @@ void _db_enter_(const char *_func_, const char *_file_,
*
*/

void _db_return_(uint _line_, struct _db_stack_frame_ *_stack_frame_)
MYSQL_PLUGIN_API void _db_return_(
uint _line_, struct _db_stack_frame_ *_stack_frame_)
{
int save_errno=errno;
uint _slevel_= _stack_frame_->level & ~TRACE_ON;
Expand Down Expand Up @@ -1305,7 +1308,7 @@ void _db_return_(uint _line_, struct _db_stack_frame_ *_stack_frame_)
*
*/

void _db_pargs_(uint _line_, const char *keyword)
MYSQL_PLUGIN_API void _db_pargs_(uint _line_, const char *keyword)
{
CODE_STATE *cs;
get_code_state_or_return;
Expand All @@ -1331,7 +1334,7 @@ void _db_pargs_(uint _line_, const char *keyword)
* function evaluates to 1.
*/

int _db_enabled_()
MYSQL_PLUGIN_API int _db_enabled_()
{
CODE_STATE *cs;

Expand Down Expand Up @@ -1370,7 +1373,7 @@ int _db_enabled_()

#include <stdarg.h>

void _db_doprnt_(const char *format,...)
MYSQL_PLUGIN_API void _db_doprnt_(const char *format,...)
{
va_list args;
CODE_STATE *cs;
Expand Down Expand Up @@ -1433,7 +1436,7 @@ static void DbugVfprintf(FILE *stream, const char* format, va_list args)
* Is used to examine corrupted memory or arrays.
*/

void _db_dump_(uint _line_, const char *keyword,
MYSQL_PLUGIN_API void _db_dump_(uint _line_, const char *keyword,
const unsigned char *memory, size_t length)
{
int pos;
Expand Down Expand Up @@ -1764,7 +1767,7 @@ static void FreeState(CODE_STATE *cs, struct settings *state, int free_state)
* To be called at the very end of the program.
*
*/
void _db_end_()
MYSQL_PLUGIN_API void _db_end_()
{
struct settings *discard;
static struct settings tmp;
Expand Down Expand Up @@ -1865,7 +1868,7 @@ FILE *_db_fp_(void)
*
*/

int _db_keyword_(CODE_STATE *cs, const char *keyword, int strict)
MYSQL_PLUGIN_API int _db_keyword_(CODE_STATE *cs, const char *keyword, int strict)
{
bool result;
get_code_state_if_not_set_or_return FALSE;
Expand Down Expand Up @@ -2283,7 +2286,7 @@ static void DbugFlush(CODE_STATE *cs)

/* For debugging */

void _db_flush_()
MYSQL_PLUGIN_API void _db_flush_()
{
CODE_STATE *cs= NULL;
get_code_state_or_return;
Expand All @@ -2297,7 +2300,7 @@ void _db_flush_()
extern void __gcov_flush();
#endif

void _db_flush_gcov_()
MYSQL_PLUGIN_API void _db_flush_gcov_()
{
#ifdef HAVE_GCOV
// Gcov will assert() if we try to flush in parallel.
Expand All @@ -2307,7 +2310,7 @@ void _db_flush_gcov_()
#endif
}

void _db_suicide_()
MYSQL_PLUGIN_API void _db_suicide_()
{
int retval;
sigset_t new_mask;
Expand All @@ -2332,23 +2335,23 @@ void _db_suicide_()
#endif /* ! _WIN32 */


void _db_lock_file_()
MYSQL_PLUGIN_API void _db_lock_file_()
{
CODE_STATE *cs;
get_code_state_or_return;
native_mutex_lock(&THR_LOCK_dbug);
cs->locked=1;
}

void _db_unlock_file_()
MYSQL_PLUGIN_API void _db_unlock_file_()
{
CODE_STATE *cs;
get_code_state_or_return;
cs->locked=0;
native_mutex_unlock(&THR_LOCK_dbug);
}

const char* _db_get_func_(void)
MYSQL_PLUGIN_API const char* _db_get_func_(void)
{
CODE_STATE *cs;
get_code_state_or_return NULL;
Expand Down
12 changes: 7 additions & 5 deletions extra/regex/my_regex.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
/* ========= begin header generated by ./mkh ========= */

#include "m_ctype.h"
#include "my_sharedlib.h"

#ifdef __cplusplus
extern "C" {
Expand Down Expand Up @@ -31,8 +32,8 @@ typedef struct {

/* === regcomp.c === */
typedef int (*my_regex_stack_check_t)(int);
extern int my_regcomp(my_regex_t *, const char *, int,
const CHARSET_INFO *charset);
extern MYSQL_PLUGIN_LEGACY_API int my_regcomp(
my_regex_t *, const char *, int, const CHARSET_INFO *charset);
#define MY_REG_BASIC 0000
#define MY_REG_EXTENDED 0001
#define MY_REG_ICASE 0002
Expand Down Expand Up @@ -66,7 +67,8 @@ extern size_t my_regerror(int, const my_regex_t *, char *, size_t);


/* === regexec.c === */
extern int my_regexec(const my_regex_t *, const char *, size_t, my_regmatch_t [], int);
extern MYSQL_PLUGIN_LEGACY_API int my_regexec(
const my_regex_t *, const char *, size_t, my_regmatch_t [], int);
#define MY_REG_NOTBOL 00001
#define MY_REG_NOTEOL 00002
#define MY_REG_STARTEND 00004
Expand All @@ -76,14 +78,14 @@ extern int my_regexec(const my_regex_t *, const char *, size_t, my_regmatch_t []


/* === regfree.c === */
extern void my_regfree(my_regex_t *);
extern MYSQL_PLUGIN_LEGACY_API void my_regfree(my_regex_t *);

/* === reginit.c === */

/* Should be called for multithread progs */
extern void my_regex_init(const CHARSET_INFO *cs,
my_regex_stack_check_t func);
extern void my_regex_end(void); /* If one wants a clean end */
extern MYSQL_PLUGIN_LEGACY_API void my_regex_end(void); /* If one wants a clean end */

#ifdef __cplusplus
}
Expand Down
2 changes: 1 addition & 1 deletion extra/regex/regcomp.c
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ static int never = 0; /* for use in asserts; shuts lint up */
= #define MY_REG_PEND 0040
= #define MY_REG_DUMP 0200
*/
int /* 0 success, otherwise MY_REG_something */
MYSQL_PLUGIN_LEGACY_API int /* 0 success, otherwise MY_REG_something */
my_regcomp(preg, pattern, cflags, charset)
my_regex_t *preg;
const char *pattern;
Expand Down
2 changes: 1 addition & 1 deletion extra/regex/regexec.c
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@
@return 0 success, MY_REG_NOMATCH failure
*/
int
MYSQL_PLUGIN_LEGACY_API int
my_regexec(preg, str, nmatch, pmatch, eflags)
const my_regex_t *preg;
const char *str;
Expand Down
Loading

0 comments on commit bc4eff8

Please sign in to comment.