Commit Graph

654 Commits

Author SHA1 Message Date
Dean 27873b0f74
Merge pull request #4407 from oneandonlydean/up4/fix-mspace-fragments
fix(libc): round mspace block sizes to the 32-byte alignment
2026-10-13 09:34:01 +13:00
AlxcBTW 428963d3b3 feat(agc): write the worker sampler's stacks as collapsed stacks
APS5_SAMPLE_WORKER=<file> now also writes <file stem>.collapsed.txt: one
"frame;...;frame count" line per distinct stack of queue worker 0, root
first, frames as module+0xRVA, which speedscope.app and flamegraph.pl
open. Walks go up to 64 frames, and nothing allocates while the worker is
suspended.

The libraries are built with -fno-asynchronous-unwind-tables, so most of
their functions have no .pdata entry, only a DWARF record in .ehfram, and a
walk ended at the first such frame. The worker's walk now steps those
frames through their record, with the CIE/FDE decoding and the call frame
instructions of libc's unwinder, which move from Unwind.cpp into its
header unchanged. A module is indexed after the worker resumes, the first
time a walk meets it, and every register the step restores is read inside
the worker's stack. The process sampler (APS5_SAMPLE_THREADS) keeps its 12
frames through .pdata.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 21:23:11 +02:00
Dean 9c99f43440
Merge pull request #4537 from coltken95/claude/sleepy-dirac-e44kw4
fix(libc): sort with FreeBSD 11's qsort so equal elements keep its order
2026-10-13 07:32:15 +13:00
Dean a29ea3a2e3
Merge pull request #4529 from NahuelGenchi/fix/libc-new-length-error
fix(libc): throw bad_alloc from operator new when the default heap rejects a size
2026-10-13 07:31:32 +13:00
Dean 3b5c96377d
Merge pull request #4516 from Ondra97/codex/file-lock-lifetime
fix(libs): share Windows flock state between duplicated descriptors
2026-10-13 07:30:48 +13:00
Dean 66013d910b
Merge pull request #4511 from rebelittle/fix/windows-seh-unwind
fix(libc): unwind guest exceptions through Windows DLL frames
2026-10-13 07:30:11 +13:00
Dean d4ccf91e03
Merge pull request #4462 from milescoviello/carry/libc-umodti3-4460
feat(libc): implement __umodti3
2026-10-13 07:27:06 +13:00
Dean b9f194a890
Merge pull request #4455 from SibteProf/fix/libc-secure-copy-size-limits
fix(libc): reject oversized secure copy destinations
2026-10-13 07:26:35 +13:00
Dean 715bfabdac
Merge pull request #4426 from babyhuey/feat/libc-overflow-error
feat(libc): export std::overflow_error type info, vtable and destructor
2026-10-13 07:25:42 +13:00
Dean 57f91221c4
Merge pull request #4380 from AzazelSensei/fix/libc-stream-errors
fix(libc): return stream errors from fwrite, fread and fputs instead of throwing
2026-10-13 07:22:52 +13:00
Dean b701bc5d8d
Merge pull request #4372 from milescoviello/fix/fflush-read-stream
fix(libc): leave a stream that is reading untouched in fflush on Linux
2026-10-13 07:22:17 +13:00
Dean f30e89ee7c
Merge pull request #4365 from Gashrod1/fix/libc-strxfrm-truncation
fix(libc): truncate strxfrm like FreeBSD's C locale
2026-10-13 07:20:51 +13:00
Dean dfe9ccf6a2
Merge pull request #4360 from milescoviello/fix/wide-printf-grouping-flag
fix(libc): accept the ' flag in the wide printf family
2026-10-13 07:20:09 +13:00
Dean 15e64abd77
Merge pull request #4359 from milescoviello/fix/syslog-wide-format
fix(libc): format guest wide arguments in syslog on Linux
2026-10-13 07:19:47 +13:00
Dean 655cba83d5
Merge pull request #4358 from milescoviello/fix/scanf-binary-prefix
fix(libc): read %i without the C23 binary prefix in the scanf family on Linux
2026-10-13 07:19:26 +13:00
Dean 2c579b55f9
Merge pull request #4357 from milescoviello/fix/wide-printf-positional
fix(libc): format positional arguments in the wide printf family
2026-10-13 07:19:05 +13:00
Dean b538b28d8b
Merge pull request #4354 from milescoviello/fix/fopen-append-position
fix(libc): start append-mode streams at the end of the file
2026-10-13 07:18:50 +13:00
Dean bde332a59c
Merge pull request #4353 from milescoviello/fix/printf-errno-message
fix(libc): print the guest errno message for %m in the printf family
2026-10-13 07:18:29 +13:00
Claude ef09cda468
fix(libc): sort with FreeBSD 11's qsort so equal elements keep its order
qsort was a heapsort. It sorted correctly, but elements that compare
equal ended in a different order from FreeBSD's Bentley-McIlroy qsort,
in 18947 of 20000 random arrays with repeated keys, and below 7
elements, where FreeBSD's insertion sort keeps equal elements in
place, a heapsort does not. qsort now follows FreeBSD 11 qsort.c,
including its comparator call sequence.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VZWLdTjf1S57iLgn2rcaFb
2026-10-12 15:01:35 +00:00
Nahuel Genchi 22d1fbbc73 fix(libc): throw bad_alloc from operator new when the default heap rejects a size 2026-10-12 11:32:47 -03:00
Dean 858f75dbee
Merge pull request #3725 from Recapi/carry/screamm-sinhf-asinl
feat(libc): implement sinhf and asinl (carried from #3519)
2026-10-13 03:07:47 +13:00
Ondra97 bd842bc7d2 fix(libs): share Windows flock state between duplicated descriptors 2026-10-12 16:03:47 +02:00
Reagan Little 74392900d5 fix(libc): unwind guest exceptions through Windows DLL frames
The Windows unwinder stopped at the first frame of a module without the
project's .ehmeta or .ehfram tables, so an exception could not cross
libstdc++-6.dll and libwinpthread-1.dll (std::call_once through
pthread_once) or system DLLs. For such a frame it now looks up the
function's PE unwind data with RtlLookupFunctionEntry and takes the
caller's registers, including the nonvolatile rsi, rdi and xmm6-xmm15,
from RtlVirtualUnwind. A frame whose unwind data has an exception or
termination handler still stops the walk, since those handlers are not
run.

windows_exceptions gets back the std::call_once case of #1423.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 09:42:51 -04:00
Dean 3b83f71e0f
Merge pull request #3905 from aureau/aureau/carry-libc-strtod-no-conversion-zero
fix(libc): return positive zero when float parsing consumes no input
2026-10-13 02:34:59 +13:00
Dean 57dc136026
Merge pull request #3936 from MarcZX100/codex/carry-fopen-s-output-null
fix(libc): clear fopen_s output on invalid arguments
2026-10-13 02:32:30 +13:00
Abdullah 7e2832475f fix(libc): return stream errors from fwrite, fread and fputs instead of throwing 2026-10-12 16:14:25 +03:00
Dean 4bf963d660
Merge pull request #3966 from MarcZX100/codex/carry-strcasecmp-lowered
fix(libc): compare strcasecmp results after lowercasing bytes
2026-10-13 01:56:24 +13:00
Dean 0ef9dc9282
Merge pull request #4277 from BharatYadav007/bharat/libc-mktime-negative-one
fix(libc): normalize valid mktime minus-one results
2026-10-13 01:30:26 +13:00
Dean d58ba1010e
Merge pull request #4232 from MarcZX100/codex/carry-fdopen-modes-4022
fix(libc): accept FreeBSD fdopen modes
2026-10-13 01:30:04 +13:00
Dean e50326224c
Merge pull request #4103 from yunusshaikh7/fix/libc-difftime-negative-times-windows
fix(libc): subtract negative times in difftime on Windows
2026-10-13 01:29:12 +13:00
Dean 256cc9f976
Merge pull request #4099 from yunusshaikh7/fix/libc-asctime-years-before-1900-windows
fix(libc): format years before 1900 in asctime on Windows
2026-10-13 01:28:18 +13:00
screamm 23ac439214 feat(libc): implement __umodti3
Kart PS5 (PPSA99611, Phi1ow/mkwii-ps5 v1.0.0-rc1) stops on it right
after __divti3. The related open PR #4037 reports: "with this change it
passes `__divti3` and stops at `ELSr5qm4K1M` (`__umodti3`)".
PS5CEMU-HAR (PPSA99360) imports it too: tools/import_audit.py lists
ELSr5qm4K1M __umodti3 as absent from libSceLibcInternal.prx (registry
index 359), so the predicted stop is
"FAIL: unresolved ELF import ELSr5qm4K1M from libSceLibcInternal.prx".
libSceLibcInternal imports fall back to libc.prx, so the export lives in
libc beside __udivti3. compute_nid and aerolib (zecoxao/sce_symbols
2883963a) both give ELSr5qm4K1M = __umodti3.

__umodti3 is compiler-rt's lib/builtins/umodti3.c (llvm-project
0ee439b705e82a4fe20e266bc8fea96d0e60e1ec): the remainder that
__udivmodti4 leaves. The restoring division of SonyUdivti3 already
computes it, so the loop moves to SonyUdivmod128 and both helpers use
it. A zero divisor reaches a 64-bit divide in __udivmodti4 and traps on
x86-64; this throws instead, as __udivti3 does, and names the dividend.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-12 12:26:15 +00:00
Dean 029c1bc17d
Merge pull request #3926 from MarcZX100/codex/carry-fclose-error
fix(libc): return fclose failures to callers
2026-10-13 01:24:43 +13:00
Dean 906ce3f20c
Merge pull request #3599 from CouchRiv/fix-libc-exp2-errno
fix(libc): exp2 leaves errno unchanged
2026-10-13 01:24:15 +13:00
Dean baee04e810
Merge pull request #4037 from Nixitov/feat/libc-divti3
feat(libc): implement __divti3
2026-10-13 01:20:26 +13:00
SibteProf 5ffafa920f fix(libc): reject oversized secure copy destinations 2026-10-12 17:06:54 +05:00
Dean 7cb5238d53
Merge pull request #4281 from eljackjoestar-cmd/codex/reserve-direct-memory
perf(libkernel): commit Windows direct backing when mapped
2026-10-12 23:49:42 +13:00
Dean Galvin 9b91d2f66b fix(libc): round mspace block sizes to the 32-byte alignment 2026-10-12 22:21:01 +13:00
Hannah Lyons d316fcd8d5 feat(libc): export std::overflow_error type info, vtable and destructor 2026-10-12 05:20:17 -04:00
screamm 5f3fb3dddd feat(libc): implement asinl
RetroArch 1.0.0-beta.1 (PPSA99169) stops on main 0f863c10 at

    FAIL: unresolved ELF import Nx-F5v0-qU8 from libSceLibcInternal.prx

