|
Message-ID: <20150412015923.GP6817@brightrain.aerifal.cx> Date: Sat, 11 Apr 2015 21:59:23 -0400 From: Rich Felker <dalias@...c.org> To: musl@...ts.openwall.com Subject: Re: Dynamic linker changes On Sat, Apr 11, 2015 at 04:21:52PM -0400, Rich Felker wrote: > On Wed, Apr 08, 2015 at 07:19:11PM -0400, Rich Felker wrote: > > 3. The original plan was to have one early-ldso-relocation step and > > avoid all possible GOT/globals use and everything after that free to > > use arbitrary global data and symbols, with a single barrier in > > between to prevent reordering of GOT loads before they're relocated. > > This seems impractical since it's hard, due to issue 1, do to symbolic > > relocations without being able to make function calls. > > > > Instead I'd like to treat the early-ldso-relocation process as two > > steps. The first is generalizing and making arch-agnostic the work > > mips, microblaze, and powerpc are doing now to get to a state where > > all non-symbolic global accesses are safe. The second would be a > > separate function call from the asm (or chained from the first if > > there's an obvious way to do it) that performs symbolic relocations on > > itself. It would end by (as proposed in the sketch before) doing a > > symbol lookup and final call into the code that will setup the dso > > chain, load dependencies, perform all remaining relocations, and pass > > control to the program's entry point. > > I've got the first working draft of the above design, and it's three > stages: > > 1. Perform relative relocations on ldso/libc itself referencing > nothing but its arguments and the data they point to. > > 2. Setup a dso structure for ldso/libc and perform symbolic > relocations on it using nothing but static functions/data from > dynlink.c. > > 3. Do nearly everything the old __dynlink did, but with the ldso dso > structure already setup and fully usable (not depending on > -Bsymbolic-functions and arch-specific __reloc_self to make it > almost-fully-usable like we did before). > > Currently, stage 1 calls into stage 2 and 3 via very primitive > symbol-lookup code. This has some trade-offs. > > Pros: The dynamic linker entry point asm does not need to be aware of > the details of the dynamic linking process. It just calls one function > with minimal args (original SP and &_DYNAMIC) and uses the return > value as a jump destination (along with a simple SP-fixup trick). > > Cons: Stage 1 is coupled with the rest of the dynamic linking process. > This is somewhat unfortunate since the stage 1 code, minus this last > symbol lookup step but including the entry point asm prior to calling > stage 1, is _exactly_ what would be needed for "static PIE" Rcrt1.o. > It could be made to work 'unmodified' for static PIE by having the > source for Rcrt1.o provide its own definitions of the stage 2 and 3 > functions, but since stage 1 looks them up by name at runtime, > stripping dynamic symbol names (which should in principle work for > static PIE) would break it. > > I'm attaching a diff with the work so far for comments. It's > unfinished (only i386 and mips are implemented so far; mips was chosen > because it's the one arch that needs ugly arch-specific relocations > and I had to check and make sure they work right in the new design) > but seems to work. OK, so some big ideas for resolving this: Let's get rid of all the ldso/*/start.s files. Instead, I want to reuse crt_arch.h, which requires making the following changes to it: 1. Fix any existing cases where crt_arch.h uses addressing methods that would not work prior to relocations. This is probably only mips. 2. Add the ability for the calling file to rename the _start function via a macro defined before including crt_arch.h. 3. Add conditional loading of &_DYNAMIC in the second arg slot before calling __cstart. At this point, we have minimal entry point asm that can be reused by crt1.o, Scrt1.o, dlstart.lo, and the future rcrt1.o for static PIE. For dlstart.c would look like this: #ifndef START #define START "_dl_start" #endif #define NEED_DYNAMIC #include "crt_arch.h" void __cstart(size_t *sp, size_t *dynv) { /* body of existing stage 1 */ } And the future rcrt1.c would look like this: #define START "_start" #include "dlstart.c" /* stage 2 and 3 functions */ where stage 2 is empty, and stage 3 looks like the __cstart in crt1.c. Rich
Powered by blists - more mailing lists
Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.