Skip to content

newlib: fix definition of time_t and off_t#5132

Open
dybucc wants to merge 6 commits into
rust-lang:mainfrom
dybucc:newlib-fix-time_t
Open

newlib: fix definition of time_t and off_t#5132
dybucc wants to merge 6 commits into
rust-lang:mainfrom
dybucc:newlib-fix-time_t

Conversation

@dybucc

@dybucc dybucc commented Jun 1, 2026

Copy link
Copy Markdown
Contributor

Description

This PR addresses bit width mismatches for both time_t and file offset types. This applies to the linux/newlib module.

Upstream and forks for each supported target provide conditional definitions. time_t can be configured in the newlib build script. File offset types require manual intervention in a specific header file. The file containing the default definition will check for a macro that is defined in that specific "override" file. The default definition is a C long.

A number of supported targets were using either one of the above overrides. This was not being taken into account in the libc crate. This patch fixes that by further expanding conditionally compiled type definitions.

Sources

Checklist

  • Relevant tests in libc-test/semver have been updated
  • No placeholder or unstable values like *LAST or *MAX are included (see #3131)
  • Tested locally (cd libc-test && cargo test --target mytarget); especially relevant for platforms that may not be checked in CI

@dybucc

dybucc commented Jun 2, 2026

Copy link
Copy Markdown
Contributor Author

CI seems to be failing for reasons unrelated to the changes introduced in the patch. A rerun should
do it.

@dybucc dybucc changed the title refactor: fix definition of time_t in Newlib refactor: fix definition of time_t and off_t in Newlib Jun 3, 2026
@dybucc
dybucc force-pushed the newlib-fix-time_t branch 4 times, most recently from 7152f77 to e821035 Compare June 7, 2026 16:34
@dybucc
dybucc marked this pull request as ready for review June 7, 2026 16:35
@dybucc
dybucc force-pushed the newlib-fix-time_t branch from e821035 to de697e2 Compare June 9, 2026 07:11
@rustbot

This comment has been minimized.

@dybucc

dybucc commented Jun 9, 2026

Copy link
Copy Markdown
Contributor Author

CI actually passes. There seems to be an issue with a glob import that is not used, but this has not
been changed in the patch (it's not even part of it, for that matter.) For some reason, rebasing
onto main with dependabot updates has ended up with a warning across all of my open PRs due to
that one (now apparently unused) import.

@dybucc
dybucc force-pushed the newlib-fix-time_t branch from de697e2 to 0e027c7 Compare June 15, 2026 15:11
@rustbot

This comment has been minimized.

@dybucc
dybucc force-pushed the newlib-fix-time_t branch from 0e027c7 to 6abed2e Compare June 18, 2026 16:20
@rustbot

This comment has been minimized.

@tgross35

Copy link
Copy Markdown
Contributor

I couldn't remember what the possible env+os combinations were for these platforms, here's a quick list.

> $cfg | find 'target_env="newlib"' | get tgt | each {|tgt| $cfg | find $tgt -n | find -nr '(target_env|target_os)' } | flatten
  #               tgt                        cfg
─────────────────────────────────────────────────────────
  0   armv6k-nintendo-3ds            target_env="newlib"
  1   armv6k-nintendo-3ds            target_os="horizon"
  2   armv7-rtems-eabihf             target_env="newlib"
  3   armv7-rtems-eabihf             target_os="rtems"
  4   armv7-sony-vita-newlibeabihf   target_env="newlib"
  5   armv7-sony-vita-newlibeabihf   target_os="vita"
  6   riscv32imac-esp-espidf         target_env="newlib"
  7   riscv32imac-esp-espidf         target_os="espidf"
  8   riscv32imafc-esp-espidf        target_env="newlib"
  9   riscv32imafc-esp-espidf        target_os="espidf"
 10   riscv32imc-esp-espidf          target_env="newlib"
 11   riscv32imc-esp-espidf          target_os="espidf"
 12   xtensa-esp32-espidf            target_env="newlib"
 13   xtensa-esp32-espidf            target_os="espidf"
 14   xtensa-esp32s2-espidf          target_env="newlib"
 15   xtensa-esp32s2-espidf          target_os="espidf"
 16   xtensa-esp32s3-espidf          target_env="newlib"
 17   xtensa-esp32s3-espidf          target_os="espidf"

@tgross35 tgross35 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm having some difficulty extracting a simplified goal from the top post. Is this the net delta on targets we currently support?

  • On armv7-rtems, time_t changes from i32 to i64
  • On armv7-rtems, off_t changes from i64 to c_long, which should be i64->i32
  • On armv7-vita, off_t changes from c_int to c_long. I think there is no change here?

If this sounds accurate, ping the target maintainer (see https://doc.rust-lang.org/rustc/platform-support/armv7-rtems-eabihf.html) for confirmation. This is generally a good idea when tricky things like this change on less popular targets, there may be config or other nuance that doesn't show up in the source code.

Also please don't call this a refactor, that term usually means cleaning up code without changing behavior - if the user experience changes somehow then it's kind of misleading. (Applies to some of your other PRs as well).

Note this option is "documented" as being meant for end users of the libc crate to enable, but no information on it is provided anywhere in all of the libc crate.

It's mostly intended to be set by espidf build tooling, but it would be good to at least mention it. A PR would be welcome in the crate-level docs, after #5179 adds some structure.

It would also be great to know whether the libc crate considers horizon to be the OS for both the Nintendo Switch and the Nintendo 3DS targets, or only for the Nintendo 3DS target.

aarch64-nintendo-switch-freestanding does not appear to set a target_env, so I would assume the latter.

View changes since this review

@tgross35

Copy link
Copy Markdown
Contributor

@rustbot author for clarification

@rustbot

rustbot commented Jun 19, 2026

Copy link
Copy Markdown
Collaborator

Reminder, once the PR becomes ready for a review, use @rustbot ready.

@dybucc dybucc changed the title refactor: fix definition of time_t and off_t in Newlib newlib: fix definition of time_t and off_t Jun 19, 2026
@dybucc

dybucc commented Jun 19, 2026

Copy link
Copy Markdown
Contributor Author

The changes here are required to fit the definitions upstream of time_t, which was generally mismatched.

The changes for file offset types are concerned with either

  1. having a mirrored definition, rather an an equivalent one, and
  2. with the same bit width mismatches as with time_t.

I'll open a PR soon with the documentation for ESP-IDF.

@rustbot ready

@dybucc
dybucc force-pushed the newlib-fix-time_t branch from 6abed2e to c2b0970 Compare June 19, 2026 10:56
@rustbot

This comment has been minimized.

@dybucc

dybucc commented Jun 19, 2026

Copy link
Copy Markdown
Contributor Author

Hey @thesummer!

I was wondering if I could get confirmation on these changes on the RTEMS target you maintain?

@dybucc

dybucc commented Jun 19, 2026

Copy link
Copy Markdown
Contributor Author

Hey @nikarh @pheki @zetanumbers!

I was wondering if I could get confirmation on these changes on the Sony PS Vita target you maintain?

@pheki pheki left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for asking!

Just need a change as the Vita uses 32-bit time_t.

Keeping it on the top-level comment for easy reference, here are the sources I could find (somewhat redundant with the finds in the root PR comment but in vitasdk's fork):

off_t

time_t

View changes since this review

Comment thread src/unix/newlib/mod.rs Outdated
Comment on lines +9 to +14
if #[cfg(any(
target_os = "espidf",
target_os = "vita",
target_os = "rtems",
target_arch = "aarch64"
))] {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For vita, this one seems correct, as by looking at the definitions it seems to be defined as a long. There should also be no change in behavior as both c_int and c_long are aliases to i32 in this platform.

Sources in the top level review comment.

Comment thread src/unix/newlib/mod.rs
Comment on lines +60 to +61
} else {
pub type time_t = i64;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This one looks wrong for the vita, which uses 32-bit time, as --enable-newlib-long-time_t is set when building newlib in vitasdk (currently the only supported SDK).

The correct definition would be c_long (effectively i32).

Sources in the top-level comment.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks. That's fixed now.

@dybucc

dybucc commented Jul 7, 2026

Copy link
Copy Markdown
Contributor Author

that's it. before i removed the powerpc bindings, that one would have also been affected by the time_t change. but from grepping through the target_env cfg of all supported rust powerpc targets, none seem to use newlib.

in terms of changes affecting something other than the bit width of some types, both the aarch64 bindings and the powerpc bindings were removed.

@rusbot ready

@dybucc
dybucc force-pushed the newlib-fix-time_t branch from af1919a to 4c2721c Compare July 7, 2026 17:28

@tgross35 tgross35 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Couple more things. Could you also split the table from #5132 (comment) into two and paste it into the "newlib: change definition of time_t" and "newlib: change definition of file offset types"? That's easier to understand than something text-y.

View changes since this review

Comment thread src/unix/newlib/mod.rs
Comment on lines 941 to 958
if #[cfg(target_os = "espidf")] {
mod espidf;
pub use self::espidf::*;
} else if #[cfg(target_os = "horizon")] {
mod horizon;
pub use self::horizon::*;
} else if #[cfg(target_os = "vita")] {
mod vita;
pub use self::vita::*;
} else if #[cfg(target_arch = "arm")] {
mod arm;
pub use self::arm::*;
} else if #[cfg(target_arch = "powerpc")] {
mod powerpc;
pub use self::powerpc::*;
} else {
// Only tested on ARM so far. Other platforms might have different
// definitions for types and constants.
pub use target_arch_not_implemented;
}
}

