-
Notifications
You must be signed in to change notification settings - Fork 1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Switch to 64 bit file and time APIs on GNU libc for 32bit systems #3175
base: main
Are you sure you want to change the base?
Conversation
Thanks for the pull request, and welcome! The Rust team is excited to review your changes, and you should hear from @JohnTitor (or someone else) soon. Please see the contribution instructions for more information. Namely, in order to ensure the minimum review times lag, PR authors and assigned reviewers should ensure that the review label (
|
Oops, left some debug/test commits in there. Removed now. |
Hi @JohnTitor , do you have any feedback on this change?
I'm not a Rust developer and not sure how I can create that type alias. |
☔ The latest upstream changes (presumably #3218) made this pull request unmergeable. Please resolve the merge conflicts. |
5dfc8ed
to
7d2c859
Compare
Thanks for the PR! But I think this is a huge breaking change and we have to discuss it before reviewing the changes (or, even submitting a PR). Could you open an issue instead? |
Sure, I'll do that. |
I'm working on updating this PR to handle problem 2 mentioned above and to pass tests on more platforms. Expect an update later this week. |
5314484
to
eb997cb
Compare
Sorry for the many pushes, that was meant only for my fork. Anyway, now the PR should handle the duplicate functions mentioned in problem 2, and also pass tests on more platforms. |
☔ The latest upstream changes (presumably #3237) made this pull request unmergeable. Please resolve the merge conflicts. |
Just rebased on main. Passes all tests in main.yml and bors.yml workflows. I considered adding a cargo feature to control this, but as that would be braking the ABI I guess I shouldn't? |
☔ The latest upstream changes (presumably #3437) made this pull request unmergeable. Please resolve the merge conflicts. |
I've reconstructed the PR to support an environment variable |
#[cfg(gnu_time64_abi)] | ||
__sec: ::c_ulong, | ||
#[cfg(gnu_time64_abi)] | ||
__usec: ::c_ulong, | ||
pub type_: ::__u16, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This breaks the evdev-rs crate with no obvious non-hacky way of fixing it (evdev-rs has other errors too, but they are errors I can deal with)
692s error[E0560]: struct input_event
has no field named time
692s --> src/lib.rs:265:13
692s |
692s 265 | time: self.time.as_raw(),
692s | ^^^^ input_event
does not have this field
692s |
692s = note: available fields are: __sec
, __usec
The original C header deals with this using macros, which are defined differently for the non-time64 and time64 cases.
(non-time64)
#define input_event_sec time.tv_sec
#define input_event_usec time.tv_usec
(time64)
#define input_event_sec __sec
#define input_event_usec __usec
Not sure how this can be best dealt with in rust, the best I can think of would be to add get/set/get_mut methods.
I also suspect this structure definition is wrong on 32-bit linux systems with 64-bit time using C libraries other than glibc but that isn't directly related to this PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for testing.
Does this definition of struct input_event
work for evdev-rs - it will require code changes.
pub struct input_event {
#[cfg(any(target_pointer_width = "64", not(gnu_time64_abi)))]
pub input_event_sec: ::time_t,
#[cfg(all(target_pointer_width = "32", gnu_time64_abi))]
pub input_event_sec: ::c_ulong,
#[cfg(any(target_pointer_width = "64", not(gnu_time64_abi)))]
pub input_event_usec: ::suseconds_t,
#[cfg(all(target_pointer_width = "32", gnu_time64_abi))]
pub input_event_usec: ::c_ulong,
#[cfg(target_arch = "sparc64")]
_pad1: ::c_int,
pub type_: ::__u16,
pub code: ::__u16,
pub value: ::__s32,
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Structurally this looks like a sensible compromise and one to which downstream code could be adapted fairly easily.
I still think the definition is probablly wrong on 32-bit linux systems with 64-bit time and C libraries other than glibc. Since afaict this is a kernel data structure I would not expect the field sizes to change with which C library is in use.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're probably right, I'll have to think about this some more.
But I'll update with this struct definition for now.
After patching the filetime crate to build against the patched libc crate, i'm seeing a test failure. I guess there is some sort of problem with the file time APIs. git clone https://github.com/plugwash/filetime
|
@plugwash , you need to use the Also, you might want to change to the |
The gnu_time64_abi option indicates that a 32-bit arch should use 64-bit time_t and 64-bit off_t and simliar file related types. 32-bit platforms are identified by CARGO_CFG_TARGET_POINTER_WIDTH, but x86_64-unknown-linux-gnux32 is a 64-bit platform and should not use gnu_time64_abi even if it has 32-bit pointers. riscv32 is a 32-bit platform but has always used 64-bit types for time and file operations. It should not use the gnu_time64_abi The default - all relevant platforms should use 64-bit time - can be overridden by setting the RUST_LIBC_TIME_BITS environment variable to 32. It can also be set to 64 to force gnu_time64_abi, or default which is the same as leaving it unset. The last two options are mainly useful for CI flows.
Set _TIME_BITS=64 and _FILE_OFFSET_BITS=64 preprocessor symbols for the C test code as for building the code.
Set the basic types correctly for gnu_time64_abi (_TIME_BITS=64 and _FILE_OFFSET_BITS=64).
Set the link names of relevant symbols to use be the same as when a C program is built against GNU libc with -D_TIME_BITS=64 and -D_FILE_OFFSET_BITS=64.
The actual values may be different on 32bit archs and glibc with 64-bit time.
Also add the F_[SG]ET*64 constants.
For 64 bit time on 32 bit linux glibc timeval.tv_usec is actually __suseconds64_t (64 bits) while suseconds_t is still 32 bits.
Big-endian platforms wants 32 bits of padding before tv_nsec, little-endian after. GNU libc always uses long for tv_nsec.
299e6da
to
473fcae
Compare
Do not use gnu/b32/time*.rs for riscv32 and sparc. Add timex to gnu/b32/(riscv32|sparc)/mod.rs instead.
Move the stat struct from gnu/b32/mod.rs to gnu/b32/time*.rs For arm, mips, powerpc, riscv32, and x86, move stat64 to time32.rs and add an stat64 = stat alias to time64.rs. For sparc, do the same for statfs64 and statvfs64.
In Linux Tier1, run the tests for i686-unknown-linux-gnu with RUST_LIBC_TIME_BITS set to 32, 64, and default. In Linux Tier2, run the tests for arm-unknown-linux-gnueabihf and powerpc-unknown-linux-gnu with RUST_LIBC_TIME_BITS set to 32, 64, and default. Use RUST_LIBC_TIME_BITS=defaults for the other platforms. In Build Channels Linux, build the relevant platforms with RUST_LIBC_TIME_BITS unset and set to 32 and 64.
This is great!
I don't see what we can do about this.
I have no idea why glibc did not choose to redefine
Not going via
https://salsa.debian.org/rust-team/debcargo-conf/-/blob/master/src/libpulse-binding/debian/patches/avoid-suseconds_t.patch#L34
https://salsa.debian.org/rust-team/debcargo-conf/-/blob/master/src/nix/debian/patches/time_t_workarounds.diff#L66
I've pushed the new input_event struct that looks like (except for conditionals and stuff) pub struct input_event {
pub input_event_sec: ::time_t,
pub input_event_sec: ::c_ulong,
}; I think it is correct for all archs, I cannot figure out any where it shouldn't be.
Just use the
|
@plugwash, I reread your comment about this, and I now I can figure out where it wouldn't work. :) |
Use the 64 bit types and APIs included in GNU libc also for 32-bit systems. These are the types and APIs used when you compile your C code against GNU libc headers with the preprocessor options -D_FILE_OFFSET_BITS=64 -D_TIME_BITS=64.
This is required for 2038 compatible software built for 32-bit systems.
This PR is not done, I need some guidance with finishing it.
struct stat
andstruct stat64
be different names for the same struct. I don't know how to do that.I've done one commit for each modified type so it is easier to review the changes in isolation.