From: Gary V. Vaughan Date: Tue, 1 Dec 1998 18:24:08 +0000 (+0000) Subject: Test for leading underscore on compiled symbols at configure time. X-Git-Tag: release-1-2d~36 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=efbf1218c568d5f2ed6a59c6700c14a44d45af5e;p=thirdparty%2Flibtool.git Test for leading underscore on compiled symbols at configure time. Use the results of that test in the demo program. --- diff --git a/ChangeLog b/ChangeLog index 54382885e..784dd8171 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,15 @@ +1998-12-01 Gary V. Vaughan + + * libtool.m4 (AM_SYS_SYMBOL_UNDERSCORE): New macro; find out + whether compiled symbols have an extra leading underscore. + (AM_SYS_NM_PARSE): New macro (converted to m4 from ltconfig.in); + find a sed expression to parse global symbols from the output of + $NM. + (AM_PROG_LIBTOOL): require AM_SYS_NM_PARSE and + AM_SYS_SYMBOL_UNDERSCORE. + * demo/dlmain.c (main): Remove a single leading underscore from + compiled symbol names if necessary. + 1998-12-01 Alexandre Oliva * config.guess, config.sub: imported from autoconf pre-2.13 @@ -5,7 +17,7 @@ 1998-11-27 Gary V. Vaughan * libtool (AM_PROG_LD): Oops... we need to know the host_os for - the above changes. I'm not sure whether mingw32 and os2 support + the changes below. I'm not sure whether mingw32 and os2 support UNC paths, if they did we wouldn't need the check, we could use UNC paths on all three; or if the bug with $LD not being shell-meta escaped was fixed, we could use '\\' separators on all diff --git a/demo/dlmain.c b/demo/dlmain.c index c0268faf4..1374aa49e 100644 --- a/demo/dlmain.c +++ b/demo/dlmain.c @@ -46,13 +46,21 @@ main (argc, argv) while (s->name) { if (s->address) { - /* FIXME: we are simplistic about leading underscores. */ - printf ("found symbol: %s\n", s->name); - if (!strcmp ("hello", s->name)) + char *name = s->name; +#ifdef WITH_SYMBOL_UNDERSCORE + if (*name != '_') + { + fprintf(stderr, "ERROR: configure detected leading underscores incorrectly.\n"); + exit(1); + } + name++; +#endif + printf ("found symbol: %s\n", name); + if (!strcmp ("hello", name)) phello = s->address; - else if (!strcmp ("foo", s->name)) + else if (!strcmp ("foo", name)) pfoo = s->address; - else if (!strcmp ("nothing", s->name)) + else if (!strcmp ("nothing", name)) pnothing = s->address; } else printf ("found file: %s\n", s->name); diff --git a/libtool.m4 b/libtool.m4 index 8131e3674..7a0e1d981 100644 --- a/libtool.m4 +++ b/libtool.m4 @@ -31,6 +31,8 @@ AC_REQUIRE([AC_PROG_RANLIB])dnl AC_REQUIRE([AC_PROG_CC])dnl AC_REQUIRE([AM_PROG_LD])dnl AC_REQUIRE([AM_PROG_NM])dnl +AC_REQUIRE([AM_SYS_NM_PARSE])dnl +AC_REQUIRE([AM_SYS_SYMBOL_UNDERSCORE])dnl AC_REQUIRE([AC_PROG_LN_S])dnl dnl # Always use our own libtool. @@ -324,8 +326,218 @@ AC_MSG_RESULT([$NM]) AC_SUBST(NM) ]) +# AM_SYS_NM_PARSE - Check for command ro grab the raw symbol name followed +# by C symbol name from nm. +AC_DEFUN(AM_SYS_NM_PARSE, +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AM_PROG_NM])dnl +# Check for command to grab the raw symbol name followed by C symbol from nm. +AC_MSG_CHECKING([command to parse $NM output]) +AC_CACHE_VAL(ac_cv_sys_global_symbol_pipe, +[# These are sane defaults that work on at least a few old systems. +# {They come from Ultrix. What could be older than Ultrix?!! ;)} + +changequote(,)dnl +# Character class describing NM global symbol codes. +ac_symcode='[BCDEGRSTU]' + +# Regexp to match symbols that can be accessed directly from C. +ac_sympat='\([_A-Za-z][_A-Za-z0-9]*\)' + +# Transform the above into a raw symbol and a C symbol. +ac_symxfrm='\1 \1' + +# Define system-specific variables. +case "$host_os" in +aix*) + ac_symcode='[BCDTU]' + ;; +sunos* | cygwin32* | mingw32*) + ac_sympat='_\([_A-Za-z][_A-Za-z0-9]*\)' + ac_symxfrm='_\1 \1' + ;; +irix*) + # Cannot use undefined symbols on IRIX because inlined functions mess us up. + ac_symcode='[BCDEGRST]' + ;; +solaris*) + ac_symcode='[BDTU]' + ;; +esac + +# If we're using GNU nm, then use its standard symbol codes. +if $NM -V 2>&1 | egrep '(GNU|with BFD)' > /dev/null; then + ac_symcode='[ABCDGISTUW]' +fi + +case "$host_os" in +cygwin32* | mingw32*) + # We do not want undefined symbols on cygwin32. The user must + # arrange to define them via -l arguments. + ac_symcode='[ABCDGISTW]' + ;; +esac +changequote([,])dnl + +# Write the raw and C identifiers. +ac_cv_sys_global_symbol_pipe="sed -n -e 's/^.* $ac_symcode $ac_sympat$/$ac_symxfrm/p'" + +# Check to see that the pipe works correctly. +ac_pipe_works=no +cat > conftest.$ac_ext < $ac_nlist) && test -s "$ac_nlist"; then + + # Try sorting and uniquifying the output. + if sort "$ac_nlist" | uniq > "$ac_nlist"T; then + mv -f "$ac_nlist"T "$ac_nlist" + ac_wcout=`wc "$ac_nlist" 2>/dev/null` +changequote(,)dnl + ac_count=`echo "X$ac_wcout" | sed -e 's,^X,,' -e 's/^[ ]*\([0-9][0-9]*\).*$/\1/'` +changequote([,])dnl + (test "$ac_count" -ge 0) 2>/dev/null || ac_count=-1 + else + rm -f "$ac_nlist"T + ac_count=-1 + fi + + # Make sure that we snagged all the symbols we need. + if egrep ' nm_test_var$' "$ac_nlist" >/dev/null; then + if egrep ' nm_test_func$' "$ac_nlist" >/dev/null; then + cat < conftest.c +#ifdef __cplusplus +extern "C" { +#endif + +EOF + # Now generate the symbol file. + sed 's/^.* \(.*\)$/extern char \1;/' < "$ac_nlist" >> conftest.c + + cat <> conftest.c +#if defined (__STDC__) && __STDC__ +# define __ptr_t void * +#else +# define __ptr_t char * +#endif + +/* The number of symbols in dld_preloaded_symbols, -1 if unsorted. */ +int dld_preloaded_symbol_count = $ac_count; + +/* The mapping between symbol names and symbols. */ +struct { + char *name; + __ptr_t address; +} +changequote(,)dnl +dld_preloaded_symbols[] = +changequote([,])dnl +{ +EOF + sed 's/^\(.*\) \(.*\)$/ {"\1", (__ptr_t) \&\2},/' < "$ac_nlist" >> conftest.c + cat <<\EOF >> conftest.c + {0, (__ptr_t) 0} +}; + +#ifdef __cplusplus +} +#endif +EOF + # Now try linking the two files. + mv conftest.$ac_objext conftestm.$ac_objext + ac_save_LIBS="$LIBS" + ac_save_CFLAGS="$CFLAGS" + LIBS="conftestm.$ac_objext" + CFLAGS="$CFLAGS$no_builtin_flag" + if AC_TRY_EVAL(ac_link) && test -s conftest; then + ac_pipe_works=yes + else + echo "configure: failed program was:" >&AC_FD_CC + cat conftest.c >&AC_FD_CC + fi + LIBS="$ac_save_LIBS" + CFLAGS="$ac_save_CFLAGS" + else + echo "cannot find nm_test_func in $ac_nlist" >&AC_FD_CC + fi + else + echo "cannot find nm_test_var in $ac_nlist" >&AC_FD_CC + fi + else + echo "cannot run $ac_cv_sys_global_symbol_pipe" >&AC_FD_CC + fi +else + echo "$progname: failed program was:" >&AC_FD_CC + cat conftest.c >&AC_FD_CC +fi +rm -rf conftest* + +# Do not use the global_symbol_pipe unless it works. +test "$ac_pipe_works" = yes || ac_cv_sys_global_symbol_pipe= +]) + +ac_result=yes +if test -z "$ac_cv_sys_global_symbol_pipe"; then + ac_result=no +fi +AC_MSG_RESULT($ac_result) +]) + # AM_SYS_LIBTOOL_CYGWIN32 - find tools needed on cygwin32 AC_DEFUN(AM_SYS_LIBTOOL_CYGWIN32, [AC_CHECK_TOOL(DLLTOOL, dlltool, false) AC_CHECK_TOOL(AS, as, false) ]) + +# AM_SYS_SYMBOL_UNDERSCORE - does the compiler prefix global symbols +# with an underscore? +AC_DEFUN(AM_SYS_SYMBOL_UNDERSCORE, +[AC_REQUIRE([AM_PROG_NM])dnl +AC_REQUIRE([AM_SYS_NM_PARSE])dnl +AC_MSG_CHECKING([for _ prefix in compiled symbols]) +AC_CACHE_VAL(ac_cv_sys_symbol_underscore, +[ac_cv_sys_symbol_underscore=no +cat > conftest.$ac_ext < $ac_nlist) && test -s "$ac_nlist"; then + # See whether the symbols have a leading underscore. + if egrep '^_nm_test_func' "$ac_nlist" >/dev/null; then + ac_cv_sys_symbol_underscore=yes + else + if egrep '^nm_test_func ' "$ac_nlist" >/dev/null; then + : + else + echo "configure: cannot find nm_test_func in $ac_nlist" >&AC_FD_CC + fi + fi + else + echo "configure: cannot run $ac_cv_sys_global_symbol_pipe" >&AC_FD_CC + fi +else + echo "configure: failed program was:" >&AC_FD_CC + cat conftest.c >&AC_FD_CC +fi +rm -rf conftest* +]) +AC_MSG_RESULT($ac_cv_sys_symbol_underscore) +if test x$ac_cv_sys_symbol_underscore == xyes; then + AC_DEFINE(WITH_SYMBOL_UNDERSCORE,1, + [define if compiled symbols have a leading underscore]) +fi +])