Commit Graph
144 Commits
Author SHA1 Message Date
Rich Felker f44e239f9f fix indention-with-spaces 2013-07-27 21:37:05 -04:00
Rich Felker a97a050eca make ldd report the libc/dynamic linker itself 2013-07-26 14:41:12 -04:00
Rich Felker 876748ead3 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.
2013-07-26 14:25:51 -04:00
Rich Felker e152ee9778 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.
2013-07-24 11:53:23 -04:00
Rich Felker 17276be316 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.
2013-07-24 02:38:05 -04:00
Rich Felker 1da53dad27 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.
2013-07-22 14:08:33 -04:00
Rich Felker 7586360bad 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.
2013-07-21 03:00:54 -04:00
Rich Felker 1b413572b2 fix order of fini_array execution for shared libs 2013-07-21 02:35:46 -04:00
Rich Felker e69ae844dc add support for init_array/fini_array ctors/dtors to dynamic linker 2013-07-20 18:26:17 -04:00
Rich Felker f389c4984a 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.
2013-07-18 19:29:44 -04:00
Rich Felker 30763fd01b 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.
2013-07-10 14:38:20 -04:00
Rich Felker 780cbbe63a implement minimal dlinfo function 2013-06-29 12:46:46 -04:00
Rich Felker 509b50eda8 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.
2013-06-29 02:24:02 -04:00
Rich Felker 59b481d970 remove useless conditional before free from dynamic linker path code 2013-06-26 10:51:36 -04:00
Rich Felker 11bc173765 fix dynamic linker handling of empty path file or error reading path file
previously, the path string was being used despite being invalid. with
this change, empty path file or error reading the path file is treated
as an empty path. this is preferable to falling back to a default
path, so that attacks to prevent reading of the path file could not
result in loading incorrect and possibly dangerous (outdated or
mismatching ABI) libraries from.

the code to strip the final newline has also been removed; now that
newline is accepted as a delimiter, it's harmless to leave it in
place.
2013-06-26 10:17:29 -04:00
Rich Felker 8813c956e5 make newline-delimited dynamic linker path file actually work
apparently the original commit was never tested properly, since
getline was only ever reading one line. the intent was to read the
entire file, so use getdelim with the null byte as delimiter as a
cheap way to read a whole file into memory.
2013-06-25 21:39:35 -04:00
Rich Felker 44b4d09fc0 ensure that thread dtv pointer is never null to optimize __tls_get_addr 2013-06-03 16:35:59 -04:00
Rich Felker 8c203eae1e make dynamic linker accept : or \n as path separator
this allows /etc/ld-musl-$(ARCH).path to contain one path per line,
which is much more convenient for users than the :-delimited format,
which was a source of repeated and unnecessary confusion. for
simplicity, \n is also accepted in environment variables, though it
should probably not be used there.

at the same time, issues with overly long paths invoking UB or getting
truncated have been fixed. such issues should not have arisen with the
environment (which is size-limited) but could have been generated by a
path file larger than 2**31 bytes in length.
2013-04-20 11:51:58 -04:00
Rich Felker 74025c80ce fix uninitialized map_len being used in munmap failure paths in load_library
this bug seems to have been introduced when the map_library signatures
was changed to return the mapping in a temp dso structure instead of
into separate variables.
2013-02-02 00:59:25 -05:00
Rich Felker 4d07e5521e add support for RTLD_NOLOAD to dlopen
based on patch by Pierre Carrier <[email protected]> that just added
the flag constant, but with minimal additional code so that it
actually works as documented. this is a nonstandard option but some
major software (reportedly, Firefox) uses it and it was easy to add
anyway.
2013-01-23 22:07:45 -05:00
Rich Felker 637dd2d383 fix regression in dlsym: rejection of special RTLD_* handles as invalid 2013-01-23 20:21:36 -05:00
Rich Felker 4d98280388 fix warning building dynlink.c stub for static libc
struct dso was not defined in this case, and it's not needed in the
code that was using it anyway; void pointers work just as well.
2013-01-16 11:49:00 -05:00
Rich Felker cdc5c74c6a fix bug in dladdr that prevented resolving addresses in the PLT 2013-01-16 11:47:35 -05:00
Rich Felker 6468fc9e37 check for invalid handles in dlsym/dlclose
this is wasteful and useless from a standpoint of sane programs, but
it is required by the standard, and the current requirements were
upheld with the closure of Austin Group issue #639:
http://austingroupbugs.net/view.php?id=639
2013-01-10 14:05:40 -05:00
Rich Felker 1d7c4f8f93 fix breakage in ldd (failure to print library load address) 2012-12-15 23:34:08 -05:00
Rich Felker a7936f61b2 fix ordering of shared library ctors with respect to libc init
previously, shared library constructors were being called before
important internal things like the environment (extern char **environ)
and hwcap flags (needed for sjlj to work right with float on arm) were
initialized in __libc_start_main. rather than trying to have to
dynamic linker make sure this stuff all gets initialized right, I've
opted to just defer calling shared library constructors until after
the main program's entry point is reached. this also fixes the order
of ctors to be the exact reverse of dtors, which is a desirable
property and possibly even mandated by some languages.

