pullup from trunk
authorTom Yu <tlyu@mit.edu>
Thu, 7 Apr 2005 21:38:55 +0000 (21:38 +0000)
committerTom Yu <tlyu@mit.edu>
Thu, 7 Apr 2005 21:38:55 +0000 (21:38 +0000)
ticket: 2981
version_fixed: 1.4.1

git-svn-id: svn://anonsvn.mit.edu/krb5/branches/krb5-1-4@17169 dc483132-0cff-0310-8789-dd5450dbe970

src/config/ChangeLog
src/config/lib.in
src/config/shlib.conf
src/include/ChangeLog
src/include/k5-platform.h

index ba2c712af574d456d6694f718761fb44993c5c34..b8221ff92395f90d6b5c97b0c34e051d28ecfe8e 100644 (file)
@@ -1,3 +1,13 @@
+2005-03-25  Ken Raeburn  <raeburn@mit.edu>
+
+       * lib.in (hpux10.exports): New target, constructed similar to
+       osf1.exports but with HP-UX 10.x linker options, no initializers,
+       and "errno" explicitly added to the export list.
+       * shlib.conf (*-*-hpux*): Combine PICFLAGS setting with
+       SHLIB_EXPFLAGS and LDCOMBINE setting.  Add linker option "-c
+       hpux10.exports" to LDCOMBINE.  Set SHLIB_EXPORT_FILE_DEP to
+       hpux10.exports.  Set use_linker_fini_option.
+
 2005-02-08  Ken Raeburn  <raeburn@mit.edu>
 
        * lib.in (config.status): Change target to be in $thisconfigdir
index eea4601d594e03470a40615e5fa16455b3c91201..ef159f528cbcdc459ac9ba56009a4ca5f60bbf46 100644 (file)
@@ -72,6 +72,18 @@ osf1.exports: $(SHLIB_EXPORT_FILE) Makefile
        done; echo " $$a" >> osf1.tmp; \
        mv -f osf1.tmp osf1.exports
 
+hpux10.exports: $(SHLIB_EXPORT_FILE) Makefile
+       $(RM) hpux10.tmp hpux10.exports
+       sed "s/^/+e /" < $(SHLIB_EXPORT_FILE) > hpux10.tmp
+       a=""; \
+       for f in . $(LIBFINIFUNC); do \
+         if test "$$f" != .; then \
+           a="+I $${f}__auxfini $$a"; \
+         else :; fi; \
+       done; echo "$$a" >> hpux10.tmp
+       echo "+e errno" >> hpux10.tmp
+       mv -f hpux10.tmp hpux10.exports
+
 lib$(LIBBASE)$(PFLIBEXT): $(PFOBJLISTS)
        $(RM) $@
        @echo "building profiled $(LIBBASE) library"
index 4d09e84e464448651a8513b8d612ec73d7d200ee..3261b672ceff8281576483469d8f8ca6b8251787 100644 (file)
@@ -75,27 +75,42 @@ alpha*-dec-osf*)
 # on the commandline of the linker will determine which path
 # (compiled-in or SHLIB_PATH) will be searched first.
 #
+# +I initproc routine gets called at load and unload time for
+#    shl_load calls, but appears to never be called for link-time
+#    specified libraries.
+# +e sym exports symbol and supposedly prevents other symbols
+#    from being exported, according to the man page, but the
+#    latter bit doesn't actually seem to work
+# -O +dpv should display any routines eliminated as unused, but -b
+#        apparently turns that off
 *-*-hpux*)
-       if test "$krb5_cv_prog_gcc" = yes; then
-               PICFLAGS=-fPIC
-       else
-               PICFLAGS=+z
-       fi
        INSTALL_SHLIB='$(INSTALL)'
        SHLIBEXT=.sl
        SHLIBVEXT='.$(LIBMAJOR).$(LIBMINOR)'
        SHLIBSEXT='.$(LIBMAJOR)'
        RPATH_FLAG='-Wl,+b,'
        if test "$krb5_cv_prog_gcc" = yes; then
+               PICFLAGS=-fPIC
                SHLIB_EXPFLAGS='-Wl,+s -Wl,+b,$(SHLIB_RDIRS) $(SHLIB_DIRS) $(SHLIB_EXPLIBS)'
-               LDCOMBINE='gcc -fPIC -shared -Wl,+h,lib$(LIBBASE)$(SHLIBSEXT)'
+               LDCOMBINE='gcc -fPIC -shared -Wl,+h,lib$(LIBBASE)$(SHLIBSEXT) -Wl,-c,hpux10.exports'
        else