cfg_if! {
if #[cfg(target_os = "rtems")] {
} else if #[cfg(target_os = "rtems")] {
mod rtems;
pub use self::rtems::*;
} else {
core::compile_error!("unsupported target");
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"newlib: remove powerpc bindings": After this patch, when is the rtems arm ever being hit?

Previously rtems was created and imported only if target_os = "rtems", which makes sense. Now it needs to not hit target_arch = "arm" - but our only rtems platform is arm?

The pattern is preexisting but mixing arch and OS in the same cfg_if is kind of weird.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed. Back when I finished the patch, I thought RTEMS targets wouldn't even
build because they'd fall back to the branch where the dummy
target_arch_not_implemented module is. I failed to realize it goes into the
arm branch beforehand, and so I transitevely failed to realize adding RTEMS to
that cfg_if invocation would skip over the target OS' module.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can't remember whether I told you already or not, but I've added a script ./etc/libc-util.py check-all-targets libc that will make sure all targets build. It takes a little while and like 60GB in ~/cache (to avoid toolchain pinning), though you can restrict with --only/--skip.

Anyway I run that with some frequency and as far as I'm aware, the only nonbuilding targets are listed at

libc/etc/libc-util.py

Lines 343 to 361 in 5db5914

BROKEN_TARGETS = [
# libc problems
("aarch64-unknown-nto-qnx800", "libc error, unsupported arch"),
("aarch64.*-gnu_ilp32.*time_bits=64", "libc error, time64 mismatches"),
("armv6k-nintendo-3ds", "libc error, stat missing"),
("armv7-sony-vita-newlibeabihf", "libc error, stat missing"),
("csky.*gnu.*time_bits=64", "libc error, time64 mismatches"),
("i686-pc-nto-qnx700", "libc error, unsupported arch"),
("managarm-mlibc", "libc error, unresolved import"),
("x86_64-lynx-lynxos178", "libc error, unresolved import"),
("x86_64-pc-nto-qnx800", "libc error, unsupported arch"),
("x86_64-unknown-linux-none", "libc error, unresolved import"),
# rustc problems
("xtensa-esp32.*", "target string mismatch in rustc"),
("amdgcn-amd-amdhsa", "unsupported instructions with some CPUs"),
# llvm problems
("m68k-unknown-.*", "llvm crash building core"),
("mipsisa32r6(el)?-.*", "llvm crash building core"),
]
.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Noted. I noticed there were new utilities while rebasing PRs, but I hadn't taken
a look at the scripts. Thanks.

@physwkim

This comment was marked as low quality.

@tgross35

Copy link
Copy Markdown
Contributor

@physwkim did you see my comment at #5132 (comment) about the fallthrough?

If you have a reason to believe this PR is incorrect, please leave a succinct handwritten review comment. Do not post AI-generated blobs to communicate to humans.

@physwkim

Copy link
Copy Markdown

@physwkim did you see my comment at #5132 (comment) about the fallthrough?

If you have a reason to believe this PR is incorrect, please leave a succinct handwritten review comment. Do not post AI-generated blobs to communicate to humans.

Sorry, I missed your earlier comment about the fallthrough - yes, same issue.

@rustbot

This comment has been minimized.

@dybucc

dybucc commented Jul 22, 2026

Copy link
Copy Markdown
Contributor Author

Couple more things. Could you also split the table from #5132 (comment) into two and paste it into the "newlib: change definition of time_t" and "newlib: change definition of file offset types"? That's easier to understand than something text-y.

Done.

@rustbot ready

@rustbot

This comment has been minimized.

dybucc added 6 commits July 25, 2026 08:41
Replace `time_t` definition in `newlib` for certain targets. This option
is configurable in upstream newlib [^1] and some targets seem to have it
enabled in their build scripts. Effective changes include the following.

OS                                 | old         | new    | effective change
-----------------------------------|-------------|--------|---------------------------
risc32/xtensa32-espidf time32      | `i32`       | `long` | alias only, no size change
risc32/xtensa32-espidf not(time32) | `long long` | `i64`  | alias only, no size change
arm32-horizon                      | `long long` | `i64`  | alias only, no size change
arm32-rtems                        | `i32`       | `i64`  | ABI change, 32->64 bits
arm32-vita                         | `i32`       | `long` | alias only, no size change

[^1]:
https://github.com/cygwin/cygwin/blob/41e6325ad64fa00f5e61e25c2020a8bc716c29a0/newlib/README#L351
Use mirrored definition of file offset types in `vita` target. Effective
changes include the following.

OS                     | ty      | old              | new              | effective change
-----------------------|---------|------------------|------------------|---------------------------
risc32/xtensa32-espidf | `dev_t` | `short`          | `short`          | none
arm32-horizon          | `dev_t` | `u32`            | `u32`            | none
arm32-rtems            | `dev_t` | `u32`            | `u32`            | none
arm32-vita             | `dev_t` | `short`          | `short`          | none
-----------------------|---------|------------------|------------------|---------------------------
risc32/xtensa32-espidf | `ino_t` | `unsigned short` | `unsigned short` | none
arm32-horizon          | `ino_t` | `i64`            | `i64`            | none
arm32-rtems            | `ino_t` | `i64`            | `i64`            | none
arm32-vita             | `ino_t` | `unsigned short` | `unsigned short` | none
-----------------------|---------|------------------|------------------|---------------------------
risc32/xtensa32-espidf | `off_t` | `long`           | `long`           | none
arm32-horizon          | `off_t` | `i64`            | `i64`            | none
arm32-rtems            | `off_t` | `i64`            | `i64`            | none
arm32-vita             | `off_t` | `int`            | `long`           | alias only, no size change
Remove AArch64 bindigns in newlib. Rust has no officially supported
target using newlib in AArch64.
Force a compile error on targets with no file offset type definitions.
This ensures any new target needs providing defintions for these types.
Move the `generic` module into the top-level `newlib` module. They were
already reexported by all supported targets in their respective modules.
These types were also conditionally defined anyway.
Remove PowerPC definitions. There's no Rust target using newlib on
PowerPC.
@dybucc
dybucc force-pushed the newlib-fix-time_t branch from 84c4a56 to 8b8665b Compare July 25, 2026 06:42
@rustbot

rustbot commented Jul 25, 2026

Copy link
Copy Markdown
Collaborator

This PR was rebased onto a different main commit. Here's a range-diff highlighting what actually changed.

Rebasing is a normal part of keeping PRs up to date, so no action is needed—this note is just to help reviewers.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants