Skip to content

linux(uclibc): add cfg option for file offset bindings on 32-bit targets#5165

Open
dybucc wants to merge 5 commits into
rust-lang:mainfrom
dybucc:uclibc-file-offset-transition
Open

linux(uclibc): add cfg option for file offset bindings on 32-bit targets#5165
dybucc wants to merge 5 commits into
rust-lang:mainfrom
dybucc:uclibc-file-offset-transition

Conversation

@dybucc

@dybucc dybucc commented Jun 13, 2026

Copy link
Copy Markdown
Contributor

Description

This PR adds a new cfg for file offset types in uClibc to ensure target triples with a 32-bit machine word size can also have 64-bit unsuffixed file offset types. None of these changes affect 64-bit platforms.

The LFS64 types continue being exposed by default in all platforms, but when the cfg option is issued, they will have equivalent definitions to the unsuffixed types.

There were also some records that were altogether removed because they collided with structures from top-level modules such as unix/linux_like/linux_l4re_shared.

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

@rustbot label +stable-nominated

@dybucc
dybucc marked this pull request as draft June 13, 2026 09:12
@dybucc
dybucc force-pushed the uclibc-file-offset-transition branch from 8755269 to c883cf6 Compare June 15, 2026 13:58
@tgross35

Copy link
Copy Markdown
Contributor

It would be ideal if this could be gated behind a cfg, similar to what we have on musl and glibc, to give users a chance to test things out prior to 1.0. Same for any other platforms that haven't had this done yet. I'm less concerned about it for tier 3 targets but would have some reservations about merging this or other PRs that only target main until we're closer to 1.0, given how conflict-prone it tends to make any backports.

There's one record I'm particularily doubtful of. In libc we choose to expose ever so slightly different definition for the statvfs structure depending on the target's endianness. This only affects whether a field appears before or after some padding, the latter of which depends on the target's word size. Other modules under the uclibc module do not seem to use this endian-dependent field ordering, so that has been removed as there's neither any indication in the upstream definition of there being need for that. Still, this is very much a change prone to reversion, if I'm, indeed, missing something. Input here is very much welcome.

That very well could have been a copy+paste error, I very much doubt anybody is using these structs on uclibc today to the point that these kind of bugs would show up.

@tgross35

Copy link
Copy Markdown
Contributor

The author of #5046 indicated that uclibc has a preference for keeping the small sizes, so I think this will need to remain configurable even post-1.0.

Cc @skrap for your thoughts here.

@dybucc dybucc changed the title refactor: change file off bindings in linux uclibc linux(uclibc): change file offset bindings Jun 19, 2026
@dybucc
dybucc force-pushed the uclibc-file-offset-transition branch 2 times, most recently from 19237c8 to 0ca05d1 Compare June 20, 2026 08:40
@rustbot rustbot added the A-CI Area: CI-related items label Jun 20, 2026
@dybucc
dybucc force-pushed the uclibc-file-offset-transition branch from bfeb785 to c120d9a Compare June 20, 2026 09:05
@dybucc

dybucc commented Jun 20, 2026

Copy link
Copy Markdown
Contributor Author

Just read through that PR and the comments. I'm not quite sure I understand why that is the case. Hopefully the maintainer can clear things up (not pinging again.)

I've already updated the PR with support for the cfg. The option ensures the unsuffixed types are exposed for targets with a 32-bit machine word size, as otherwise suffixed and unsuffixed types are equivalent.

A bunch of the suffixed type definitions were removed from the uclibc module in favor of the top-level unix, unix/linux_like and unix/linux_like/linux modules. Those already provide the base types for most file offset types. The rest have been left in the linux/uclibc module.

@dybucc

dybucc commented Jun 20, 2026

Copy link
Copy Markdown
Contributor Author

The CI label is wrong. At one point, I changed files concerning CI but I then realized all targets using uClibc are tier 3, and the only included target in verify_build.py uses L4Re and not Linux.

@rustbot

rustbot commented Jun 20, 2026

Copy link
Copy Markdown
Collaborator

Error: Label A-CI can only be set by Rust team members

Please file an issue on GitHub at triagebot if there's a problem with this bot, or reach out on #triagebot on Zulip.

@dybucc dybucc changed the title linux(uclibc): change file offset bindings linux(uclibc): add cfg option for file offset bindings on 32-bit targets Jun 20, 2026
@rustbot rustbot added the stable-nominated This PR should be considered for cherry-pick to libc's stable release branch label Jun 20, 2026
@dybucc
dybucc marked this pull request as ready for review June 20, 2026 14:28
@skrap

