Subject: Problem with semantics of ELF-ld.so
To: None <tech-toolchain@netbsd.org>
From: Joachim Kuebart <kuebart@mathematik.uni-ulm.de>
List: tech-toolchain
Date: 10/13/1999 17:01:23
--UHN/qo2QbUvPLonB
Content-Type: multipart/mixed; boundary="envbJBWh7q8WU6mo"


--envbJBWh7q8WU6mo
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: quoted-printable

Hi,

this is on NetBSD-current/i386, from Oct 2, 1999.

When using dlsym() to find a symbol in an object loaded by dlopen(),
the chain of all loaded objects is checked for the symbol instead
of the object passed to dlsym(). IMHO, this is broken. The module
passed to dlsym() should be checked first.

Attached you find a project that loads dynamic modules using dlopen().
All of those modules have an "info()" function that needs to be
called. The trouble is, with the current ld.so implementation the
info() function of the first dynamically loaded module is always
returned by dlsym().

A workaround is to use the -Bsymbolic linker flag, but this can't be
the right solution???

The following patch would fix the problem from my perspective, but
probably breaks lots of other things?

cvs diff: Diffing /usr/src/libexec/ld.elf_so/
Index: /usr/src/libexec/ld.elf_so//symbol.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /home/cvs/netbsd/src/libexec/ld.elf_so/symbol.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 symbol.c
--- symbol.c	1999/06/14 20:19:21	1.1.1.1
+++ symbol.c	1999/10/13 14:58:40
@@ -143,7 +143,7 @@
 	}
 	hash =3D _rtld_elf_hash(name);
=20
-	if (refobj->symbolic) {	/* Look first in the referencing object */
+	if (1) {	/* Look first in the referencing object */
 		const Elf_Sym *def;
=20
 		def =3D _rtld_symlook_obj(name, hash, refobj, in_plt);


cu Jo

--envbJBWh7q8WU6mo
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename=Makefile

PROG =		ldsotest
CLEANFILES +=	m1.so m2.so
DPADD +=	m1.so m2.so

.ifdef WORKS
SYMBOLIC =	-Wl,-Bsymbolic
.endif

.SUFFIXES: .so

.c.so:
	$(CC) $(SYMBOLIC) -shared -o ${.TARGET} ${.IMPSRC}

.include <bsd.prog.mk>

--envbJBWh7q8WU6mo
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="ldsotest.c"

#include <dlfcn.h>
#include <stdio.h>

static void modinfo(const char *);

int
main(void)
{
	modinfo("./m1.so");
	modinfo("./m2.so");

	return 0;
}

void
modinfo(const char *name)
{
	void *h;
	void (*info)(void);

	if ((h = dlopen(name, DL_LAZY)) == NULL) {
		fprintf(stderr, "%s: %s\n", name, dlerror());
		return;
	}

	if ((info = dlsym(h, "info")) != NULL)
		info();
	else
		fprintf(stderr, "%s: %s\n", name, dlerror());
}

--envbJBWh7q8WU6mo
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="m1.c"

#include <stdio.h>

void
info(void)
{
	printf("m1\n");
}

--envbJBWh7q8WU6mo
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="m2.c"

#include <stdio.h>

void
info(void)
{
	printf("m2\n");
}

--envbJBWh7q8WU6mo--

--UHN/qo2QbUvPLonB
Content-Type: application/pgp-signature

-----BEGIN PGP SIGNATURE-----
Version: PGPfreeware 5.0i for non-commercial use
MessageID: 7I5pmO5jXz06Xe71W7OQzLHe2XXj5z0L

iQA/AwUBOASewrSpDHeqrG9TEQJ3sgCg2y/NQ64Cy9ukhjZi7Ja967ozCm4AoPVk
21hKkY3Qa87un6a3T/tji12j
=/EvQ
-----END PGP SIGNATURE-----

--UHN/qo2QbUvPLonB--