From 74015f0fe72daf8e007298975d6415e0e9ee5e47 Mon Sep 17 00:00:00 2001
From: Jim Huang <jim.huang@linaro.org>
Date: Wed, 20 Apr 2011 04:28:44 +0800
Subject: [PATCH] Hide private symbols using GCC visibility pragma

libc.so should not export all private symbols to reflect Android NDK.
This patch attempts to use GCC visibility pragma to hide the private
symbols in bionic. It also lets the optimizer produce better and
smaller code.

Reference code size measurements for HTC Passion:
$ arm-eabi-size out/target/product/passion/system/lib/libc.so

[before]
   text	   data	    bss	    dec	    hex	filename
 260000	  10004	  45944	 315948	  4d22c	out/target/product/passion/system/lib/libc.so

[after]
   text	   data	    bss	    dec	    hex	filename
 248655	   9940	  45944	 304539	  4a59b	out/target/product/passion/system/lib/libc.so

Change-Id: Id6e845e1cdba19f578a435d796267a8d07c291c3
---
 libc/include/sys/cdefs_hidden_pop.h  |   41 ++++++++++++++++++++++++++++++++++
 libc/include/sys/cdefs_hidden_push.h |   41 ++++++++++++++++++++++++++++++++++
 libc/netbsd/isc/eventlib_p.h         |    3 ++
 libc/netbsd/resolv/res_private.h     |    4 +++
 libc/private/arpa_nameser.h          |    4 +++
 libc/private/bionic_tls.h            |    4 +++
 libc/private/ctype_private.h         |    3 ++
 libc/private/isc/eventlib.h          |    4 +++
 libc/private/logd.h                  |    4 +++
 libc/private/nsswitch.h              |    4 +++
 libc/private/rand48.h                |    5 ++++
 libc/private/resolv_cache.h          |    4 +++
 libc/private/resolv_private.h        |    4 +++
 libc/private/resolv_static.h         |    4 +++
 libc/private/thread_private.h        |    4 +++
 libc/stdio/local.h                   |    4 +++
 16 files changed, 137 insertions(+), 0 deletions(-)
 create mode 100644 libc/include/sys/cdefs_hidden_pop.h
 create mode 100644 libc/include/sys/cdefs_hidden_push.h

diff --git a/libc/include/sys/cdefs_hidden_pop.h b/libc/include/sys/cdefs_hidden_pop.h
new file mode 100644
index 0000000..741fede
--- /dev/null
+++ b/libc/include/sys/cdefs_hidden_pop.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/* Ignore GCC visibility if debug build */
+#if !defined(DEBUG) || defined(NDEBUG)
+
+#if !defined(__LIBC_HIDDEN_PUSH_DEFINED)
+#error "Unbalanced pair of GCC visibility push/pop"
+#endif
+
+#define __LIBC_HIDDEN_POP_DEFINED
+#undef __LIBC_HIDDEN_PUSH_DEFINED
+
+#pragma GCC visibility pop
+
+#endif
diff --git a/libc/include/sys/cdefs_hidden_push.h b/libc/include/sys/cdefs_hidden_push.h
new file mode 100644
index 0000000..3b12cbd
--- /dev/null
+++ b/libc/include/sys/cdefs_hidden_push.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/* Ignore GCC visibility if debug build */
+#if !defined(DEBUG) || defined(NDEBUG)
+
+#if defined(__LIBC_HIDDEN_PUSH_DEFINED)
+#error "Disallow nested GCC visibility declaration"
+#endif
+
+#define __LIBC_HIDDEN_PUSH_DEFINED
+#undef __LIBC_HIDDEN_POP_DEFINED
+
+#pragma GCC visibility push(hidden)
+
+#endif
diff --git a/libc/netbsd/isc/eventlib_p.h b/libc/netbsd/isc/eventlib_p.h
index 7edc5a0..1620f6d 100644
--- a/libc/netbsd/isc/eventlib_p.h
+++ b/libc/netbsd/isc/eventlib_p.h
@@ -44,6 +44,7 @@
 #include <isc/list.h>
 #include <isc/memcluster.h>
 
+#include <sys/cdefs_hidden_push.h>
 
 #define	EV_MASK_ALL	(EV_READ | EV_WRITE | EV_EXCEPT)
 #define EV_ERR(e)		return (errno = (e), -1)
@@ -230,4 +231,6 @@ evWait *evFreeWait(evContext_p *ctx, evWait *old);
 /* Global options */
 int		__evOptMonoTime;
 
+#include <sys/cdefs_hidden_pop.h>
+
 #endif /*_EVENTLIB_P_H*/
diff --git a/libc/netbsd/resolv/res_private.h b/libc/netbsd/resolv/res_private.h
index 8341913..d77974d 100644
--- a/libc/netbsd/resolv/res_private.h
+++ b/libc/netbsd/resolv/res_private.h
@@ -3,6 +3,8 @@
 #ifndef res_private_h
 #define res_private_h
 
