The mips arch is special in that it uses different RLIMIT_
numbers than other archs, so allow bits/resource.h to override
the default RLIMIT_ numbers (empty on all archs except mips).
Reported by orc.
it will be needed to implement some things in sysconf, and the syscall
can't easily be used directly because the x32 syscall uses the wrong
structure layout. the l (uncreative, for "linux") prefix is used since
the symbol name __sysinfo is already taken for AT_SYSINFO from the aux
vector.
the way the x32 override of this function works is also changed to be
simpler and avoid the useless jump instruction.
aside from potentially offering better performance, this change is
needed since the old coprocessor-based approach to barriers is
deprecated in arm v7, and some compilers/assemblers issue errors when
using the deprecated instruction for v7 targets.
the "m" constraint could give a memory reference with an offset that's
not compatible with ldrex/strex, so the arm-specific "Q" constraint is
needed instead.
this is perhaps not the optimal implementation; a_cas still compiles
to nested loops due to the different interface contracts of the kuser
helper cas function (whose contract this patch implements) and the
a_cas function (whose contract mimics the x86 cmpxchg). fixing this
may be possible, but it's more complicated and thus deferred until a
later time.
aside from improving performance and code size, this patch also
provides a means of producing binaries which can run on hardened
kernels where the kuser helpers have been disabled. however, at
present this requires producing binaries for armv6k or later, which
will not run on older cpus. a real solution to the problem of kernels
that omit the kuser helpers would be runtime detection, so that
universal binaries which run on all arm cpu models can also be
compatible with all kernel hardening profiles. robust detection
however is a much harder problem, and will be addressed at a later
time.
the kernel entry point for syscalls on microblaze nominally saves and
restores all registers, and testing on qemu always worked since qemu
behaves this way too. however, the real kernel treats r3:r4 as a
potential 64-bit return value from the syscall function, and copies
both over top of the saved registers before returning to userspace.
thus, we need to treat r4 as always-clobbered.
the excess space was unused and unintentional. this change does not
affect the ABI between applications and libc. while it does
theoretically affect linkage between third-party translation units
using jmp_buf as part of a structure, we've already changed jmp_buf at
least once on all archs, and problems were never observed, likely
because such usage would be very unusual. in any case it's best to get
things right now rather than making changes sometime during the 1.0.x
series or later.
Applications ended up with copy relocations for this array, which
resulted in libc's references to this array pointing to the
application's copy. The dynamic linker, however, can require this array
before the application is relocated, and therefore before the
application's copy of this array is initialized. This resulted in
garbage being loaded into FPSCR before executing main, which violated
the ABI.
We fix this by putting the array in crt1 and making the libc copy
private. This prevents libc's reference to the array from pointing to
an uninitialized copy in the application.
The mips statfs struct layout is different than on other archs, so the
statfs, fstatfs, statvfs and fstatvfs APIs were broken on mips.
Now the ordering is fixed, the types are kept consistent with other archs.
these have been wrong for a long time and were never detected or
corrected. powerpc needs some gratuitous extra padding/reserved slots
in ipc_perm, big-endian ordering for the padding of time_t slots that
was intended by the kernel folks to allow a transition to 64-bit
time_t, and some minor gratuitous reordering of struct members.
the definition was found to be incorrect at least for powerpc, and
fixing this cleanly requires making the definition arch-specific. this
will allow cleaning up the definition for other archs to make it more
specific, and reversing some of the ugliness (time_t hacks) introduced
with the x32 port.
this first commit simply copies the existing definition to each arch
without any changes. this is intentional, to make it easier to review
changes made on a per-arch basis.
the kernel uses long longs in the struct, but the documentation
says they're long. so we need to fixup the mismatch between the
userspace and kernelspace structs.
since the struct offers a mem_unit member, we can avoid truncation
by adjusting that value.
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.
Userspace emulated floating-point (gcc -msoft-float) is not compatible
with the default mips abi (assumes an FPU or in kernel emulation of it).
Soft vs hard float abi should not be mixed, __mips_soft_float is checked
in musl's configure script and there is no runtime check. The -sf subarch
does not save/restore floating-point registers in setjmp/longjmp and only
provides dummy fenv implementation.
the reordering of headers caused some risc archs to not see
the __syscall declaration anymore.
this caused build errors on mips with any compiler,
and on arm and microblaze with clang.
we now declare it locally just like the powerpc port does.
it's legal to call the __syscall functions with more arguments than
necessary, and the __syscall_cp cancel dummy impl. does just that.
thus we must insert the switch for all possible syscalls numbers
into all of the syscallN inline functions.
- the nanosleep fixup "fixed" the second timespec* argument erroneusly.
- the futex fixup was missing the check for FUTEX_WAIT.
- general cleanup using a macro.
the operand size is unnecessary, since the assembler knows it from the
destination register size. removing the suffix makes it so the same
code should work for x32.
the fix should be complete on archs that use the generic definitions
(i386, arm, x86_64, microblaze), but mips and powerpc have not been
checked thoroughly and may need more fixes.
previously these macros wrongly had type double rather than long
double. I see no way an application could detect the error in C99, but
C11's _Generic can trivially detect it.
at the same time, even though these archs do not have excess
precision, the number of decimal places used to represent these
constants has been increased to 21 to be consistent with the decimal
representations used for the DBL_* macros.
atomic store was lacking a barrier, which was fine for legacy arm with
no real smp and kernel-emulated cas, but unsuitable for more modern
systems. the kernel provides another "kuser" function, at 0xffff0fa0,
which could be used for the barrier, but using that would drop support
for kernels 2.6.12 through 2.6.14 unless an extra conditional were
added to check for barrier availability. just using the barrier in the
kernel cas is easier, and, based on my reading of the assembly code in
the kernel, does not appear to be significantly slower.
at the same time, other atomic operations are adapted to call the
kernel cas function directly rather than using a_cas; due to small
differences in their interface contracts, this makes the generated
code much simpler.
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.
msg.h was wrong for big-endian (wrong endiannness padding).
shm.h was just plain wrong (mips is not supposed to have padding).
both changes were tested using libc-test on qemu-system-mips.
it turns out that __SOFTFP__ does not indicate the ABI in use but
rather that fpu instructions are not to be used at all. this is
specified in ARM's documentation so I'm unclear on how I previously
got the wrong idea. unfortunately, this resulted in the 0.9.12 release
producing a dynamic linker with the wrong name. fortunately, there do
not yet seem to be any public toolchain builds using the wrong name.
the __ARM_PCS_VFP macro does not seem to be official from ARM, and in
fact it was missing from the very earliest gcc versions (around 4.5.x)
that added -mfloat-abi=hard. it would be possible on such versions to
perform some ugly linker-based tests instead in hopes that the linker
will reject ABI-mismatching object files, if there is demand for
supporting such versions. I would probably prefer to document which
versions are broken and warn users to manually add -D__ARM_PCS_VFP if
using such a version.
there's definitely an argument to be made that the fenv macros should
be exposed even in -mfloat-abi=softfp mode. for now, I have chosen not
to expose them in this case, since the math library will not
necessarily have the capability to raise exceptions (it depends on the
CFLAGS used to compile it), and since exceptions are officially
excluded from the ARM EABI, which the plain "arm" arch aims to
follow.