summaryrefslogtreecommitdiff
path: root/src/ldso
AgeCommit message (Collapse)AuthorLines
2012-10-19support looking up thread-local objects with dlsymRich Felker-0/+6
2012-10-19fix breakage in dlsym for looking up RTLD_DEFAULT, etc.Rich Felker-2/+5
this was broken during the early dynamic-linked TLS commits, which rearranged some of the code for handling new relocation types.
2012-10-17fix microblaze asm relocations for shared libcRich Felker-3/+3
only @PLT relocations are considered functions for purposes of -Bsymbolic-functions, so always use @PLT. it should not hurt in the static-linked case.
2012-10-15add support for TLS variant I, presently needed for arm and mipsRich Felker-3/+32
despite documentation that makes it sound a lot different, the only ABI-constraint difference between TLS variants II and I seems to be that variant II stores the initial TLS segment immediately below the thread pointer (i.e. the thread pointer points to the end of it) and variant I stores the initial TLS segment above the thread pointer, requiring the thread descriptor to be stored below. the actual value stored in the thread pointer register also tends to have per-arch random offsets applied to it for silly micro-optimization purposes. with these changes applied, TLS should be basically working on all supported archs except microblaze. I'm still working on getting the necessary information and a working toolchain that can build TLS binaries for microblaze, but in theory, static-linked programs with TLS and dynamic-linked programs where only the main executable uses TLS should already work on microblaze. alignment constraints have not yet been heavily tested, so it's possible that this code does not always align TLS segments correctly on archs that need TLS variant I.
2012-10-14fix main program TLS alignment for dynamic-linked programsRich Felker-6/+5
this change brings the behavior in line with the static-linked code, which seems to be correct.
2012-10-13fix namespace clash (libc) in dynlink.cRich Felker-14/+13
this makes it so the #undef libc and __libc name are no longer needed, which were problematic because the "accessor function" mode for accessing the libc struct could not be used, breaking build on any compiler without (working) visibility.
2012-10-13remove dead code from dynamic linkerRich Felker-10/+0
2012-10-07clean up and refactor program initializationRich Felker-2/+2
the code in __libc_start_main is now responsible for parsing auxv, rather than duplicating the parsing all over the place. this should shave off a few cycles and some code size. __init_libc is left as an external-linkage function despite the fact that it could be static, to prevent it from being inlined and permanently wasting stack space when main is called. a few other minor changes are included, like eliminating per-thread ssp canaries (they were likely broken when combined with certain dlopen usages, and completely unnecessary) and some other unnecessary checks. since this code gets linked into every program, it should be as small and simple as possible.
2012-10-07fix breakage due to initializing thread pointer when loading libsRich Felker-1/+1
at initial program load, all libraries must be loaded before the thread pointer can be setup, since the TP-relative addresses of all initial TLS objects must be constant.
2012-10-06make new TLS setup block even implementation-internals signalsRich Felker-2/+1
this is needed to ensure async-cancel-safety, i.e. to make it safe to access TLS objects when async cancellation is enabled. otherwise, if cancellation were acter upon after the atomic fetch/add but before the thread saved the obtained memory, another access to the same TLS in the cancellation handler could end up performing the atomic fetch/add again, consuming more memory than is actually available and overflowing into other objects on the heap.
2012-10-06don't crash if TLS library is loaded into process with no thread pointerRich Felker-0/+5
2012-10-06fix symbol acceptance/rejection rules for TLSRich Felker-8/+14
symbol value of 0 is not "undefined" for TLS; it's the address of the first symbol in the TLS segment. however, non-definition TLS references also have values of 0, so check the section. hopefully the new logic is more clear, too.
2012-10-06TLS fixes, mainly alignment handlingRich Felker-39/+48
compute offsets from the thread pointer statically when loading the library, rather than repeating the logic on each thread creation. not only is the latter less efficient at runtime; it also fails to provide solid guarantees that the offsets will remain the same when the initial alignment of memory is different. the new alignment handling is both more rigorous and simpler. the old code was also clobbering TLS bss with random image data in some cases due to using tls_size (size of TLS segment) instead of tls_len (length of the TLS data image).
2012-10-05fix/improve shared library ctor/dtor handling, allow recursive dlopenRich Felker-7/+29
some libraries call dlopen from their constructors, resulting in recursive calls to dlopen. previously, this resulted in deadlock. I'm now unlocking the dlopen lock before running constructors (this is especially important since the lock also blocked pthread_create and was being held while application code runs!) and using a separate recursive mutex protecting the ctor/dtor state instead. in order to prevent the same ctor from being called more than once, a module is considered "constructed" just before the ctor runs. also, switch from using atexit to register each dtor to using a single atexit call to register the dynamic linker's dtor processing as just one handler. this is necessary because atexit performs allocation and may fail, but the library has already been loaded and cannot be backed-out at the time dtor registration is performed. this change also ensures that all dtors run after all atexit functions, rather than in mixed order.
2012-10-05small dynamic linker module search fixRich Felker-1/+2
libraries loaded more than once by pathname should not get shortnames that would cause them to later be used to satisfy non-pathname load requests.
2012-10-05support for TLS in dynamic-loaded (dlopen) modulesRich Felker-19/+81
unlike other implementations, this one reserves memory for new TLS in all pre-existing threads at dlopen-time, and dlopen will fail with no resources consumed and no new libraries loaded if memory is not available. memory is not immediately distributed to running threads; that would be too complex and too costly. instead, assurances are made that threads needing the new TLS can obtain it in an async-signal-safe way from a buffer belonging to the dynamic linker/new module (via atomic fetch-and-add based allocator). I've re-appropriated the lock that was previously used for __synccall (synchronizing set*id() syscalls between threads) as a general pthread_create lock. it's a "backwards" rwlock where the "read" operation is safe atomic modification of the live thread count, which multiple threads can perform at the same time, and the "write" operation is making sure the count does not increase during an operation that depends on it remaining bounded (__synccall or dlopen). in static-linked programs that don't use __synccall, this lock is a no-op and has no cost.
2012-10-05fix race condition in dlopenRich Felker-1/+3
orig_tail was being saved before the lock was obtained, allowing dlopen failure to roll-back other dlopens that had succeeded.
2012-10-04dynamic-linked TLS support for everything but dlopen'd libsRich Felker-38/+58
currently, only i386 is tested. x86_64 and arm should probably work. the necessary relocation types for mips and microblaze have not been added because I don't understand how they're supposed to work, and I'm not even sure if it's defined yet on microblaze. I may be able to reverse engineer the requirements out of gcc/binutils output.
2012-10-04remove freeing of dynamic linker data when dlopen/dlsym are not usedRich Felker-11/+0
this was an optimization to save/recover a minimal amount of extra memory for use by malloc, that's becoming increasingly costly to keep around. freeing this data: 1. breaks debugging with gdb (it can't find library symbols) 2. breaks thread-local storage in shared libraries it would be possible to disable freeing when TLS is used, but in addition to the above breakages, tracking whether dlopen/dlsym is used adds a cost to every symbol lookup, possibly making program startup slower for large programs. combined with the complexity, it's not worth it. we already save/recover plenty of memory in the dynamic linker with reclaim_gaps.
2012-10-04beginnings of full TLS support in shared librariesRich Felker-0/+10
this code will not work yet because the necessary relocations are not supported, and cannot be supported without some internal changes to how relocation processing works (coming soon).
2012-10-04partial TLS support for dynamic-linked programsRich Felker-22/+72
only TLS in the main program is supported so far; TLS defined in shared libraries will not work yet.
2012-10-04TLS (GNU/C11 thread-local storage) support for static-linked programsRich Felker-0/+10
the design for TLS in dynamic-linked programs is mostly complete too, but I have not yet implemented it. cost is nonzero but still low for programs which do not use TLS and/or do not use threads (a few hundred bytes of new code, plus dependency on memcpy). i believe it can be made smaller at some point by merging __init_tls and __init_security into __libc_start_main and avoiding duplicate auxv-parsing code. at the same time, I've also slightly changed the logic pthread_create uses to allocate guard pages to ensure that guard pages are not counted towards commit charge.
2012-09-29more close-on-exec fixes, mostly using new "e" flag to fopenRich Felker-1/+1
2012-09-29fix some more O_CLOEXEC/SOCK_CLOEXEC issuesRich Felker-2/+2
2012-09-29microblaze portRich Felker-0/+32
based on initial work by rdp, with heavy modifications. some features including threads are untested because qemu app-level emulation seems to be broken and I do not have a proper system image for testing.
2012-09-06use restrict everywhere it's required by c99 and/or posix 2008Rich Felker-4/+4
to deal with the fact that the public headers may be used with pre-c99 compilers, __restrict is used in place of restrict, and defined appropriately for any supported compiler. we also avoid the form [restrict] since older versions of gcc rejected it due to a bug in the original c99 standard, and instead use the form *restrict.
2012-08-27fix bug caused by main app & libc having map set; cannot free themRich Felker-1/+1
2012-08-26dladdr support for dynamic linker (nonstandard extension)Rich Felker-0/+95
based on patches submitted by boris brezillon. this commit also fixes the issue whereby the main application and libc don't have the address ranges of their mappings stored, which was theoretically a problem for RTLD_NEXT support in dlsym; it didn't actually matter because libc never calls dlsym, and it seemed to be doing the right thing (by chance) for symbols in the main program as well.
2012-08-25fix bug in gnu hash lookup on dlsym(handle, name) lookupsRich Felker-1/+1
wrong hash was being passed; just a copy/paste error. did not affect lookups in the global namespace; this is probably why it was not caught in testing.
2012-08-25clean up search_vec usage for vdsoRich Felker-2/+2
2012-08-25use new search_vec function to find vdso in dynamic linkerRich Felker-4/+2
2012-08-25ensure canary is setup if stack-prot libs are dlopen'd into non-ssp appRich Felker-1/+4
previously, this usage could lead to a crash if the thread pointer was still uninitialized, and otherwise would just cause the canary to be zero (less secure).
2012-08-25add gnu hash support in the dynamic linkerRich Felker-12/+85
based on the patches contributed by boris brezillon.
2012-08-18make dynamic linker report all failures before exitingRich Felker-2/+6
before, only the first library that failed to load or symbol that failed to resolve was reported, and then the dynamic linker immediately exited. when attempting to fix a library compatibility issue, this is about the worst possible behavior. now we print all errors as they occur and exit at the very end if errors were encountered.
2012-08-17fix bug computing argc when invoking ld-musl-mips.so.1 progname ...Rich Felker-3/+3
2012-08-07fix bug dlsym bug that slipped in during dynamic linker cleanupRich Felker-1/+1
2012-08-05dlsym RTLD_NEXT support for mipsRich Felker-0/+15
untested
2012-08-05more changes that were lost when committing mips dynamic linkerRich Felker-0/+4
2012-08-05fix change lost in the process of integrating mips dynamic linkerRich Felker-2/+2
2012-08-05mips dynamic linker supportRich Felker-0/+49
not heavily tested, but the basics are working. the basic concept is that the dynamic linker entry point code invokes a pure-PIC (no global accesses) C function in reloc.h to perform the early GOT relocations needed to make the dynamic linker itself functional, then invokes __dynlink like on other archs. since mips uses some ugly arch-specific hacks to optimize relocating the GOT (rather than just using the normal DT_REL[A] tables like on other archs), the dynamic linker has been modified slightly to support calling arch-specific relocation code in reloc.h. most of the actual mips-specific behavior was developed by reading the output of readelf on libc.so and simple executable files. i could not find good reference information on which relocation types need to be supported or their semantics, so it's possible that some legitimate usage cases will not work yet.
2012-08-05more cleanup of dynamic linker internalsRich Felker-8/+9
2012-08-05more dynamic linker internals cleanupRich Felker-6/+6
changing the string printed for the dso name is not a regression; the old code was simply using the wrong dso name (head rather than the dso currently being relocated). this will be fixed in a later commit.
2012-08-05dynamic linker internals cleanupRich Felker-5/+7
2012-07-13make dynamic linker tell the debugger its own pathnameRich Felker-0/+5
use the main program's PT_INTERP header if possible, since this is sure to be a correct (and hopefully absolute) pathname.
2012-07-11make dynamic linker depend on -DSHARED not -fPICRich Felker-1/+1
if libc.a is compiled PIC for use in static PIE code, this should not cause the dynamic linker (which still does not support static-linked main program) to be built into libc.a.
2012-07-11fix lots of breakage on dlopen, mostly with explicit pathnamesRich Felker-14/+21
most importantly, the name for such libs was being set from an uninitialized buffer. also, shortname always had an initial '/' character, making it useless for looking up already-loaded libraries by name, and thus causing repeated searches through the library path. major changes now: - shortname is the base name for library lookups with no explicit pathname. it's initially clear for libraries loaded with an explicit pathname (and for the main program), but will be set if the same library (detected via inodes match) is later found by a search. - exact name match is never used to identify libraries loaded with an explicit pathname. in this case, there's no explicit search, so we can just stat the file and check for inode match.
2012-07-07fix dlsym RTLD_NEXT supportRich Felker-1/+3
previously this was being handled the same as a library-specific, dependency-order lookup on the next library in the global chain, which is likely to be utterly meaningless. instead the lookup needs to be in the global namespace, but omitting the initial portion of the global library chain up through the calling library.
2012-06-09fix char signedness bug (arm-specific) in dynamic linkerRich Felker-1/+1
2012-06-06treat failure of mprotect in map_library as a fatal load failureRich Felker-9/+9
the error will propagate up and be printed to the user at program start time; at runtime, dlopen will just fail and leave a message for dlerror. previously, if mprotect failed, subsequent attempts to perform relocations would crash the program. this was resulting in an increasing number of false bug reports on grsec systems where rwx permission is not possible in cases where users were wrongly attempting to use non-PIC code in shared libraries. supporting that usage is in theory possible, but the x86_64 toolchain does not even support textrels, and the cost of keeping around the necessary information to handle textrels without rwx permissions is disproportionate to the benefit (which is essentially just supporting broken library setups on grsec machines). also, i unified the error-out code in map_library now that there are 3 places from which munmap might have to be called.
2012-05-27add ldd and main program loading support to dynamic linkerRich Felker-21/+89