Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 17 Jun 1998 17:30:47 +0200 (MET DST)
From:      =?ISO-8859-1?Q?Mikko_Ty=F6l=E4j=E4rvi?= <mikko@securitydynamics.com>
To:        freebsd-hackers@FreeBSD.ORG
Subject:   Problem with ld.so + LD_PRELOAD + _init()
Message-ID:  <Pine.GSO.3.96.980617172736.26318G-100000@spirit.dynas.se>

next in thread | raw e-mail | index | archive | help

Hi!

Fiddling around with LD_PRELOAD and wrapping of system calls, I
discovered that the "_init()" function of the preloaded lib never gets
called.

It is not entirely clear from the man-page that it should be,
but on Solaris 2.[56], it is.  And it works for libraries linked with
the program, as well as libraries loaded with dlopen().  Also, it
sometimes makes life a lot easier...

A quick look in rtld.c seems to indicate that _init() functions are
called in order by traversing the dependency graph, starting from the
main program.  But preloaded libraries are never added to this graph,
so they never get initialized.  Preloaded libs are included in the
library search order though, so except for _init() never being called,
it works as expected.

This is true on both 2.2.6 and CURRENT as of Jun, 12.

The question is whether this is intentional or not?


	/Mikko

P.S.
Below is a little sh-kludge that demonstrates the problem on both
FreeBSD and Solaris 2.[56] (with gcc).


 Mikko Tyo"la"ja"rvi________________________________mikko@securitydynamics.com
 SecurityDynamics

#!/bin/sh
set -e

test -d inittest || mkdir inittest
cd inittest
PWD=`pwd`

# Tiny lib
cat > lib.c << \EOF
void
_init()
{
    printf("\t_init()\n");
}
EOF

# Equally tiny program
cat > prog.c << \EOF
int
main()
{
    printf("\tmain()\n");
    return 0;
}    	
EOF

# Program explicitly using dlopen()
cat > dprog.c << \EOF
#include <dlfcn.h>
int
main()
{
    void *handle;

    printf("\tmain()\n");
    handle = dlopen("./lib.so", RTLD_LAZY);
    if (!handle) printf("\tdlopen failed\n");
    return 0;
}
EOF

gcc -fpic -c lib.c
case `uname` in
FreeBSD)
    DLLIB=
    ld -Bshareable -Bforcearchive -o lib.so lib.o;;
SunOS)
    DLLIB=-ldl
    ld -G -z text -o lib.so lib.o;;
*)
    echo "Wrong OS"; exit 1;;
esac
rm -f libinittest.so.1.0 libinittest.so
ln -s lib.so libinittest.so.1.0
ln -s lib.so libinittest.so

echo "Linked (I expect: _init + main):"
gcc -o libprog prog.c -L$PWD -Xlinker -R$PWD -linittest
./libprog

echo "Explicit use of dlopen (I expect main + _init):"
gcc -o dprog dprog.c $DLLIB
./dprog

echo "Preloaded (I expect: _init + main):"
gcc -o nullprog prog.c
LD_PRELOAD=$PWD/lib.so ./nullprog || exit 1



To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-hackers" in the body of the message



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?Pine.GSO.3.96.980617172736.26318G-100000>