Commit Graph

9 Commits

Author SHA1 Message Date
Rich Felker f56d57f8a7 move IPC_64 from public bits/ipc.h to syscall_arch.h
the definition of the IPC_64 macro controls the interface between libc
and the kernel through syscalls; it's not a public API. the meaning is
rather obscure. long ago, Linux's sysvipc *id_ds structures used
16-bit uids/gids and wrong types for a few other fields. this was in
the libc5 era, before glibc. the IPC_64 flag (64 is a misnomer; it's
more like 32) tells the kernel to use the modern[-ish] versions of the
structures.

the definition of IPC_64 has nothing to do with whether the arch is
32- or 64-bit. rather, due to either historical accident or
intentional obnoxiousness, the kernel only accepts and masks off the
0x100 IPC_64 flag conditional on CONFIG_ARCH_WANT_IPC_PARSE_VERSION,
i.e. for archs that want to provide, or that accidentally provided,
both. for archs which don't define this option, no masking is
performed and commands with the 0x100 bit set will fail as invalid. so
ultimately, the definition is just a matter of matching an arbitrary
switch defined per-arch in the kernel.
2019-07-30 14:23:56 -04:00
Rich Felker 4c307bed03 remove x32 syscall timespec fixup hacks
the x32 syscall interfaces treat timespec's tv_nsec member as 64-bit
despite the API type being long and long being 32-bit in the ABI. this
is no problem for syscalls that store timespecs to userspace as
results, but caused uninitialized padding to be misinterpreted as the
high bits in syscalls that take timespecs as input.

since the beginning of the port, we've dealt with this situation with
hacks in syscall_arch.h, and injected between __syscall_cp_c and
__syscall_cp_asm, to special-case the syscall numbers that involve
timespecs as inputs and copy them to a form suitable to pass to the
kernel.

commit 40aa18d55a set the stage for
removal of these hacks by letting us treat the "normal" x32 syscalls
dealing with timespec as if they're x32's "time64" syscalls,
effectively making x32 ax "time64-only 32-bit arch" like riscv32 will
be when it's added. since then, all users of syscalls that x32's
syscall_arch.h had hacks for have been updated to use time64 syscalls,
so the hacks can be removed.

there are still at least a few other timespec-related syscalls broken
on x32, which were overlooked when the x32 hacks were done or added
later. these include at least recvmmsg, adjtimex/clock_adjtime, and
timerfd_settime, and they will be fixed independently later on.
2019-07-29 00:19:21 -04:00
Rich Felker 40aa18d55a internally, define time64 syscalls on x32 as the existing syscalls
x32 is odd in that it's the only ILP32 arch/ABI we have where time_t
is 64-bit rather than (32-bit) long, and this has always been
problematic in that it results in struct timespec having unused
padding space, since tv_nsec has type long, which the kernel insists
be zero- or sign-extended (due to negative tv_nsec being invalid, it
doesn't matter which) to match the x86_64 type.

up til now, we've had really ugly hacks in x32/syscall_arch.h to patch
up the timespecs passed to the kernel. but the same requirement to
zero- or sign-extend tv_nsec also applies to all the new time64
syscalls on true 32-bit archs. so let's take advantage of this to
clean things up.

this patch defines all of the time64 syscalls for x32 as aliases for
the existing syscalls by the same name. this establishes the following
invariants:

- if the time64 form is defined, it takes time arguments as 64-bit
  objects, and tv_nsec inputs must be zero-/sign-extended to 64-bit.

- if the time64 form is not defined, or if the time64 form is defined
  and is not equal to the "plain" form, the plain form takes time
  arguments as longs.

this will avoid the need for protocols for archs to define appropriate
types for each family of syscalls, and for the reader of the code to
have to be aware of such type definitions.

in some sense it might be simpler if the plain syscall form were
undefined for x32, so that it would always take longs if defined.
however, a number of these syscalls are used in contexts with a null
time argument, or (e.g. futex) for commands that don't involve time at
all, and having to introduce time64-specific logic to all those call
points does not make sense. thus, while the "plain" forms are kept now
just because they're needed until the affected code is converted over,
they'll also almost surely be kept in the future as well.
2019-07-27 13:43:13 -04:00
Rich Felker b93183e399 don't use futimesat syscall as utimensat fallback on x32
kernel support for x32 was added long after the utimensat syscall was
already available, so having a fallback is just wasted code size.

also, for changes related to time64 support on 32-bit archs, I want to
be able to assume the old futimesat syscall always works with longs,
which is true except for x32. by ensuring that it's not used on x32,
the needed invariant is established.
2019-07-27 13:43:13 -04:00
Rich Felker 4f69594689 fix dangling pointers in x32 syscall timespec fixup code
the lifetime of compound literals is the block in which they appear.
the temporary struct __timespec_kernel objects created as compound
literals no longer existed at the time their addresses were passed to
the kernel.
2015-05-01 21:22:27 -04:00
rofl0r d05aaedaab fix x32 syscall arch.h timespec fixup code
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.
2014-02-23 20:49:58 +01:00
Rich Felker d8b587796f mostly-cosmetic fixups to x32 port merge 2014-02-23 05:43:09 -05:00
rofl0r 664cd34192 x32 port (diff against vanilla x86_64) 2014-02-23 11:09:16 +01:00
rofl0r 323272db17 import vanilla x86_64 code as x32 2014-02-23 11:07:18 +01:00