about summary refs log tree commit diff
path: root/src/ldso
Commit message (Collapse)AuthorAgeFilesLines
...
* fix breakage in dlsym for looking up RTLD_DEFAULT, etc.Rich Felker2012-10-191-2/+5
| | | | | this was broken during the early dynamic-linked TLS commits, which rearranged some of the code for handling new relocation types.
* fix microblaze asm relocations for shared libcRich Felker2012-10-172-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.
* add support for TLS variant I, presently needed for arm and mipsRich Felker2012-10-151-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.
* fix main program TLS alignment for dynamic-linked programsRich Felker2012-10-141-6/+5
| | | | | this change brings the behavior in line with the static-linked code, which seems to be correct.
* fix namespace clash (libc) in dynlink.cRich Felker2012-10-131-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.
* remove dead code from dynamic linkerRich Felker2012-10-131-10/+0
|
* clean up and refactor program initializationRich Felker2012-10-071-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.
* fix breakage due to initializing thread pointer when loading libsRich Felker2012-10-071-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.
* make new TLS setup block even implementation-internals signalsRich Felker2012-10-061-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.
* don't crash if TLS library is loaded into process with no thread pointerRich Felker2012-10-061-0/+5
|
* fix symbol acceptance/rejection rules for TLSRich Felker2012-10-061-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.
* TLS fixes, mainly alignment handlingRich Felker2012-10-061-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).
* fix/improve shared library ctor/dtor handling, allow recursive dlopenRich Felker2012-10-051-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.
* small dynamic linker module search fixRich Felker2012-10-051-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.
* support for TLS in dynamic-loaded (dlopen) modulesRich Felker2012-10-051-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.
* fix race condition in dlopenRich Felker2012-10-051-1/+3
| | | | | orig_tail was being saved before the lock was obtained, allowing dlopen failure to roll-back other dlopens that had succeeded.
* dynamic-linked TLS support for everything but dlopen'd libsRich Felker2012-10-041-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.
* remove freeing of dynamic linker data when dlopen/dlsym are not usedRich Felker2012-10-041-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.
* beginnings of full TLS support in shared librariesRich Felker2012-10-041-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).
* partial TLS support for dynamic-linked programsRich Felker2012-10-041-22/+72
| | | | | only TLS in the main program is supported so far; TLS defined in shared libraries will not work yet.
* TLS (GNU/C11 thread-local storage) support for static-linked programsRich Felker2012-10-041-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.
* more close-on-exec fixes, mostly using new "e" flag to fopenRich Felker2012-09-291-1/+1
|
* fix some more O_CLOEXEC/SOCK_CLOEXEC issuesRich Felker2012-09-291-2/+2
|
* microblaze portRich Felker2012-09-292-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.
* use restrict everywhere it's required by c99 and/or posix 2008Rich Felker2012-09-062-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.
* fix bug caused by main app & libc having map set; cannot free themRich Felker2012-08-271-1/+1
|
* dladdr support for dynamic linker (nonstandard extension)Rich Felker2012-08-262-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.
* fix bug in gnu hash lookup on dlsym(handle, name) lookupsRich Felker2012-08-251-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.
* clean up search_vec usage for vdsoRich Felker2012-08-251-2/+2
|
* use new search_vec function to find vdso in dynamic linkerRich Felker2012-08-251-4/+2
|
* ensure canary is setup if stack-prot libs are dlopen'd into non-ssp appRich Felker2012-08-251-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).
* add gnu hash support in the dynamic linkerRich Felker2012-08-251-12/+85
| | | | based on the patches contributed by boris brezillon.
* make dynamic linker report all failures before exitingRich Felker2012-08-181-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.
* fix bug computing argc when invoking ld-musl-mips.so.1 progname ...Rich Felker2012-08-171-3/+3
|
* fix bug dlsym bug that slipped in during dynamic linker cleanupRich Felker2012-08-071-1/+1
|
* dlsym RTLD_NEXT support for mipsRich Felker2012-08-051-0/+15
| | | | untested
* more changes that were lost when committing mips dynamic linkerRich Felker2012-08-051-0/+4
|
* fix change lost in the process of integrating mips dynamic linkerRich Felker2012-08-051-2/+2
|
* mips dynamic linker supportRich Felker2012-08-052-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.
* more cleanup of dynamic linker internalsRich Felker2012-08-051-8/+9
|
* more dynamic linker internals cleanupRich Felker2012-08-051-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.
* dynamic linker internals cleanupRich Felker2012-08-051-5/+7
|
* make dynamic linker tell the debugger its own pathnameRich Felker2012-07-131-0/+5
| | | | | use the main program's PT_INTERP header if possible, since this is sure to be a correct (and hopefully absolute) pathname.
* make dynamic linker depend on -DSHARED not -fPICRich Felker2012-07-111-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.
* fix lots of breakage on dlopen, mostly with explicit pathnamesRich Felker2012-07-111-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.
* fix dlsym RTLD_NEXT supportRich Felker2012-07-071-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.
* fix char signedness bug (arm-specific) in dynamic linkerRich Felker2012-06-091-1/+1
|
* treat failure of mprotect in map_library as a fatal load failureRich Felker2012-06-061-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.
* add ldd and main program loading support to dynamic linkerRich Felker2012-05-274-21/+89
|
* cleanup dynamic linker start code cruftRich Felker2012-05-273-13/+6
| | | | | | | | | | | | | two actual issues: one is that __dynlink no longer wants/needs a GOT pointer argument, so the code to generate that argument can be removed. the other issue was that in the i386 code, argc/argv were being loaded into registers that would be call-clobbered, then copied to preserved registers, rather than just being loaded into the proper call-preserved registers to begin with. this cleanup is in preparation for adding new dynamic linker functionality (ability to explicitly invoke the dynamic linker to run a program).