Cheaper cursor, a fortify panic that names its function; Finch's gap

The cursor now costs nothing for a byte inside an escape sequence and
one cell fewer for a plain glyph: the grid is the truth, so the old
cursor cell is repainted after the byte, and not at all when a glyph
has just been drawn over it.

__fortify_panic says "r8169: rtl_open.cold+0x..." through ldlsd's module
list, so a photograph of the screen is enough, and exits instead of
spinning on a core and holding /dev/netdev.

docs/plan/finch.md: only integrating Finch is later; finishing it is
not. The self-hosting gap measured against Finch's own bootstrap test.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015f73FesGZGYPkmDvUcj6QX
This commit is contained in:
Nexoniarz 2026-10-25 18:31:40 +01:00
commit 9c729edac1
5 changed files with 101 additions and 15 deletions

View file

@ -326,6 +326,33 @@ find_symbol(struct ko *k, const char *want)
return 0;
}
// "r8169: rtl_open.cold+0x4f" for an address in a loaded module, so that a
// photograph of the screen is enough to find the line. Modules are named by
// the file they were loaded from, with the directory and ".ko" dropped.
static const char *g_modname[MAXMOD];
static void
where(unsigned long addr)
{
for (int m = 0; m < g_nmods; m++) {
struct ko *k = g_mods[m];
for (int i = 0; i < k->nsym; i++) {
const struct ko_sym *s = &k->sym[i];
if (s->st_shndx == KO_SHN_UNDEF || s->st_shndx >= (unsigned short)k->nsh ||
!k->sec[s->st_shndx].alloc || s->st_size == 0 || (s->st_info & 0xf) != 2)
continue;
unsigned long long a = k->sec[s->st_shndx].addr + s->st_value;
if (addr >= a && addr < a + s->st_size) {
puts_(g_modname[m]); puts_(": ");
puts_(k->str + s->st_name); puts_("+");
puthex(addr - a);
return;
}
}
}
puthex(addr);
}
// --- reading and writing a struct at an offset BTF gave us --------------------
static unsigned int
@ -1009,8 +1036,14 @@ load_module(const char *path)
puts_("\n");
entry = find_symbol(k, "init_module");
if (g_nmods < MAXMOD)
if (g_nmods < MAXMOD) {
const char *b = path, *q;
for (q = path; *q; q++)
if (*q == '/') b = q + 1;
g_modname[g_nmods] = b;
g_mods[g_nmods++] = k;
kpi_where = where;
}
if (!entry) { puts_(" no init_module -- nothing to call\n"); return; }
puts_("\n calling init_module\n\n");