Nx-F5v0-qU8 is asinl (tools/nid_names.py, aerolib).

The implementation follows the asinl of the libc.prx bundled with
PPSA28319, read from its disassembly: FreeBSD msun's e_asinl.c with
the ld80 invtrig.c coefficients (9f043204), which the binary holds as
the same 80-bit constants, computed in the x87 long double the guest
uses. +-1 returns +-pi/2 rounded to 64 bits and +-0 keeps its sign.
For |x| > 1, the infinities and NaN, Sony's error helper raises
FE_INVALID and sets errno to EDOM before returning (x - x) / (x - x),
so a NaN argument sets EDOM too.

20 million random arguments in (-1, 1) plus the branch edges give the
same bits as that code from the title's libc.prx run on a Windows
host. guest_math pins a set of those bits and checks the domain
errors' errno and FE_INVALID, and that errno is untouched otherwise.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-12 10:51:59 +02:00
screamm 2c6e3f53ff feat(libc): implement sinhf
Ruffle Flash 1.2.0 (PPSA68091) stops on main 0f863c10 at

    FAIL: unresolved ELF import 1t1-JoZ0sZQ from libSceLibcInternal.prx

1t1-JoZ0sZQ is sinhf (tools/nid_names.py, aerolib). RetroArch
1.0.0-beta.1 (PPSA99169) imports it as well.

