Skip to content

feat(libc): implement malloc_usable_size - #3225

Merged
adriadam10 merged 1 commit into
boykopovar:mainfrom
adriadam10:feat/libc-malloc-usable-size
Oct 11, 2026
Merged

adriadam10 merged 1 commit into
boykopovar:mainfrom
adriadam10:feat/libc-malloc-usable-size

Conversation

@adriadam10

Copy link
Copy Markdown
Collaborator

What

malloc_usable_size (NDcSfcYZRC8, imported from libSceLibcInternal) isn't exported. Since #1529, Linux binds those imports to the system libraries, so a catalog homebrew title stops on it at load on main:

Title Stop on main f1ae427
OpenRCT2 Native Port (PPSA99728) ./app.elf: symbol lookup error: ./app.elf: undefined symbol: NDcSfcYZRC8

It goes through the application heap the same way malloc_stats_fast does:

  • The title registered its own allocator: the call goes to entry 9 of the replacement table, the pointer passed through unchanged, null included. Sony's libc.prx (the one Astro's Playroom ships) does the same: its malloc_usable_size is a jump through that table slot. The entry order follows KytyPS5's MallocReplace (malloc, free, calloc, realloc, memalign, reallocalign, posix_memalign, malloc_stats, malloc_stats_fast, malloc_usable_size). If the table leaves that entry null, it throws, as malloc_stats_fast does.
  • The default allocator: null gives 0, as in Sony's default allocator. Any other pointer gives the size the block was requested with, i.e. the range registered for it in GuestAllocations. Sony's allocator reports its rounded-up chunk size instead. Both satisfy "at least the requested size", and handing out bytes past the registered range would let the title write memory that isn't write-watched. TechnicalDebt records this.

Tested

Linux (CachyOS), GCC 16, Release.

  • application_heap_stats, application_heap_stats_default and application_heap_stats_missing pass. The new cases:
    • replacement allocator: the callback gets the pointer, and null, and its value comes back;
    • default allocator: 16-byte and 100000-byte blocks report 16 and 100000, and null reports 0 without calling anything;
    • table without entry 9: both a block and null throw.
  • On main the test doesn't link.
  • Negative checks, each one makes the test fail: not rejecting a null entry, not calling the replacement, the default returning 0, the default returning the raw block size, and null not handled specially.
  • Title stop: catalog release (sha256-checked) relinked for Linux with main's relinker and launched. It stops at load with the line above.
  • tools/check_conventions.py passes.

Checklist

  • Based on current main; no other open PR implements the same functions
  • One topic per PR; follow-ups go in a new PR
  • No comments in code except technical debt
  • Unimplemented paths throw (NotImplemented_nid_no_patch); silent stubs are listed in TechnicalDebt
  • No notes, investigation .md files or images added to the repository (attach them to this PR)
  • New third-party code is a submodule built from source
  • Generic behaviour, not specific to one title
  • Depends on: none
  • AI-assisted: yes

@github-actions

github-actions Bot commented Oct 11, 2026 •

Copy link
Copy Markdown

Progress report (aac0f1b → 859f2f3)

📈 System libraries: 86.0% (+0.01%, +1 implemented functions)

✅ 1 implemented
Library Name
libc malloc_usable_size_nid_postfix

@github-actions github-actions Bot added the needs rebase Conflicts with main, rebase needed label Oct 11, 2026
@babyhuey babyhuey mentioned this pull request Oct 11, 2026
9 tasks done
Co-Authored-By: Claude <noreply@anthropic.com>
@adriadam10

Copy link
Copy Markdown
Collaborator Author

Rebased on main after #3229. The only conflict was the TechnicalDebt line's neighbour; the line moved next to the other heap entries. application_heap_stats* pass again.

@adriadam10
adriadam10 force-pushed the feat/libc-malloc-usable-size branch from 6c76263 to 859f2f3 Compare October 11, 2026 02:41
@adriadam10
adriadam10 merged commit 6c9cb3a into boykopovar:main Oct 11, 2026
14 checks passed
@adriadam10

Copy link
Copy Markdown
Collaborator Author

Merged: Linux CI is red only on agc_unit_shadow, which main has failed since #2864 (reported in #3215). Windows passed, and application_heap_stats* passed on both.

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

Labels

needs rebase Conflicts with main, rebase needed

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant