|
Message-ID: <20140121021838.GI24286@brightrain.aerifal.cx> Date: Mon, 20 Jan 2014 21:18:38 -0500 From: Rich Felker <dalias@...ifal.cx> To: musl@...ts.openwall.com Subject: Re: Discussion of partly-invasive changes needed for x32 port On Tue, Jan 21, 2014 at 02:47:24AM +0100, John Spencer wrote: > Rich Felker wrote: > >1. System calls take 64-bit arguments, whereas the existing syscall > >framework in musl (and on the kernel side for all other archs/abis) > >uses long arguments. > > > >The current internal syscall macros cast all arguments to long; this > >allows accepting either pointers or integer types smaller than long > >without the caller having to make any casts. However this does not > >work for x32, where some syscalls actually need 64-bit arguments (e.g. > >lseek). The following macro, which replaces the long cast on x32, > >solves the problem: > > > >#define __scc(X) sizeof(1?(X):0ULL) < 8 ? (unsigned long) (X) : (long long) (X) > > when i understood your last mail correctly, it's ok to go forward with a > GNUC enhanced version of this macro that can deal with timespec ? > that would solve 1 + 2. I think so. Keep in mind the timespec one needs to apply only to const timespec pointers (non-const ones are results where the kernel needs to write the result into the caller's structure). I think we should also use Jens' idea to avoid multiple-evaluation of the argument. And the result should be cast to unsigned long, so that the final result of the __scc macro always has integer type. > > to cancel_impl.c. I'm not opposed to this, but if we go this way, the > > type name should be self-documenting (e.g. klong, klong_t, > > syscall_long_t, or something similar) rather than the current proposal > > (__sca) that's non-obvious unless you go digging for it. Alernatively, > > src/internal/syscall.h could pull in register_t from alltypes.h > > (having internal headers use alltypes.h directly is not something we > > do yet, but it could be done) and we could simply always use > > register_t for these arguments. > > afaik mips n32 uses long arguments for syscalls, so using register_t > would not work there. There's no reason __syscall_cp has to use the same calling convention as the kernel, as long as the argument type is sufficiently wide to convey all possible arguments. So register_t would work even when it's 64-bit and the kernel uses 32-bit. However I tend to think using the right type is probably cleaner since getting register_t requires at least one hack anyway. > so it seems our choices are either _Klong in alltypes.h or in a > special bits header (bits/k_long.h), so we dont have to include > syscall_arch.h in other bits headers and expose other unrelated > internals (point 3). Well this possibility is unrelated to items 1/2, so I think you're getting ahead of yourself. In any case, bits/k_long.h would not be the right place (bits/* are _never_ included directly and don't have multiple-include guards; they're included only from the associated public header they go with). > >3. A number of other structures in the public headers differ from > >their userspace C type layout on other archs because they're setup to > >match the 64-bit kernel structs. This requires either changing some > >member types to match the 64-bit kernel ones (this is usually a bad > >idea, and sometimes even non-conforming like with tv_nsec) or adding > >adjacent padding members for the unused "high" part of the 64-bit > >value. In many cases, this requires either moving structures from the > >shared headers to bits/*, or coming up with clever ways to avoid doing > >so. > > i've seen this in linux/sysinfo.h today: > __kernel_ulong_t totalhigh; /* Total high memory size */ > __kernel_ulong_t freehigh; /* Available high memory size */ > __u32 mem_unit; /* Memory unit size in bytes */ > char _f[20-2*sizeof(__kernel_ulong_t)-sizeof(__u32)]; /* > Padding: libc5 uses this.. */ > > so the padding evaluates to either char _f[0] where __kernel_ulong_t > is 64bit, or _f[8] for 32bit. > > seems like a workable solution, which doesn't even require bitfield hacks. > but we need again the kernel_long to work with... > it seems there's no way around it. This is a rather ugly legacy interface that's really the least of our concerns. And the x32 modification of it breaks the documented API (where the members are longs); for example, correct programs may be passing them to printf with %lu... As usual, the kernel/glibc folks did not think before they did this stuff... Rich
Powered by blists - more mailing lists
Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.