--- a/sys/src/9/port/allocb.c Wed Apr 8 17:18:16 2026 +++ b/sys/src/9/port/allocb.c Sat Aug 2 14:41:43 2025 @@ -55,11 +55,11 @@ _xinc(&b->ref); /* align start of data portion by rounding up */ - b->base = (uchar*)ALIGNUP((ulong)b + sizeof(Block)); + b->base = (uchar*)ALIGNUP((uintptr)b + sizeof(Block)); /* align end of data portion by rounding down */ b->lim = (uchar*)b + (malloced? msize(b): blocksize(usable)); - b->lim = (uchar*)((ulong)b->lim & ~(BLOCKALIGN-1)); + b->lim = (uchar*)((uintptr)b->lim & ~(BLOCKALIGN-1)); /* leave sluff at beginning for added headers */ b->wp = b->rp = b->lim - ALIGNUP(usable); --- a/sys/src/9/port/auth.c Wed Apr 8 17:18:16 2026 +++ b/sys/src/9/port/auth.c Sun Feb 8 16:50:30 2026 @@ -19,8 +19,8 @@ return strcmp(eve, up->user) == 0; } -long -sysfversion(ulong *arg) +uintptr +sysfversion(uintptr *arg) { char *vers; uint arglen, m, msize; @@ -46,8 +46,8 @@ return m; } -long -sys_fsession(ulong *arg) +uintptr +sys_fsession(uintptr *arg) { /* deprecated; backwards compatibility only */ @@ -58,8 +58,8 @@ return 0; } -long -sysfauth(ulong *arg) +uintptr +sysfauth(uintptr *arg) { Chan *c, *ac; char *aname; --- a/sys/src/9/port/chan.c Wed Apr 8 17:18:16 2026 +++ b/sys/src/9/port/chan.c Sun Feb 8 11:14:10 2026 @@ -1700,14 +1700,14 @@ * to access unchecked addresses.) */ static char* -validname0(char *aname, int slashok, int dup, ulong pc) +validname0(char *aname, int slashok, int dup, uintptr pc) { char *ename, *name, *s; int c, n; Rune r; name = aname; - if((ulong)name < KZERO){ + if((uintptr)name < KZERO){ if(!dup) print("warning: validname called from %#p with user pointer", pc); ename = vmemchr(name, 0, (1<<16)); --- a/sys/src/9/port/devproc.c Wed Apr 8 17:18:16 2026 +++ b/sys/src/9/port/devproc.c Sat Mar 21 11:00:35 2026 @@ -1,6 +1,7 @@ #include "u.h" #include #include "tos.h" +#include "../port/tos32.h" #include "../port/lib.h" #include "mem.h" #include "dat.h" @@ -158,20 +159,31 @@ static int tproduced, tconsumed; void (*proctrace)(Proc*, int, vlong); +void (*ureg64to32)(void*, Ureg*); +void (*ureg32to64)(Ureg*, void*); +uint ureg32size; + extern int unfair; static void profclock(Ureg *ur, Timer *) { - Tos *tos; - if(up == 0 || up->state != Running) return; /* user profiling clock */ if(userureg(ur)){ - tos = (Tos*)(USTKTOP-sizeof(Tos)); - tos->clock += TK2MS(1); + if(!up->compat32){ + Tos *tos; + + tos = (Tos*)(USTKTOP-sizeof(Tos)); + tos->clock += TK2MS(1); + }else{ + Tos32 *tos; + + tos = (Tos32*)(USTKTOP-sizeof(Tos32)); + tos->clock += TK2MS(1); + } segclock(ur->pc); } } @@ -259,6 +271,10 @@ len *= sizeof(*q->profile); } break; + case Qregs: + if(p->compat32) + len = ureg32size; + break; } mkqid(&qid, path|tab->qid.path, c->qid.vers, QTFILE); @@ -678,7 +694,7 @@ int i, j, m, navail, ne, pid, rsize; long l; uchar *rptr; - ulong offset; + uintptr offset; Confmem *cm; Mntwalk *mw; Proc *p; @@ -742,9 +758,9 @@ error(Eperm); /* validate kernel addresses */ - if(offset < (ulong)end) { - if(offset+n > (ulong)end) - n = (ulong)end - offset; + if(offset < (uintptr)end) { + if(offset+n > (uintptr)end) + n = (uintptr)end - offset; memmove(a, (char*)offset, n); return n; } @@ -810,8 +826,14 @@ return n; case Qregs: - rptr = (uchar*)p->dbgreg; - rsize = sizeof(Ureg); + if(p->compat32){ + ureg64to32(up->genbuf, p->dbgreg); + rptr = (uchar*)up->genbuf; + rsize = ureg32size; + }else{ + rptr = (uchar*)p->dbgreg; + rsize = sizeof(Ureg); + } goto regread; case Qkregs: --- a/sys/src/9/port/fault.c Wed Apr 8 17:18:16 2026 +++ b/sys/src/9/port/fault.c Thu Mar 12 09:29:59 2026 @@ -14,7 +14,7 @@ if(up == nil) panic("fault: nil up"); if(up->nlocks.ref) - print("fault: addr %#p: nlocks %ld\n", addr, up->nlocks.ref); + print("fault: addr %#p: nlocks %ld\n", (uintptr)addr, up->nlocks.ref); sps = up->psstate; up->psstate = "Fault"; @@ -324,10 +324,10 @@ vmemchr(void *s, int c, int n) { int m; - ulong a; + uintptr a; void *t; - a = (ulong)s; + a = (uintptr)s; while(PGROUND(a) != PGROUND(a+n-1)){ /* spans pages; handle this page */ m = BY2PG - (a & (BY2PG-1)); --- a/sys/src/9/port/lib.h Wed Apr 8 17:18:17 2026 +++ b/sys/src/9/port/lib.h Sun Sep 28 09:27:36 2025 @@ -122,7 +122,7 @@ * one-of-a-kind */ extern char* cleanname(char*); -extern ulong getcallerpc(void*); +extern uintptr getcallerpc(void*); extern long strtol(char*, char**, int); extern ulong strtoul(char*, char**, int); --- a/sys/src/9/port/portdat.h Wed Apr 8 17:18:17 2026 +++ b/sys/src/9/port/portdat.h Sat Mar 21 10:42:47 2026 @@ -135,7 +135,7 @@ struct Sargs { - ulong args[MAXSYSARG]; + uintptr args[MAXSYSARG]; }; /* @@ -419,9 +419,9 @@ }; #define PG_ONSWAP 1 -#define onswap(s) (((ulong)s)&PG_ONSWAP) -#define pagedout(s) (((ulong)s)==0 || onswap(s)) -#define swapaddr(s) (((ulong)s)&~PG_ONSWAP) +#define onswap(s) (((uintptr)s)&PG_ONSWAP) +#define pagedout(s) (((uintptr)s)==0 || onswap(s)) +#define swapaddr(s) (((uintptr)s)&~PG_ONSWAP) #define SEGMAXSIZE (SEGMAPSIZE*PTEMAPMEM) @@ -776,6 +776,7 @@ */ Edf *edf; /* if non-null, real-time proc, edf contains scheduling params */ int trace; /* process being traced? */ + int compat32; /* 32-bit process running on a 64-bit kernel */ ulong qpc; /* pc calling last blocking qlock */ @@ -828,6 +829,7 @@ extern char* sysname; extern uint qiomaxatomic; extern char* sysctab[]; +extern uint ureg32size; Watchdog*watchdog; int watchdogon; --- a/sys/src/9/port/portfns.h Wed Apr 8 17:18:17 2026 +++ b/sys/src/9/port/portfns.h Sat Mar 21 10:40:56 2026 @@ -361,6 +361,8 @@ void uncachepage(Page*); long unionread(Chan*, void*, long); void unlock(Lock*); +void (*ureg32to64)(Ureg*, void*); +void (*ureg64to32)(void*, Ureg*); uvlong us2fastticks(uvlong); void userinit(void); ulong userpc(void); --- a/sys/src/9/port/proc.c Wed Apr 8 17:18:16 2026 +++ b/sys/src/9/port/proc.c Mon Mar 23 11:28:54 2026 @@ -765,7 +765,7 @@ s = splhi(); if(up->nlocks.ref) - print("process %lud sleeps with %lud locks held, last lock %#p locked at pc %#lux, sleep called from %#p\n", + print("process %lud sleeps with %lud locks held, last lock %#p locked at pc %#p, sleep called from %#p\n", up->pid, up->nlocks.ref, up->lastlock, up->lastlock->pc, getcallerpc(&r)); lock(r); lock(&up->rlock); @@ -1167,6 +1167,7 @@ } if(!freemem) + if(getconf("*nobroken") == nil) addbroken(up); qlock(&up->seglock); @@ -1278,7 +1279,7 @@ s = p->psstate; if(s == 0) s = statename[p->state]; - print("%3lud:%10s pc %8lux dbgpc %8lux %8s (%s) ut %ld st %ld bss %lux qpc %lux nl %lud nd %lud lpc %lux pri %lud\n", + print("%3lud:%10s pc %8lux dbgpc %8lux %8s (%s) ut %ld st %ld bss %lux qpc %lux nl %lud nd %lud lpc %p pri %lud\n", p->pid, p->text, p->pc, dbgpc(p), s, statename[p->state], p->time[0], p->time[1], bss, p->qpc, p->nlocks.ref, p->delaysched, p->lastlock ? p->lastlock->pc : 0, p->priority); } --- a/sys/src/9/port/segment.c Wed Apr 8 17:18:16 2026 +++ b/sys/src/9/port/segment.c Mon Apr 6 13:25:44 2026 @@ -648,7 +648,7 @@ if(va != 0 && va >= USTKTOP) error(Ebadarg); - validaddr((ulong)name, 1, 0); + validaddr((uintptr)name, 1, 0); vmemchr(name, 0, ~0); for(sno = 0; sno < NSEG; sno++) @@ -731,8 +731,8 @@ } } -long -syssegflush(ulong *arg) +uintptr +syssegflush(uintptr *arg) { Segment *s; ulong addr, l; --- a/sys/src/9/port/swap.c Wed Apr 8 17:18:16 2026 +++ b/sys/src/9/port/swap.c Sat Sep 27 11:12:44 2025 @@ -76,7 +76,7 @@ uchar *idx; lock(&swapalloc); - idx = &swapalloc.swmap[((ulong)p)/BY2PG]; + idx = &swapalloc.swmap[((uintptr)p)/BY2PG]; if(--(*idx) == 0) { swapalloc.free++; if(idx < swapalloc.last) @@ -91,7 +91,7 @@ dupswap(Page *p) { lock(&swapalloc); - if(++swapalloc.swmap[((ulong)p)/BY2PG] == 0) + if(++swapalloc.swmap[((uintptr)p)/BY2PG] == 0) panic("dupswap"); unlock(&swapalloc); } --- a/sys/src/9/port/syscallfmt.c Wed Apr 8 17:18:16 2026 +++ b/sys/src/9/port/syscallfmt.c Sun Feb 15 14:58:07 2026 @@ -20,10 +20,10 @@ fmtprint(f, "0x0%s", suffix); return; } - validaddr((ulong)a, n, 0); + validaddr((uintptr)a, n, 0); t = smalloc(n+1); for(i = 0; i < n; i++) - if(a[i] > 0x20 && a[i] < 0x7f) /* printable ascii? */ + if(a[i] >= 0x20 && a[i] < 0x7f) /* printable ascii? */ t[i] = a[i]; else t[i] = '.'; @@ -42,7 +42,7 @@ fmtprint(f, "0/\"\"%s", suffix); return; } - validaddr((ulong)a, 1, 0); + validaddr((uintptr)a, 1, 0); n = ((char*)vmemchr(a, 0, 0x7fffffff) - a) + 1; t = smalloc(n+1); memmove(t, a, n); @@ -113,9 +113,22 @@ a = va_arg(list, char*); fmtuserstring(&fmt, a, ""); argv = va_arg(list, char**); + if(up->compat32){ + validalign(PTR2UINT(argv), sizeof(ulong)); + for(;;){ + validaddr((uintptr)argv, sizeof(ulong), 0); + a = (char*)*(ulong*)argv; + if(a == nil) + break; + fmtprint(&fmt, " "); + fmtuserstring(&fmt, a, ""); + argv = (char**)((uintptr)argv + sizeof(ulong)); + } + break; + } validalign(PTR2UINT(argv), sizeof(char*)); for(;;){ - validaddr((ulong)argv, sizeof(char**), 0); + validaddr((uintptr)argv, sizeof(char**), 0); a = *(char **)argv; if(a == nil) break; --- a/sys/src/9/port/sysfile.c Wed Apr 8 17:18:16 2026 +++ b/sys/src/9/port/sysfile.c Sun Feb 8 16:39:15 2026 @@ -169,8 +169,8 @@ return o; } -long -sysfd2path(ulong *arg) +uintptr +sysfd2path(uintptr *arg) { Chan *c; @@ -182,8 +182,8 @@ return 0; } -long -syspipe(ulong *arg) +uintptr +syspipe(uintptr *arg) { int fd[2]; Chan *c[2]; @@ -220,8 +220,8 @@ return 0; } -long -sysdup(ulong *arg) +uintptr +sysdup(uintptr *arg) { int fd; Chan *c, *oc; @@ -261,8 +261,8 @@ return fd; } -long -sysopen(ulong *arg) +uintptr +sysopen(uintptr *arg) { int fd; Chan *c; @@ -310,8 +310,8 @@ cclose(c); } -long -sysclose(ulong *arg) +uintptr +sysclose(uintptr *arg) { fdtochan(arg[0], -1, 0, 0); fdclose(arg[0], 0); @@ -624,7 +624,7 @@ } static long -read(ulong *arg, vlong *offp) +read(uintptr *arg, vlong *offp) { long n, nn, nnn; uchar *p; @@ -693,14 +693,14 @@ return nnn; } -long -sys_read(ulong *arg) +uintptr +sys_read(uintptr *arg) { return read(arg, nil); } -long -syspread(ulong *arg) +uintptr +syspread(uintptr *arg) { vlong v; va_list list; @@ -717,7 +717,7 @@ } static long -write(ulong *arg, vlong *offp) +write(uintptr *arg, vlong *offp) { Chan *c; long m, n; @@ -766,14 +766,14 @@ return m; } -long -sys_write(ulong *arg) +uintptr +sys_write(uintptr *arg) { return write(arg, nil); } -long -syspwrite(ulong *arg) +uintptr +syspwrite(uintptr *arg) { vlong v; va_list list; @@ -790,7 +790,7 @@ } static void -sseek(ulong *arg) +sseek(uintptr *arg) { Chan *c; uchar buf[sizeof(Dir)+100]; @@ -858,8 +858,8 @@ poperror(); } -long -sysseek(ulong *arg) +uintptr +sysseek(uintptr *arg) { validaddr(arg[0], sizeof(vlong), 1); validalign(arg[0], sizeof(vlong)); @@ -867,17 +867,17 @@ return 0; } -long -sysoseek(ulong *arg) +uintptr +sysoseek(uintptr *arg) { union { vlong v; ulong u[2]; } o; - ulong a[5]; + uintptr a[5]; o.v = (long)arg[1]; - a[0] = (ulong)&o.v; + a[0] = (uintptr)&o.v; a[1] = arg[0]; a[2] = o.u[0]; a[3] = o.u[1]; @@ -928,11 +928,11 @@ return p->s; } -long -sysfstat(ulong *arg) +uintptr +sysfstat(uintptr *arg) { Chan *c; - uint l; + uintptr l; l = arg[2]; validaddr(arg[1], l, 1); @@ -947,12 +947,12 @@ return l; } -long -sysstat(ulong *arg) +uintptr +sysstat(uintptr *arg) { char *name; Chan *c; - uint l; + uintptr l; l = arg[2]; validaddr(arg[1], l, 1); @@ -972,8 +972,8 @@ return l; } -long -syschdir(ulong *arg) +uintptr +syschdir(uintptr *arg) { Chan *c; @@ -985,7 +985,7 @@ return 0; } -long +uintptr bindmount(int ismount, int fd, int afd, char* arg0, char* arg1, ulong flag, char* spec) { int ret; @@ -1001,7 +1001,7 @@ error(Ebadarg); if(ismount){ - validaddr((ulong)spec, 1, 0); + validaddr((uintptr)spec, 1, 0); spec = validnamedup(spec, 1); if(waserror()){ free(spec); @@ -1035,7 +1035,7 @@ cclose(bc); }else{ spec = 0; - validaddr((ulong)arg0, 1, 0); + validaddr((uintptr)arg0, 1, 0); c0 = namec(arg0, Abind, 0, 0); } @@ -1044,7 +1044,7 @@ nexterror(); } - validaddr((ulong)arg1, 1, 0); + validaddr((uintptr)arg1, 1, 0); c1 = namec(arg1, Amount, 0, 0); if(waserror()){ cclose(c1); @@ -1065,26 +1065,26 @@ return ret; } -long -sysbind(ulong *arg) +uintptr +sysbind(uintptr *arg) { return bindmount(0, -1, -1, (char*)arg[0], (char*)arg[1], arg[2], nil); } -long -sysmount(ulong *arg) +uintptr +sysmount(uintptr *arg) { return bindmount(1, arg[0], arg[1], nil, (char*)arg[2], arg[3], (char*)arg[4]); } -long -sys_mount(ulong *arg) +uintptr +sys_mount(uintptr *arg) { return bindmount(1, arg[0], -1, nil, (char*)arg[1], arg[2], (char*)arg[3]); } -long -sysunmount(ulong *arg) +uintptr +sysunmount(uintptr *arg) { Chan *cmount, *cmounted; @@ -1117,8 +1117,8 @@ return 0; } -long -syscreate(ulong *arg) +uintptr +syscreate(uintptr *arg) { int fd; Chan *c; @@ -1137,8 +1137,8 @@ return fd; } -long -sysremove(ulong *arg) +uintptr +sysremove(uintptr *arg) { Chan *c; @@ -1193,11 +1193,11 @@ return l; } -long -syswstat(ulong *arg) +uintptr +syswstat(uintptr *arg) { Chan *c; - uint l; + uintptr l; l = arg[2]; validaddr(arg[1], l, 0); @@ -1207,11 +1207,11 @@ return wstat(c, (uchar*)arg[1], l); } -long -sysfwstat(ulong *arg) +uintptr +sysfwstat(uintptr *arg) { Chan *c; - uint l; + uintptr l; l = arg[2]; validaddr(arg[1], l, 0); @@ -1254,11 +1254,11 @@ PBIT16(p, d->dev); } -long -sys_stat(ulong *arg) +uintptr +sys_stat(uintptr *arg) { Chan *c; - uint l; + uintptr l; uchar buf[128]; /* old DIRLEN plus a little should be plenty */ char strs[128], *name; Dir d; @@ -1288,12 +1288,12 @@ return 0; } -long -sys_fstat(ulong *arg) +uintptr +sys_fstat(uintptr *arg) { Chan *c; char *name; - uint l; + uintptr l; uchar buf[128]; /* old DIRLEN plus a little should be plenty */ char strs[128]; Dir d; @@ -1322,15 +1322,15 @@ return 0; } -long -sys_wstat(ulong *) +uintptr +sys_wstat(uintptr *) { error("old wstat system call - recompile"); return -1; } -long -sys_fwstat(ulong *) +uintptr +sys_fwstat(uintptr *) { error("old fwstat system call - recompile"); return -1; --- a/sys/src/9/port/sysproc.c Wed Apr 8 17:18:17 2026 +++ b/sys/src/9/port/sysproc.c Mon Apr 6 10:48:01 2026 @@ -1,5 +1,6 @@ #include "u.h" #include "tos.h" +#include "../port/tos32.h" #include "../port/lib.h" #include "mem.h" #include "dat.h" @@ -9,20 +10,26 @@ #include +#ifndef AOUT_MAGIC_COMPAT32 +#define AOUT_MAGIC_COMPAT32 AOUT_MAGIC +#define UTZERO_COMPAT32 UTZERO +#define UTROUND_COMPAT32(n) UTROUND(n) +#endif + int shargs(char*, int, char**); extern void checkpages(void); extern void checkpagerefs(void); -long -sysr1(ulong*) +uintptr +sysr1(uintptr*) { checkpagerefs(); return 0; } -long -sysrfork(ulong *arg) +uintptr +sysrfork(uintptr *arg) { Proc *p; int n, i; @@ -84,6 +91,7 @@ p = newproc(); + p->compat32 = up->compat32; p->fpsave = up->fpsave; p->scallnr = up->scallnr; p->s = up->s; @@ -218,24 +221,65 @@ return (cp[0]<<24) | (cp[1]<<16) | (cp[2]<<8) | cp[3]; } -long -sysexec(ulong *arg) +ulong +ll2be(uvlong l) +{ + uchar *cp; + + cp = (uchar*)&l; + return ((uvlong)cp[0]<<56) | ((uvlong)cp[1]<<48) | ((uvlong)cp[2]<<40) | ((uvlong)cp[3]<<32) | + (cp[4]<<24) | (cp[5]<<16) | (cp[6]<<8) | cp[7]; +} + +static char* +getptr_compat32(void **argp) +{ + return (char*)*(ulong*)(uintptr)argp; +} + +static char* +getptr_native(void **argp) +{ + return (char*)*argp; +} + +static void +putptr_compat32(void **argp, uintptr v) +{ + *(ulong*)argp = v; +} + +static void +putptr_native(void **argp, uintptr v) +{ + *argp = (void*)v; +} + +uintptr +sysexec(uintptr *arg) { Segment *s, *ts; ulong t, d, b; - int i; + int i, compat32; Chan *tc; char **argv, **argp; + int oBY2WD, nBY2WD; + char* (*getptr)(void**); + void (*putptr)(void**, uintptr); + char *a, *charp, *args, *file, *file0; char *progarg[sizeof(Exec)/2+1], *elem, progelem[64]; ulong ssize, spage, nargs, nbytes, n, bssend; int indir; - Exec exec; + struct { + Exec; + uvlong llentry; + } exec; char line[sizeof(Exec)]; Fgrp *f; Image *img; - ulong magic, text, entry, data, bss; - Tos *tos; + ulong execsize, magic, text, data, bss; + uvlong entry; indir = 0; elem = nil; @@ -247,6 +291,13 @@ nexterror(); } file = file0; + if(up->compat32){ + oBY2WD = 4; + getptr = getptr_compat32; + }else{ + oBY2WD = sizeof(uintptr); + getptr = getptr_native; + } for(;;){ tc = namec(file, Aopen, OEXEC, 0); if(waserror()){ @@ -256,17 +307,32 @@ if(!indir) kstrdup(&elem, up->genbuf); - n = devtab[tc->type]->read(tc, &exec, sizeof(Exec), 0); + n = devtab[tc->type]->read(tc, &exec, sizeof(exec), 0); if(n < 2) error(Ebadexec); magic = l2be(exec.magic); text = l2be(exec.text); entry = l2be(exec.entry); - if(n==sizeof(Exec) && (magic == AOUT_MAGIC)){ - if(text >= USTKTOP-UTZERO - || entry < UTZERO+sizeof(Exec) - || entry >= UTZERO+sizeof(Exec)+text) - error(Ebadexec); + if(n>=sizeof(Exec) && (magic == AOUT_MAGIC || magic == AOUT_MAGIC_COMPAT32)){ + compat32 = (magic != AOUT_MAGIC); + execsize = sizeof(Exec); + if(magic&HDR_MAGIC){ + if(n!=sizeof(exec)) + error(Ebadexec); + execsize = n; + entry = ll2be(exec.llentry); + } + if(!compat32){ + if(text >= USTKTOP-UTZERO + || entry < UTZERO+execsize + || entry >= UTZERO+execsize+text) + error(Ebadexec); + }else{ + if(text >= USTKTOP-UTZERO_COMPAT32 + || entry < UTZERO_COMPAT32+execsize + || entry >= UTZERO_COMPAT32+execsize+text) + error(Ebadexec); + } break; /* for binary */ } @@ -285,8 +351,8 @@ */ progarg[n++] = file; progarg[n] = 0; - validaddr(arg[1], BY2WD, 1); - arg[1] += BY2WD; + validaddr(arg[1], oBY2WD, 1); + arg[1] += oBY2WD; file = progarg[0]; if(strlen(elem) >= sizeof progelem) error(Ebadexec); @@ -296,19 +362,33 @@ cclose(tc); } + if(compat32){ + nBY2WD = 4; + putptr = putptr_compat32; + }else{ + nBY2WD = sizeof(uintptr); + putptr = putptr_native; + } + data = l2be(exec.data); bss = l2be(exec.bss); - t = UTROUND(UTZERO+sizeof(Exec)+text); + if(compat32) + t = UTROUND_COMPAT32(UTZERO_COMPAT32+execsize+text); + else + t = UTROUND(UTZERO+execsize+text); d = (t + data + (BY2PG-1)) & ~(BY2PG-1); bssend = t + data + bss; b = (bssend + (BY2PG-1)) & ~(BY2PG-1); - if(t >= KZERO || d >= KZERO || b >= KZERO) + if(t >= USTKTOP || d >= USTKTOP || b >= USTKTOP) error(Ebadexec); /* * Args: pass 1: count */ - nbytes = sizeof(Tos); /* hole for profiling clock at top of stack (and more) */ + if(!compat32) + nbytes = sizeof(Tos); /* hole for profiling clock at top of stack (and more) */ + else + nbytes = sizeof(Tos32); nargs = 0; if(indir){ argp = progarg; @@ -318,25 +398,25 @@ nargs++; } } - validalign(arg[1], sizeof(char**)); + validalign(arg[1], oBY2WD); argp = (char**)arg[1]; - validaddr((ulong)argp, BY2WD, 0); - while(*argp){ - a = *argp++; - if(((ulong)argp&(BY2PG-1)) < BY2WD) - validaddr((ulong)argp, BY2WD, 0); - validaddr((ulong)a, 1, 0); + validaddr((uintptr)argp, oBY2WD, 0); + while((a = getptr(argp)) != nil){ + argp = (char**)((uintptr)argp + oBY2WD); + if(((uintptr)argp&(BY2PG-1)) < oBY2WD) + validaddr((uintptr)argp, oBY2WD, 0); + validaddr((uintptr)a, 1, 0); nbytes += ((char*)vmemchr(a, 0, 0x7FFFFFFF) - a) + 1; nargs++; } - ssize = BY2WD*(nargs+1) + ((nbytes+(BY2WD-1)) & ~(BY2WD-1)); + ssize = nBY2WD*(nargs+1) + ((nbytes+(nBY2WD-1)) & ~(nBY2WD-1)); /* - * 8-byte align SP for those (e.g. sparc) that need it. - * execregs() will subtract another 4 bytes for argc. + * 16-byte align SP for the strictest requirement (arm64) + * execregs() will subtract another 4 or 8 bytes for argc. */ - if((ssize+4) & 7) - ssize += 4; + if(((ssize+nBY2WD) & 15) != 0) + ssize += 16 - nBY2WD; spage = (ssize+(BY2PG-1)) >> PGSHIFT; /* @@ -355,12 +435,23 @@ /* * Args: pass 2: assemble; the pages will be faulted in */ - tos = (Tos*)(TSTKTOP - sizeof(Tos)); - tos->cyclefreq = m->cyclefreq; - cycles((uvlong*)&tos->pcycles); - tos->pcycles = -tos->pcycles; - tos->kcycles = tos->pcycles; - tos->clock = 0; + if(!compat32){ + Tos *tos; + tos = (Tos*)(TSTKTOP - sizeof(Tos)); + tos->cyclefreq = m->cyclefreq; + cycles((uvlong*)&tos->pcycles); + tos->pcycles = -tos->pcycles; + tos->kcycles = tos->pcycles; + tos->clock = 0; + }else{ + Tos32 *tos; + tos = (Tos32*)(TSTKTOP - sizeof(Tos32)); + tos->cyclefreq = m->cyclefreq; + cycles((uvlong*)&tos->pcycles); + tos->pcycles = -tos->pcycles; + tos->kcycles = tos->pcycles; + tos->clock = 0; + } argv = (char**)(TSTKTOP - ssize); charp = (char*)(TSTKTOP - nbytes); args = charp; @@ -374,9 +465,16 @@ indir = 0; argp = (char**)arg[1]; } - *argv++ = charp + (USTKTOP-TSTKTOP); - n = strlen(*argp) + 1; - memmove(charp, *argp++, n); + putptr(argv, (uintptr)(charp + (USTKTOP-TSTKTOP))); + argv = (char**)((uintptr)argv + nBY2WD); + if(indir){ + n = strlen(*argp) + 1; + memmove(charp, *argp++, n); + }else{ + n = strlen(getptr(argp)) + 1; + memmove(charp, getptr(argp), n); + argp = (char**)((uintptr)argp + oBY2WD); + } charp += n; } free(file0); @@ -426,12 +524,15 @@ /* Text. Shared. Attaches to cache image if possible */ /* attachimage returns a locked cache image */ - img = attachimage(SG_TEXT|SG_RONLY, tc, UTZERO, (t-UTZERO)>>PGSHIFT); + if(compat32) + img = attachimage(SG_TEXT|SG_RONLY, tc, UTZERO_COMPAT32, (t-UTZERO_COMPAT32)>>PGSHIFT); + else + img = attachimage(SG_TEXT|SG_RONLY, tc, UTZERO, (t-UTZERO)>>PGSHIFT); ts = img->s; up->seg[TSEG] = ts; ts->flushme = 1; ts->fstart = 0; - ts->flen = sizeof(Exec)+text; + ts->flen = execsize+text; unlock(img); /* Data. Shared. */ @@ -480,6 +581,7 @@ up->notify = 0; up->notified = 0; up->privatemem = 0; + up->compat32 = compat32; procsetup(up); qunlock(&up->debug); if(up->hang) @@ -492,7 +594,7 @@ for(i=0; i<=f->maxfd; i++) fdclose(i, CCEXEC); - return execregs(entry, ssize, nargs); + return (ulong)execregs(entry, ssize, nargs); } int @@ -532,8 +634,8 @@ return 0; } -long -syssleep(ulong *arg) +uintptr +syssleep(uintptr *arg) { int n; @@ -552,14 +654,14 @@ return 0; } -long -sysalarm(ulong *arg) +uintptr +sysalarm(uintptr *arg) { return procalarm(arg[0]); } -long -sysexits(ulong *arg) +uintptr +sysexits(uintptr *arg) { char *status; char *inval = "invalid exit string"; @@ -570,7 +672,7 @@ if(waserror()) status = inval; else{ - validaddr((ulong)status, 1, 0); + validaddr((uintptr)status, 1, 0); if(vmemchr(status, 0, ERRMAX) == 0){ memmove(buf, status, ERRMAX); buf[ERRMAX-1] = 0; @@ -584,8 +686,8 @@ return 0; /* not reached */ } -long -sys_wait(ulong *arg) +uintptr +sys_wait(uintptr *arg) { int pid; Waitmsg w; @@ -609,8 +711,8 @@ return pid; } -long -sysawait(ulong *arg) +uintptr +sysawait(uintptr *arg) { int i; int pid; @@ -650,7 +752,7 @@ if(nbuf == 0) error(Ebadarg); - validaddr((ulong)buf, nbuf, 1); + validaddr((uintptr)buf, nbuf, 1); if(nbuf > sizeof tmp) nbuf = sizeof tmp; memmove(tmp, buf, nbuf); @@ -663,21 +765,21 @@ return 0; } -long -syserrstr(ulong *arg) +uintptr +syserrstr(uintptr *arg) { return generrstr((char*)arg[0], arg[1]); } /* compatibility for old binaries */ -long -sys_errstr(ulong *arg) +uintptr +sys_errstr(uintptr *arg) { return generrstr((char*)arg[0], 64); } -long -sysnotify(ulong *arg) +uintptr +sysnotify(uintptr *arg) { if(arg[0] != 0) validaddr(arg[0], sizeof(ulong), 0); @@ -685,16 +787,16 @@ return 0; } -long -sysnoted(ulong *arg) +uintptr +sysnoted(uintptr *arg) { if(arg[0]!=NRSTR && !up->notified) error(Egreg); return 0; } -long -syssegbrk(ulong *arg) +uintptr +syssegbrk(uintptr *arg) { int i; ulong addr; @@ -719,14 +821,14 @@ return 0; /* not reached */ } -long -syssegattach(ulong *arg) +uintptr +syssegattach(uintptr *arg) { return segattach(up, arg[0], (char*)arg[1], arg[2], arg[3]); } -long -syssegdetach(ulong *arg) +uintptr +syssegdetach(uintptr *arg) { int i; ulong addr; @@ -770,8 +872,8 @@ return 0; } -long -syssegfree(ulong *arg) +uintptr +syssegfree(uintptr *arg) { Segment *s; ulong from, to; @@ -796,14 +898,16 @@ } /* For binary compatibility */ -long -sysbrk_(ulong *arg) +uintptr +sysbrk_(uintptr *arg) { + if(arg[0] != (ulong)arg[0]) + error(Enovmem); return ibrk(arg[0], BSEG); } -long -sysrendezvous(ulong *arg) +uintptr +sysrendezvous(uintptr *arg) { uintptr tag, val; Proc *p, **l; @@ -1079,8 +1183,8 @@ return 1; } -long -syssemacquire(ulong *arg) +uintptr +syssemacquire(uintptr *arg) { int block; long *addr; @@ -1091,15 +1195,15 @@ addr = (long*)arg[0]; block = arg[1]; - if((s = seg(up, (ulong)addr, 0)) == nil) + if((s = seg(up, (uintptr)addr, 0)) == nil) error(Ebadarg); if(*addr < 0) error(Ebadarg); return semacquire(s, addr, block); } -long -systsemacquire(ulong *arg) +uintptr +systsemacquire(uintptr *arg) { long *addr; ulong ms; @@ -1110,15 +1214,15 @@ addr = (long*)arg[0]; ms = arg[1]; - if((s = seg(up, (ulong)addr, 0)) == nil) + if((s = seg(up, (uintptr)addr, 0)) == nil) error(Ebadarg); if(*addr < 0) error(Ebadarg); return tsemacquire(s, addr, ms); } -long -syssemrelease(ulong *arg) +uintptr +syssemrelease(uintptr *arg) { long *addr, delta; Segment *s; @@ -1128,7 +1232,7 @@ addr = (long*)arg[0]; delta = arg[1]; - if((s = seg(up, (ulong)addr, 0)) == nil) + if((s = seg(up, (uintptr)addr, 0)) == nil) error(Ebadarg); /* delta == 0 is a no-op, not a release */ if(delta < 0 || *addr < 0) @@ -1136,8 +1240,8 @@ return semrelease(s, addr, delta); } -long -sysnsec(ulong *arg) +uintptr +sysnsec(uintptr *arg) { validaddr(arg[0], sizeof(vlong), 1); validalign(arg[0], sizeof(vlong)); --- a/sys/src/9/port/systab.h Wed Apr 8 17:18:17 2026 +++ b/sys/src/9/port/systab.h Sun Feb 8 16:30:10 2026 @@ -1,6 +1,6 @@ #include "/sys/src/libc/9syscall/sys.h" -typedef long Syscall(ulong*); +typedef uintptr Syscall(uintptr*); Syscall sysr1; Syscall sys_errstr; --- a/sys/src/9/port/taslock.c Wed Apr 8 17:18:17 2026 +++ b/sys/src/9/port/taslock.c Sun Feb 8 11:51:52 2026 @@ -51,12 +51,12 @@ } void -lockloop(Lock *l, ulong pc) +lockloop(Lock *l, uintptr pc) { Proc *p; p = l->p; - print("lock %#p loop key %#lux pc %#lux held by pc %#lux proc %lud\n", + print("lock %#p loop key %#lux pc %#p held by pc %#p proc %lud\n", l, l->key, pc, l->pc, p ? p->pid : 0); dumpaproc(up); if(p != nil) @@ -67,7 +67,7 @@ lock(Lock *l) { int i; - ulong pc; + uintptr pc; pc = getcallerpc(&l); @@ -98,7 +98,7 @@ * Priority inversion, yield on a uniprocessor; on a * multiprocessor, the other processor will unlock */ - print("inversion %#p pc %#lux proc %lud held by pc %#lux proc %lud\n", + print("inversion %#p pc %#p proc %lud held by pc %#p proc %lud\n", l, pc, up ? up->pid : 0, l->pc, l->p ? l->p->pid : 0); up->edf->d = todget(nil); /* yield to process with lock */ } @@ -129,7 +129,7 @@ ilock(Lock *l) { ulong x; - ulong pc; + uintptr pc; pc = getcallerpc(&l); lockstats.locks++; @@ -203,9 +203,9 @@ if(l->key == 0) print("unlock: not locked: pc %#p\n", getcallerpc(&l)); if(l->isilock) - print("unlock of ilock: pc %lux, held by %lux\n", getcallerpc(&l), l->pc); + print("unlock of ilock: pc %p, held by %p\n", getcallerpc(&l), l->pc); if(l->p != up) - print("unlock: up changed: pc %#p, acquired at pc %lux, lock p %#p, unlock up %#p\n", getcallerpc(&l), l->pc, l->p, up); + print("unlock: up changed: pc %#p, acquired at pc %p, lock p %#p, unlock up %#p\n", getcallerpc(&l), l->pc, l->p, up); l->m = nil; coherence(); l->key = 0; @@ -241,9 +241,9 @@ if(l->key == 0) print("iunlock: not locked: pc %#p\n", getcallerpc(&l)); if(!l->isilock) - print("iunlock of lock: pc %#p, held by %#lux\n", getcallerpc(&l), l->pc); + print("iunlock of lock: pc %#p, held by %#p\n", getcallerpc(&l), l->pc); if(islo()) - print("iunlock while lo: pc %#p, held by %#lux\n", getcallerpc(&l), l->pc); + print("iunlock while lo: pc %#p, held by %#p\n", getcallerpc(&l), l->pc); sr = l->sr; l->m = nil; --- a/sys/src/9/port/xalloc.c Wed Apr 8 17:18:17 2026 +++ b/sys/src/9/port/xalloc.c Sun Feb 8 11:10:51 2026 @@ -68,8 +68,8 @@ n = maxpages; /* first give to kernel */ if(n > 0){ - m->kbase = (ulong)KADDR(m->base); - m->klimit = (ulong)KADDR(m->base+n*BY2PG); + m->kbase = (ulong)(uintptr)KADDR(m->base); + m->klimit = (ulong)(uintptr)KADDR(m->base+n*BY2PG); xhole(m->base, n*BY2PG); kpages -= n; } @@ -90,8 +90,8 @@ void* xspanalloc(ulong size, int align, ulong span) { - ulong a, v, t; - a = (ulong)xalloc(size+align+span); + uintptr a, v, t; + a = (uintptr)xalloc(size+align+span); if(a == 0) panic("xspanalloc: %lud %d %lux", size, align, span); @@ -159,7 +159,7 @@ { Xhdr *x; - x = (Xhdr*)((ulong)p - offsetof(Xhdr, data[0])); + x = (Xhdr*)((uintptr)p - offsetof(Xhdr, data[0])); if(x->magix != Magichole) { xsummary(); panic("xfree(%#p) %#ux != %#lux", p, Magichole, x->magix); @@ -172,8 +172,8 @@ { Xhdr *p, *q; - p = (Xhdr*)(((ulong)vp - offsetof(Xhdr, data[0]))); - q = (Xhdr*)(((ulong)vq - offsetof(Xhdr, data[0]))); + p = (Xhdr*)(((uintptr)vp - offsetof(Xhdr, data[0]))); + q = (Xhdr*)(((uintptr)vq - offsetof(Xhdr, data[0]))); if(p->magix != Magichole || q->magix != Magichole) { int i; ulong *wd; --- a/sys/src/9/ip/ptclbsum.c Tue May 28 13:14:59 2002 +++ b/sys/src/9/ip/ptclbsum.c Sun Sep 28 09:56:43 2025 @@ -21,7 +21,7 @@ mdsum = 0; x = 0; - if((ulong)addr & 1) { + if((uintptr)addr & 1) { if(len) { hisum += addr[0]; len--; --- a/sys/src/9/port/tos32.h Sun Mar 9 14:48:16 2025 +++ b/sys/src/9/port/tos32.h Sun Jan 4 21:39:04 2026 @@ -0,0 +1,22 @@ +typedef struct Tos32 Tos32; +typedef struct Plink Plink; + +struct Tos32 { + struct /* Per process profiling */ + { + ulong pp; /* known to be 0(ptr) */ + ulong next; /* known to be 4(ptr) */ + ulong last; + ulong first; + ulong pid; + ulong what; + } prof; + uvlong cyclefreq; /* cycle clock frequency if there is one, 0 otherwise */ + vlong kcycles; /* cycles spent in kernel */ + vlong pcycles; /* cycles spent in process (kernel + user) */ + ulong pid; /* might as well put the pid here */ + ulong clock; + /* scratch space for kernel use (e.g., mips fp delay-slot execution) */ + ulong kscr[4]; + /* top of stack is here */ +};