riscv32gc-unknown-linux-gnu: `timex` uses the 32-bit `c_long` layout (144 bytes), glibc's riscv32 `struct timex` is 208 bytes
I maintainer di solito rispondono entro 1 giorno
Valutazione
- Difficoltà
- 2/5
- Tempo stimato
- 1-3 ore
- Idoneità per principianti
- 76/100
- Tipo di issue
- Bug
- Chiarezza
- Specificata chiaramente
- Stato di attività
- Attiva
- Stack tecnologico
- rust
- Ambito
- backend, operating-systems
Direzione di ricerca
Leggi src/unix/linux_like/linux/gnu/b32/mod.rs e la configurazione della destinazione in build.rs descritta nell’issue. Confronta le disposizioni di timex con bits/timex.h di glibc per riscv32, poi controlla la disposizione di riscv32 e assicurati che i686 e armv7 mantengano le dimensioni attuali. Il lavoro è completato quando timex corrisponde alla disposizione di 208 byte di glibc su riscv32 senza scrivere oltre la sua fine.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
Target: riscv32gc-unknown-linux-gnu (glibc; 64-bit time_t is this target's only ABI)
Versions: libc 0.2.186, 0.2.191 and 1.0.0-alpha.5 (the declarations quoted below are unchanged on main); glibc 2.44; rustc 1.98.1.
src/unix/linux_like/linux/gnu/b32/mod.rs declares timex twice: the c_longlong layout under #[cfg(gnu_time_bits64)] (0.2.191 lines 191-227) and the c_long layout under #[cfg(not(gnu_time_bits64))] (lines 229-262). The build script never sets gnu_time_bits64 on riscv32, because its time_t is 64-bit already (build.rs:329-345):
// 32-bit arches with 64-bit time_t by default. rv32 is 64-only, `x86_64` covers the x32 arch,
// `!(linux|windows|hurd)` covers vxworks and future platforms.
let gnu32_already_time64 = target_arch == "riscv32"
|| target_arch == "x86_64"
|| !matches!(target_os.as_str(), "linux" | "windows" | "hurd");
let gnu = target_env == "gnu";
let gnu32_time64 = gnu && target_ptr_width == "32" && (gnu32_timebits == "64" || time64);
if gnu32_time64 && !gnu32_already_time64 {
so riscv32 gets the time32 layout, with 32-bit long fields:
#[cfg(not(gnu_time_bits64))]
pub struct timex {
pub modes: c_uint,
pub offset: c_long,
pub freq: c_long,
pub maxerror: c_long,
pub esterror: c_long,
pub status: c_int,
pub constant: c_long,
pub precision: c_long,
pub tolerance: c_long,
pub time: crate::timeval,
...
glibc's riscv32 struct timex takes the long long layout whenever __TIMESIZE == 64 && __WORDSIZE == 32 (glibc 2.44, bits/timex.h:26-36; riscv32's bits/timesize.h defines __TIMESIZE as 64):
struct timex
{
# if defined __USE_TIME64_REDIRECTS || (__TIMESIZE == 64 && __WORDSIZE == 32)
unsigned int modes; /* mode selector */
int :32; /* pad */
long long offset; /* time offset (usec) */
long long freq; /* frequency offset (scaled ppm) */
long long maxerror; /* maximum error (usec) */
long long esterror; /* estimated error (usec) */
int status; /* clock command/status */
int :32; /* pad */
Layouts, measured
libc timex |
glibc struct timex |
|
|---|---|---|
| size | 144 | 208 |
offset of freq |
8 | 16 |
offset of status |
20 | 40 |
offset of time |
40 | 72 |
offset of tai |
92 | 160 |
The libc column: const assertions under cargo check --target riscv32gc-unknown-linux-gnu, the same on 0.2.186, 0.2.191 and 1.0.0-alpha.5. The glibc column: _Static_asserts compiled by riscv32-unknown-linux-gnu-gcc 16.2.1 against glibc 2.44's headers.
At run time (qemu-riscv32 10.2.3, glibc 2.44, libc 0.2.191): adjtimex() with modes = 0, called on a libc::timex at the head of a canary-filled 256-byte buffer, changes the 20 bytes at offsets 144-163 (glibc's errcnt, stbcnt and tai): it writes past the end of the Rust struct. And status reads 0x0 (the upper half of glibc's freq) while glibc's status holds 0x40, STA_UNSYNC, so an unsynchronized clock reads as synchronized.
Minimal example (no dependency but libc):
#![no_std]
const _: [(); 208] = [(); core::mem::size_of::<libc::timex>()];
cargo check --target riscv32gc-unknown-linux-gnu fails with expected an array with a size of 208, found one with a size of 144.
A possible fix: give riscv32 the c_longlong layout too, #[cfg(any(gnu_time_bits64, target_arch = "riscv32"))] on the first declaration and #[cfg(not(any(gnu_time_bits64, target_arch = "riscv32")))] on the second. With that change on 0.2.191: riscv32 208 bytes, adjtimex() changes nothing past the struct, status reads 0x40; i686 and armv7 keep their 128 bytes.
Related: the time64 tracking issue #5507.
- Lingua principale
- Rust
- Stelle
- 2.6k
- Fork
- 1.3k
- Merge medio
- 2g 8h
- PR unite (30g)
- 27
Preparare l'ambiente
- Nessun Dockerfile né file Docker Compose
- Ha un modello di pull request
- Leggi la guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di rust-lang/libc
-
Expose `open_how` on AndroidForse già presa Una pull request collegata a questa issue è aperta o già unita. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 72/100
rust-lang/libc#5673 · 1 commento ·
I maintainer di solito rispondono entro 1 giorno
-
RTEMS: `dirfd` is not declaredForse già presa Una pull request collegata a questa issue è aperta o già unita. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
rust-lang/libc#5655 · 1 commento ·
I maintainer di solito rispondono entro 1 giorno
-
C-bug O-macos
Difficoltà 2/5 1-3 ore Idoneità per principianti 68/100
rust-lang/libc#5650 · 16 commenti ·
I maintainer di solito rispondono entro 1 giorno
-
NuttX missing signal.h itemsApertaC-API-request
Difficoltà 2/5 1-3 ore Idoneità per principianti 67/100
I maintainer di solito rispondono entro 1 giorno
-
libc-test: some semver files are never checkedForse già presa @Deepak-negi11 l’ha presa 25 giorni fa. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 67/100
rust-lang/libc#5622 · 1 commento · 1 reazione ·
I maintainer di solito rispondono entro 1 giorno
Tutte le issue di rust-lang/libc
Issue simili
-
bug
Difficoltà 2/5 1-3 ore Idoneità per principianti 73/100
I maintainer di solito rispondono entro 1 giorno
-
🐞 bug 🧩 bevy_gantz_egui
Difficoltà 2/5 1-3 ore Idoneità per principianti 82/100
nannou-org/gantz#500 ·
I maintainer di solito rispondono entro 1 giorno
-
[Feature]: Fedora 45 repoApertaenhancement
Difficoltà 2/5 1-3 ore Idoneità per principianti 68/100
metasequoiaime/msime#10989 ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
fritzprix/libr-agent#2612 ·
I maintainer di solito rispondono entro 1 giorno
-
find: -printf %h drops a doubled slashForse già presa @qodelicious l’ha presa oggi. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 68/100
I maintainer di solito rispondono entro 1 giorno