+               PICFLAGS=+z
                SHLIB_EXPFLAGS='+s +b $(SHLIB_RDIRS) $(SHLIB_DIRS) $(SHLIB_EXPLIBS)'
-               LDCOMBINE='ld -b +h lib$(LIBBASE)$(SHLIBSEXT)'
+               LDCOMBINE='ld -b +h lib$(LIBBASE)$(SHLIBSEXT) -c hpux10.exports'
        fi
        CC_LINK_SHARED='$(CC) $(PROG_LIBPATH) -Wl,+s $(RPATH_FLAG)$(PROG_RPATH) $(CFLAGS) $(LDFLAGS)'
        CC_LINK_STATIC='$(CC) $(PROG_LIBPATH) $(CFLAGS) $(LDFLAGS)'
        RUN_ENV='SHLIB_PATH=`echo $(PROG_LIBPATH) | sed -e "s/-L//g" -e "s/ /:/g"`; export SHLIB_PATH;'
+       SHLIB_EXPORT_FILE_DEP=hpux10.exports
+       # Do *not* set use_linker_init_option=yes here, because in the
+       # case where the library is specified at program link time, the
+       # initialization function appears not to get called, only for
+       # shl_load.  But for finalization functions, the shl_load case
+       # is the one we care about.
+       #
+       # Not setting use_linker_init_option here should cause compilation
+       # failures if the user tries to disable delayed initialization.
+       use_linker_fini_option=yes
        ;;
 
 mips-sgi-irix6.3)      # This is a Kludge; see below
index 29358cafd638d2d773914dece6d4656227096799..7ecb536b7ad186372038f47b72efdf15a6765302 100644 (file)
@@ -1,3 +1,10 @@
+2005-03-25  Ken Raeburn  <raeburn@mit.edu>
+
+       * k5-platform.h: Expand on init/fini comments some more.
+       (MAKE_FINI_FUNCTION): Add an HP-UX specific variant that defines
+       an auxiliary function fitting the signature of HP-UX 10 library
+       combined initializer/finalizer functions.
+
 2005-03-04  Ken Raeburn  <raeburn@mit.edu>
 
        * configure.in: Check return type of gmtime_r, and define
index 5c634bfc4100202782f7fa54bae8d347917a1347..b178622d8702840f205742f0e0bb38aa7bc449bc 100644 (file)
    At top level, before the functions are defined or even declared:
    MAKE_INIT_FUNCTION(init_fn);
    MAKE_FINI_FUNCTION(fini_fn);
+   Then:
    int init_fn(void) { ... }
    void fini_fn(void) { if (INITIALIZER_RAN(init_fn)) ... }
-
    In code, in the same file:
    err = CALL_INIT_FUNCTION(init_fn);
 
    To trigger or verify the initializer invocation from another file,
-   an additional function must be created.
+   a helper function must be created.
+
+   This model handles both the load-time execution (Windows) and
+   delayed execution (pthread_once) approaches, and should be able to
+   guarantee in both cases that the init function is run once, in one
+   thread, before other stuff in the library is done; furthermore, the
+   finalization code should only run if the initialization code did.
+   (Maybe I could've made the "if INITIALIZER_RAN" test implicit, via
+   another function hidden in macros, but this is hairy enough
+   already.)
 
    The init_fn and fini_fn names should be chosen such that any
    exported names staring with those names, and optionally followed by
    the library in question.
 
 
+   There's also PROGRAM_EXITING() currently always defined as zero.
+   If there's some trivial way to find out if the fini function is
+   being called because the program that the library is linked into is
+   exiting, we can just skip all the work because the resources are
+   about to be freed up anyways.  Generally this is likely to be the
+   same as distinguishing whether the library was loaded dynamically
+   while the program was running, or loaded as part of program
+   startup.  On most platforms, I don't think we can distinguish these
+   cases easily, and it's probably not worth expending any significant
+   effort.  (Note in particular that atexit() won't do, because if the
+   library is explicitly loaded and unloaded, it would have to be able
+   to deregister the atexit callback function.  Also, the system limit
+   on atexit callbacks may be small.)
+
+
    Implementation outline:
 
    Windows: MAKE_FINI_FUNCTION creates a symbol with a magic name that
    just check the flag) and returns the stored error code (or the
    pthread_once error).
 
