aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYang Tse <yangsita@gmail.com>2009-10-28 19:45:26 +0000
committerYang Tse <yangsita@gmail.com>2009-10-28 19:45:26 +0000
commit0d9f14f5c17e4a3888dedbc8d568a55979fc05f0 (patch)
tree876a88fbc370edca79dbd0a0ea3eef31a550a6ad
parent9fced16efb544dc37fe54b8ed94622ed22dd55be (diff)
Initial step towards the ability to reduce c-ares exported symbols
based on the 'visibility' attribute for GNUC and __global for Sun compilers, taking also in account __declspec function decoration for Win32 and Symbian DLL's. Introducing configure options --enable-hidden-symbols and --disable-hidden-symbols following libcurl's naming.
-rw-r--r--ares/Makefile.am4
-rw-r--r--ares/ares.h262
-rw-r--r--ares/configure.ac23
-rw-r--r--ares/m4/cares-compilers.m496
-rw-r--r--ares/m4/cares-confopts.m463
5 files changed, 373 insertions, 75 deletions
diff --git a/ares/Makefile.am b/ares/Makefile.am
index 302ac9d8e..b1f364a13 100644
--- a/ares/Makefile.am
+++ b/ares/Makefile.am
@@ -91,9 +91,7 @@ if NO_UNDEFINED
UNDEF = -no-undefined
endif
-# EXPORT_SYMBOLS = -export-symbols-regex '^ares_[[:alnum:]].*'
-
-libcares_la_LDFLAGS = $(UNDEF) $(VER) $(EXPORT_SYMBOLS)
+libcares_la_LDFLAGS = $(UNDEF) $(VER)
# Makefile.inc provides the CSOURCES and HHEADERS defines
include Makefile.inc
diff --git a/ares/ares.h b/ares/ares.h
index d7c0ad293..c5ff24266 100644
--- a/ares/ares.h
+++ b/ares/ares.h
@@ -45,9 +45,9 @@
#endif
#if defined(WATT32)
- #include <netinet/in.h>
- #include <sys/socket.h>
- #include <tcp.h>
+# include <netinet/in.h>
+# include <sys/socket.h>
+# include <tcp.h>
#elif defined(WIN32)
# ifndef WIN32_LEAN_AND_MEAN
# define WIN32_LEAN_AND_MEAN
@@ -56,14 +56,36 @@
# include <winsock2.h>
# include <ws2tcpip.h>
#else
- #include <sys/socket.h>
- #include <netinet/in.h>
+# include <sys/socket.h>
+# include <netinet/in.h>
#endif
#ifdef __cplusplus
extern "C" {
#endif
+/*
+** c-ares external API function linkage decorations.
+*/
+
+#if !defined(CARES_STATICLIB) && \
+ (defined(WIN32) || defined(_WIN32) || defined(__SYMBIAN32__))
+ /* __declspec function decoration for Win32 and Symbian DLL's */
+# if defined(CARES_BUILDING_LIB)
+# define CARES_EXTERN __declspec(dllexport)
+# else
+# define CARES_EXTERN __declspec(dllimport)
+# endif
+#else
+ /* visibility function decoration for other cases */
+# ifdef CARES_HIDDEN_SYMBOLS
+# define CARES_EXTERN CARES_EXTERN_SYMBOL
+# else
+# define CARES_EXTERN
+# endif
+#endif
+
+
#define ARES_SUCCESS 0
/* Server error codes (ARES_ENODATA indicates no relevant answer) */
@@ -241,62 +263,143 @@ struct hostent;
struct timeval;
struct sockaddr;
struct ares_channeldata;
+
typedef struct ares_channeldata *ares_channel;
-typedef void (*ares_callback)(void *arg, int status, int timeouts,
- unsigned char *abuf, int alen);
-typedef void (*ares_host_callback)(void *arg, int status, int timeouts,
+
+typedef void (*ares_callback)(void *arg,
+ int status,
+ int timeouts,
+ unsigned char *abuf,
+ int alen);
+
+typedef void (*ares_host_callback)(void *arg,
+ int status,
+ int timeouts,
struct hostent *hostent);
-typedef void (*ares_nameinfo_callback)(void *arg, int status, int timeouts,
- char *node, char *service);
+
+typedef void (*ares_nameinfo_callback)(void *arg,
+ int status,
+ int timeouts,
+ char *node,
+ char *service);
+
typedef int (*ares_sock_create_callback)(ares_socket_t socket_fd,
- int type, void *data);
-
-int ares_library_init(int flags);
-void ares_library_cleanup(void);
-const char *ares_version(int *version);
-
-int ares_init(ares_channel *channelptr);
-int ares_init_options(ares_channel *channelptr, struct ares_options *options,
- int optmask);
-int ares_save_options(ares_channel channel, struct ares_options *options,
- int *optmask);
-void ares_destroy_options(struct ares_options *options);
-int ares_dup(ares_channel *dest, ares_channel src);
-void ares_destroy(ares_channel channel);
-void ares_cancel(ares_channel channel);
+ int type,
+ void *data);
+
+CARES_EXTERN int ares_library_init(int flags);
+
+CARES_EXTERN void ares_library_cleanup(void);
+
+CARES_EXTERN const char *ares_version(int *version);
+
+CARES_EXTERN int ares_init(ares_channel *channelptr);
+
+CARES_EXTERN int ares_init_options(ares_channel *channelptr,
+ struct ares_options *options,
+ int optmask);
+
+CARES_EXTERN int ares_save_options(ares_channel channel,
+ struct ares_options *options,
+ int *optmask);
+
+CARES_EXTERN void ares_destroy_options(struct ares_options *options);
+
+CARES_EXTERN int ares_dup(ares_channel *dest,
+ ares_channel src);
+
+CARES_EXTERN void ares_destroy(ares_channel channel);
+
+CARES_EXTERN void ares_cancel(ares_channel channel);
+
void ares_set_socket_callback(ares_channel channel,
ares_sock_create_callback callback,
void *user_data);
-void ares_send(ares_channel channel, const unsigned char *qbuf, int qlen,
- ares_callback callback, void *arg);
-void ares_query(ares_channel channel, const char *name, int dnsclass,
- int type, ares_callback callback, void *arg);
-void ares_search(ares_channel channel, const char *name, int dnsclass,
- int type, ares_callback callback, void *arg);
-void ares_gethostbyname(ares_channel channel, const char *name, int family,
- ares_host_callback callback, void *arg);
-int ares_gethostbyname_file(ares_channel channel, const char *name,
- int family, struct hostent **host);
-void ares_gethostbyaddr(ares_channel channel, const void *addr, int addrlen,
- int family, ares_host_callback callback, void *arg);
-void ares_getnameinfo(ares_channel channel, const struct sockaddr *sa,
- ares_socklen_t salen, int flags,
- ares_nameinfo_callback callback,
- void *arg);
-int ares_fds(ares_channel channel, fd_set *read_fds, fd_set *write_fds);
-int ares_getsock(ares_channel channel, int *socks, int numsocks);
-struct timeval *ares_timeout(ares_channel channel, struct timeval *maxtv,
- struct timeval *tv);
-void ares_process(ares_channel channel, fd_set *read_fds, fd_set *write_fds);
-void ares_process_fd(ares_channel channel, ares_socket_t read_fd,
- ares_socket_t write_fd);
-
-int ares_mkquery(const char *name, int dnsclass, int type, unsigned short id,
- int rd, unsigned char **buf, int *buflen);
-int ares_expand_name(const unsigned char *encoded, const unsigned char *abuf,
- int alen, char **s, long *enclen);
-int ares_expand_string(const unsigned char *encoded, const unsigned char *abuf,
- int alen, unsigned char **s, long *enclen);
+
+CARES_EXTERN void ares_send(ares_channel channel,
+ const unsigned char *qbuf,
+ int qlen,
+ ares_callback callback,
+ void *arg);
+
+CARES_EXTERN void ares_query(ares_channel channel,
+ const char *name,
+ int dnsclass,
+ int type,
+ ares_callback callback,
+ void *arg);
+
+CARES_EXTERN void ares_search(ares_channel channel,
+ const char *name,
+ int dnsclass,
+ int type,
+ ares_callback callback,
+ void *arg);
+
+CARES_EXTERN void ares_gethostbyname(ares_channel channel,
+ const char *name,
+ int family,
+ ares_host_callback callback,
+ void *arg);
+
+CARES_EXTERN int ares_gethostbyname_file(ares_channel channel,
+ const char *name,
+ int family,
+ struct hostent **host);
+
+CARES_EXTERN void ares_gethostbyaddr(ares_channel channel,
+ const void *addr,
+ int addrlen,
+ int family,
+ ares_host_callback callback,
+ void *arg);
+
+CARES_EXTERN void ares_getnameinfo(ares_channel channel,
+ const struct sockaddr *sa,
+ ares_socklen_t salen,
+ int flags,
+ ares_nameinfo_callback callback,
+ void *arg);
+
+CARES_EXTERN int ares_fds(ares_channel channel,
+ fd_set *read_fds,
+ fd_set *write_fds);
+
+CARES_EXTERN int ares_getsock(ares_channel channel,
+ int *socks,
+ int numsocks);
+
+CARES_EXTERN struct timeval *ares_timeout(ares_channel channel,
+ struct timeval *maxtv,
+ struct timeval *tv);
+
+CARES_EXTERN void ares_process(ares_channel channel,
+ fd_set *read_fds,
+ fd_set *write_fds);
+
+CARES_EXTERN void ares_process_fd(ares_channel channel,
+ ares_socket_t read_fd,
+ ares_socket_t write_fd);
+
+CARES_EXTERN int ares_mkquery(const char *name,
+ int dnsclass,
+ int type,
+ unsigned short id,
+ int rd,
+ unsigned char **buf,
+ int *buflen);
+
+CARES_EXTERN int ares_expand_name(const unsigned char *encoded,
+ const unsigned char *abuf,
+ int alen,
+ char **s,
+ long *enclen);
+
+CARES_EXTERN int ares_expand_string(const unsigned char *encoded,
+ const unsigned char *abuf,
+ int alen,
+ unsigned char **s,
+ long *enclen);
/*
* NOTE: before c-ares 1.6.1 we would most often use the system in6_addr
@@ -338,21 +441,40 @@ struct srv_reply {
** their TTLs in that array, and set *naddrttls to the number of addresses
** so written.
*/
-int ares_parse_a_reply(const unsigned char *abuf, int alen,
- struct hostent **host,
- struct addrttl *addrttls, int *naddrttls);
-int ares_parse_aaaa_reply(const unsigned char *abuf, int alen,
- struct hostent **host,
- struct addr6ttl *addrttls, int *naddrttls);
-int ares_parse_ptr_reply(const unsigned char *abuf, int alen, const void *addr,
- int addrlen, int family, struct hostent **host);
-int ares_parse_ns_reply(const unsigned char *abuf, int alen,
- struct hostent **host);
-int ares_parse_srv_reply(const unsigned char* abuf, int alen,
- struct srv_reply** srv_out, int *nsrvreply);
-void ares_free_string(void *str);
-void ares_free_hostent(struct hostent *host);
-const char *ares_strerror(int code);
+
+CARES_EXTERN int ares_parse_a_reply(const unsigned char *abuf,
+ int alen,
+ struct hostent **host,
+ struct addrttl *addrttls,
+ int *naddrttls);
+
+CARES_EXTERN int ares_parse_aaaa_reply(const unsigned char *abuf,
+ int alen,
+ struct hostent **host,
+ struct addr6ttl *addrttls,
+ int *naddrttls);
+
+CARES_EXTERN int ares_parse_ptr_reply(const unsigned char *abuf,
+ int alen,
+ const void *addr,
+ int addrlen,
+ int family,
+ struct hostent **host);
+
+CARES_EXTERN int ares_parse_ns_reply(const unsigned char *abuf,
+ int alen,
+ struct hostent **host);
+
+CARES_EXTERN int ares_parse_srv_reply(const unsigned char* abuf,
+ int alen,
+ struct srv_reply** srv_out,
+ int *nsrvreply);
+
+CARES_EXTERN void ares_free_string(void *str);
+
+CARES_EXTERN void ares_free_hostent(struct hostent *host);
+
+CARES_EXTERN const char *ares_strerror(int code);
#ifdef __cplusplus
}
diff --git a/ares/configure.ac b/ares/configure.ac
index 42ccd496d..92db52eb0 100644
--- a/ares/configure.ac
+++ b/ares/configure.ac
@@ -14,6 +14,7 @@ CARES_CHECK_OPTION_DEBUG
CARES_CHECK_OPTION_OPTIMIZE
CARES_CHECK_OPTION_WARNINGS
CARES_CHECK_OPTION_CURLDEBUG
+CARES_CHECK_OPTION_HIDDEN_SYMBOLS
CARES_CHECK_PATH_SEPARATOR_REQUIRED
@@ -110,6 +111,25 @@ esac
dnl libtool setup
AC_PROG_LIBTOOL
+AC_MSG_CHECKING([if we need CARES_BUILDING_LIB])
+case $host in
+ *-*-mingw*)
+ AC_DEFINE(CARES_BUILDING_LIB, 1, [when building c-ares library])
+ AC_MSG_RESULT(yes)
+ AC_MSG_CHECKING([if we need CARES_STATICLIB])
+ if test "X$enable_shared" = "Xno"
+ then
+ AC_DEFINE(CARES_STATICLIB, 1, [when not building a shared library])
+ AC_MSG_RESULT(yes)
+ else
+ AC_MSG_RESULT(no)
+ fi
+ ;;
+ *)
+ AC_MSG_RESULT(no)
+ ;;
+esac
+
dnl **********************************************************************
dnl platform/compiler/architecture specific checks/flags
dnl **********************************************************************
@@ -144,6 +164,7 @@ esac
CARES_CHECK_COMPILER_HALT_ON_ERROR
CARES_CHECK_COMPILER_ARRAY_SIZE_NEGATIVE
+CARES_CHECK_COMPILER_HIDDEN_SYMBOLS
CARES_CHECK_NO_UNDEFINED
AM_CONDITIONAL(NO_UNDEFINED, test x$need_no_undefined = xyes)
@@ -876,6 +897,8 @@ fi
CARES_CHECK_OPTION_NONBLOCKING
CARES_CHECK_NONBLOCKING_SOCKET
+CARES_CONFIGURE_HIDDEN_SYMBOLS
+
CARES_PRIVATE_LIBS="$LIBS"
AC_SUBST(CARES_PRIVATE_LIBS)
diff --git a/ares/m4/cares-compilers.m4 b/ares/m4/cares-compilers.m4
index e4fd1ec63..77e4651a7 100644
--- a/ares/m4/cares-compilers.m4
+++ b/ares/m4/cares-compilers.m4
@@ -16,7 +16,7 @@
#***************************************************************************
# File version for 'aclocal' use. Keep it a single number.
-# serial 56
+# serial 59
dnl CARES_CHECK_COMPILER
@@ -1249,6 +1249,100 @@ AC_DEFUN([CARES_CHECK_COMPILER_ARRAY_SIZE_NEGATIVE], [
])
+dnl CARES_CHECK_COMPILER_HIDDEN_SYMBOLS
+dnl -------------------------------------------------
+dnl Verify if compiler supports hiding library internal symbols, setting
+dnl shell variable hidden_symbols_supported value as appropriate, as well
+dnl as variable hidden_symbols_CFLAGS when supported.
+
+AC_DEFUN([CARES_CHECK_COMPILER_HIDDEN_SYMBOLS], [
+ AC_REQUIRE([CARES_CHECK_COMPILER])dnl
+ AC_BEFORE([$0],[CARES_CONFIGURE_HIDDEN_SYMBOLS])dnl
+ AC_MSG_CHECKING([if compiler supports hiding library internal symbols])
+ hidden_symbols_supported="no"
+ hidden_symbols_CFLAGS=""
+ tmp_CFLAGS=""
+ tmp_extern=""
+ case "$compiler_id" in
+ GNU_C)
+ dnl Only gcc 3.4 or later
+ if test "$compiler_num" -ge "304"; then
+ if $CC --help --verbose 2>&1 | grep fvisibility= > /dev/null ; then
+ tmp_extern="__attribute__ ((visibility (\"default\")))"
+ tmp_CFLAGS="-fvisibility=hidden"
+ hidden_symbols_supported="yes"
+ echo " " >&6
+ echo "debug: should work with this compiler and version" >&6
+ echo " " >&6
+ fi
+ fi
+ ;;
+ INTEL_UNIX_C)
+ dnl Only icc 9.0 or later
+ if test "$compiler_num" -ge "900"; then
+ if $CC --help --verbose 2>&1 | grep fvisibility= > /dev/null ; then
+ tmp_extern="__attribute__ ((visibility (\"default\")))"
+ tmp_CFLAGS="-fvisibility=hidden"
+ hidden_symbols_supported="yes"
+ echo " " >&6
+ echo "debug: should work with this compiler and version" >&6
+ echo " " >&6
+ fi
+ fi
+ ;;
+ SUNPRO_C)
+ if $CC 2>&1 | grep flags >/dev/null && $CC -flags | grep xldscope= >/dev/null ; then
+ tmp_extern="__global"
+ tmp_CFLAGS="-xldscope=hidden"
+ hidden_symbols_supported="yes"
+ echo " " >&6
+ echo "debug: should work with this compiler and version" >&6
+ echo " " >&6
+ fi
+ ;;
+ esac
+ if test "$hidden_symbols_supported" = "yes"; then
+ tmp_save_CFLAGS="$CFLAGS"
+ CFLAGS="$tmp_save_CFLAGS $tmp_CFLAGS"
+ squeeze CFLAGS
+ AC_COMPILE_IFELSE([
+ AC_LANG_PROGRAM([[
+ $tmp_extern char *dummy(char *buff);
+ char *dummy(char *buff)
+ {
+ if(buff)
+ return ++buff;
+ else
+ return buff;
+ }
+ ]],[[
+ char b[16];
+ char *r = dummy(&b);
+ if(r)
+ return (int)*r;
+ ]])
+ ],[
+ hidden_symbols_supported="yes"
+ ],[
+ hidden_symbols_supported="no"
+ sed 's/^/cc-src: /' conftest.$ac_ext >&6
+ sed 's/^/cc-err: /' conftest.err >&6
+ ])
+ CFLAGS="$tmp_save_CFLAGS"
+ fi
+ if test "$hidden_symbols_supported" = "yes"; then
+ AC_MSG_RESULT([yes])
+ AC_DEFINE_UNQUOTED(CARES_HIDDEN_SYMBOLS, 1,
+ [Define to 1 to enable hiding of library internal symbols.])
+ AC_DEFINE_UNQUOTED(CARES_EXTERN_SYMBOL, $tmp_extern,
+ [Definition to make a library symbol externally visible.])
+ hidden_symbols_CFLAGS="$tmp_CFLAGS"
+ else
+ AC_MSG_RESULT([no])
+ fi
+])
+
+
dnl CARES_CHECK_COMPILER_STRUCT_MEMBER_SIZE
dnl -------------------------------------------------
dnl Verifies if the compiler is capable of handling the
diff --git a/ares/m4/cares-confopts.m4 b/ares/m4/cares-confopts.m4
index cc03a09d6..5af3232ad 100644
--- a/ares/m4/cares-confopts.m4
+++ b/ares/m4/cares-confopts.m4
@@ -16,7 +16,7 @@
#***************************************************************************
# File version for 'aclocal' use. Keep it a single number.
-# serial 5
+# serial 6
dnl CARES_CHECK_OPTION_CURLDEBUG
@@ -92,6 +92,46 @@ AC_HELP_STRING([--disable-debug],[Disable debug build options]),
])
+dnl CARES_CHECK_OPTION_HIDDEN_SYMBOLS
+dnl -------------------------------------------------
+dnl Verify if configure has been invoked with option
+dnl --enable-hidden-symbols or --disable-hidden-symbols,
+dnl setting shell variable want_hidden_symbols value.
+
+AC_DEFUN([CARES_CHECK_OPTION_HIDDEN_SYMBOLS], [
+ AC_BEFORE([$0],[CARES_CHECK_COMPILER_HIDDEN_SYMBOLS])dnl
+ AC_MSG_CHECKING([whether to enable hiding symbols])
+ OPT_HIDDEN_SYMBOLS="default"
+ AC_ARG_ENABLE(hidden-symbols,
+AC_HELP_STRING([--enable-hidden-symbols],[Enable hiding of library internal symbols])
+AC_HELP_STRING([--disable-hidden-symbols],[Disable hiding of library internal symbols]),
+ OPT_HIDDEN_SYMBOLS=$enableval)
+ case "$OPT_HIDDEN_SYMBOLS" in
+ no)
+ dnl --disable-hidden-symbols option used.
+ dnl This is an indication to not attempt hiding of library internal
+ dnl symbols. Default symbol visibility will be used, which normally
+ dnl exposes all library internal symbols.
+ want_hidden_symbols="no"
+ AC_MSG_RESULT([no])
+ ;;
+ default)
+ dnl configure's hidden-symbols option not specified.
+ dnl Handle this as if --enable-hidden-symbols option was given.
+ want_hidden_symbols="yes"
+ AC_MSG_RESULT([not specified (assuming yes)])
+ ;;
+ *)
+ dnl --enable-hidden-symbols option used.
+ dnl This is an indication to attempt hiding of library internal
+ dnl symbols. This is only supported on some compilers/linkers.
+ want_hidden_symbols="yes"
+ AC_MSG_RESULT([yes])
+ ;;
+ esac
+])
+
+
dnl CARES_CHECK_OPTION_NONBLOCKING
dnl -------------------------------------------------
dnl Verify if configure has been invoked with option
@@ -252,3 +292,24 @@ AC_DEFUN([CARES_CHECK_NONBLOCKING_SOCKET], [
fi
])
+
+dnl CARES_CONFIGURE_HIDDEN_SYMBOLS
+dnl -------------------------------------------------
+dnl Depending on --enable-hidden-symbols or --disable-hidden-symbols
+dnl configure option, and compiler capability to actually honor such
+dnl option, compiler flags will be modified as appropriate.
+dnl This macro should not be used until all compilation tests have
+dnl been done to prevent interferences on other tests.
+
+AC_DEFUN([CARES_CONFIGURE_HIDDEN_SYMBOLS], [
+ AC_MSG_CHECKING([whether to actually hide library internal symbols])
+ if test "$want_hidden_symbols" = "yes" &&
+ test "$hidden_symbols_supported" = "yes"; then
+ tmp_save_CFLAGS="$CFLAGS"
+ CFLAGS="$tmp_save_CFLAGS $hidden_symbols_CFLAGS"
+ AC_MSG_RESULT([yes])
+ else
+ AC_MSG_RESULT([no])
+ fi
+])
+