Commit Graph

12 Commits

Author SHA1 Message Date
Szabolcs Nagy 18f75b80fd fix __syscall declaration with wrong visibility in syscall_arch.h
remove __syscall declaration where it is not needed (aarch64, arm,
microblaze, or1k) and add the hidden attribute where it is (mips).
2015-04-30 16:22:57 -04:00
Rich Felker 25748db301 fix possible clobbering of syscall return values on mips
depending on the compiler's interpretation of __asm__ register names
for register class objects, it may be possible for the return value in
r2 to be clobbered by the function call to __stat_fix. I have not
observed any such breakage in normal builds and suspect it only
happens with -O0 or other unusual build options, but since there's an
ambiguity as to the semantics of this feature, it's best to use an
explicit temporary to avoid the issue.

based on reporting and patch by Eugene.
2015-04-07 12:47:19 -04:00
Rich Felker 1312930f9b fix regression that negated some mips syscall error returns
due to what was essentially a copy and paste error, the changes made
in commit f61be1f875 caused syscalls
with 5 or 6 arguments (and syscalls with 2, 3, or 4 arguments when
compiled with clang compatibility) to negate the returned error code a
second time, breaking errno reporting.
2014-07-20 12:38:26 -04:00
Rich Felker f61be1f875 fix mips struct stat dev_t members for big endian
the mips version of this structure on the kernel side wrongly has
32-bit type rather than 64-bit type. fortunately there is adjacent
padding to bring it up to 64 bits, and on little-endian, this allows
us to treat the adjacent kernel st_dev and st_pad0[0] as as single
64-bit dev_t. however, on big endian, such treatment results in the
upper and lower 32-bit parts of the dev_t value being swapped. for the
purpose of just comparing st_dev values this did not break anything,
but it precluded actually processing the device numbers as major/minor
values.

since the broken kernel behavior that needs to be worked around is
isolated to one arch, I put the workarounds in syscall_arch.h rather
than adding a stat fixup path in the common code. on little endian
mips, the added code optimizes out completely.

the changes necessary were incompatible with the way the __asm_syscall
macro was factored so I just removed it and flattened the individual
__syscallN functions. this arguably makes the code easier to read and
understand, anyway.
2014-07-19 23:37:21 -04:00
Szabolcs Nagy 8258014fd1 fix for broken kernel side RLIM_INFINITY on mips
On 32 bit mips the kernel uses -1UL/2 to mark RLIM_INFINITY (and
this is the definition in the userspace api), but since it is in
the middle of the valid range of limits and limits are often
compared with relational operators, various kernel side logic is
broken if larger than -1UL/2 limits are used. So we truncate the
limits to -1UL/2 in get/setrlimit and prlimit.

Even if the kernel side logic consistently treated -1UL/2 as greater
than any other limit value, there wouldn't be any clean workaround
that allowed using large limits:
* using -1UL/2 as RLIM_INFINITY in userspace would mean different
infinity value for get/setrlimt and prlimit (where infinity is always
-1ULL) and userspace logic could break easily (just like the kernel
is broken now) and more special case code would be needed for mips.
* translating -1UL/2 kernel side value to -1ULL in userspace would
mean that -1UL/2 limit cannot be set (eg. -1UL/2+1 had to be passed
to the kernel instead).
2014-05-30 03:09:26 -04:00
rofl0r dbed392410 fixup general __syscall breakage introduced in x32 port
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.
2014-02-24 17:06:06 -05:00
Rich Felker ccc7b4c3a1 remove __SYSCALL_SSLEN arch macro in favor of using public _NSIG
the issue at hand is that many syscalls require as an argument the
kernel-ABI size of sigset_t, intended to allow the kernel to switch to
a larger sigset_t in the future. previously, each arch was defining
this size in syscall_arch.h, which was redundant with the definition
of _NSIG in bits/signal.h. as it's used in some not-quite-portable
application code as well, _NSIG is much more likely to be recognized
and understood immediately by someone reading the code, and it's also
shorter and less cluttered.

note that _NSIG is actually 65/129, not 64/128, but the division takes
care of throwing away the off-by-one part.
2013-03-26 23:07:31 -04:00
Rich Felker 4221f154ff fix buggy constraints in mips inline syscall asm
if same register is used for input/output, the compiler must be told.
otherwise is generates random junk code that clobbers the result. in
pure syscall-wrapper functions, nothing went wrong, but in more
complex functions where register allocation is non-trivial, things
broke badly.
2012-09-15 02:22:10 -04:00
Rich Felker cfc09b1ecf improve mips syscall asm constraints to use immediates, if possible
by using the "ir" constraint (immediate or register) and the carefully
constructed instruction addu $2,$0,%2 which can take either an
immediate or a register for %2, the new inline asm admits maximal
optimization with no register spillage to the stack when the compiler
successfully performs constant propagration, but still works by
allocating a register when the syscall number cannot be recognized as
a constant. in the case of syscalls with 0-3 arguments it barely
matters, but for 4-argument syscalls, using an immediate for the
syscall number avoids creating a stack frame for the syscall wrapper
function.
2012-09-11 02:23:47 -04:00
Rich Felker b94067eeae eliminate assumption that mips syscall restart preserves r25
all past and current kernel versions have done so, but there seems to
be no reason it's necessary and the sentiment from everyone I've asked
has been that we should not rely on it. instead, use r7 (an argument
register) which will necessarily be preserved upon syscall restart.
however this only works for 0-3 argument syscalls, and we have to
resort to the function call for 4-argument syscalls.
2012-09-10 22:43:22 -04:00
Rich Felker 328810d325 inline syscall support for mips
this drastically reduces the size of some functions which are purely
syscall wrappers.

disabled for clang due to known bugs satisfying register constraints.
2012-09-09 01:01:19 -04:00
Rich Felker 208eb584ef syscall organization overhaul
now public syscall.h only exposes __NR_* and SYS_* constants and the
variadic syscall function. no macros or inline functions, no
__syscall_ret or other internal details, no 16-/32-bit legacy syscall
renaming, etc. this logic has all been moved to src/internal/syscall.h
with the arch-specific parts in arch/$(ARCH)/syscall_arch.h, and the
amount of arch-specific stuff has been reduced to a minimum.

changes still need to be reviewed/double-checked. minimal testing on
i386 and mips has already been performed.
2012-09-08 22:43:14 -04:00