Age | Commit message (Collapse) | Author | Lines |
|
|
|
i originally omitted these (optional, per POSIX) interfaces because i
considered them backwards implementation details. however, someone
later brought to my attention a fairly legitimate use case: allocating
thread stacks in memory that's setup for sharing and/or fast transfer
between CPU and GPU so that the thread can move data to a GPU directly
from automatic-storage buffers without having to go through additional
buffer copies.
perhaps there are other situations in which these interfaces are
useful too.
|
|
|
|
signedness issue kept %ls with no precision from working at all
|
|
printf was not printing too many characters, but it was reading one
too many wchar_t elements from the input. this could lead to crashes
if running off the page, or spurious failure if the conversion of the
extra wchar_t resulted in EILSEQ.
|
|
the field width limit was not being cleared before reading the
literal, causing spurious failures in scanf in cases like "%2d:"
scanning "00:".
|
|
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.
|
|
|
|
Per POSIX, "The abort() function shall cause abnormal process
termination to occur, unless the signal SIGABRT is being caught and
the signal handler does not return."
If SIGABRT is blocked or if a signal handler is installed and does
return, abort is still required to cause abnormal program termination.
We cannot use a_crash() to do this, since a SIGILL handler could also
be installed (and might even longjmp out of the abort, not expecting
to be invoked from within abort), nor can we rely on resetting the
signal handler and re-raising the signal (this has race conditions in
multi-threaded programs). On the other hand, SIGKILL is a perfectly
safe, unblockable way to obtain abnormal program termination, and it
requires no ugly loop-and-retry logic.
|
|
for some nonsensical reason, glibc's headers use inline functions that
redirect some of the standard functions to ugly nonstandard names (and
likewise for some of their nonstandard functions).
|
|
I've been looking for data that would suggest a good default, and
since little has shown up, i'm doing this based on the limited data I
have. the value 80k is chosen to accommodate 64k of application data
(which happens to be the size of the buffer in git that made it crash
without a patch to call pthread_attr_setstacksize) plus the max stack
usage of most libc functions (with a few exceptions like crypt, which
will be fixed soon to avoid excessive stack usage, and [n]ftw, which
inherently uses a fair bit in recursive directory searching).
if further evidence emerges suggesting that the default should be
larger, I'll consider changing it again, but I'd like to avoid it
getting too large to avoid the issues of large commit charge and rapid
address space exhaustion on 32-bit machines.
|
|
this fix is necessary because a program could be started with some of
the implementation-reserved signals masked (e.g. due to exec having
been called from a signal handler, or from a non-musl program) and
then could obtain an invalid-to-use-later sigset_t as the old/saved
signal mask.
|
|
this action is now performed in pthread_self initialization; it must
be performed there in case the first call to pthread_create is from a
signal handler, in which case the old signal mask could be restored on
return from the signal.
|
|
this should be the last major fix needed to support running
glibc-linked conforming POSIX programs with musl in place of glibc, as
long as musl provides the features they need and they don't use
pthread cancellation (which is implemented as c++ exceptions in glibc,
and fundamentally incompatible with musl).
|
|
this was fixed previously on i386 but the corresponding code on x86_64
was missed.
|
|
|
|
these will NOT be used when compiling with -D_LARGEFILE64_SOURCE on
musl; instead, they exist in the hopes of eventually being able to run
some glibc-linked apps with musl sitting in place of glibc.
also remove the (apparently incorrect) fcntl alias.
|
|
|
|
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).
|
|
bug report and solution by Richard Pennington
|
|
issue reported by Richard Pennington; slightly simpler fix applied
|
|
bug report and solution by Richard Pennington
|
|
unfortunately in dynamic-linked programs, these macros cause
pthread_self to be initialized, which costs a couple syscalls, and
(much worse) would necessarily fail, crash, and burn on ancient (2.4
and earlier) kernels where setting up a thread pointer does not work.
i'd like to do this in a more generic way that avoids all use of
cleanup push/pop before pthread_self has been successfully called and
avoids ugly if/else constructs like the one in this commit, but for
now, this will suffice.
|
|
if the process started with these signals blocked, cancellation could
fail or setxid could deadlock. there is no way to globally unblock
them after threads have been created. by unblocking them in the
pthread_self initialization for the main thread, we ensure that
they're unblocked before any other threads are created and also
outside of any signal handler context (sigaction initialized
pthread_self), which is important so that return from a signal handler
won't re-block them.
|
|
TRE has a broken assumption that wchar_t is signed, which is a sane
expectation, but not required by the standard, and false on ARM's ABI.
i leave tre_char_t as wchar_t for now, since a pointer to it is
directly passed to functions that need pointer to wchar_t. it does not
seem to break anything. and since the maximum unicode scalar value is
0x10ffff, just use that explicitly rather than using the max value of
any particular C type.
|
|
|
|
the bug was that cancellation requests which arrived while a
cancellation point was interrupted by a signal handler would not be
acted upon when the signal handler returns. this was because cp_sp was
never set; it's no longer needed or used.
instead, just always re-raise the signal when cancellation was not
acted upon. this wastes a tiny amount of time in the rare case where
it even matters, but it ensures correctness and simplifies the code.
|
|
|
|
the old code could be kept for cases where SYS_utime is available, but
it's not really worth the ifdef ugliness. and better to avoid
deprecated stuff just in case the kernel devs ever get crazy enough to
start removing it from archs where it was part of the ABI and breaking
static bins...
|
|
|
|
stale state information indicating that a thread was possibly blocked
at a cancellation point could get left behind if longjmp was used to
exit a signal handler that interrupted a cancellation point.
to fix the issue, we throw away the state information entirely and
simply compare the saved instruction pointer to a range of code
addresses in the __syscall_cp_asm function. all the ugly PIC work
(which becomes minimal anyway with this approach) is defered to
cancellation time instead of happening at every syscall, which should
improve performance too.
this commit also fixes cancellation on arm, which was mildly broken
(race condition, not checking cancellation flag once inside the
cancellation point zone). apparently i forgot to implement that. the
new arm code is untested, but appears correct; i'll test and fix it
later if there are problems.
|
|
no need to pass unnecessary extra arguments on to the core code in
pthread_create.c. this just wastes cycles and code bloat.
|
|
i made a best attempt, but the intended semantics of this function are
fundamentally contradictory. there is no consistent way to handle
ownership of locks when forking a multi-threaded process. the code
could have worked by accident for programs that only used normal
mutexes and nothing else (since they don't actually store or care
about their owner), but that's about it. broken-by-design interfaces
that aren't even in glibc (only solaris) don't belong in musl.
|
|
|
|
it's ok to overlap with integer slot 3 on 32-bit because only slots
0-2 are used on process-local barriers.
|
|
|
|
these are cruft from the original code which used an explicit string
length rather than null termination. i blindly converted all the
checks to null terminator checks, without noticing that in several
cases, the subsequent switch statement would automatically handle the
null byte correctly.
|
|
i don't understand why this has to be conditional on being in BRE
mode, but enabling this code unconditionally breaks a huge number of
ERE test cases.
|
|
i've been trying out openmp and it seems like it won't be much use
without this...
|
|
we do not bother making h_errno thread-local since the only interfaces
that use it are inherently non-thread-safe. but still use the
potentially-thread-local ABI to access it just to avoid lock-in.
|
|
|
|
|
|
|
|
there's no sense in using a powerful lock in exit, because it will
never be unlocked. a thread that arrives at exit while exit is already
in progress just needs to hang forever. use the pause syscall for this
because it's cheap and easy and universally available.
|
|
|
|
backported fix from freebsd:
http://svnweb.FreeBSD.org/base?view=revision&revision=233973
|
|
|
|
|
|
|
|
|