The implementation follows the sinhf of the libc.prx bundled with
PPSA28319, read from its disassembly: FreeBSD msun's e_sinhf.c as of
5aa554c7 (before __ldexp_expf, so expf(|x| / 2) is squared between
logf(FLT_MAX) and the overflow threshold), calling msun stable/9
expm1f and expf (59bc2f09), whose paths for the arguments sinhf passes
are inlined. Past the threshold Sony's error helper sets errno to
ERANGE before returning x * 1e37; NaN and the infinities return x + x
and leave errno alone.

Running that code from the title's libc.prx on a Windows host gives
the same bits as this implementation for every finite argument up to
the threshold, both signs (2,238,032,378 inputs). guest_math pins a
set of those bits, the overflow errno and FE_OVERFLOW, and checks that
errno is untouched otherwise.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-12 10:51:00 +02:00
Dean c22e2344ba
Merge pull request #4227 from MarcZX100/codex/carry-mbstowcs-4027
fix(libc): count full string with null mbstowcs destination
2026-10-12 21:42:35 +13:00
Dean 375e99ec33
Merge pull request #4095 from yunusshaikh7/fix/libc-towctrans-descriptors
fix(libc): map _Towctrans descriptors 1 and 2 to lower and upper case
2026-10-12 21:40:02 +13:00
Dean 9b152c43d0
Merge pull request #4090 from yunusshaikh7/fix/libc-fopen-delete-sharing-windows
fix(libc): open fopen streams with delete sharing on Windows
2026-10-12 21:39:18 +13:00
Dean 57c90b3835
Merge pull request #4056 from Celegans12/fix/libc-terminate-full-what
fix(libc): write the whole what() when terminate reports an exception
2026-10-12 21:38:13 +13:00
milescoviello 89bc9d1082 fix(libc): read %i without the C23 binary prefix in the scanf family on Linux
On Linux sscanf, vsscanf, fscanf and sscanf_s hand their conversions to
glibc. Since glibc 2.38, code built as GNU C++ calls the C23 entry
points (__isoc23_vsscanf, __isoc23_vfscanf, __isoc23_sscanf), whose %i
reads a 0b/0B binary prefix. On main,
sscanf("0b101 x", "%i%n%7s", &value, &end, rest) stores value 5 and
end 5 and leaves "x" for the %s; " -0B11" gives -3. TechnicalDebt
records this.

