Repository navigation
fix(libc): format strftime and asctime fields as measured on a PS5 - #10129
Conversation
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…a PS5 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…memccpy Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…sured on a PS5 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…e measured gaps Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…sured-ps5 # Conflicts: # docs/dev/debt/libc.md
MarcZX10
left a comment
There was a problem hiding this comment.
The linked probe reports substantive strftime/asctime differences and the test matrix is broad. GCC 12.2 syntax checks passed for the changed source and tests; exact-worktree conventions, diff-check, and main-sync also pass (6 ahead/29 behind; merge clean). The author reports seven related Windows CTests passing three times; I did not run the full CTest suite locally. Please split the independent fetestexcept implementation/test/debt change into a separate topic PR from the strftime/asctime implementation, as required by the repository’s one-branch-per-topic rule. The non-exported memmem/memccpy note is also separate from this formatter behavior and should move to a focused documentation change if retained. In addition, coordinate the debt-file integration with #10134: the pairwise heads conflict in the guest-time-conversion / __isfinitel section. Refresh the formatter branch, rerun its focused tests and overlap/convention checks, and retain the measured probe caveats.
|
Other open pull requests touch the same code. Merging one will break the other, or both implement the same thing. If this one builds on them, list them in Depends on.
Some comparisons could not be completed because a pull request conflicts with the base branch. Review these shared files manually before concluding that there is no overlap.
|
… requests Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…sured-ps5 # Conflicts: # docs/dev/debt/libc.md
|
@MarcZX10 Split as requested: |
MarcZX10
left a comment
There was a problem hiding this comment.
Re-review of current head ed75f2fee18f75f03c79dfb2c68b5824b06ea049. The unrelated fetestexcept and memmem work has been split out, and this PR now declares Depends on: #10134; the remaining changed files are the formatter, its tests and the debt note. Exact-head conventions and git diff --check pass, and the author reports the focused formatter tests passing three consecutive runs after the refresh.
The PR is currently CONFLICTING / DIRTY against current main, so the current merged tree cannot be built or reviewed as a landing candidate. Please rebase onto current main, preserve the #10134 prerequisite and both sets of debt evidence, rerun the focused formatter/time tests, and update the report to the resulting exact head. This is the remaining integration blocker; no closure is requested.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
@MarcZX10 The branch is refreshed: |
MarcZX10
left a comment
There was a problem hiding this comment.
Re-review of exact current head c1ce36f9eea92e4333e945172593911573299754.
The prior blockers are resolved: fetestexcept and the unrelated memmem/memccpy note are split into separate PRs; the branch now declares its #10134 dependency; and it is clean against current main (938812df14). The remaining diff is limited to strftime/asctime, focused tests, and the corresponding libc debt note. The measured PS5 behavior and the explicitly unmeasured cases are documented in the PR.
I independently ran tools/check_conventions.py on this exact head, git diff --check, and GCC C++20 -Wall -Wextra -Werror -fsyntax-only on the changed Time.cpp; all passed. The author reports six focused Windows CTests passing three consecutive times. Current hosted eligibility, conventions, labels, report, relinker (Ubuntu/Windows/macOS including x86_64), ASan relinker, register-context, and write-watch checks pass. Linux and Windows full product build jobs were skipped by path policy; I did not run the six CTests locally.
The #10134 dependency is explicit and its commit is present in this branch as described. Approving this exact head.
The %Z check now expects the guest tzname, since main leaves tzname[1] as three spaces for a zone without daylight saving time. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
@orezraey #10409 shrinks Proposed order: this PR lands first. #10409 then takes your |
|
A cross-check from Windows, against a different console binary from the one you measured. Method. A scratch loader maps the decrypted This PR on Windows (GCC 15.2.0 UCRT r7, Release): Fuzz against the titles' copy:
What still differs:
None of these affect in-range dates. Items 1 to 3 need impossible field combinations, and item 4 only affects the buffer contents on a 0 return. I'm posting them in case you want to close the remaining gaps or record them in the debt entry. The harness is ad hoc and not part of any PR; I can rerun it on a later head. 🤖 Generated with Claude Code |
… zone gmtime_s now stores tm_isdst -1, so strftime must not drop %z or empty %Z for it. Follow the rule boykopovar#10129 measured on a PS5: %z is the guest zone's offset, one hour more only when tm_isdst is positive, and %Z is tzname[tm_isdst > 0]. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
@ntamas94 Agreed: this PR lands first, and #10409 then keeps only the @JJenkx Thanks for the cross-check. Items 1 and 2 differ from what |
|
@orezraey @JJenkx A third data point for the out-of-range weeks and the fit rule, from a PS4 Pro (firmware 10.71). One probe called
That matches JJenkx's part-by-part result for composites and orezraey's rule for single conversions. These are PS4 modules, not the PS5 ones you measured, so they do not settle the PS5 behaviour directly. But on the PS4 the system libc and a title's libc.prx agree here, which makes it less likely that the two PS5 modules differ. The probe and its full output are in this gist: https://gist.github.com/ntamas94/38aca1712084acbea1c70058568147ff. AI-assisted: yes (Claude Code) |
…y part %U and %W take the weekday as (tm_wday + 7) % 7 and (tm_wday + 6) % 7 with the C remainder, which fits the PS5 rows of libSceLibcInternal.sprx and of the libc.prx titles ship. A composite conversion is written part by part, each part all or nothing. %G, %g and %V throw for a tm_yday past the year and a tm_wday below -6, where no rule fits the console. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
@ntamas94 @JJenkx Thanks, that settles |
|
@orezraey thanks for the week-number and composite-buffer fixes, those cases read right against the code. One thing has to change before this can merge: |
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Done in |
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
@karimibrahim07 @UnhealthyKraken @JJenkx: #6713, #8937, #10113, #10226 and #10345 change the same lines as this PR in |
|
@JJenkx: #9613 changes the same lines as this PR in |
|
#10706 replaces the local |
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
What
strftimeandasctimemeasured on a retail PS5 (firmware 13.60) with five homebrew probes callinglibSceLibcInternal.sprxfrom a payload process. The sources and console logs are in this gist (strftostrf4).strftimewas FreeBSD's; the console's is a different implementation. It now follows the console:%k,%l,%P,%s,%+,%v,%Qand any other unknown conversion%k)%k→13), or the letter alone (%Q→Q)%-d,%_d,%0e,%^a,%#b,%10Y)EorObefore a conversion%Ec=%c); before an unknown one dropped (%EE→%E,%Ek→%k)%EE→EESunorJan, also for%Aand%B;%m00?%m13, 14, …;%uand%wthe value mod 10?%d,%e,%H,%I,%M,%S,%j,%U,%W)%jat 1000):%Hof 101 is01%I(hour + 11) % 12 + 1, so hour -1 is11and -12 is00hour % 12or 12%Y,%G%y,%g99)%Ctm_year / 100 + 19mod 100 (year 1 →01, year 10001 →00)%U,%W(tm_wday + 7) % 7and(tm_wday + 6) % 7with the C remainder, so weekday 9 counts as 2 and -19 as -5tm_wdayas given%ztm_isdstis positive;tm_gmtoffignored, also printed fortm_isdst-1tm_gmtoff, nothing fortm_isdst-1%Ztzname[tm_isdst > 0];tm_zoneignoredtm_zone, elsetznameab%Ycdin 5 bytes writes onlyab) and the call returns 0; a composite is written part by part (%t%Din 8 bytes leaves\t10/02/)%cis%a %b %e %H:%M:%S %Y,%xand%Dare%m/%d/%y, and%ris%I:%M:%S %p, as before.asctimeuses the same field rules:"%s %s%3d %02d:%02d:%02d %04d\n"with those names, day, time and year (Fri Oct 56 00:61:61 2026for day 123456 and hour -10, year 10000 as0000). Before, the year was printed in full and an out-of-range name was???.Not followed:
%Eor%O; here that throws.%G,%gand%Vthrow for a negativetm_yday. The console gave%V01, 00, 00 and 52 fortm_yday-25, -13, -12 and -1 withtm_wday5, and 52 for -10 withtm_wday4; neither FreeBSD's ISO-week loop nor the variants I tried reproduce these, so the rule is unknown. They also throw for atm_ydaypast the end of the year and atm_wdaybelow -6:tm_yday400 of 2026 rolls into week 01 of 2027, but 415 of 1997 stays week 59 and 365 of 2013 week 53, andtm_wday-12 withtm_yday18 is week 04 where FreeBSD's loop gives 03 (JJenkx, ntamas94). Every ISO case inside the year withtm_wdayfrom -6 up matches, including the year boundaries. The ISO-week arithmetic is now 64-bit, so out-of-range fields no longer overflow.%Zprintstzname. The console'stznameand%Zwere both empty in the payload process; AnyPS5'stznamekeeps the host's names (separate debt entry).The debt entries record all of these, and that
fegetexceptflagwith a mask wider than 0x3f, which now also stores MXCSR control bits, was not measured.The
fetestexceptchange moved to #10175 and thememmem/memccpynote to #10176, as requested in review.Tested
main(f26434afa3, with refactor(libs): add full export headers for libs #10706):6b1962e978. The test takes its declarations fromlibc/include/Api.hpp.guest_crt,guest_mktime,guest_strftime,guest_time_conversion,guest_time_extrasandguest_wide_formattingpass three runs in a row on Windows (MinGW) and on Linux (WSL Ubuntu, GCC);public_headersaudit andcheck_conventionspass.Windows 11, MinGW (winlibs), at head
c1ce36f9ee: this branch with currentmain(938812df14) merged in and docs(libc): record nearbyintf, getw, putw, __isfinitel and _FSinh measured on a PS5 #10134's commit2151929559kept.guest_strftimeis rewritten from the console logs: the conversions, the alternative forms, weekday and month -3 to 14, fields from -25 to 123456, years from -12345 to 12345, 14 ISO-week cases, the buffer limits andasctime. Onmainit reports 47 mismatches.guest_time_conversionnow checks the console's handling of the unknown and modified conversions, in place of FreeBSD's.974e0a89f2,guest_strftimealso checks%Uand%Won the ten out-of-range rows JJenkx and ntamas94 posted and the two composite rows that do not fit (%t%Din 8 bytes,%X%#Hin 2); with theTime.cppbefore that commit it reports 5 failures. The unknown ISO cases are not pinned in tests (removed in68a4482acdat oneandonlydean's request); they still throw inTime.cppwith their debt entry.guest_strftime,guest_time_conversion,guest_wide_formatting,guest_crt,guest_mktimeandguest_time_extraspass three runs in a row.git diff --checkis clean.tools/check_conventions.pypasses.Checklist
main; no other open PR implements the same functionsNotImplemented_nid_no_patch); silent stubs are listed under Silent stubs in their library's technical debt file.mdfiles or images added to the repository (attach them to this PR)libc.mdsection; this branch carries its commit until it merges); fix(libc): use the default heap for an executable without process parameters #6713, feat(libc): implement fesetenv #8937, fix(libc): compute expf with FreeBSD msun's algorithm, as titles' libc.prx does #10113, fix(libc): compute erff and erfcf with fdlibm's algorithm, as titles' libc.prx does #10226, fix(libc): set EDOM in fmod and fmodf where titles' libc.prx does #10345 edit the same lines too (merge order only); docs(debt): cite the bundled libc.prx for _Mtx_trylock, strdup and strndup #9613 edits the same lines too (merge order only); refactor(libs): add full export headers for libs #10706 removes the test declarations this PR adds toGuestStrftime.cpp(merge order only); feat(libc): implement _LCosh and _LSinh #10742 adds an entry next to the same debt line (merge order only)