the main practical effect of this change is that shared libraries
calling getenv from ctors will no longer fail.
2012-11-30 17:56:23 -05:00
Rich Felker 75a31faaed eliminate gdb complaints about missing linux-gate.so.1
actually, the hard-coded name should be eliminated too, and replaced
by a search for the soname in the headers, but that can be done
separately later.
2012-11-25 20:56:31 -05:00
Rich Felker 71955b2ff8 fix typo in dynamic linker path file loading code
fortunately the memory corruption could not hurt anything, but it
prevented clearing the final newline and thus prevented the last path
element from working.
2012-11-17 20:04:36 -05:00
Rich Felker bb9abdef48 arg-skipping code for powerpc dynamic linker
this allows using the dynamic linker as a command to load programs.
2012-11-17 17:25:17 -05:00
Rich Felker a4db94ab78 dynamic linking support for powerpc
incomplete but at least partly working. requires all files to be
compiled in the new "secure" plt model, not the old one that put plt
code in the data segment. TLS is untested but may work. invoking the
dynamic linker explicitly to load a program does not yet handle argv
correctly.
2012-11-16 22:22:34 -05:00
Rich Felker d1bf452d75 fix indention with spaces in powerpc asm 2012-11-14 14:27:51 -05:00
Rich Felker c6d441e3a2 Merge remote-tracking branch 'ppc-port/ppc-squashed' 2012-11-14 14:01:39 -05:00
rofl0r 1c8eb8bad7 PPC port cleaned up, static linking works well now. 2012-11-13 19:12:25 +01:00
Richard Penningtonandrofl0r 7669d1e334 import preliminary ppc work by rdp. 2012-11-13 18:15:10 +01:00
Rich Felker 65465101ee support ldso path files without final newline 2012-11-09 13:49:40 -05:00
Rich Felker 40d5f7eb83 change ldso path file logic to replace rather than add to search path
this change was originally intended just to avoid repeated attempts to
open a nonexistant /etc/ls-musl-$(ARCH).path file, but I realized it
also prevents the default paths from being searched when such a path
file exists. despite the potential to break existing usage, I believe
the new behavior is the right behavior, and it's better to fix it
sooner rather than later. with the old behavior, it was impossible to
inhibit search of default paths which might contain musl-incompatible
libs (or even libs from a different cpu arch, on multi-arch machines).
2012-11-08 22:41:16 -05:00
Rich Felker 1e717ea3d2 fix dlsym asm for mips
saving the return address from the delay slot is not valid -- by the
time the instruction executes, the return address has already been
replaced.
2012-11-08 14:31:49 -05:00
Rich Felker 2f2f115b58 remove one unnecessary static var from dynamic linker 2012-11-01 23:49:57 -04:00
Rich Felker a617a8e2ad fix more unused variable warnings
some of these were coming from stdio functions locking files without
unlocking them. I believe it's useful for this to throw a warning, so
I added a new macro that's self-documenting that the file will never
be unlocked to avoid the warning in the few places where it's wrong.
2012-11-01 23:46:39 -04:00
Rich Felker 18c0e02e2b add dl_iterate_phdr interface
patches by Alex Caudill (npx). the dynamic-linked version is almost
identical to the final submitted patch; I just added a couple missing
lines for saving the phdr address when the dynamic linker is invoked
directly to run a program, and removed a couple to avoid introducing
another unnecessary type. the static-linked version is based on npx's
draft. it could use some improvements which are contingent on the
startup code saving some additional information for later use.
2012-10-31 21:27:48 -04:00
Rich Felker 0a1c2c1c17 support looking up thread-local objects with dlsym 2012-10-19 21:57:56 -04:00
Rich Felker deb15b3cf2 fix breakage in dlsym for looking up RTLD_DEFAULT, etc.
this was broken during the early dynamic-linked TLS commits, which
rearranged some of the code for handling new relocation types.
2012-10-19 21:41:30 -04:00
Rich Felker ef2f595f74 fix microblaze asm relocations for shared libc
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-17 23:45:21 -04:00
Rich Felker 9ec4283b28 add support for TLS variant I, presently needed for arm and mips
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-15 18:51:53 -04:00
Rich Felker c62b9f3980 fix main program TLS alignment for dynamic-linked programs
this change brings the behavior in line with the static-linked code,
which seems to be correct.
2012-10-14 19:56:50 -04:00
Rich Felker e23d358fd6 fix namespace clash (libc) in dynlink.c
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-13 23:25:20 -04:00
Rich Felker 31f340a17a remove dead code from dynamic linker 2012-10-13 23:23:29 -04:00
Rich Felker 0a96a37f06 clean up and refactor program initialization
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-07 21:43:46 -04:00
Rich Felker 017bf140ff fix breakage due to initializing thread pointer when loading libs
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-07 20:19:11 -04:00
Rich Felker 00902c7384 make new TLS setup block even implementation-internals signals
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-06 23:57:51 -04:00