| Commit message (Expand) | Author | Age | Files | Lines |
| * | add options when explicitly invoking dynamic loader•••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.
| Rich Felker | 2014-04-16 | 1 | -2/+21 |
| * | remove lazy ssp initialization•••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.
| Timo Teräs | 2014-03-25 | 1 | -13/+0 |
| * | if dynamic linker's relro mprotect call fails, include reason in message | Rich Felker | 2014-03-25 | 1 | -1/+1 |
| * | cosmetic improvements in dynamic linker cleanup•••consistent use of braces in if/else structure, line length.
| Rich Felker | 2014-03-25 | 1 | -5/+5 |
| * | clean up internal dynamic linker functions enumerating phdrs•••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.
| Timo Teräs | 2014-03-25 | 1 | -28/+23 |
| * | implement PT_GNU_RELRO support | Timo Teräs | 2014-03-25 | 1 | -15/+37 |
| * | always initialize thread pointer at program start•••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.
| Rich Felker | 2014-03-24 | 1 | -9/+19 |
| * | rename superh port to "sh" for consistency•••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.
| Rich Felker | 2014-02-27 | 2 | -0/+0 |
| * | superh port | Bobby Bingham | 2014-02-23 | 2 | -0/+36 |
| * | x32 port (diff against vanilla x86_64) | rofl0r | 2014-02-23 | 1 | -7/+15 |
| * | import vanilla x86_64 code as x32 | rofl0r | 2014-02-23 | 2 | -0/+22 |
| * | fix crash in dynamic linker when certain copy relocations are unsatisfied•••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.
| Rich Felker | 2014-01-21 | 1 | -1/+2 |
| * | const-qualify the address argument to dladdr•••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.
| Rich Felker | 2014-01-06 | 2 | -4/+4 |
| * | fix dynamic linker entry point for microblaze•••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.
| Rich Felker | 2013-12-14 | 1 | -3/+4 |
| * | include cleanups: remove unused headers and add feature test macros | Szabolcs Nagy | 2013-12-12 | 1 | -0/+1 |
| * | add infrastructure to record and report the version of libc.so•••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.
| Rich Felker | 2013-12-01 | 1 | -2/+7 |
| * | remove duplicate includes from dynlink.c, strfmon.c and getaddrinfo.c | Szabolcs Nagy | 2013-11-25 | 1 | -3/+0 |
| * | fix uninitialized variable in dladdr•••the affected branch only applies for DSOs that lack standard hash
table and only have the GNU hash table present.
| Rich Felker | 2013-10-04 | 1 | -1/+1 |
| * | support configurable page size on mips, powerpc and microblaze•••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.
| Szabolcs Nagy | 2013-09-15 | 1 | -0/+1 |
| * | do not use default when dynamic linker fails to open existing path file•••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.
| Rich Felker | 2013-09-09 | 1 | -0/+2 |
| * | make dlopen honor the rpath of the main program•••this seems to match what other systems do, and seems useful for
programs that have their libraries and plugins stored relative to the
executable.
| Rich Felker | 2013-08-23 | 1 | -1/+1 |
| * | fix bugs in $ORIGIN handling•••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.
| Rich Felker | 2013-08-23 | 1 | -3/+9 |
| * | use AT_EXECFN, if available, for dynamic linker to identify main program•••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.
| Rich Felker | 2013-08-23 | 1 | -1/+5 |
| * | add rpath $ORIGIN processing to dynamic linker | Rich Felker | 2013-08-23 | 1 | -3/+59 |
| * | add recursive rpath support to dynamic linker•••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.
| Rich Felker | 2013-08-23 | 1 | -12/+13 |
| * | work around libraries with versioned symbols in dynamic linker•••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.
| Rich Felker | 2013-08-08 | 1 | -11/+14 |
| * | add system for resetting TLS to initial values•••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.
| Rich Felker | 2013-08-03 | 1 | -0/+13 |
| * | move RPATH search after LD_LIBRARY_PATH search•••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.
| Rich Felker | 2013-08-02 | 1 | -2/+2 |
| * | if map_library has allocated a buffer for phdrs, free it on success too•••this fixes an oversight in the previous commit.
| Rich Felker | 2013-08-02 | 1 | -0/+1 |
| * | improve error handling in map_library and support long phdrs•••previously, errno could be meaningless when the caller wrote it to the
dlerror string or stderr. try to make it meaningful. also, fix
incorrect check for over-long program headers and instead actually
support them by allocating memory if needed.
| Rich Felker | 2013-08-02 | 1 | -12/+21 |
| * | fix uninitialized dyn variable in map_library•••this can only happen for invalid library files, but they were not
detected reliably because the variable was uninitialized.
| Rich Felker | 2013-08-02 | 1 | -1/+1 |
| * | fix theoretical out-of-bound access in dynamic linker•••one of the arguments to memcmp may be shorter than the length l-3, and
memcmp is under no obligation not to access past the first byte that
differs. instead use strncmp which conveys the correct semantics. the
performance difference is negligible here and since the code is only
use for shared libc, both functions are already linked anyway.
| Rich Felker | 2013-07-31 | 1 | -1/+1 |
| * | prevent passing PT_INTERP name to dlopen from double-loading libc•••the dev/inode for the main app and the dynamic linker ("interpreter")
are not available, so the subsequent checks don't work. in general we
don't want to make exact string matches to existing libraries prevent
loading new ones, since this breaks loading upgraded modules in
module-loading systems. so instead, special-case it.
the motivation for this fix is that calling dlopen on the names
returned by dl_iterate_phdr or walking the link map (obtained by
dlinfo) seem to be the only methods available to an application to
actually get a list of open dso handles.
| Rich Felker | 2013-07-31 | 1 | -6/+11 |
| * | add some sanity checks in dynamic loader code•••reject elf files which are not ET_EXEC/ET_DYN type as bad exec format,
and reject ET_EXEC files when they cannot be loaded at the correct
address, since they are not relocatable at runtime. the main practical
benefit of this is to make dlopen of the main program fail rather than
producing an unsafe-to-use handle.
| Rich Felker | 2013-07-31 | 1 | -0/+10 |
| * | fix bug where read error was treated as success reading library headers | Rich Felker | 2013-07-31 | 1 | -1/+1 |
| * | don't call null pointer if DT_INIT/DT_FINI are null•••it's not clear to me why the linker even outputs these headers if they
are null, but apparently it does so. with the default startfiles, they
will never be null anyway, but this patch allows eliminating crti,
crtn, crtbegin, and crtend (leaving only crt1) if the toolchain is
using init_array/fini_array (or for a C-only, no-ctor environment).
| Rich Felker | 2013-07-31 | 1 | -2/+2 |
| * | fix indention-with-spaces | Rich Felker | 2013-07-27 | 1 | -1/+1 |
| * | make ldd report the libc/dynamic linker itself | Rich Felker | 2013-07-26 | 1 | -0/+22 |
| * | fix computation of entry point and main app phdrs when invoking via ldso•••entry point was wrong for PIE. e_entry was being treated as an
absolute value, whereas it's actually relative to the load address
(which is zero for non-PIE).
phdr pointer was wrong for non-PIE. e_phoff was being treated as
load-address-relative, whereas it's actually a file offset in the ELF
file. in any case, map_library was already computing it correctly, and
the incorrect code in __dynlink was overwriting it with junk.
| Rich Felker | 2013-07-26 | 1 | -3/+1 |
| * | support STB_GNU_UNIQUE symbol bindings in dynamic linker•••these are needed for some C++ library binaries including most builds
of libstdc++. I'm not entirely clear on the rationale. this patch does
not implement any special semantics for them, but as far as I can
tell, no special treatment is needed in correctly-linked programs;
this binding seems to exist only for catching incorrectly-linked
programs.
| Rich Felker | 2013-07-24 | 1 | -1/+1 |
| * | move the dynamic linker's jmp_buf from static to automatic storage•••this more than compensates for the size increase of jmp_buf, and
greatly reduces bss/data size on archs with huge jmp_buf.
| Rich Felker | 2013-07-24 | 1 | -5/+7 |
| * | disable legacy init/fini processing on ARM•••since the old, poorly-thought-out musl approach to init/fini arrays on
ARM (when it was the only arch that needed them) was to put the code
in crti/crtn and have the legacy _init/_fini code run the arrays,
adding proper init/fini array support caused the arrays to get
processed twice on ARM. I'm not sure skipping legacy init/fini
processing is the best solution to the problem, but it works, and it
shouldn't break anything since the legacy init/fini system was never
used for ARM EABI.
| Rich Felker | 2013-07-22 | 1 | -0/+4 |
| * | add support for init/fini array in main program, and greatly simplify•••modern (4.7.x and later) gcc uses init/fini arrays, rather than the
legacy _init/_fini function pasting and crtbegin/crtend ctors/dtors
system, on most or all archs. some archs had already switched a long
time ago. without following this change, global ctors/dtors will cease
to work under musl when building with new gcc versions.
the most surprising part of this patch is that it actually reduces the
size of the init code, for both static and shared libc. this is
achieved by (1) unifying the handling main program and shared
libraries in the dynamic linker, and (2) eliminating the
glibc-inspired rube goldberg machine for passing around init and fini
function pointers. to clarify, some background:
the function signature for __libc_start_main was based on glibc, as
part of the original goal of being able to run some glibc-linked
binaries. it worked by having the crt1 code, which is linked into
every application, static or dynamic, obtain and pass pointers to the
init and fini functions, which __libc_start_main is then responsible
for using and recording for later use, as necessary. however, in
neither the static-linked nor dynamic-linked case do we actually need
crt1.o's help. with dynamic linking, all the pointers are available in
the _DYNAMIC block. with static linking, it's safe to simply access
the _init/_fini and __init_array_start, etc. symbols directly.
obviously changing the __libc_start_main function signature in an
incompatible way would break both old musl-linked programs and
glibc-linked programs, so let's not do that. instead, the function can
just ignore the information it doesn't need. new archs need not even
provide the useless args in their versions of crt1.o. existing archs
should continue to provide it as long as there is an interest in
having newly-linked applications be able to run on old versions of
musl; at some point in the future, this support can be removed.
| Rich Felker | 2013-07-21 | 1 | -8/+6 |
| * | fix order of fini_array execution for shared libs | Rich Felker | 2013-07-21 | 1 | -2/+2 |
| * | add support for init_array/fini_array ctors/dtors to dynamic linker | Rich Felker | 2013-07-20 | 1 | -2/+13 |
| * | make the dynamic linker find its path file relative to its own location•••prior to this change, using a non-default syslibdir was impractical on
systems where the ordinary library paths contain musl-incompatible
library files. the file containing search paths was always taken from
/etc, which would either correspond to a system-wide musl
installation, or fail to exist at all, resulting in searching of the
default library path.
the new search strategy is safe even for suid programs because the
pathname used comes from the PT_INTERP header of the program being
run, rather than any external input.
as part of this change, I have also begun differentiating the names of
arch variants that differ by endianness or floating point calling
convention. the corresponding changes in the build system and and gcc
wrapper script (to use an alternate dynamic linker name) for these
configurations have not yet been made.
| Rich Felker | 2013-07-18 | 1 | -1/+20 |
| * | fix invalid library phdr pointers passed to callback from dl_iterate_phdr•••map_library was saving pointers to an automatic-storage buffer rather
than pointers into the mapping. this should be a fairly simple fix,
but the patch here is slightly complicated by two issues:
1. supporting gratuitously obfuscated ELF files where the program
headers are not right at the beginning of the file.
2. cleaning up the map_library function so that data isn't clobbered
by the time we need it.
| Rich Felker | 2013-07-10 | 1 | -9/+16 |
| * | implement minimal dlinfo function | Rich Felker | 2013-06-29 | 2 | -0/+20 |
| * | fix missing synchronization in calls from dynamic linker to global ctors•••this change is needed to correctly handle the case where a constructor
creates a new thread which calls dlopen. previously, the lock was not
held in this case. the reason for the complex logic to avoid locking
whenever possible is that, since the mutex is recursive, it will need
to inspect the thread pointer to get the current thread's tid, and
this requires initializing the thread pointer. we do not want
non-multi-threaded programs to attempt to access the thread pointer
unnecessarily; doing so could make them crash on ancient kernels that
don't support threads but which may otherwise be capable of running
the program.
| Rich Felker | 2013-06-29 | 1 | -0/+4 |
| * | remove useless conditional before free from dynamic linker path code | Rich Felker | 2013-06-26 | 1 | -1/+1 |