From owner-freebsd-current Mon Jan 20 16:43:45 1997 Return-Path: Received: (from root@localhost) by freefall.freebsd.org (8.8.4/8.8.4) id QAA15038 for current-outgoing; Mon, 20 Jan 1997 16:43:45 -0800 (PST) Received: from phaeton.artisoft.com (phaeton.Artisoft.COM [198.17.250.211]) by freefall.freebsd.org (8.8.4/8.8.4) with SMTP id QAA15012; Mon, 20 Jan 1997 16:43:30 -0800 (PST) Received: (from terry@localhost) by phaeton.artisoft.com (8.6.11/8.6.9) id RAA16750; Mon, 20 Jan 1997 17:25:40 -0700 From: Terry Lambert Message-Id: <199701210025.RAA16750@phaeton.artisoft.com> Subject: Re: Static binaries and dlopen(3) with a new crypt(3) lib. To: mark@grondar.za (Mark Murray) Date: Mon, 20 Jan 1997 17:25:40 -0700 (MST) Cc: chuckr@glue.umd.edu, terry@lambert.org, jdp@polstra.com, mark@grondar.za, peter@freebsd.org, current@freebsd.org In-Reply-To: <199701202107.XAA07293@grackle.grondar.za> from "Mark Murray" at Jan 20, 97 11:07:28 pm X-Mailer: ELM [version 2.4 PL24] MIME-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit Sender: owner-current@freebsd.org X-Loop: FreeBSD.org Precedence: bulk > I woke this sleeping bear. What I need is the ability to link in a > DES crypt only if it exists, and this must work for the /bin/* and > /sbin/* applets too. You need to map an object so that it is faulted by reference rather than by value for the first fault. To do this, you would establish a virtual mapping for a file, and actualize it on reference. You can do this by using a call table for your symbol references, and pointing the call table to a common routine. The job of the common routine is to resolve the symbol from the shared image for the entry point the call table was entered through: calling code: ... call table[ n] ... table[ n]: jmp [long addr] <- default this to "relocator" relocator: get return address off stack look at call instruction at return address to determine target resolve table in which target is located get index by dividing table base by sizeof(jmp [long addr]) map image in table header, if possible; otherwise ret error modify table[ n]->[long addr] to point to mapping location restore registers and stack jmp table[n]->[long addr] On average this will add 6 clock cycles to the call (after the initial call); alternately, you could back-patch the calling code and save the 6 clocks, at the cost of having to copy-on-write the page (unless you synced mappings with other callers to the same library). Basically, the copy-on-write table gets rewritten in any case. Note: this will fail in the case of tail optimization, where functions jmp to other functions instead of calling them and ret'ing to their own callers. To deal with this requires determining the JMP instrustion from the set of all allowable jmp instructions, and looking at the stack pointers. This actually becomes more difficult in the presence of library constructors (for things like virtual base classes in C++ libraries, and so on). You must delay the constructor call until the mapping phase takes place. This allows you to run without the library present, yet still have the virtual base classes constructued before use. For subclasses of constructed classes, there is an implicit invocation of the constructor -- which is code in the library; the mapping still occurs, and the construction of the base takes place before the base constructure is actually called. I did code similar to this for entry/exit block profiling in MSVC++, which can generate calls on function entry, but not on function exit. To deal with the problem, I established a per thread return address stack of my own, and replaced the return address for the caller on the stack with my return handler function. It then did the profiling and then poped the entry off the thread stack onto the user stack to rebuild the call frame, and returned. Unfortuantely, it's all MASM code, so it would need to be rewritten for GAS in any case... probably from scratch, since it is dependent on the optimizations which the compiler might do during assembly code generation. Terry Lambert terry@lambert.org --- Any opinions in this posting are my own and not those of my present or previous employers.