RE: dlopen() and friends from a statically-linked binary?
Daniel O'Connor writes: > > On 20-Jul-00 Raymond Wiker wrote: > > Is it possible, at all, to use dlopen etc from a > > statically-linked executable? My experiments with FreeBSD-4.0 (see > > below) indicate that it's not possible. > > You can't do it from a statically linked binary, however you can > create a dynamic executable with no external unresolved > references.. I forget how though :-/ OK... I'll take a look at this. Thanks to everyone who responded. > > > The reason that I'd like this to work is that SBCL (a Common > > Lisp implementation, see http://sbcl.sourceforge.net) needs the > > addresses of certain library symbols (e.g, errno) when building the > > initial lisp image. This seems to require static linking. On the other > > hand, SBCL is severely handicapped if it cannot subsequently use > > dlopen() to load foreign code into the running lisp system. > > Well, I don't see why it would need static linking for that.. When > the binary runs the libraries it uses will get loaded, and then it > can use dlsym() to get the addresses it needs.. (ie what I am > saying is I don't understand your explanation :) A running SBCL system includes a runtime substrate written in C, along with Lisp code compiled into native code or byte-code. The C runtime calls a top-level function in the Lisp system at startup; this call does not return until the top-level Lisp function exits. The top-level Lisp function calls into the C substrate for various low-level services, including garbage-collecting of Lisp objects. This implies a circular dependency: the C runtime must have the address of the top-level Lisp function, while the Lisp code needs the addresses of various code and data in the C runtime. In SBCL this is solved in the bootstrapping process, by a function that patches up the Lisp code with the addresses from the C code. This cannot be done at startup, as the Lisp object format differs from the conventional formats (a.out or ELF). At the moment, my options seem to be: 1) find a way of compiling the C runtime so that there are no unresolved externals, while still producing a dynamic executable. 2) identify a small set of symbols from libc.so, and encapsulate them (possibly using dlsym("foo", RTLD_NEXT)?) 3) modify SBCL so that the patchup is done at startup time, instead of at compilation time. Of these, 1) is probably the least work, 2) is slightly more work and inelegant, and 3) is the most work but carries a few other benefits (notably, it reduces the Lisp -> C dependency). //Raymond. To Unsubscribe: send mail to [EMAIL PROTECTED] with "unsubscribe freebsd-hackers" in the body of the message
RE: dlopen() and friends from a statically-linked binary?
On Sat, 22 Jul 2000, Daniel O'Connor wrote: > > On 20-Jul-00 Raymond Wiker wrote: > > Is it possible, at all, to use dlopen etc from a > > statically-linked executable? My experiments with FreeBSD-4.0 (see > > below) indicate that it's not possible. > > You can't do it from a statically linked binary, however you can create a > dynamic executable with no external unresolved references.. I forget how though > :-/ The same way it's done with the kernel nowadays.. Look into your /sys/compile/WHATEVER/Makefile, and hack.c file there. Andrzej Bialecki // <[EMAIL PROTECTED]> WebGiro AB, Sweden (http://www.webgiro.com) // --- // -- FreeBSD: The Power to Serve. http://www.freebsd.org // --- Small & Embedded FreeBSD: http://www.freebsd.org/~picobsd/ To Unsubscribe: send mail to [EMAIL PROTECTED] with "unsubscribe freebsd-hackers" in the body of the message
RE: dlopen() and friends from a statically-linked binary?
On 20-Jul-00 Raymond Wiker wrote: > Is it possible, at all, to use dlopen etc from a > statically-linked executable? My experiments with FreeBSD-4.0 (see > below) indicate that it's not possible. You can't do it from a statically linked binary, however you can create a dynamic executable with no external unresolved references.. I forget how though :-/ > The reason that I'd like this to work is that SBCL (a Common > Lisp implementation, see http://sbcl.sourceforge.net) needs the > addresses of certain library symbols (e.g, errno) when building the > initial lisp image. This seems to require static linking. On the other > hand, SBCL is severely handicapped if it cannot subsequently use > dlopen() to load foreign code into the running lisp system. Well, I don't see why it would need static linking for that.. When the binary runs the libraries it uses will get loaded, and then it can use dlsym() to get the addresses it needs.. (ie what I am saying is I don't understand your explanation :) > raw : ~ $ gcc -static dltest.c -o dltest > raw : ~ $ ./dltest > dlopen returned 0: Service unavailable > Handle: 0x0, main: 0x0 > > raw : ~ $ gcc dltest.c -o dltest > raw : ~ $ ./dltest > Handle: 0x2805e000, main: 0x0 > Handle: 0x0, main: 0x0 > > [ Note: this seems wrong; according to the manpage for dlsym, the > second call should give the same output as the first. ] Agreed. --- Daniel O'Connor software and network engineer for Genesis Software - http://www.gsoft.com.au "The nice thing about standards is that there are so many of them to choose from." -- Andrew Tanenbaum To Unsubscribe: send mail to [EMAIL PROTECTED] with "unsubscribe freebsd-hackers" in the body of the message
Re: dlopen() and friends from a statically-linked binary?
> "Raymond" == Raymond Wiker <[EMAIL PROTECTED]> writes: Raymond> raw : ~ $ cat dltest.c Raymond> #include Raymond> #include Raymond> main() Raymond> { Raymond> void *handle; Raymond> void *sym; Raymond> handle = dlopen(0, RTLD_LAZY); Raymond> if (handle == 0) Raymond> { Raymond> fprintf(stderr, "dlopen returned 0: %s\n", dlerror()); Raymond> } Raymond> else Raymond> { Raymond> fprintf(stderr, "Handle: %p, main: %p\n", handle, dlsym(handle, "main")); Raymond> } Raymond> fprintf(stderr, "Handle: %p, main: %p\n", 0, dlsym(0, "main")); Raymond> return 0; Raymond> } Raymond> raw : ~ $ gcc -static dltest.c -o dltest Raymond> raw : ~ $ ./dltest Raymond> dlopen returned 0: Service unavailable Raymond> Handle: 0x0, main: 0x0 Raymond> raw : ~ $ gcc dltest.c -o dltest Raymond> raw : ~ $ ./dltest Raymond> Handle: 0x2805e000, main: 0x0 Raymond> Handle: 0x0, main: 0x0 Raymond> [ Note: this seems wrong; according to the manpage for dlsym, the Raymond> second call should give the same output as the first. ] It does, it returns NULL. I'm not sure what your issues with SBCL are (I'll try to take a look later if I get time). I believe to get your sample code above to work you want... gcc dltest.c -Xlinker -export-dynamic -o dltest This then gives me Handle: 0x2805d000, main: 0x8048508 Handle: 0x0, main: 0x8048508 Hope this helps, Martin To Unsubscribe: send mail to [EMAIL PROTECTED] with "unsubscribe freebsd-hackers" in the body of the message
Re: dlopen() and friends from a statically-linked binary?
> raw : ~ $ gcc dltest.c -o dltest > raw : ~ $ ./dltest > Handle: 0x2805e000, main: 0x0 > Handle: 0x0, main: 0x0 > > [ Note: this seems wrong; according to the manpage for dlsym, the > second call should give the same output as the first. ] Sorry about the confusion... the "main" symbol does not appear to work for this illustration (possibly because it doesn't come from a dynamic library?). If I try with "errno" instead, I get raw : ~ $ ./dltest Handle: 0x2805e000, errno: 0x280f5cd4 Handle: 0x0, errno: 0x0 raw : ~ $ --- according to the manpage for dlsym(), passing 0 for handle should have the same effect as passing 0 as the path to dlopen; i.e, to access the symbol table for the running program. -- Raymond Wiker To Unsubscribe: send mail to [EMAIL PROTECTED] with "unsubscribe freebsd-hackers" in the body of the message