+   (That's the basic idea.  With some debugging assert() calls and
+   such, it's a bit more complicated.  And we also need to handle
+   doing the pthread test at run time on systems where that works, so
+   we use the k5_once_t stuff instead.)
+
    UNIX, with compiler support: MAKE_FINI_FUNCTION declares the
    function as a destructor, and the run time linker support or
    whatever will cause it to be invoked when the library is unloaded,
    UNIX, no library finalization support: The finalization function
    never runs, and we leak memory.  Tough.
 
+   DELAY_INITIALIZER will be defined by the configure script if we
+   want to use k5_once instead of load-time initialization.  That'll
+   be the preferred method on most systems except Windows, where we
+   have to initialize some mutexes.
+
+
 
 
    For maximum flexibility in defining the macros, the function name
    parameter should be a simple name, not even a macro defined as
    another name.  The function should have a unique name, and should
    conform to whatever namespace is used by the library in question.
+   (We do have export lists, but (1) they're not used for all
+   platforms, and (2) they're not used for static libraries.)
 
    If the macro expansion needs the function to have been declared, it
    must include a declaration.  If it is not necessary for the symbol
 
    This is going to be compiler- and environment-specific, and may
    require some support at library build time, and/or "asm"
-   statements.
+   statements.  But through macro expansion and auxiliary functions,
+   we should be able to handle most things except #pragma.
 
    It's okay for this code to require that the library be built
    with the same compiler and compiler options throughout, but
    work, we'll only have memory leaks in a load/use/unload cycle.  If
    anyone (like, say, the OS vendor) complains about this, they can
    tell us how to get a shared library finalization function invoked
-   automatically.  */
+   automatically.
+
+   Currently there's --disable-delayed-initialization for preventing
+   the initialization from being delayed on UNIX, but that's mainly
+   just for testing the linker options for initialization, and will
+   probably be removed at some point.  */
 
 /* Helper macros.  */
 
@@ -194,8 +237,11 @@ static inline int k5_call_init_function(k5_init_t *i)
    multiple active threads mucking around in our library at this
    point.  So ignore the once_t object and just look at the flag.
 
-   XXX Could we have problems with memory coherence between
-   processors if we don't invoke mutex/once routines?  */
+   XXX Could we have problems with memory coherence between processors
+   if we don't invoke mutex/once routines?  Probably not, the
+   application code should already be coordinating things such that
+   the library code is not in use by this point, and memory
+   synchronization will be needed there.  */
 # define INITIALIZER_RAN(NAME) \
        (JOIN__2(NAME, once).did_run && JOIN__2(NAME, once).error == 0)
 
@@ -206,6 +252,7 @@ static inline int k5_call_init_function(k5_init_t *i)
 /* Run initializer at load time, via GCC/C++ hook magic.  */
 
 # ifdef USE_LINKER_INIT_OPTION
+     /* Both gcc and linker option??  Favor gcc.  */
 #  define MAYBE_DUMMY_INIT(NAME)               \
        void JOIN__2(NAME, auxinit) () { }
 # else
@@ -273,9 +320,35 @@ typedef struct { int error; unsigned char did_run; } k5_init_t;
    matter what compiler we're using.  Do it the same way
    regardless.  */
 
-# define MAKE_FINI_FUNCTION(NAME)      \
+# ifdef __hpux
+
+     /* On HP-UX, we need this auxiliary function.  At dynamic load or
+       unload time (but *not* program startup and termination for
+       link-time specified libraries), the linker-indicated function
+       is called with a handle on the library and a flag indicating
+       whether it's being loaded or unloaded.
+
+       The "real" fini function doesn't need to be exported, so
+       declare it static.
+
+       As usual, the final declaration is just for syntactic
+       convenience, so the top-level invocation of this macro can be
+       followed by a semicolon.  */
+
+#  include <dl.h>
+#  define MAKE_FINI_FUNCTION(NAME)                                         \
+       static void NAME(void);                                             \
+       void JOIN__2(NAME, auxfini)(shl_t, int); /* silence gcc warnings */ \
+       void JOIN__2(NAME, auxfini)(shl_t h, int l) { if (!l) NAME(); }     \
+       static void NAME(void)
+
+# else /* not hpux */
+
+#  define MAKE_FINI_FUNCTION(NAME)     \
        void NAME(void)
 
+# endif
+
 #elif defined(__GNUC__) && defined(DESTRUCTOR_ATTR_WORKS)
 /* If we're using gcc, if the C++ support works, the compiler should
    build executables and shared libraries that support the use of