summaryrefslogtreecommitdiff
path: root/src/ldso
AgeCommit message (Collapse)AuthorLines
2015-03-11add aarch64 portSzabolcs Nagy-0/+115
This adds complete aarch64 target support including bigendian subarch. Some of the long double math functions are known to be broken otherwise interfaces should be fully functional, but at this point consider this port experimental. Initial work on this port was done by Sireesh Tripurari and Kevin Bortis.
2015-03-11copy the dtv pointer to the end of the pthread struct for TLS_ABOVE_TP archsSzabolcs Nagy-3/+3
There are two main abi variants for thread local storage layout: (1) TLS is above the thread pointer at a fixed offset and the pthread struct is below that. So the end of the struct is at known offset. (2) the thread pointer points to the pthread struct and TLS starts below it. So the start of the struct is at known (zero) offset. Assembly code for the dynamic TLSDESC callback needs to access the dynamic thread vector (dtv) pointer which is currently at the front of the pthread struct. So in case of (1) the asm code needs to hard code the offset from the end of the struct which can easily break if the struct changes. This commit adds a copy of the dtv at the end of the struct. New members must not be added after dtv_copy, only before it. The size of the struct is increased a bit, but there is opportunity for size optimizations.
2015-03-06fix over-alignment of TLS, insufficient builtin TLS on 64-bit archsRich Felker-2/+8
a conservative estimate of 4*sizeof(size_t) was used as the minimum alignment for thread-local storage, despite the only requirements being alignment suitable for struct pthread and void* (which struct pthread already contains). additional alignment required by the application or libraries is encoded in their headers and is already applied. over-alignment prevented the builtin_tls array from ever being used in dynamic-linked programs on 64-bit archs, thereby requiring allocation at startup even in programs with no TLS of their own.
2015-03-03make all objects used with atomic operations volatileRich Felker-1/+1
the memory model we use internally for atomics permits plain loads of values which may be subject to concurrent modification without requiring that a special load function be used. since a compiler is free to make transformations that alter the number of loads or the way in which loads are performed, the compiler is theoretically free to break this usage. the most obvious concern is with atomic cas constructs: something of the form tmp=*p;a_cas(p,tmp,f(tmp)); could be transformed to a_cas(p,*p,f(*p)); where the latter is intended to show multiple loads of *p whose resulting values might fail to be equal; this would break the atomicity of the whole operation. but even more fundamental breakage is possible. with the changes being made now, objects that may be modified by atomics are modeled as volatile, and the atomic operations performed on them by other threads are modeled as asynchronous stores by hardware which happens to be acting on the request of another thread. such modeling of course does not itself address memory synchronization between cores/cpus, but that aspect was already handled. this all seems less than ideal, but it's the best we can do without mandating a C11 compiler and using the C11 model for atomics. in the case of pthread_once_t, the ABI type of the underlying object is not volatile-qualified. so we are assuming that accessing the object through a volatile-qualified lvalue via casts yields volatile access semantics. the language of the C standard is somewhat unclear on this matter, but this is an assumption the linux kernel also makes, and seems to be the correct interpretation of the standard.
2014-11-23adapt dynamic linker for new binutils versions that omit DT_RPATHRich Felker-0/+2
the new DT_RUNPATH semantics for search order are always used, and since binutils had always set both DT_RPATH and DT_RUNPATH when the latter was used, processing only DT_RPATH worked fine. however, recent binutils has stopped generating DT_RPATH when DT_RUNPATH is used, which broke support for this feature completely.
2014-11-19save auxv pointer into libc struct early in dynamic linker startupRich Felker-0/+1
this allows most code to assume it has already been saved, and is a prerequisite for upcoming changes for arm atomic/tls operations.
2014-08-08add dlerror message for static-linked dlsym failureRich Felker-0/+2
2014-08-08fix dlerror when using dlopen with a static libcClément Vasseur-0/+2
when the dynamic loader is disabled, dlopen fails correctly but dlerror did not return a human readable error string like it should have.
2014-07-18add or1k (OpenRISC 1000) architecture portStefan Kristiansson-0/+39
With the exception of a fenv implementation, the port is fully featured. The port has been tested in or1ksim, the golden reference functional simulator for OpenRISC 1000. It passes all libc-test tests (except the math tests that requires a fenv implementation). The port assumes an or1k implementation that has support for atomic instructions (l.lwa/l.swa). Although it passes all the libc-test tests, the port is still in an experimental state, and has yet experienced very little 'real-world' use.
2014-07-11explicitly reject empty names in dynamic linker load_library functionRich Felker-0/+5
previously passing an empty string for name resulted in failure, as expected, but only after spurious syscalls, and it produced confusing errno values (and thus dlerror strings). in addition to dlopen calls, this issue affected use of LD_PRELOAD with trailing whitespace or colon characters.
2014-07-11make dynamic linker accept colon as a separator for LD_PRELOADRich Felker-2/+2
2014-06-30fix regression in mips dynamic linkerRich Felker-1/+6
this issue caused the address of functions in shared libraries to resolve to their PLT thunks in the main program rather than their correct addresses. it was observed causing crashes, though the mechanism of the crash was not thoroughly investigated. since the issue is very subtle, it calls for some explanation: on all well-behaved archs, GOT entries that belong to the PLT use a special relocation type, typically called JMP_SLOT, so that the dynamic linker can avoid having the jump destinations for the PLT resolve to PLT thunks themselves (they also provide a definition for the symbol, which must be used whenever the address of the function is taken so that all DSOs see the same address). however, the traditional mips PIC ABI lacked such a JMP_SLOT relocation type, presumably because, due to the way PIC works, the address of the PLT thunk was never needed and could always be ignored. prior to commit adf94c19666e687a728bbf398f9a88ea4ea19996, the mips version of reloc.h contained a hack that caused all symbol lookups to be treated like JMP_SLOT, inhibiting undefined symbols from ever being used to resolve symbolic relocations. this hack goes all the way back to commit babf820180368f00742ec65b2050a82380d7c542, when the mips dynamic linker was first made usable. during the recent refactoring to eliminate arch-specific relocation processing (commit adf94c19666e687a728bbf398f9a88ea4ea19996), this hack was overlooked and no equivalent functionality was provided in the new code. fixing the problem is not as simple as adding back an equivalent hack, since there is now also a "non-PIC ABI" that can be used for the main executable, which actually does use a PLT. the closest thing to official documentation I could find for this ABI is nonpic.txt, attached to Message-ID: 20080701202236.GA1534@caradoc.them.org, which can be found in the gcc mailing list archives and elsewhere. per this document, undefined symbols corresponding to PLT thunks have the STO_MIPS_PLT bit set in the symbol's st_other field. thus, I have added an arch-specific rule for mips, applied at the find_sym level rather than the relocation level, to reject undefined symbols with the STO_MIPS_PLT bit clear. the previous hack of treating all mips relocations as JMP_SLOT-like, rather than rejecting the unwanted symbols in find_sym, probably also caused dlsym to wrongly return PLT thunks in place of the correct address of a function under at least some conditions. this should now be fixed, at least for global-scope symbol lookups.
2014-06-29fix regression in dynamic linker error reportingRich Felker-9/+5
due to a mistake when refactoring the error printing for the dynamic linker (commit 7c73cacd09a51a87484db5689864743e4984a84d), all messages were suppressed and replaced by blank lines.
2014-06-23rename dynamic linker _start to _dlstart in the stub versionRich Felker-1/+1
the renaming was previously applied to all real versions of the function in commit 3fa2eb2aba8d6b54dec53e7ad4c37e17392b166f.
2014-06-20rename dynamic linker entry point from _start to _dlstartRich Felker-19/+19
the main motivation for this change is to aid in debugging. since the main program's entry point is also named _start, it was difficult to set breakpoints or quickly identify which _start execution stopped in.
2014-06-19add tlsdesc support for x86_64Rich Felker-0/+40
2014-06-19separate __tls_get_addr implementation from dynamic linker/init_tlsRich Felker-6/+6
such separation serves multiple purposes: - by having the common path for __tls_get_addr alone in its own function with a tail call to the slow case, code generation is greatly improved. - by having __tls_get_addr in it own file, it can be replaced on a per-arch basis as needed, for optimization or ABI-specific purposes. - by removing __tls_get_addr from __init_tls.c, a few bytes of code are shaved off of static binaries (which are unlikely to use this function unless the linker messed up).
2014-06-19add tlsdesc support for i386Rich Felker-0/+27
2014-06-19change dynamic TLS installation strategy to optimize accessRich Felker-8/+14
previously, accesses to dynamic TLS had to check two conditions before being able to use a dtv slot: (1) that the module index was within the bounds of the current dtv size, and (2) that the dynamic tls for the requested module index was already installed in the dtv. this commit changes the installation strategy so that, whenever an attempt is made to access dynamic TLS that's not yet installed in the dtv, the dynamic TLS for all lower-index modules is also installed. thus it provides a new invariant: if a given module index is within the bounds of the current dtv size, we automatically know that its TLS is installed and directly available. the requirement that the second condition (above) be checked is eliminated.
2014-06-19add arch-generic support for tlsdesc relocations to dynamic linkerRich Felker-0/+54
this code is non-functional without further changes to link up the arch-specific reloc types for tlsdesc and add asm implementations of __tlsdesc_static and __tlsdesc_dynamic.
2014-06-18reduce code duplication in dynamic linker error pathsRich Felker-16/+16
eventually this should help making dlerror thread-safe too.
2014-06-18refactor to remove arch-specific relocation code from dynamic linkerRich Felker-8/+89
this was one of the main instances of ugly code duplication: all archs use basically the same types of relocations, but roughly equivalent logic was duplicated for each arch to account for the different naming and numbering of relocation types and variation in whether REL or RELA records are used. as an added bonus, both REL and RELA are now supported on all archs, regardless of which is used by the standard toolchain.
2014-04-16add options when explicitly invoking dynamic loaderRich Felker-2/+21
so far the options are --library-path and --preload which override the corresponding environment variables, and --list which forces the behavior of ldd even if the invocation name is not ldd. both the two-arg form and the one-arg form using an equals sign are supported. based loosely on a patch proposed by Rune.
2014-03-25remove lazy ssp initializationTimo Teräs-13/+0
now that thread pointer is initialized always, ssp canary initialization can be done unconditionally. this simplifies the ldso as it does not try to detect ssp usage, and the init function itself as it is always called exactly once. this also merges ssp init path for shared and static linking.
2014-03-25if dynamic linker's relro mprotect call fails, include reason in messageRich Felker-1/+1
2014-03-25cosmetic improvements in dynamic linker cleanupRich Felker-5/+5
consistent use of braces in if/else structure, line length.
2014-03-25clean up internal dynamic linker functions enumerating phdrsTimo Teräs-28/+23
record phentsize in struct dso, so the phdrs can be easily enumerated via it. simplify all functions enumerating phdrs to require only struct dso. also merge find_map_range and find_dso to kernel_mapped_dso function that does both tasks during single phdr enumeration.
2014-03-25implement PT_GNU_RELRO supportTimo Teräs-15/+37
2014-03-24always initialize thread pointer at program startRich Felker-9/+19
this is the first step in an overhaul aimed at greatly simplifying and optimizing everything dealing with thread-local state. previously, the thread pointer was initialized lazily on first access, or at program startup if stack protector was in use, or at certain random places where inconsistent state could be reached if it were not initialized early. while believed to be fully correct, the logic was fragile and non-obvious. in the first phase of the thread pointer overhaul, support is retained (and in some cases improved) for systems/situation where loading the thread pointer fails, e.g. old kernels. some notes on specific changes: - the confusing use of libc.main_thread as an indicator that the thread pointer is initialized is eliminated in favor of an explicit has_thread_pointer predicate. - sigaction no longer needs to ensure that the thread pointer is initialized before installing a signal handler (this was needed to prevent a situation where the signal handler caused the thread pointer to be initialized and the subsequent sigreturn cleared it again) but it still needs to ensure that implementation-internal thread-related signals are not blocked. - pthread tsd initialization for the main thread is deferred in a new manner to minimize bloat in the static-linked __init_tp code. - pthread_setcancelstate no longer needs special handling for the situation before the thread pointer is initialized. it simply fails on systems that cannot support a thread pointer, which are non-conforming anyway. - pthread_cleanup_push/pop now check for missing thread pointer and nop themselves out in this case, so stdio no longer needs to avoid the cancellable path when the thread pointer is not available. a number of cases remain where certain interfaces may crash if the system does not support a thread pointer. at this point, these should be limited to pthread interfaces, and the number of such cases should be fewer than before.
2014-02-27rename superh port to "sh" for consistencyRich Felker-0/+0
linux, gcc, etc. all use "sh" as the name for the superh arch. there was already some inconsistency internally in musl: the dynamic linker was searching for "ld-musl-sh.path" as its path file despite its own name being "ld-musl-superh.so.1". there was some sentiment in both directions as to how to resolve the inconsistency, but overall "sh" was favored.
2014-02-23superh portBobby Bingham-0/+36
2014-02-23x32 port (diff against vanilla x86_64)rofl0r-7/+15
2014-02-23import vanilla x86_64 code as x32rofl0r-0/+22
2014-01-21fix crash in dynamic linker when certain copy relocations are unsatisfiedRich Felker-1/+2
STB_WEAK is only a weak reference for undefined symbols (those with a section of SHN_UNDEF). otherwise, it's a weak definition. normally this distinction would not matter, since a relocation referencing a symbol that also provides a definition (not SHN_UNDEF) will always succeed in finding the referenced symbol itself. however, in the case of copy relocations, the referenced symbol itself is ignored in order to search for another symbol to copy from, and thus it's possible that no definition is found. in this case, if the symbol being resolved happened to be a weak definition, it was misinterpreted as a weak reference, suppressing the error path and causing a crash when the copy relocation was performed with a null source pointer passed to memcpy. there are almost certainly still situations in which invalid combinations of symbol and relocation types can cause the dynamic linker to crash (this is pretty much inevitable), but the intent is that crashes not be possible for symbol/relocation tables produced by a valid linker.
2014-01-06const-qualify the address argument to dladdrRich Felker-4/+4
this agrees with implementation practice on glibc and BSD systems, and is the const-correct way to do things; it eliminates warnings from passing pointers to const. the prototype without const came from seemingly erroneous man pages.
2013-12-14fix dynamic linker entry point for microblazeRich Felker-3/+4
the ABI allows the callee to clobber stack slots that correspond to arguments passed in registers, so the caller must adjust the stack pointer to reserve space appropriately. prior to this fix, the argv array was possibly clobbered by dynamic linker code before passing control to the main program.
2013-12-12include cleanups: remove unused headers and add feature test macrosSzabolcs Nagy-0/+1
2013-12-01add infrastructure to record and report the version of libc.soRich Felker-2/+7
this is still experimental and subject to change. for git checkouts, an attempt is made to record the exact revision to aid in bug reports and debugging. no version information is recorded in the static libc.a or binaries it's linked into.
2013-11-25remove duplicate includes from dynlink.c, strfmon.c and getaddrinfo.cSzabolcs Nagy-3/+0
2013-10-04fix uninitialized variable in dladdrRich Felker-1/+1
the affected branch only applies for DSOs that lack standard hash table and only have the GNU hash table present.
2013-09-15support configurable page size on mips, powerpc and microblazeSzabolcs Nagy-0/+1
PAGE_SIZE was hardcoded to 4096, which is historically what most systems use, but on several archs it is a kernel config parameter, user space can only know it at execution time from the aux vector. PAGE_SIZE and PAGESIZE are not defined on archs where page size is a runtime parameter, applications should use sysconf(_SC_PAGE_SIZE) to query it. Internally libc code defines PAGE_SIZE to libc.page_size, which is set to aux[AT_PAGESZ] in __init_libc and early in __dynlink as well. (Note that libc.page_size can be accessed without GOT, ie. before relocations are done) Some fpathconf settings are hardcoded to 4096, these should be actually queried from the filesystem using statfs.
2013-09-09do not use default when dynamic linker fails to open existing path fileRich Felker-0/+2
if fopen fails for a reason other than ENOENT, we must assume the intent is that the path file be used. failure may be due to misconfiguration or intentional resource-exhaustion attack (against suid programs), in which case falling back to loading libraries from an unintended path could be dangerous.
2013-08-23make dlopen honor the rpath of the main programRich Felker-1/+1
this seems to match what other systems do, and seems useful for programs that have their libraries and plugins stored relative to the executable.
2013-08-23fix bugs in $ORIGIN handlingRich Felker-3/+9
1. an occurrence of ${ORIGIN} before $ORIGIN would be ignored due to the strstr logic. (note that rpath contains multiple :-delimited paths to be searched.) 2. data read by readlink was not null-terminated.
2013-08-23use AT_EXECFN, if available, for dynamic linker to identify main programRich Felker-1/+5
fallback to argv[0] as before. unlike argv[0], AT_EXECFN was a valid (but possibly relative) pathname for the new program image at the time the execve syscall was made. as a special case, ignore AT_EXECFN if it begins with "/proc/", in order not to give bogus (and possibly harmful) results when fexecve was used.
2013-08-23add rpath $ORIGIN processing to dynamic linkerRich Felker-3/+59
2013-08-23add recursive rpath support to dynamic linkerRich Felker-12/+13
previously, rpath was only honored for direct dependencies. in other words, if A depends on B and B depends on C, only B's rpath (if any), not A's rpath, was being searched for C. this limitation made rpath-based deployment difficult in the presence of multiple levels of library dependency. at present, $ORIGIN processing in rpath is still unsupported.
2013-08-08work around libraries with versioned symbols in dynamic linkerRich Felker-11/+14
this commit does not add versioning support; it merely fixes incorrect lookups of symbols in libraries that contain versioned symbols. previously, the version information was completely ignored, and empirically this seems to have resulted in the oldest version being chosen, but I am uncertain if that behavior was even reliable. the new behavior being introduced is to completely ignore symbols which are marked "hidden" (this seems to be the confusing nomenclature for non-current-version) when versioning is present. this should solve all problems related to libraries with symbol versioning as long as all binaries involved are up-to-date (compatible with the latest-version symbols), and it's the needed behavior for dlsym under all circumstances.
2013-08-03add system for resetting TLS to initial valuesRich Felker-0/+13
this is needed for reused threads in the SIGEV_THREAD timer notification system, and could be reused elsewhere in the future if needed, though it should be refactored for such use. for static linking, __init_tls.c is simply modified to export the TLS info in a structure with external linkage, rather than using statics. this perhaps makes the code more clear, since the statics were poorly named for statics. the new __reset_tls.c is only linked if it is used. for dynamic linking, the code is in dynlink.c. sharing code with __copy_tls is not practical since __reset_tls must also re-zero thread-local bss.
2013-08-02move RPATH search after LD_LIBRARY_PATH searchRich Felker-2/+2
this is the modern way, and the only way that makes any sense. glibc has this complicated mechanism with RPATH and RUNPATH that controls whether RPATH is processed before or after LD_LIBRARY_PATH, presumably to support legacy binaries, but there is no compelling reason to support this, and better behavior is obtained by just fixing the search order.