+#include <sys/cdefs_hidden_push.h>
+
 struct __res_state_ext {
 	union res_sockaddr_union nsaddrs[MAXNS];
 	struct sort_list {
@@ -19,4 +21,6 @@ struct __res_state_ext {
 extern int
 res_ourserver_p(const res_state statp, const struct sockaddr *sa);
 
+#include <sys/cdefs_hidden_pop.h>
+
 #endif
diff --git a/libc/private/arpa_nameser.h b/libc/private/arpa_nameser.h
index 438dc04..c20b3de 100644
--- a/libc/private/arpa_nameser.h
+++ b/libc/private/arpa_nameser.h
@@ -58,6 +58,8 @@
 #include <sys/types.h>
 #include <sys/cdefs.h>
 
+#include <sys/cdefs_hidden_push.h>
+
 /*
  * Revision information.  This is the release date in YYYYMMDD format.
  * It can change every day so the right thing to do with it is use it
@@ -574,4 +576,6 @@ __END_DECLS
 #define  XLOG(...)   do {} while (0)
 #endif
 
+#include <sys/cdefs_hidden_pop.h>
+
 #endif /* !_ARPA_NAMESER_H_ */
diff --git a/libc/private/bionic_tls.h b/libc/private/bionic_tls.h
index 008fd2f..498c483 100644
--- a/libc/private/bionic_tls.h
+++ b/libc/private/bionic_tls.h
@@ -83,6 +83,8 @@ __BEGIN_DECLS
 /* set the Thread Local Storage, must contain at least BIONIC_TLS_SLOTS pointers */
 extern void __init_tls(void**  tls, void*  thread_info);
 
+#include <sys/cdefs_hidden_push.h>
+
 /* syscall only, do not call directly */
 extern int __set_tls(void *ptr);
 
@@ -134,6 +136,8 @@ extern void*  __get_tls( void );
 /* return the stack base and size, used by our malloc debugger */
 extern void*  __get_stack_base(int  *p_stack_size);
 
+#include <sys/cdefs_hidden_pop.h>
+
 __END_DECLS
 
 #endif /* _SYS_TLS_H */
diff --git a/libc/private/ctype_private.h b/libc/private/ctype_private.h
index 39cc792..8efb598 100644
--- a/libc/private/ctype_private.h
+++ b/libc/private/ctype_private.h
@@ -1,3 +1,5 @@
+#include <sys/cdefs_hidden_push.h>
+
 /* $OpenBSD: ctype_private.h,v 1.1 2005/08/08 05:53:00 espie Exp $ */
 /* Written by Marc Espie, public domain */
 #define CTYPE_NUM_CHARS       256
@@ -5,3 +7,4 @@ extern const char _C_ctype_[];
 extern const short _C_toupper_[];
 extern const short _C_tolower_[];
 
+#include <sys/cdefs_hidden_pop.h>
diff --git a/libc/private/isc/eventlib.h b/libc/private/isc/eventlib.h
index 9185f67..1cbfc4c 100644
--- a/libc/private/isc/eventlib.h
+++ b/libc/private/isc/eventlib.h
@@ -31,6 +31,8 @@
 #include <sys/time.h>
 #include <stdio.h>
 
+#include <sys/cdefs_hidden_push.h>
+
 #ifndef __P
 # define __EVENTLIB_P_DEFINED
 # ifdef __STDC__
@@ -201,4 +203,6 @@ int evDefer __P((evContext, evWaitFunc, void *));
 # undef __P
 #endif
 
+#include <sys/cdefs_hidden_pop.h>
+
 #endif /*_EVENTLIB_H*/
diff --git a/libc/private/logd.h b/libc/private/logd.h
index 43fa742..fb52f4f 100644
--- a/libc/private/logd.h
+++ b/libc/private/logd.h
@@ -30,6 +30,8 @@
 
 #include <stdarg.h>
 
+#include <sys/cdefs_hidden_push.h>
+
 enum  {
     ANDROID_LOG_UNKNOWN = 0,
     ANDROID_LOG_DEFAULT,    /* only for SetMinPriority() */
@@ -47,4 +49,6 @@ enum  {
 int __libc_android_log_print(int prio, const char *tag, const char *fmt, ...);
 int __libc_android_log_vprint(int prio, const char *tag, const char *fmt, va_list ap);
 
+#include <sys/cdefs_hidden_pop.h>
+
 #endif /* _ANDROID_BIONIC_LOGD_H */
diff --git a/libc/private/nsswitch.h b/libc/private/nsswitch.h
index e03844b..2fe0370 100644
--- a/libc/private/nsswitch.h
+++ b/libc/private/nsswitch.h
@@ -220,6 +220,8 @@ typedef struct {
 
 #include <sys/cdefs.h>
 
+#include <sys/cdefs_hidden_push.h>
+
 __BEGIN_DECLS
 int	nsdispatch(void *, const ns_dtab [], const char *,
 			const char *, const ns_src [], ...);
@@ -234,4 +236,6 @@ int		 _nsyylex(void);
 
 __END_DECLS
 
+#include <sys/cdefs_hidden_pop.h>
+
 #endif /* !_NSSWITCH_H */
diff --git a/libc/private/rand48.h b/libc/private/rand48.h
index afa49f6..2835244 100644
--- a/libc/private/rand48.h
+++ b/libc/private/rand48.h
@@ -18,6 +18,9 @@
 
 #include <math.h>
 #include <stdlib.h>
+#include <sys/cdefs.h>
+
+#include <sys/cdefs_hidden_push.h>
 
 void		__dorand48(unsigned short[3]);
 
@@ -29,4 +32,6 @@ void		__dorand48(unsigned short[3]);
 #define	RAND48_MULT_2	(0x0005)
 #define	RAND48_ADD	(0x000b)
 
+#include <sys/cdefs_hidden_pop.h>
+
 #endif /* _RAND48_H_ */
diff --git a/libc/private/resolv_cache.h b/libc/private/resolv_cache.h
index cd876fb..ca10089 100644
--- a/libc/private/resolv_cache.h
+++ b/libc/private/resolv_cache.h
@@ -28,6 +28,8 @@
 #ifndef _RESOLV_CACHE_H_
 #define _RESOLV_CACHE_H_
 
+#include <sys/cdefs_hidden_push.h>
+
 struct resolv_cache;  /* forward */
 
 /* get cache instance, can be NULL if cache is disabled
@@ -63,4 +65,6 @@ _resolv_cache_add( struct resolv_cache*  cache,
                    const void*           answer,
                    int                   answerlen );
 
+#include <sys/cdefs_hidden_pop.h>
+
 #endif /* _RESOLV_CACHE_H_ */
diff --git a/libc/private/resolv_private.h b/libc/private/resolv_private.h
index 0f3c6c0..560e7af 100644
--- a/libc/private/resolv_private.h
+++ b/libc/private/resolv_private.h
@@ -57,6 +57,8 @@
 #include <resolv.h>
 #include "resolv_static.h"
 
+#include <sys/cdefs_hidden_push.h>
+
 /*
  * Revision information.  This is the release date in YYYYMMDD format.
  * It can change every day so the right thing to do with it is use it
@@ -496,4 +498,6 @@ u_int  res_randomid(void);
 
 __END_DECLS
 
+#include <sys/cdefs_hidden_pop.h>
+
 #endif /* !_RESOLV_PRIVATE_H_ */
diff --git a/libc/private/resolv_static.h b/libc/private/resolv_static.h
index 8f2a095..19ebc32 100644
--- a/libc/private/resolv_static.h
+++ b/libc/private/resolv_static.h
@@ -3,6 +3,8 @@
 
 #include <netdb.h>
 
+#include <sys/cdefs_hidden_push.h>
+
 /* this structure contains all the variables that were declared
  * 'static' in the original NetBSD resolver code.
  *
@@ -29,4 +31,6 @@ typedef struct res_static {
 
 extern res_static __res_get_static(void);
 
+#include <sys/cdefs_hidden_pop.h>
+
 #endif /* _RESOLV_STATIC_H */
diff --git a/libc/private/thread_private.h b/libc/private/thread_private.h
index c03f0ab..e66d8cd 100644
--- a/libc/private/thread_private.h
+++ b/libc/private/thread_private.h
@@ -7,6 +7,8 @@
 
 #include <pthread.h>
 
+#include <sys/cdefs_hidden_push.h>
+
 /*
  * This file defines the thread library interface to libc.  Thread
  * libraries must implement the functions described here for proper
@@ -159,4 +161,6 @@ void	_thread_atexit_unlock(void);
 						_thread_atexit_unlock();\
 				} while (0)
 
+#include <sys/cdefs_hidden_pop.h>
+
 #endif /* _THREAD_PRIVATE_H_ */
diff --git a/libc/stdio/local.h b/libc/stdio/local.h
index 3db1fc5..88270f2 100644
--- a/libc/stdio/local.h
+++ b/libc/stdio/local.h
@@ -35,6 +35,8 @@
 #include "wcio.h"
 #include "fileext.h"
 
+#include <sys/cdefs_hidden_push.h>
+
 #ifndef DEFFILEMODE
 #define DEFFILEMODE  (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH)
 #endif
@@ -89,3 +91,5 @@ extern int __sdidinit;
 	free((char *)(fp)->_lb._base); \
 	(fp)->_lb._base = NULL; \
 }
+
+#include <sys/cdefs_hidden_pop.h>
-- 
1.7.4.1
