On Wed, 2009-06-24 at 11:25 +0200, Michael Haubenwallner wrote:
> On Wed, 2009-05-27 at 00:16 +0200, Michael Haubenwallner wrote:
> > Hi,
> >
> > now I've managed to get 'make install DESTDIR=...' working on
> > hppa-hpux10 and hppa-hpux11 with libtool.
>
> But wait, there's another subtlety: When the 'internal name' of a shared
> library does contain an absolute path instead of just a filename (or
> relative path), this absolute path is recorded as-is in the 'shared
> library list' as the fallback path into subsequent binaries.
>
> I'm playing around with "+h $install_libdir/$soname", to come up with
> another patch to avoid the +cdp thing, which is a mess regarding cmdline
> length.
Ok, here's the third way of supporting DESTDIR on hppa-hpux, now without
the +cdp linker flag (#2), but using the absolute target libdir in the
'internal name' instead, to fix the security issue of #1.
Fix DESTDIR install for hpux10 and hppa-hpux11 (32bit).
* libltdl/m4/libtool.m4: Set hardcode_into_libs=yes, to allow
for dlopening local uninstalled shared libraries even when they
have the final target location encoded as fallback for dependant
local shared libraries. Do not explicitly set runpath (+b linker
flag) in archive_cmds, as this would defeat
hardcode_into_libs=yes. Set hardcode_libdir_flag_spec_ld only
when archive_cmds contains $LD, to get hardcode_into_libs
working.
Add check if gcc does work with nonexistent fallback locations
for dependant shared libraries. If yes, prepend shared library's
'internal name' with "$install_libdir/" to have the final target
location stored into subsequent binaries as fallback instead of
the linktime location. Also set hardcode_minus_L=no in this
case, as it is not hardcoded when 'internal name' contains an
absolute path.
* tests/demo-hardcode.test: Try 'chatr' to read hardcoded paths,
to detect 'static'-type dependant shared libraries, and to avoid
false positives due to cc/aCC storing the cmdline into object
files.
Do you think the change to use absolute path in 'internal name' should
be explicitly mentioned in doc/notes.texi?
This patch does have the same effect on test-results as before: 12 tests
changing from SKIP/XFAIL to PASS on hppa-hpux1[01] 32bit, no result
change for other tests/platforms.
Thank you!
/haubi/
diff --git a/libltdl/m4/libtool.m4 b/libltdl/m4/libtool.m4
index 1fe09d2..dba121e 100644
--- a/libltdl/m4/libtool.m4
+++ b/libltdl/m4/libtool.m4
@@ -2332,6 +2332,10 @@ hpux9* | hpux10* | hpux11*)
shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH
library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
soname_spec='${libname}${release}${shared_ext}$major'
+ case $host_os in
+ hpux9*) ;;
+ *) hardcode_into_libs=yes ;;
+ esac
;;
esac
# HP-UX runs *really* slowly unless shared libraries are mode 555, ...
@@ -4760,25 +4764,64 @@ _LT_EOF
;;
hpux10*)
+ # gcc-3.0.1 does some post-link processing which breaks when the
+ # just created binary has a nonexistent 'dynamic dependency'.
+ AC_CACHE_CHECK([for absolute path of internal name with $CC],
+ [_LT_TAGVAR(lt_cv_abspath_internal_name, $1)],
+ [_LT_TAGVAR(lt_cv_abspath_internal_name, $1)=
+ if test "$GCC" = yes; then
+ save_LDFLAGS=$LDFLAGS
+ LDFLAGS="$LDFLAGS -Wl,+cdp -Wl,/usr/lib:/nonexistent -Wl,+cdp -Wl,/lib:/nonexistent"
+ AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])],
+ [_LT_TAGVAR(lt_cv_abspath_internal_name, $1)='$install_libdir/'],
+ [_LT_TAGVAR(lt_cv_abspath_internal_name, $1)=])
+ LDFLAGS="$save_LDFLAGS"
+ else
+ _LT_TAGVAR(lt_cv_abspath_internal_name, $1)='$install_libdir/'
+ fi
+ ])
if test "$GCC" = yes && test "$with_gnu_ld" = no; then
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC ${wl}+h ${wl}'"[$]_LT_TAGVAR(lt_cv_abspath_internal_name, $1)"'$soname -o $lib $libobjs $deplibs $compiler_flags'
else
- _LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(archive_cmds, $1)='$LD -b +h '"[$]_LT_TAGVAR(lt_cv_abspath_internal_name, $1)"'$soname -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='+b $libdir'
fi
if test "$with_gnu_ld" = no; then
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
- _LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='+b $libdir'
_LT_TAGVAR(hardcode_libdir_separator, $1)=:
_LT_TAGVAR(hardcode_direct, $1)=yes
_LT_TAGVAR(hardcode_direct_absolute, $1)=yes
_LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
# hardcode_minus_L: Not really in the search PATH,
- # but as the default location of the library.
- _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ # but as the default location of the library, when it does not
+ # have an absolute path in 'internal name' (the +h linker flag).
+ if test "X$_LT_TAGVAR(lt_cv_abspath_internal_name, $1)" = X; then
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ else
+ _LT_TAGVAR(hardcode_minus_L, $1)=no
+ fi
fi
;;
hpux11*)
+ case $host_cpu in hppa*64* | ia64*) ;;
+ *)
+ AC_CACHE_CHECK([for absolute path of internal name with $CC],
+ [_LT_TAGVAR(lt_cv_abspath_internal_name, $1)],
+ [_LT_TAGVAR(lt_cv_abspath_internal_name, $1)=
+ if test "$GCC" = yes; then
+ save_LDFLAGS=$LDFLAGS
+ LDFLAGS="$LDFLAGS -Wl,+cdp -Wl,/usr/lib:/nonexistent -Wl,+cdp -Wl,/lib:/nonexistent"
+ AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])],
+ [_LT_TAGVAR(lt_cv_abspath_internal_name, $1)='$install_libdir/'],
+ [_LT_TAGVAR(lt_cv_abspath_internal_name, $1)=])
+ LDFLAGS="$save_LDFLAGS"
+ else
+ _LT_TAGVAR(lt_cv_abspath_internal_name, $1)='$install_libdir/'
+ fi
+ ])
+ ;;
+ esac
if test "$GCC" = yes && test "$with_gnu_ld" = no; then
case $host_cpu in
hppa*64*)
@@ -4788,7 +4831,7 @@ _LT_EOF
_LT_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
;;
*)
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC ${wl}+h ${wl}'"[$]_LT_TAGVAR(lt_cv_abspath_internal_name, $1)"'$soname -o $lib $libobjs $deplibs $compiler_flags'
;;
esac
else
@@ -4805,9 +4848,11 @@ _LT_EOF
# (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does)
_LT_LINKER_OPTION([if $CC understands -b],
_LT_TAGVAR(lt_cv_prog_compiler__b, $1), [-b],
- [_LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'],
- [_LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'])],
- [_LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'])
+ [_LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}'"$_LT_TAGVAR(lt_cv_abspath_internal_name, $1)"'$soname -o $lib $libobjs $deplibs $compiler_flags'],
+ [_LT_TAGVAR(archive_cmds, $1)='$LD -b +h '"$_LT_TAGVAR(lt_cv_abspath_internal_name, $1)"'$soname -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='+b $libdir'
+ ])],
+ [_LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}'"$_LT_TAGVAR(lt_cv_abspath_internal_name, $1)"'$soname -o $lib $libobjs $deplibs $compiler_flags'])
;;
esac
fi
@@ -4826,8 +4871,13 @@ _LT_EOF
_LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
# hardcode_minus_L: Not really in the search PATH,
- # but as the default location of the library.
- _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ # but as the default location of the library, when it does not
+ # have an absolute path in 'internal name' (the +h linker flag).
+ if test "X$_LT_TAGVAR(lt_cv_abspath_internal_name, $1)" = X; then
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ else
+ _LT_TAGVAR(hardcode_minus_L, $1)=no
+ fi
;;
esac
fi
@@ -5749,11 +5799,30 @@ if test "$_lt_caught_CXX_error" != yes; then
_LT_TAGVAR(hardcode_shlibpath_var, $1)=no
;;
*)
+ AC_CACHE_CHECK([for absolute path of internal name with $CC],
+ [_LT_TAGVAR(lt_cv_abspath_internal_name, $1)],
+ [_LT_TAGVAR(lt_cv_abspath_internal_name, $1)=
+ if test "$GCC" = yes; then
+ save_LDFLAGS=$LDFLAGS
+ LDFLAGS="$LDFLAGS -Wl,+cdp -Wl,/usr/lib:/nonexistent -Wl,+cdp -Wl,/lib:/nonexistent"
+ AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])],
+ [_LT_TAGVAR(lt_cv_abspath_internal_name, $1)='$install_libdir/'],
+ [_LT_TAGVAR(lt_cv_abspath_internal_name, $1)=])
+ LDFLAGS="$save_LDFLAGS"
+ else
+ _LT_TAGVAR(lt_cv_abspath_internal_name, $1)='$install_libdir/'
+ fi
+ ])
_LT_TAGVAR(hardcode_direct, $1)=yes
_LT_TAGVAR(hardcode_direct_absolute, $1)=yes
- _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH,
- # but as the default
- # location of the library.
+ # hardcode_minus_L: Not really in the search PATH,
+ # but as the default location of the library, when it does not
+ # have an absolute path in 'internal name' (the +h linker flag).
+ if test "X$_LT_TAGVAR(lt_cv_abspath_internal_name, $1)" = X; then
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ else
+ _LT_TAGVAR(hardcode_minus_L, $1)=no
+ fi
;;
esac
@@ -5771,7 +5840,7 @@ if test "$_lt_caught_CXX_error" != yes; then
_LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
;;
*)
- _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}'"$_LT_TAGVAR(lt_cv_abspath_internal_name, $1)"'$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
;;
esac
# Commands to make compiler produce verbose output that lists
@@ -5795,7 +5864,7 @@ if test "$_lt_caught_CXX_error" != yes; then
_LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
;;
*)
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}'"$_LT_TAGVAR(lt_cv_abspath_internal_name, $1)"'$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
;;
esac
fi
diff --git a/tests/demo-hardcode.test b/tests/demo-hardcode.test
index 31b2e1d..d7c2180 100755
--- a/tests/demo-hardcode.test
+++ b/tests/demo-hardcode.test
@@ -39,6 +39,7 @@ func_make "hardcode"
# Extra tools we might need
: ${DUMPSTABS=dumpstabs}
+: ${CHATR=chatr}
# Suck in all the hardcode_* variable settings.
func_msg "Finding libtool.m4's guesses at hardcoding values"
@@ -70,11 +71,31 @@ for file in hc-*; do
# Discover whether the objdir really was hardcoded.
hardcoded=no
+ # hppa-hpux (SOM) stores either the 'internal name' (+h), when it contains
+ # an absolute path, or the absolute location where the library was found
+ # at linktime in the the 'shared library list' of the resulting binary.
+ # When the type of such an entry is 'static', the runpath is ignored
+ # for that library. As this is unwanted, we treat this as hardcoded,
+ # even if it does not contain the objdir.
+ # For hppa64-hpux (ELF) and ia64-hpux (ELF), 'chatr' does not tell whether
+ # the shared library location is 'static' or 'dynamic', as the path
+ # component is not stored anyway when the library was found via '-L'.
+ # Additionally, aCC/cc store commandline and other information used to
+ # create object files into these (as 'ccom options', 'driver_command'),
+ # which may also lead to false positives when using 'cat'.
+ if { $CHATR $file ;} >/dev/null 2>&1; then
+ if $CHATR $file 2>/dev/null \
+ | $SED -e "s|^ *static */|$objdir&|" \
+ | $FGREP "$objdir" >/dev/null 2>&1; then
+ hardcoded=yes
+ else
+ hardcoded=no
+ fi
# Solaris cc may store the command line in a debugging section,
# which leads to false positives. Unfortunately, Solaris strip
# is not capable to remove the section (unlike GNU binutils strip).
# So we use dumpstabs if it seems to work.
- if { $DUMPSTABS -d $file; } >/dev/null 2>&1; then
+ elif { $DUMPSTABS -d $file; } >/dev/null 2>&1; then
if $DUMPSTABS -d $file 2>/dev/null | $FGREP "$objdir" >/dev/null 2>&1; then
hardcoded=yes
else