skrap commented Jun 20, 2026

Copy link
Copy Markdown
Contributor

Do these changes necessitate a minimum version of uclibc in order to pass the libc tests? I see that the checkbox indicating the libc-test has not been marked complete. Please make sure you do so, because there's often some subtle bugs which the tests catch!

As for the 32- vs 64-bit file lengths, it's my experience that the length of this field varies between uclibc configurations. Is that understanding not up to date?

@rustbot

This comment has been minimized.

@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.

There seem to be some struct fixes and cleanups that aren't related to uclibc_file_offset_bits64 changes. Can anything that is either a correction or a non-functional cleanup be split to a PR? Those don't need to be involved in LFS64 alias discussion, which seems more complicated on uclibc than other targets.

Not positive about what to do with the rest here if it's configurable on uclibc.

View changes since this review

@rustbot

rustbot commented Jun 23, 2026

Copy link
Copy Markdown
Collaborator

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

@dybucc

dybucc commented Jun 23, 2026

Copy link
Copy Markdown
Contributor Author

Do these changes necessitate a minimum version of uclibc in order to pass the libc tests? I see that the checkbox indicating the libc-test has not been marked complete. Please make sure you do so, because there's often some subtle bugs which the tests catch!

As for the 32- vs 64-bit file lengths, it's my experience that the length of this field varies between uclibc configurations. Is that understanding not up to date?

About configurability:

  • It's configurable. There's some things to note. 32-bit targets see a difference. They get 64-bit suffixed types. Their unsuffixed types remain 32-bits. 64-bit targets have no effective difference. Their unsuffixed types are equivalent to their suffixed types.
  • Supporting unsuffixed types is unreasonable. 32-bit targets are the exception.

About versioning:

  • I have not checked all versions. I have checked uclibc-ng. The earliest I checked was v1.0.0. The original uclibc does not have any of these. uclibc-ng has existed since 2017. It's fair to base changes off of uclibc-ng.

@dybucc

dybucc commented Jun 23, 2026

Copy link
Copy Markdown
Contributor Author

There seem to be some struct fixes and cleanups that aren't related to uclibc_file_offset_bits64 changes. Can anything that is either a correction or a non-functional cleanup be split to a PR? Those don't need to be involved in LFS64 alias discussion, which seems more complicated on uclibc than other targets.

Not positive about what to do with the rest here if it's configurable on uclibc.

View changes since this review

32-bit targets are configurable. 64-bit targets also are. The suffixed and unsuffixed types are equivalent in 64-bit targets. There's no reason to support them. 32-bit targets are the exception.

@dybucc
dybucc force-pushed the uclibc-file-offset-transition branch from c120d9a to b174093 Compare June 23, 2026 13:02
@rustbot

This comment has been minimized.

@rustbot

This comment has been minimized.

@dybucc
dybucc force-pushed the uclibc-file-offset-transition branch from b174093 to 39b2b06 Compare June 25, 2026 08:09
@rustbot

This comment has been minimized.

@dybucc
dybucc force-pushed the uclibc-file-offset-transition branch from 39b2b06 to 35062e4 Compare June 25, 2026 08:09
@rustbot

This comment has been minimized.

@dybucc
dybucc force-pushed the uclibc-file-offset-transition branch 4 times, most recently from 724a620 to 4515d23 Compare June 25, 2026 09:40
@dybucc

dybucc commented Jun 25, 2026

Copy link
Copy Markdown
Contributor Author

There seem to be some struct fixes and cleanups that aren't related to uclibc_file_offset_bits64 changes. Can anything that is either a correction or a non-functional cleanup be split to a PR? Those don't need to be involved in LFS64 alias discussion, which seems more complicated on uclibc than other targets.

Not positive about what to do with the rest here if it's configurable on uclibc.

View changes since this review

They can't be separated. They may seem tangential. They're actually necessary. An example is flock. It seems like I reorganized its definition across modules. But it also has some conditionally compiled fields. These use the cfg introduced in this PR.

Though changes have now been separated into separate commits.

@rustbot ready

@rustbot

This comment has been minimized.

@rustbot

This comment has been minimized.

pub const SYS_set_mempolicy_home_node: c_long = 4000 + 450;

