Date: Fri, 9 Jan 1998 22:52:16 +0000 (GMT) From: Terry Lambert <tlambert@primenet.com> To: dap@damon.com (Damon Anton Permezel) Cc: hasty@rah.star-gate.com, tlambert@primenet.com, dap@damon.com, nate@mt.sri.com, freebsd-hackers@FreeBSD.ORG Subject: Re: dladdr hax Message-ID: <199801092252.PAA00624@usr04.primenet.com> In-Reply-To: <199801082312.RAA20001@damon.com> from "Damon Anton Permezel" at Jan 8, 98 05:12:38 pm
next in thread | previous in thread | raw e-mail | index | archive | help
> I'd do it, but I have no access, *and* I have concerns about having to > hack on the kernel to support java. I'd prefer if the JDK worked on > "all recent versions", but certain enhancements can be accomodated > dynamically. > > My understanding of it is that it requires the full path be kept by execve(). > It can either be stored in the u area, or can be copied into the new address > space somewhere, ala argv/envp. This makes it easier for ld.so to know where > it is, and then the dladdr hack follows quite easily. > If it is kept in the u area, then some mechanism needs to be dreamed up to > let ld.so get at it, which I like less. Actually, this isn't true. It's pretty trivial to write and run a dladdr using program on a solaris box. If you do this in the main program: -------------------------------------------------------------------------- #include <stdio.h> #include <dlfcn.h> main() { Dl_info dli; if( !dladdr( (void *)&printf, &dli)) { fprintf( stderr, "No mapping found\n"); exit( 1); } printf( "file containing address range \"%s\"\n", dli.dli_fname); printf( "base address of file image 0x%08X\n", dli.dli_fbase); printf( "symbol name \"%s\"\n", dli.dli_sname); printf( "symbol address 0x%08X\n", dli.dli_saddr); exit( 0); } -------------------------------------------------------------------------- You get this as output: -------------------------------------------------------------------------- file containing address range "./dladdr" base address of file image 0x08048000 symbol name "_PROCEDURE_LINKAGE_TABLE_" symbol address 0x080486D4 -------------------------------------------------------------------------- For the program file running, you get the argv[ 0], which may pr may not be correct. The reason you get this for printf, which is in libc.so, is the th expression "&printf" is actually the address of the stub function which is generated when theC library is created, and is statically linked into your program. If I exec it, and fake up an argv[0] that's nonsensical, I get the nonsense back. HOWEVER... If I use the function as JAVA uses the function, and call it on a a local address from *within* a shared library, the expression "&printf" will refer to the address of the printf function in the library. This will cause the path to the *library actually mapped* to be returned. The "file containing address range" is actually the only field used by java. It's used to get the path to the library for the symbol in the library. Basically, to allow the java shared library "where were you loaded from". Then it goes up two directories and down one, because *by definition*, the classes file for a JNI shared library implementation is located two directories up, and one down, in the machine independent data. This is simply a convention which Sun expects everyone to follow to set relative locations in the FS for class files, relative to the location of the shared library for which the class file is a JNI. Basically, this means that there is no kernel hacking required. All change go (and *should* go) in ld.so and crt.0. For the kludge, I'd just say /usr/local/java is the "derived" directory. Then let users make symbolic links as necessary. For packages installed in the default locations, none will be necessary. Terry Lambert terry@lambert.org --- Any opinions in this posting are my own and not those of my present or previous employers.
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199801092252.PAA00624>