FreeBSD's %i knows only the 0 and 0x prefixes. FreeBSD 11.4
lib/libc/stdio/vfscanf.c, parseint, lines 345-353 and 371-380:

	case '0':
		if (base == 0) {
			base = 8;
			flags |= PFXOK;
		}
	...
	/* letters ok iff hex */
	case 'A': case 'B': case 'C':
	case 'D': case 'E': case 'F':
	case 'a': case 'b': case 'c':
	case 'd': case 'e': case 'f':
		/* no need to fix base here */
		if (base <= 10)
			break;	/* not legal here */

so "0b101" stores 0, consumes the "0" and leaves "b101", as C17 does
and as the strtol family here already does.

With glibc the scanf family now calls __isoc99_vsscanf and
__isoc99_vfscanf, the entry points GNU C++ used before glibc 2.38
(exported since 2.7), which read %i without the binary prefix. Other
hosts keep std::vsscanf and std::vfscanf. The TechnicalDebt entry is
removed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 08:38:06 +00:00
Dean 0511e86de9
Merge pull request #3984 from zmeizy/claude/scanf-wide-linux
fix(libc): throw for 16-bit wide scanf conversions on Linux
2026-10-12 21:37:08 +13:00
Dean 8f71e3010a
Merge pull request #4259 from Feuris/fix/libc-realloc-null-zero
fix(libc): allocate from realloc(NULL, 0) as malloc(0) does
2026-10-12 21:35:03 +13:00
milescoviello 1337bd7e45 fix(libc): leave a stream that is reading untouched in fflush on Linux
fflush() passed every stream to glibc's fflush(). For a stream that is
reading, glibc seeks the descriptor back and drops the read buffer, and
with a pushed-back character it gets the position wrong: after fgetc()
returned 'a' from "abcdef\n" and ungetc('Z'), fflush() returned 0 and
the next fread() returned "bcdef\n\n". The pushed-back 'Z' was lost and
the last byte came back twice.

FreeBSD's fflush() writes out only a stream that is writing and leaves
every other stream as it is, lib/libc/stdio/fflush.c:

	if ((fp->_flags & (__SWR | __SRW)) == 0)
		retval = 0;
	else
		retval = __sflush(fp);

and __sflush():

	t = fp->_flags;
	if ((t & __SWR) == 0)
		return (0);

fflush() on Linux now returns 0 without calling the host for a stream
whose last operation was not a write (__fwriting() is 0). fflush(NULL)
and streams that are writing are unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 08:00:21 +00:00
Dean 8c4a295ffb
Merge pull request #4083 from jweidenh/codex/fix-guest-array-callback-abi
fix(libc): preserve the guest ABI for array callbacks
2026-10-12 20:53:57 +13:00