#[link(name = "util")]
extern "C" {

@tgross35 tgross35 Jul 9, 2026

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.

"linux(uclibc): remove explicit linking to libutil" seems reasonable to me, especially with #5265

View changes since the review

Comment on lines -232 to -243
pub struct glob_t {
// FIXME(ulibc)
pub gl_pathc: size_t,
pub gl_pathv: *mut *mut c_char,
pub gl_offs: size_t,
pub gl_flags: c_int,
__unused1: Padding<*mut c_void>,
__unused2: Padding<*mut c_void>,
__unused3: Padding<*mut c_void>,
__unused4: Padding<*mut c_void>,
__unused5: Padding<*mut c_void>,
}

@tgross35 tgross35 Jul 9, 2026

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.

"linux(uclibc): remove conflicting records": The message currently says:

Remove records that are already declared in top-level modules. This
affects x86_64 only. There is no such supported Rust target. This change
should virtually affect nobody.

Who does this affect at all? The definitions look identical

View changes since the review

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.

i didn't mean the changes to have an effect on end users. i meant that the changes were only to the x86_64 module. that's why i top it off by saying that it should virtually affect nobody.

Comment thread build.rs Outdated
Comment on lines +211 to +216
if target_env == "uclibc"
&& target_ptr_width == "32"
&& env_flag("CARGO_CFG_LIBC_UNSTABLE_UCLIBC_FILE_OFFSET_BITS")
{
set_cfg("uclibc_file_offset_bits64");
}

@tgross35 tgross35 Jul 9, 2026

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.

"linux(uclibc): add cfg for lfs64 bindings": this should check for a value (32 or 64)

View changes since the review

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.

done.

@tgross35

tgross35 commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

They can't be separated. They may seem tangential. They're actually necessary. An example is flock. It seems like I reorganized its definition across modules. But it also has some conditionally compiled fields. These use the cfg introduced in this PR.

I don't believe this is accurate. The commit messages are "linux(uclibc): fix stat struct family defs" and "linux(uclibc): fix cross-architecture flock def" which implies something was broken prior to this PR, right?

The confusing bit is probably the dependency: those fix commits depend on "linux(uclibc): add cfg for lfs64 bindings" but they shouldn't. Instead, any fix commits should come first and do anything that is necessary to make things correct with the config we have today. Only after the current setup is fixed, "add cfg for lfs64" can introduce the cfg and use it (i.e. update stat et al) in the same patch, meaning that tests should pass on either side of that commit.

I realize that's annoying rebase work, so don't worry about it if the target maintainer is happy with the net changes as-is. Just noting that atomicity makes for history that's easier to understand.

@dybucc
dybucc force-pushed the uclibc-file-offset-transition branch from f433382 to 2310c84 Compare July 9, 2026 16:31
@rustbot

rustbot commented Jul 9, 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.

dybucc added 5 commits July 9, 2026 19:28
Adds a `cfg` to enable LFS64 bindings under 32-bit targets. This does
not apply to 64-bit targets. Their suffixed types are equivalent to
their unsuffixed types. They unconditionally get both suffixed and
unsuffixed types.

This `cfg` replicates a build option upstream.
Removes linking directory to libutil in MIPS32. This did not seem
necessary. Testing is pending.
Remove records that are already declared in top-level modules. This
affects x86_64 only. There is no such supported Rust target. This change
should virtually affect nobody.
Fixes the definitions of:

- `stat`.
- `statfs`.
- `statvfs`.

The analogous 64-bit types wer also tweaked. They are equivalent on some
target architectures. They only needed to be aliased.
Replaces existing definitions. They were not correct under MIPS. This
target needed some special casing.
@dybucc
dybucc force-pushed the uclibc-file-offset-transition branch from 2310c84 to b69830c Compare July 9, 2026 17:28
@dybucc

dybucc commented Jul 10, 2026

Copy link
Copy Markdown
Contributor Author

I don't believe this is accurate. The commit messages are "linux(uclibc): fix stat struct family defs" and "linux(uclibc): fix cross-architecture flock def" which implies something was broken prior to this PR, right?

the thing is that breakage is only made obvious when the corresponding feature test macro (i.e. FILE_OFFSET_BITS=64) is set. if some user has set it in the c standard library implementation they are linking with, but they are getting the fields in rust that would correspond with the macro not being set, things could get awkward when crossing ffi boundaries.

considering this is a fairly popular macro that we already provide a cfg for in glibc environments, i thought this was necessary.

the fix itself is in adding the cfg and conditionally defining some fields at compile-time. the only exception to this are some integer fields whose signedness was not quite right, and some padding fields that were not using our Padding util type. i just decided to package those up in the same commit.

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

Labels

A-CI Area: CI-related items S-waiting-on-review stable-nominated This PR should be considered for cherry-pick to libc's stable release branch

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants