From: Todd C. Miller Date: Tue, 17 Feb 2015 13:42:10 +0000 (-0700) Subject: Use weak symbols for sudo_warn_gettext() and sudo_warn_strerror() X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=166db8eeb400aef9cd979aa427f9fc360695df16;p=sudo Use weak symbols for sudo_warn_gettext() and sudo_warn_strerror() so distros using "-Wl,--no-undefined" in LDFLAGS don't run into problems. --- diff --git a/MANIFEST b/MANIFEST index 17feb3ea5..6146e70a5 100644 --- a/MANIFEST +++ b/MANIFEST @@ -100,6 +100,7 @@ lib/util/inet_pton.c lib/util/isblank.c lib/util/key_val.c lib/util/lbuf.c +lib/util/locale_weak.c lib/util/locking.c lib/util/memrchr.c lib/util/memset_s.c diff --git a/aclocal.m4 b/aclocal.m4 index 71d05a940..e5bb6c8bb 100644 --- a/aclocal.m4 +++ b/aclocal.m4 @@ -130,6 +130,7 @@ m4_include([m4/ax_check_compile_flag.m4]) m4_include([m4/ax_check_link_flag.m4]) m4_include([m4/ax_func_getaddrinfo.m4]) m4_include([m4/ax_func_snprintf.m4]) +m4_include([m4/ax_sys_weak_alias.m4]) m4_include([m4/libtool.m4]) m4_include([m4/ltoptions.m4]) m4_include([m4/ltsugar.m4]) diff --git a/config.h.in b/config.h.in index 884030c97..83534da00 100644 --- a/config.h.in +++ b/config.h.in @@ -804,6 +804,25 @@ /* Define to 1 if you have the header file. */ #undef HAVE_SYS_TYPES_H +/* Define this if your system can create weak aliases */ +#undef HAVE_SYS_WEAK_ALIAS + +/* Define this if weak aliases may be created with __attribute__ */ +#undef HAVE_SYS_WEAK_ALIAS_ATTRIBUTE + +/* Define this if weak aliases may be created with #pragma _CRI duplicate */ +#undef HAVE_SYS_WEAK_ALIAS_CRIDUPLICATE + +/* Define this if weak aliases in other files are honored */ +#undef HAVE_SYS_WEAK_ALIAS_CROSSFILE + +/* Define this if weak aliases may be created with #pragma _HP_SECONDARY_DEF + */ +#undef HAVE_SYS_WEAK_ALIAS_HPSECONDARY + +/* Define this if weak aliases may be created with #pragma weak */ +#undef HAVE_SYS_WEAK_ALIAS_PRAGMA + /* Define to 1 if you have the `ttyslot' function. */ #undef HAVE_TTYSLOT diff --git a/configure b/configure index fdfe9b847..85108fbf8 100755 --- a/configure +++ b/configure @@ -641,6 +641,8 @@ KRB5CONFIG FLEX YFLAGS YACC +WEAK_ALIAS_CROSSFILE +WEAK_ALIAS LIBOBJS NROFFPROG MANDOCPROG @@ -3099,6 +3101,7 @@ INIT_SCRIPT= INIT_DIR= RC_LINK= COMPAT_EXP= +WEAK_ALIAS=no CHECKSHADOW=true shadow_funcs= shadow_libs= @@ -15841,6 +15844,329 @@ $as_echo "#define volatile /**/" >>confdefs.h fi +if test "$enable_shared_libutil" = "yes"; then + + # starting point: no aliasing scheme yet... + ax_sys_weak_alias=no + + # Figure out what kind of aliasing may be supported... + # Test whether compiler accepts __attribute__ form of weak aliasing + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts function __attribute__((weak,alias()))" >&5 +$as_echo_n "checking whether $CC accepts function __attribute__((weak,alias()))... " >&6; } +if ${ax_cv_sys_weak_alias_attribute+:} false; then : + $as_echo_n "(cached) " >&6 +else + + # We add -Werror if it's gcc to force an error exit if the weak attribute + # isn't understood + if test $GCC = yes; then : + + save_CFLAGS=$CFLAGS + CFLAGS=-Werror +fi + + # Try linking with a weak alias... + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +void __weakf(int c) {} +void weakf(int c) __attribute__((weak, alias("__weakf"))); +int +main () +{ +weakf(0) + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ax_cv_sys_weak_alias_attribute=yes +else + ax_cv_sys_weak_alias_attribute=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + + # Restore original CFLAGS + if test $GCC = yes; then : + + CFLAGS=$save_CFLAGS +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_sys_weak_alias_attribute" >&5 +$as_echo "$ax_cv_sys_weak_alias_attribute" >&6; } + + # What was the result of the test? + if test $ax_sys_weak_alias = no && + test $ax_cv_sys_weak_alias_attribute = yes; then : + + ax_sys_weak_alias=attribute + +$as_echo "#define HAVE_SYS_WEAK_ALIAS_ATTRIBUTE 1" >>confdefs.h + + +fi + + # Test whether compiler accepts #pragma form of weak aliasing + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC supports #pragma weak" >&5 +$as_echo_n "checking whether $CC supports #pragma weak... " >&6; } +if ${ax_cv_sys_weak_alias_pragma+:} false; then : + $as_echo_n "(cached) " >&6 +else + + + # Try linking with a weak alias... + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +extern void weakf(int c); +#pragma weak weakf = __weakf +void __weakf(int c) {} +int +main () +{ +weakf(0) + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ax_cv_sys_weak_alias_pragma=yes +else + ax_cv_sys_weak_alias_pragma=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_sys_weak_alias_pragma" >&5 +$as_echo "$ax_cv_sys_weak_alias_pragma" >&6; } + + # What was the result of the test? + if test $ax_sys_weak_alias = no && + test $ax_cv_sys_weak_alias_pragma = yes; then : + + ax_sys_weak_alias=pragma + +$as_echo "#define HAVE_SYS_WEAK_ALIAS_PRAGMA 1" >>confdefs.h + + +fi + + # Test whether compiler accepts _HP_SECONDARY_DEF pragma from HP... + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC supports #pragma _HP_SECONDARY_DEF" >&5 +$as_echo_n "checking whether $CC supports #pragma _HP_SECONDARY_DEF... " >&6; } +if ${ax_cv_sys_weak_alias_hpsecondary+:} false; then : + $as_echo_n "(cached) " >&6 +else + + + # Try linking with a weak alias... + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +extern void weakf(int c); +#pragma _HP_SECONDARY_DEF __weakf weakf +void __weakf(int c) {} +int +main () +{ +weakf(0) + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ax_cv_sys_weak_alias_hpsecondary=yes +else + ax_cv_sys_weak_alias_hpsecondary=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_sys_weak_alias_hpsecondary" >&5 +$as_echo "$ax_cv_sys_weak_alias_hpsecondary" >&6; } + + # What was the result of the test? + if test $ax_sys_weak_alias = no && + test $ax_cv_sys_weak_alias_hpsecondary = yes; then : + + ax_sys_weak_alias=hpsecondary + +$as_echo "#define HAVE_SYS_WEAK_ALIAS_HPSECONDARY 1" >>confdefs.h + + +fi + + # Test whether compiler accepts "_CRI duplicate" pragma from Cray + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC supports #pragma _CRI duplicate" >&5 +$as_echo_n "checking whether $CC supports #pragma _CRI duplicate... " >&6; } +if ${ax_cv_sys_weak_alias_criduplicate+:} false; then : + $as_echo_n "(cached) " >&6 +else + + + # Try linking with a weak alias... + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +extern void weakf(int c); +#pragma _CRI duplicate weakf as __weakf +void __weakf(int c) {} +int +main () +{ +weakf(0) + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ax_cv_sys_weak_alias_criduplicate=yes +else + ax_cv_sys_weak_alias_criduplicate=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_sys_weak_alias_criduplicate" >&5 +$as_echo "$ax_cv_sys_weak_alias_criduplicate" >&6; } + + # What was the result of the test? + if test $ax_sys_weak_alias = no && + test $ax_cv_sys_weak_alias_criduplicate = yes; then : + + ax_sys_weak_alias=criduplicate + +$as_echo "#define HAVE_SYS_WEAK_ALIAS_CRIDUPLICATE 1" >>confdefs.h + + +fi + + + # Do we actually support aliasing? + { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to create weak aliases with $CC" >&5 +$as_echo_n "checking how to create weak aliases with $CC... " >&6; } +if ${ax_cv_sys_weak_alias+:} false; then : + $as_echo_n "(cached) " >&6 +else + ax_cv_sys_weak_alias=$ax_sys_weak_alias +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_sys_weak_alias" >&5 +$as_echo "$ax_cv_sys_weak_alias" >&6; } + + # OK, set a #define + if test $ax_cv_sys_weak_alias != no; then : + + +$as_echo "#define HAVE_SYS_WEAK_ALIAS 1" >>confdefs.h + + +fi + + # Can aliases cross object file boundaries? + # Check to see if weak aliases can cross object file boundaries + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC supports weak aliases across object file boundaries" >&5 +$as_echo_n "checking whether $CC supports weak aliases across object file boundaries... " >&6; } +if ${ax_cv_sys_weak_alias_crossfile+:} false; then : + $as_echo_n "(cached) " >&6 +else + + if test $ax_cv_sys_weak_alias = no; then : + ax_cv_sys_weak_alias_crossfile=no +else + + # conftest1 contains our weak alias definition... + cat >conftest1.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF + cat confdefs.h >>conftest1.$ac_ext + cat >>conftest1.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +#ifndef HAVE_SYS_WEAK_ALIAS_ATTRIBUTE +extern void weakf(int c); +#endif +#if defined(HAVE_SYS_WEAK_ALIAS_PRAGMA) +#pragma weak weakf = __weakf +#elif defined(HAVE_SYS_WEAK_ALIAS_HPSECONDARY) +#pragma _HP_SECONDARY_DEF __weakf weakf +#elif defined(HAVE_SYS_WEAK_ALIAS_CRIDUPLICATE) +#pragma _CRI duplicate weakf as __weakf +#endif +void __weakf(int c) {} +#ifdef HAVE_SYS_WEAK_ALIAS_ATTRIBUTE +void weakf(int c) __attribute((weak, alias("__weakf"))); +#endif +_ACEOF + # And conftest2 contains our main routine that calls it + cat >conftest2.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF + cat confdefs.h >> conftest2.$ac_ext + cat >>conftest2.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +extern void weakf(int c); +int +main () +{ + weakf(0); + return 0; +} +_ACEOF + # We must remove the object files (if any) ourselves... + rm -f conftest2.$ac_objext conftest$ac_exeext + + # Change ac_link to compile *2* files together + save_aclink=$ac_link + ac_link=`echo "$ac_link" | \ + sed -e 's/conftest\(\.\$ac_ext\)/conftest1\1 conftest2\1/'` + # Since we created the files ourselves, don't use SOURCE argument + if ac_fn_c_try_link "$LINENO"; then : + ax_cv_sys_weak_alias_crossfile=yes +else + ax_cv_sys_weak_alias_crossfile=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext + # Restore ac_link + ac_link=$save_aclink + + # We must remove the object files (if any) and C files ourselves... + rm -f conftest1.$ac_ext conftest2.$ac_ext \ + conftest1.$ac_objext conftest2.$ac_objext + +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_sys_weak_alias_crossfile" >&5 +$as_echo "$ax_cv_sys_weak_alias_crossfile" >&6; } + + # What were the results of the test? + if test $ax_cv_sys_weak_alias_crossfile = yes; then : + + +$as_echo "#define HAVE_SYS_WEAK_ALIAS_CROSSFILE 1" >>confdefs.h + + +fi + + + # OK, remember the results + WEAK_ALIAS=$ax_cv_sys_weak_alias + + WEAK_ALIAS_CROSSFILE=$ax_cv_sys_weak_alias_crossfile + + +fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for variadic macro support in cpp" >&5 $as_echo_n "checking for variadic macro support in cpp... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -20786,6 +21112,24 @@ done fi fi +if test X"$WEAK_ALIAS" != X"no"; then + COMMON_OBJS="${COMMON_OBJS} locale_weak.lo" + + for _sym in sudo_warn_strerror_v1; do + COMPAT_EXP="${COMPAT_EXP}${_sym} +" + done + + if test X"$SUDO_NLS" = X"enabled"; then + + for _sym in sudo_warn_gettext_v1; do + COMPAT_EXP="${COMPAT_EXP}${_sym} +" + done + + fi +fi + case "$enable_zlib" in yes) { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gzdopen in -lz" >&5 diff --git a/configure.ac b/configure.ac index 38f816043..416e2b2ff 100644 --- a/configure.ac +++ b/configure.ac @@ -219,6 +219,7 @@ COMPAT_EXP= dnl dnl Other vaiables dnl +WEAK_ALIAS=no CHECKSHADOW=true shadow_funcs= shadow_libs= @@ -2150,6 +2151,9 @@ dnl AC_PROG_CC_STDC AC_C_CONST AC_C_VOLATILE +if test "$enable_shared_libutil" = "yes"; then + AX_SYS_WEAK_ALIAS +fi AC_MSG_CHECKING([for variadic macro support in cpp]) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([ AC_INCLUDES_DEFAULT @@ -2926,6 +2930,18 @@ if test "$enable_nls" != "no"; then fi fi +dnl +dnl If the system has weak symbol support, use it for +dnl sudo_warn_strerror_v1() and sudo_warn_gettext_v1(). +dnl +if test X"$WEAK_ALIAS" != X"no"; then + COMMON_OBJS="${COMMON_OBJS} locale_weak.lo" + SUDO_APPEND_COMPAT_EXP(sudo_warn_strerror_v1) + if test X"$SUDO_NLS" = X"enabled"; then + SUDO_APPEND_COMPAT_EXP(sudo_warn_gettext_v1) + fi +fi + dnl dnl Deferred zlib option processing. dnl By default we use the system zlib if it is present. diff --git a/lib/util/Makefile.in b/lib/util/Makefile.in index fa7050f39..d66dd1cb2 100644 --- a/lib/util/Makefile.in +++ b/lib/util/Makefile.in @@ -1,5 +1,5 @@ # -# Copyright (c) 2011-2014 Todd C. Miller +# Copyright (c) 2011-2015 Todd C. Miller # # Permission to use, copy, modify, and distribute this software for any # purpose with or without fee is hereby granted, provided that the above @@ -96,10 +96,10 @@ DEVEL = @DEVEL@ SHELL = @SHELL@ -LTOBJS = alloc.lo event.lo fatal.lo key_val.lo gidlist.lo lbuf.lo locking.lo \ - parseln.lo progname.lo secure_path.lo setgroups.lo strtobool.lo \ - strtoid.lo strtomode.lo sudo_conf.lo sudo_debug.lo sudo_dso.lo \ - term.lo ttysize.lo @COMMON_OBJS@ @LTLIBOBJS@ +LTOBJS = alloc.lo event.lo fatal.lo key_val.lo gidlist.lo lbuf.lo \ + locking.lo parseln.lo progname.lo secure_path.lo setgroups.lo \ + strtobool.lo strtoid.lo strtomode.lo sudo_conf.lo sudo_debug.lo \ + sudo_dso.lo term.lo ttysize.lo @COMMON_OBJS@ @LTLIBOBJS@ ATOFOO_TEST_OBJS = atofoo_test.lo locale_stub.lo @@ -400,6 +400,10 @@ locale_stub.lo: $(top_srcdir)/src/locale_stub.c $(incdir)/sudo_compat.h \ $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \ $(top_builddir)/config.h $(LIBTOOL) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(DEFS) $(top_srcdir)/src/locale_stub.c +locale_weak.lo: $(srcdir)/locale_weak.c $(incdir)/sudo_compat.h \ + $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \ + $(top_builddir)/config.h + $(LIBTOOL) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(DEFS) $(srcdir)/locale_weak.c locking.lo: $(srcdir)/locking.c $(incdir)/compat/stdbool.h \ $(incdir)/sudo_compat.h $(incdir)/sudo_debug.h \ $(incdir)/sudo_queue.h $(incdir)/sudo_util.h \ diff --git a/lib/util/locale_weak.c b/lib/util/locale_weak.c new file mode 100644 index 000000000..937138442 --- /dev/null +++ b/lib/util/locale_weak.c @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2013-2015 Todd C. Miller + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include + +#include + +#ifdef HAVE_SYS_WEAK_ALIAS + +#include +#include +#ifdef HAVE_STRING_H +# include +#endif /* HAVE_STRING_H */ +#ifdef HAVE_STRINGS_H +# include +#endif /* HAVE_STRINGS_H */ + +#define DEFAULT_TEXT_DOMAIN "sudo" +#include "sudo_gettext.h" /* must be included before sudo_compat.h */ + +#include "sudo_compat.h" +#include "sudo_fatal.h" + +/* + * Weak symbols for sudo_warn_gettext_v1() and sudo_warn_strerror_v1(). + * These stubs are provided to make libsudo_util link with no undefined + * symbols. + */ + +# ifdef HAVE_LIBINTL_H +/* We only need to swap locales in the plugin. */ +char * +sudo_warn_gettext_weak(const char *msgid) +{ + return gettext(msgid); +} +# if defined(HAVE_SYS_WEAK_ALIAS_ATTRIBUTE) +char *sudo_warn_gettext_v1(const char *msgid) + __attribute__((weak, alias("sudo_warn_gettext_weak"))); +# elif defined(HAVE_SYS_WEAK_ALIAS_PRAGMA) +# pragma weak sudo_warn_gettext_v1 = sudo_warn_gettext_weak +# elif defined(HAVE_SYS_WEAK_ALIAS_HPSECONDARY) +# pragma _HP_SECONDARY_DEF sudo_warn_gettext_weak sudo_warn_gettext_v1 +# elif defined(HAVE_SYS_WEAK_ALIAS_CRIDUPLICATE) +# pragma _CRI duplicate sudo_warn_gettext_v1 as sudo_warn_gettext_weak +# endif +# endif /* HAVE_LIBINTL_H */ + +/* We only need to swap locales in the plugin. */ +char * +sudo_warn_strerror_weak(int errnum) +{ + return strerror(errnum); +} +# if defined(HAVE_SYS_WEAK_ALIAS_ATTRIBUTE) +char *sudo_warn_strerror_v1(int errnum) + __attribute__((weak, alias("sudo_warn_strerror_weak"))); +# elif defined(HAVE_SYS_WEAK_ALIAS_PRAGMA) +# pragma weak sudo_warn_strerror_v1 = sudo_warn_strerror_weak +# elif defined(HAVE_SYS_WEAK_ALIAS_HPSECONDARY) +# pragma _HP_SECONDARY_DEF sudo_warn_strerror_weak sudo_warn_strerror_v1 +# elif defined(HAVE_SYS_WEAK_ALIAS_CRIDUPLICATE) +# pragma _CRI duplicate sudo_warn_strerror_v1 as sudo_warn_strerror_weak +# endif + +#endif /* HAVE_SYS_WEAK_ALIAS */ diff --git a/m4/ax_sys_weak_alias.m4 b/m4/ax_sys_weak_alias.m4 new file mode 100644 index 000000000..e1bfd3365 --- /dev/null +++ b/m4/ax_sys_weak_alias.m4 @@ -0,0 +1,337 @@ +# =========================================================================== +# http://www.gnu.org/software/autoconf-archive/ax_sys_weak_alias.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_SYS_WEAK_ALIAS +# +# DESCRIPTION +# +# Determines whether weak aliases are supported on the system, and if so, +# what scheme is used to declare them. Also checks to see if aliases can +# cross object file boundaries, as some systems don't permit them to. +# +# Most systems permit something called a "weak alias" or "weak symbol." +# These aliases permit a library to provide a stub form of a routine +# defined in another library, thus allowing the first library to operate +# even if the other library is not linked. This macro will check for +# support of weak aliases, figure out what schemes are available, and +# determine some characteristics of the weak alias support -- primarily, +# whether a weak alias declared in one object file may be referenced from +# another object file. +# +# There are four known schemes of declaring weak symbols; each scheme is +# checked in turn, and the first one found is prefered. Note that only one +# of the mentioned preprocessor macros will be defined! +# +# 1. Function attributes +# +# This scheme was first introduced by the GNU C compiler, and attaches +# attributes to particular functions. It is among the easiest to use, and +# so is the first one checked. If this scheme is detected, the +# preprocessor macro HAVE_SYS_WEAK_ALIAS_ATTRIBUTE will be defined to 1. +# This scheme is used as in the following code fragment: +# +# void __weakf(int c) +# { +# /* Function definition... */ +# } +# +# void weakf(int c) __attribute__((weak, alias("__weakf"))); +# +# 2. #pragma weak +# +# This scheme is in use by many compilers other than the GNU C compiler. +# It is also particularly easy to use, and fairly portable -- well, as +# portable as these things get. If this scheme is detected first, the +# preprocessor macro HAVE_SYS_WEAK_ALIAS_PRAGMA will be defined to 1. This +# scheme is used as in the following code fragment: +# +# extern void weakf(int c); +# #pragma weak weakf = __weakf +# void __weakf(int c) +# { +# /* Function definition... */ +# } +# +# 3. #pragma _HP_SECONDARY_DEF +# +# This scheme appears to be in use by the HP compiler. As it is rather +# specialized, this is one of the last schemes checked. If it is the first +# one detected, the preprocessor macro HAVE_SYS_WEAK_ALIAS_HPSECONDARY +# will be defined to 1. This scheme is used as in the following code +# fragment: +# +# extern void weakf(int c); +# #pragma _HP_SECONDARY_DEF __weakf weakf +# void __weakf(int c) +# { +# /* Function definition... */ +# } +# +# 4. #pragma _CRI duplicate +# +# This scheme appears to be in use by the Cray compiler. As it is rather +# specialized, it too is one of the last schemes checked. If it is the +# first one detected, the preprocessor macro +# HAVE_SYS_WEAK_ALIAS_CRIDUPLICATE will be defined to 1. This scheme is +# used as in the following code fragment: +# +# extern void weakf(int c); +# #pragma _CRI duplicate weakf as __weakf +# void __weakf(int c) +# { +# /* Function definition... */ +# } +# +# In addition to the preprocessor macros listed above, if any scheme is +# found, the preprocessor macro HAVE_SYS_WEAK_ALIAS will also be defined +# to 1. +# +# Once a weak aliasing scheme has been found, a check will be performed to +# see if weak aliases are honored across object file boundaries. If they +# are, the HAVE_SYS_WEAK_ALIAS_CROSSFILE preprocessor macro is defined to +# 1. +# +# This Autoconf macro also makes two substitutions. The first, WEAK_ALIAS, +# contains the name of the scheme found (one of "attribute", "pragma", +# "hpsecondary", or "criduplicate"), or "no" if no weak aliasing scheme +# was found. The second, WEAK_ALIAS_CROSSFILE, is set to "yes" or "no" +# depending on whether or not weak aliases may cross object file +# boundaries. +# +# LICENSE +# +# Copyright (c) 2008 Kevin L. Mitchell +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. This file is offered as-is, without any +# warranty. + +#serial 6 + +AU_ALIAS([KLM_SYS_WEAK_ALIAS], [AX_SYS_WEAK_ALIAS]) +AC_DEFUN([AX_SYS_WEAK_ALIAS], [ + # starting point: no aliasing scheme yet... + ax_sys_weak_alias=no + + # Figure out what kind of aliasing may be supported... + _AX_SYS_WEAK_ALIAS_ATTRIBUTE + _AX_SYS_WEAK_ALIAS_PRAGMA + _AX_SYS_WEAK_ALIAS_HPSECONDARY + _AX_SYS_WEAK_ALIAS_CRIDUPLICATE + + # Do we actually support aliasing? + AC_CACHE_CHECK([how to create weak aliases with $CC], + [ax_cv_sys_weak_alias], + [ax_cv_sys_weak_alias=$ax_sys_weak_alias]) + + # OK, set a #define + AS_IF([test $ax_cv_sys_weak_alias != no], [ + AC_DEFINE([HAVE_SYS_WEAK_ALIAS], 1, + [Define this if your system can create weak aliases]) + ]) + + # Can aliases cross object file boundaries? + _AX_SYS_WEAK_ALIAS_CROSSFILE + + # OK, remember the results + AC_SUBST([WEAK_ALIAS], [$ax_cv_sys_weak_alias]) + AC_SUBST([WEAK_ALIAS_CROSSFILE], [$ax_cv_sys_weak_alias_crossfile]) +]) + +AC_DEFUN([_AX_SYS_WEAK_ALIAS_ATTRIBUTE], +[ # Test whether compiler accepts __attribute__ form of weak aliasing + AC_CACHE_CHECK([whether $CC accepts function __attribute__((weak,alias()))], + [ax_cv_sys_weak_alias_attribute], [ + # We add -Werror if it's gcc to force an error exit if the weak attribute + # isn't understood + AS_IF([test $GCC = yes], [ + save_CFLAGS=$CFLAGS + CFLAGS=-Werror]) + + # Try linking with a weak alias... + AC_LINK_IFELSE([ + AC_LANG_PROGRAM([ +void __weakf(int c) {} +void weakf(int c) __attribute__((weak, alias("__weakf")));], + [weakf(0)])], + [ax_cv_sys_weak_alias_attribute=yes], + [ax_cv_sys_weak_alias_attribute=no]) + + # Restore original CFLAGS + AS_IF([test $GCC = yes], [ + CFLAGS=$save_CFLAGS]) + ]) + + # What was the result of the test? + AS_IF([test $ax_sys_weak_alias = no && + test $ax_cv_sys_weak_alias_attribute = yes], [ + ax_sys_weak_alias=attribute + AC_DEFINE([HAVE_SYS_WEAK_ALIAS_ATTRIBUTE], 1, + [Define this if weak aliases may be created with __attribute__]) + ]) +]) + +AC_DEFUN([_AX_SYS_WEAK_ALIAS_PRAGMA], +[ # Test whether compiler accepts #pragma form of weak aliasing + AC_CACHE_CHECK([whether $CC supports @%:@pragma weak], + [ax_cv_sys_weak_alias_pragma], [ + + # Try linking with a weak alias... + AC_LINK_IFELSE([ + AC_LANG_PROGRAM([ +extern void weakf(int c); +@%:@pragma weak weakf = __weakf +void __weakf(int c) {}], + [weakf(0)])], + [ax_cv_sys_weak_alias_pragma=yes], + [ax_cv_sys_weak_alias_pragma=no]) + ]) + + # What was the result of the test? + AS_IF([test $ax_sys_weak_alias = no && + test $ax_cv_sys_weak_alias_pragma = yes], [ + ax_sys_weak_alias=pragma + AC_DEFINE([HAVE_SYS_WEAK_ALIAS_PRAGMA], 1, + [Define this if weak aliases may be created with @%:@pragma weak]) + ]) +]) + +AC_DEFUN([_AX_SYS_WEAK_ALIAS_HPSECONDARY], +[ # Test whether compiler accepts _HP_SECONDARY_DEF pragma from HP... + AC_CACHE_CHECK([whether $CC supports @%:@pragma _HP_SECONDARY_DEF], + [ax_cv_sys_weak_alias_hpsecondary], [ + + # Try linking with a weak alias... + AC_LINK_IFELSE([ + AC_LANG_PROGRAM([ +extern void weakf(int c); +@%:@pragma _HP_SECONDARY_DEF __weakf weakf +void __weakf(int c) {}], + [weakf(0)])], + [ax_cv_sys_weak_alias_hpsecondary=yes], + [ax_cv_sys_weak_alias_hpsecondary=no]) + ]) + + # What was the result of the test? + AS_IF([test $ax_sys_weak_alias = no && + test $ax_cv_sys_weak_alias_hpsecondary = yes], [ + ax_sys_weak_alias=hpsecondary + AC_DEFINE([HAVE_SYS_WEAK_ALIAS_HPSECONDARY], 1, + [Define this if weak aliases may be created with @%:@pragma _HP_SECONDARY_DEF]) + ]) +]) + +AC_DEFUN([_AX_SYS_WEAK_ALIAS_CRIDUPLICATE], +[ # Test whether compiler accepts "_CRI duplicate" pragma from Cray + AC_CACHE_CHECK([whether $CC supports @%:@pragma _CRI duplicate], + [ax_cv_sys_weak_alias_criduplicate], [ + + # Try linking with a weak alias... + AC_LINK_IFELSE([ + AC_LANG_PROGRAM([ +extern void weakf(int c); +@%:@pragma _CRI duplicate weakf as __weakf +void __weakf(int c) {}], + [weakf(0)])], + [ax_cv_sys_weak_alias_criduplicate=yes], + [ax_cv_sys_weak_alias_criduplicate=no]) + ]) + + # What was the result of the test? + AS_IF([test $ax_sys_weak_alias = no && + test $ax_cv_sys_weak_alias_criduplicate = yes], [ + ax_sys_weak_alias=criduplicate + AC_DEFINE([HAVE_SYS_WEAK_ALIAS_CRIDUPLICATE], 1, + [Define this if weak aliases may be created with @%:@pragma _CRI duplicate]) + ]) +]) + +dnl Note: This macro is modeled closely on AC_LINK_IFELSE, and in fact +dnl depends on some implementation details of that macro, particularly +dnl its use of _AC_MSG_LOG_CONFTEST to log the failed test program and +dnl its use of ac_link for running the linker. +AC_DEFUN([_AX_SYS_WEAK_ALIAS_CROSSFILE], +[ # Check to see if weak aliases can cross object file boundaries + AC_CACHE_CHECK([whether $CC supports weak aliases across object file boundaries], + [ax_cv_sys_weak_alias_crossfile], [ + AS_IF([test $ax_cv_sys_weak_alias = no], + [ax_cv_sys_weak_alias_crossfile=no], [ +dnl Must build our own test files... + # conftest1 contains our weak alias definition... + cat >conftest1.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF + cat confdefs.h >>conftest1.$ac_ext + cat >>conftest1.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +@%:@ifndef HAVE_SYS_WEAK_ALIAS_ATTRIBUTE +extern void weakf(int c); +@%:@endif +@%:@if defined(HAVE_SYS_WEAK_ALIAS_PRAGMA) +@%:@pragma weak weakf = __weakf +@%:@elif defined(HAVE_SYS_WEAK_ALIAS_HPSECONDARY) +@%:@pragma _HP_SECONDARY_DEF __weakf weakf +@%:@elif defined(HAVE_SYS_WEAK_ALIAS_CRIDUPLICATE) +@%:@pragma _CRI duplicate weakf as __weakf +@%:@endif +void __weakf(int c) {} +@%:@ifdef HAVE_SYS_WEAK_ALIAS_ATTRIBUTE +void weakf(int c) __attribute((weak, alias("__weakf"))); +@%:@endif +_ACEOF + # And conftest2 contains our main routine that calls it + cat >conftest2.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF + cat confdefs.h >> conftest2.$ac_ext + cat >>conftest2.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +extern void weakf(int c); +int +main () +{ + weakf(0); + return 0; +} +_ACEOF + # We must remove the object files (if any) ourselves... + rm -f conftest2.$ac_objext conftest$ac_exeext + + # Change ac_link to compile *2* files together + save_aclink=$ac_link + ac_link=`echo "$ac_link" | \ + sed -e 's/conftest\(\.\$ac_ext\)/conftest1\1 conftest2\1/'` +dnl Substitute our own routine for logging the conftest +m4_pushdef([_AC_MSG_LOG_CONFTEST], +[echo "$as_me: failed program was:" >&AS_MESSAGE_LOG_FD +echo ">>> conftest1.$ac_ext" >&AS_MESSAGE_LOG_FD +sed "s/^/| /" conftest1.$ac_ext >&AS_MESSAGE_LOG_FD +echo ">>> conftest2.$ac_ext" >&AS_MESSAGE_LOG_FD +sed "s/^/| /" conftest2.$ac_ext >&AS_MESSAGE_LOG_FD +])dnl + # Since we created the files ourselves, don't use SOURCE argument + AC_LINK_IFELSE(, [ax_cv_sys_weak_alias_crossfile=yes], + [ax_cv_sys_weak_alias_crossfile=no]) +dnl Restore _AC_MSG_LOG_CONFTEST +m4_popdef([_AC_MSG_LOG_CONFTEST])dnl + # Restore ac_link + ac_link=$save_aclink + + # We must remove the object files (if any) and C files ourselves... + rm -f conftest1.$ac_ext conftest2.$ac_ext \ + conftest1.$ac_objext conftest2.$ac_objext + ]) + ]) + + # What were the results of the test? + AS_IF([test $ax_cv_sys_weak_alias_crossfile = yes], [ + AC_DEFINE([HAVE_SYS_WEAK_ALIAS_CROSSFILE], 1, + [Define this if weak aliases in other files are honored]) + ]) +]) diff --git a/mkdep.pl b/mkdep.pl index bfeae9c29..b3326f0ab 100755 --- a/mkdep.pl +++ b/mkdep.pl @@ -65,7 +65,7 @@ sub mkdep { # Expand some configure bits $makefile =~ s:\@DEV\@::g; - $makefile =~ s:\@COMMON_OBJS\@:aix.lo event_poll.lo event_select.lo:; + $makefile =~ s:\@COMMON_OBJS\@:aix.lo event_poll.lo event_select.lo locale_weak.lo:; $makefile =~ s:\@SUDO_OBJS\@:openbsd.o preload.o selinux.o sesh.o solaris.o sudo_noexec.lo:; $makefile =~ s:\@SUDOERS_OBJS\@:bsm_audit.lo linux_audit.lo ldap.lo solaris_audit.lo sssd.lo:; # XXX - fill in AUTH_OBJS from contents of the auth dir instead diff --git a/src/Makefile.in b/src/Makefile.in index 69e430e9a..6dbf1f2cf 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -1,5 +1,5 @@ # -# Copyright (c) 2010-2014 Todd C. Miller +# Copyright (c) 2010-2015 Todd C. Miller # # Permission to use, copy, modify, and distribute this software for any # purpose with or without fee is hereby granted, provided that the above @@ -103,7 +103,7 @@ OBJS = conversation.o env_hooks.o exec.o exec_common.o exec_pty.o \ preserve_fds.o signal.o sudo.o sudo_edit.o tgetpass.o ttyname.o \ utmp.o @SUDO_OBJS@ -SESH_OBJS = sesh.o locale_stub.o exec_common.o +SESH_OBJS = sesh.o exec_common.o locale_stub.o CHECK_TTYNAME_OBJS = check_ttyname.o locale_stub.o ttyname.o diff --git a/src/locale_stub.c b/src/locale_stub.c index 3dc6b4637..b9bcd7082 100644 --- a/src/locale_stub.c +++ b/src/locale_stub.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2014 Todd C. Miller + * Copyright (c) 2013-2015 Todd C. Miller * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -18,6 +18,8 @@ #include +#if !defined(HAVE_SYS_WEAK_ALIAS) + #include #include #ifdef HAVE_STRING_H @@ -48,3 +50,5 @@ sudo_warn_strerror_v1(int errnum) { return strerror(errnum); } + +#endif /* !HAVE_SYS_WEAK_ALIAS */