tests/games: --pins FILE for the page, Hollow Knight's library pins

browser-linux.mjs --pins FILE (`BASE SPAN PATH` lines, gexc run --pin's
format) adds each line to the query's pins=. hollow-knight-pins.txt pins the
16 objects that have function-tier units (UnityPlayer and 15 system
libraries) at the bases gex gave them unpinned at 6158cded, so a change that
moves the loader's own choices (a master merge moved 5 of them) leaves the
units applying. libdbus loads twice; it is pinned at its second base, and
libxcb keeps the first.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
Claude-Session: https://claude.ai/code/session_1896c5b302a54696aaa92c5f4047f20b
This commit is contained in:
velzieandClaude Opus 5.5 committed 2026-10-09 14:06:46 -04:00
1 parent 3302db70fe
commit 1fc1a8dd89
2 files changed
+44 -2

No files matched your search

+21 -2
View File
@@ -9,7 +9,7 @@
// [--cwd REL] [--args ARGS] [--libs DIR:DIR] [--files LIST] [--home DIR]
// [--input SCRIPT.wl] [--size WxH] [--minutes N] [--shot DIR]
// [--profile AT,SECS[,MATCH]] [--gameplay N] [--mem64] [--fjit] [--wasmdlls SO=PATH] [--query K=V&...] [--env K=V,K=V] [--end-on-exit]
// [--lazy DIR]
// [--lazy DIR] [--pins FILE]
//
// --files lists host files the game opens, one per line (collected from a
// native `gexc run --strace`; tests/games/retrocycles-linux-files.txt).
@@ -18,6 +18,9 @@
// --lazy DIR: every file under DIR the bundle lacks, at /game/REL, read from the
// page's server as the game reads it (a megabyte at a time; `?lazy=`), not bundled.
// The input script's `move X Y` / `click X Y` are in the game window's pixels.
// --pins FILE: load addresses for libraries, `BASE SPAN PATH` per line (hex; `gexc run --pin`'s
// format), added to the query's `pins=`: units built for those bases (`elfunits=`) then keep
// applying when an unrelated change moves where the loader would have put them.
// --env: more environment for the guest. --end-on-exit: a program that exits is a result
// (its output and status are printed), not a failure.
// Needs web/public/gex built (shims/browser/build.sh), Mesa's wasm
@@ -119,6 +122,22 @@ function bundle() {
return out;
}
/** --query plus --pins FILE (`BASE SPAN PATH` lines) merged into its `pins=`. */
function query() {
const q = new URLSearchParams(opt('--query', '') || '');
const file = opt('--pins', null);
if (file) {
const more = readFileSync(file, 'utf8').split('\n').map((l) => l.replace(/#.*/, '').trim()).filter(Boolean).map((l) => {
const [base, span, path] = l.split(/\s+/);
if (!path) throw new Error(`--pins ${file}: cannot read '${l}'`);
return `${path}@${base.replace(/^0x/, '')}+${span.replace(/^0x/, '')}`;
});
q.set('pins', [q.get('pins'), ...more].filter(Boolean).join(','));
}
const s = q.toString();
return s ? `&${s}` : '';
}
/** --lazy DIR: served at /gex/lazy/NAME/ (a link), listed in /gex/nt/NAME.lazy.json. */
function lazyManifest() {
const dir = opt('--lazy', null);
@@ -192,7 +211,7 @@ async function main() {
`tar=/gex/nt/${basename(tar)}&exe=/game/${exe}&cwd=/game/${cwd}&gl=1&glbackend=wgpu&hostx=1`
+ (argv.includes('--mem64') ? '&mem64=1' : '') + (argv.includes('--fjit') ? '&fjit=1' : '')
+ (opt('--wasmdlls', null) ? `&wasmdlls=${encodeURIComponent(opt('--wasmdlls'))}` : '')
+ (opt('--query', null) ? `&${opt('--query')}` : '')
+ query()
+ (lazy ? `&lazy=${encodeURIComponent(lazy)}` : '')
+ `&size=${width}x${height}&trapstack=1&env=${encodeURIComponent(genv)}&args=${encodeURIComponent(opt('--args', ''))}`,
{ width: width + 20, height: height + 100, shotDir },
+23
View File
@@ -0,0 +1,23 @@
# Hollow Knight in the page (browser-linux.mjs --pins): where each library with a
# function-tier unit (`elfunits=`) loads, so the units built for these bases keep
# applying when a change elsewhere moves the loader's own choices. The bases are
# where gex put them unpinned at merge/unity-seed 6158cded (the Debian
# libraries the page stages); the spans are each object's PT_LOAD extent.
# libdbus loads twice (unloaded in between); unpinned, libxcb took its first base.
# BASE SPAN PATH
0x11752000 0x2674000 /game/UnityPlayer.so
0x1a465000 0x1f4000 /lib/x86_64-linux-gnu/libc.so.6
0x1a663000 0xf0000 /lib/x86_64-linux-gnu/libm.so.6
0x1a78e000 0x2b000 /lib/x86_64-linux-gnu/libxcb.so.1
0x1a7e5000 0x116000 /lib/x86_64-linux-gnu/libsystemd.so.0
0x1a907000 0x148000 /lib/x86_64-linux-gnu/libX11.so.6
0x1aa6e000 0x14000 /lib/x86_64-linux-gnu/libXi.so.6
0x1aa82000 0xd000 /lib/x86_64-linux-gnu/libXrandr.so.2
0x1aa9b000 0x45000 /lib/x86_64-linux-gnu/libudev.so.1
0x1ac10000 0x7000 /lib/x86_64-linux-gnu/libpulse-simple.so.0
0x1b7ce000 0x55000 /lib/x86_64-linux-gnu/libpulse.so.0
0x20244000 0x87000 /gex/gl/libGL.so.1
0x242d0000 0x88000 /usr/lib/x86_64-linux-gnu/pulseaudio/libpulsecommon-17.0.so
0x24358000 0x57000 /lib/x86_64-linux-gnu/libdbus-1.so.3
0x2498d000 0x121000 /lib/x86_64-linux-gnu/libasound.so.2
0x24dcd000 0x63a000 /lib/x86_64-linux-gnu/libcrypto.so.3