From e89e8a1559693b91fd201d2a0368a8561c1473b7 Mon Sep 17 00:00:00 2001 From: Valery Ushakov Date: Tue, 29 Dec 2020 20:10:33 +0300 Subject: NetBSD/arm: initial support This is more or less mechanical merge of existing NetBSD code and ARM-specific bits from Linux/arm files. --- NetBSD/arm/include/emu.h | 22 ++ NetBSD/arm/include/lib9.h | 515 ++++++++++++++++++++++++++++++++++++++++++ emu/NetBSD/asm-arm.S | 78 +++++++ emu/NetBSD/segflush-arm.c | 16 ++ lib9/getcallerpc-NetBSD-arm.S | 1 + lib9/setfcr-NetBSD-arm.S | 38 ++++ mkfiles/mkfile-NetBSD-arm | 30 +++ 7 files changed, 700 insertions(+) create mode 100644 NetBSD/arm/include/emu.h create mode 100644 NetBSD/arm/include/lib9.h create mode 100644 emu/NetBSD/asm-arm.S create mode 100644 emu/NetBSD/segflush-arm.c create mode 100644 lib9/getcallerpc-NetBSD-arm.S create mode 100644 lib9/setfcr-NetBSD-arm.S create mode 100644 mkfiles/mkfile-NetBSD-arm diff --git a/NetBSD/arm/include/emu.h b/NetBSD/arm/include/emu.h new file mode 100644 index 00000000..07e3fad7 --- /dev/null +++ b/NetBSD/arm/include/emu.h @@ -0,0 +1,22 @@ +/* + * system- and machine-specific declarations for emu: + * floating-point save and restore, signal handling primitive, and + * implementation of the current-process variable `up'. + */ + +/* + * This structure must agree with FPsave and FPrestore asm routines + */ +typedef struct FPU FPU; +struct FPU +{ + uchar env[28]; +}; + +#define KSTACK (32 * 1024) + +extern Proc* getup(void); +#define up (getup()) + +typedef sigjmp_buf osjmpbuf; +#define ossetjmp(buf) sigsetjmp(buf, 1) diff --git a/NetBSD/arm/include/lib9.h b/NetBSD/arm/include/lib9.h new file mode 100644 index 00000000..8c7fb817 --- /dev/null +++ b/NetBSD/arm/include/lib9.h @@ -0,0 +1,515 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define getwd infgetwd + +#define round infround +#define fmax inffmax +#define log2 inflog2 + +#ifndef EMU +typedef struct Proc Proc; +#endif + +/* + * math module dtoa + */ +#if _BYTE_ORDER == _LITTLE_ENDIAN +#define __LITTLE_ENDIAN +#endif + +#define nil ((void*)0) + +typedef unsigned char uchar; +typedef signed char schar; +#if 0 /* XXX: uwe: already defined in */ +typedef unsigned long ulong; +#endif + +typedef int64_t vlong; +typedef uint64_t uvlong; + +typedef uint8_t u8int; +typedef uint16_t u16int; +typedef uint32_t u32int; +typedef uvlong u64int; + +typedef uintptr_t uintptr; + +typedef signed char int8; +typedef unsigned char uint8; +typedef short int16; +typedef unsigned short uint16; +typedef int int32; +typedef unsigned int uint32; +typedef long long int64; +typedef unsigned long long uint64; + +typedef unsigned int Rune; +typedef unsigned int mpdigit; /* for /sys/include/mp.h */ + + +#define USED(x) if(x){}else{} +#define SET(x) + +#undef nelem +#define nelem(x) (sizeof(x)/sizeof((x)[0])) +#undef offsetof +#define offsetof(s, m) (ulong)(&(((s*)0)->m)) +#undef assert +#define assert(x) if(x){}else _assert(#x) + +/* + * most mem and string routines are declared by ANSI/POSIX files above + */ + +extern char* strecpy(char*, char*, char*); +extern char* strdup(const char*); +extern int cistrncmp(char*, char*, int); +extern int cistrcmp(char*, char*); +extern char* cistrstr(char*, char*); +extern int tokenize(char*, char**, int); + +enum +{ + UTFmax = 4, /* maximum bytes per rune */ + Runesync = 0x80, /* cannot represent part of a UTF sequence (<) */ + Runeself = 0x80, /* rune and UTF sequences are the same (<) */ + Runeerror = 0xFFFD, /* decoding error in UTF */ + Runemax = 0x10FFFF, /* 21-bit rune */ + Runemask = 0x1FFFFF, /* bits used by runes (see grep) */ +}; + +/* + * rune routines + */ +extern int runetochar(char*, Rune*); +extern int chartorune(Rune*, char*); +extern int runelen(long); +extern int runenlen(Rune*, int); +extern int fullrune(char*, int); +extern int utflen(char*); +extern int utfnlen(char*, long); +extern char* utfrune(char*, long); +extern char* utfrrune(char*, long); +extern char* utfutf(char*, char*); +extern char* utfecpy(char*, char*, char*); + +extern Rune* runestrcat(Rune*, Rune*); +extern Rune* runestrchr(Rune*, Rune); +extern int runestrcmp(Rune*, Rune*); +extern Rune* runestrcpy(Rune*, Rune*); +extern Rune* runestrncpy(Rune*, Rune*, long); +extern Rune* runestrecpy(Rune*, Rune*, Rune*); +extern Rune* runestrdup(Rune*); +extern Rune* runestrncat(Rune*, Rune*, long); +extern int runestrncmp(Rune*, Rune*, long); +extern Rune* runestrrchr(Rune*, Rune); +extern long runestrlen(Rune*); +extern Rune* runestrstr(Rune*, Rune*); + +extern Rune tolowerrune(Rune); +extern Rune totitlerune(Rune); +extern Rune toupperrune(Rune); +extern int isalpharune(Rune); +extern int islowerrune(Rune); +extern int isspacerune(Rune); +extern int istitlerune(Rune); +extern int isupperrune(Rune); + +/* + * malloc + */ +extern void* malloc(size_t); +extern void* mallocz(ulong, int); +extern void free(void*); +extern ulong msize(void*); +extern void* calloc(size_t, size_t); +extern void* realloc(void*, size_t); +extern void setmalloctag(void*, ulong); +extern void setrealloctag(void*, ulong); +extern ulong getmalloctag(void*); +extern ulong getrealloctag(void*); +extern void* malloctopoolblock(void*); + +/* + * print routines + */ +typedef struct Fmt Fmt; +struct Fmt{ + uchar runes; /* output buffer is runes or chars? */ + void *start; /* of buffer */ + void *to; /* current place in the buffer */ + void *stop; /* end of the buffer; overwritten if flush fails */ + int (*flush)(Fmt *); /* called when to == stop */ + void *farg; /* to make flush a closure */ + int nfmt; /* num chars formatted so far */ + va_list args; /* args passed to dofmt */ + int r; /* % format Rune */ + int width; + int prec; + ulong flags; +}; + +enum{ + FmtWidth = 1, + FmtLeft = FmtWidth << 1, + FmtPrec = FmtLeft << 1, + FmtSharp = FmtPrec << 1, + FmtSpace = FmtSharp << 1, + FmtSign = FmtSpace << 1, + FmtZero = FmtSign << 1, + FmtUnsigned = FmtZero << 1, + FmtShort = FmtUnsigned << 1, + FmtLong = FmtShort << 1, + FmtVLong = FmtLong << 1, + FmtComma = FmtVLong << 1, + FmtByte = FmtComma << 1, + + FmtFlag = FmtByte << 1 +}; + +extern int print(char*, ...); +extern char* seprint(char*, char*, char*, ...); +extern char* vseprint(char*, char*, char*, va_list); +extern int snprint(char*, int, char*, ...); +extern int vsnprint(char*, int, char*, va_list); +extern char* smprint(char*, ...); +extern char* vsmprint(char*, va_list); +extern int sprint(char*, char*, ...); +extern int fprint(int, char*, ...); +extern int vfprint(int, char*, va_list); + +extern int runesprint(Rune*, char*, ...); +extern int runesnprint(Rune*, int, char*, ...); +extern int runevsnprint(Rune*, int, char*, va_list); +extern Rune* runeseprint(Rune*, Rune*, char*, ...); +extern Rune* runevseprint(Rune*, Rune*, char*, va_list); +extern Rune* runesmprint(char*, ...); +extern Rune* runevsmprint(char*, va_list); + +extern int fmtfdinit(Fmt*, int, char*, int); +extern int fmtfdflush(Fmt*); +extern int fmtstrinit(Fmt*); +extern char* fmtstrflush(Fmt*); +extern int runefmtstrinit(Fmt*); +extern Rune* runefmtstrflush(Fmt*); + +extern int fmtinstall(int, int (*)(Fmt*)); +extern int dofmt(Fmt*, char*); +extern int dorfmt(Fmt*, Rune*); +extern int fmtprint(Fmt*, char*, ...); +extern int fmtvprint(Fmt*, char*, va_list); +extern int fmtrune(Fmt*, int); +extern int fmtstrcpy(Fmt*, char*); +extern int fmtrunestrcpy(Fmt*, Rune*); +/* + * error string for %r + * supplied on per os basis, not part of fmt library + */ +extern int errfmt(Fmt *f); + +/* + * quoted strings + */ +extern char *unquotestrdup(char*); +extern Rune *unquoterunestrdup(Rune*); +extern char *quotestrdup(char*); +extern Rune *quoterunestrdup(Rune*); +extern int quotestrfmt(Fmt*); +extern int quoterunestrfmt(Fmt*); +extern void quotefmtinstall(void); +extern int (*doquote)(int); + +/* + * random number + */ +extern int nrand(int); +extern ulong truerand(void); +extern ulong ntruerand(ulong); + +/* + * math + */ +extern int isNaN(double); +extern double NaN(void); +extern int isInf(double, int); +extern double pow(double, double); + +/* + * Time-of-day + */ + +typedef struct Tm Tm; +struct Tm { + int sec; + int min; + int hour; + int mday; + int mon; + int year; + int wday; + int yday; + char zone[4]; + int tzoff; +}; +extern vlong osnsec(void); +#define nsec osnsec + +/* + * one-of-a-kind + */ +extern void _assert(char*); +extern double charstod(int(*)(void*), void*); +extern char* cleanname(char*); +extern double frexp(double, int*); +// extern ulong getcallerpc(void*); +extern int getfields(char*, char**, int, int, char*); +extern char* getuser(void); +extern char* getwd(char*, int); +extern double ipow10(int); +extern double ldexp(double, int); +extern double modf(double, double*); +#define pow10 infpow10 +extern double pow10(int); +extern vlong strtoll(const char*, char**, int); +#define qsort infqsort +extern void qsort(void*, long, long, int (*)(void*, void*)); +extern uvlong strtoull(const char*, char**, int); +extern void sysfatal(char*, ...); +extern int dec64(uchar*, int, char*, int); +extern int enc64(char*, int, uchar*, int); +extern int dec32(uchar*, int, char*, int); +extern int enc32(char*, int, uchar*, int); +extern int dec16(uchar*, int, char*, int); +extern int enc16(char*, int, uchar*, int); +extern int encodefmt(Fmt*); + +/* + * synchronization + */ +typedef +struct Lock { + int val; + int pid; +} Lock; + +extern int _tas(int*); + +extern void lock(Lock*); +extern void unlock(Lock*); +extern int canlock(Lock*); + +typedef struct QLock QLock; +struct QLock +{ + Lock use; /* to access Qlock structure */ + Proc *head; /* next process waiting for object */ + Proc *tail; /* last process waiting for object */ + int locked; /* flag */ +}; + +extern void qlock(QLock*); +extern void qunlock(QLock*); +extern int canqlock(QLock*); +extern void _qlockinit(ulong (*)(ulong, ulong)); /* called only by the thread library */ + +typedef +struct RWLock +{ + Lock l; /* Lock modify lock */ + QLock x; /* Mutual exclusion lock */ + QLock k; /* Lock for waiting writers */ + int readers; /* Count of readers in lock */ +} RWLock; + +extern int canrlock(RWLock*); +extern int canwlock(RWLock*); +extern void rlock(RWLock*); +extern void runlock(RWLock*); +extern void wlock(RWLock*); +extern void wunlock(RWLock*); + +/* + * network dialing + */ +#define NETPATHLEN 40 + +/* + * system calls + * + */ +#define STATMAX 65535U /* max length of machine-independent stat structure */ +#define DIRMAX (sizeof(Dir)+STATMAX) /* max length of Dir structure */ +#define ERRMAX 128 /* max length of error string */ + +#define MORDER 0x0003 /* mask for bits defining order of mounting */ +#define MREPL 0x0000 /* mount replaces object */ +#define MBEFORE 0x0001 /* mount goes before others in union directory */ +#define MAFTER 0x0002 /* mount goes after others in union directory */ +#define MCREATE 0x0004 /* permit creation in mounted directory */ +#define MCACHE 0x0010 /* cache some data */ +#define MMASK 0x0017 /* all bits on */ + +#define OREAD 0 /* open for read */ +#define OWRITE 1 /* write */ +#define ORDWR 2 /* read and write */ +#define OEXEC 3 /* execute, == read but check execute permission */ +#define OTRUNC 16 /* or'ed in (except for exec), truncate file first */ +#define OCEXEC 32 /* or'ed in, close on exec */ +#define ORCLOSE 64 /* or'ed in, remove on close */ +#define OEXCL 0x1000 /* or'ed in, exclusive use (create only) */ + +#define AEXIST 0 /* accessible: exists */ +#define AEXEC 1 /* execute access */ +#define AWRITE 2 /* write access */ +#define AREAD 4 /* read access */ + +/* bits in Qid.type */ +#define QTDIR 0x80 /* type bit for directories */ +#define QTAPPEND 0x40 /* type bit for append only files */ +#define QTEXCL 0x20 /* type bit for exclusive use files */ +#define QTMOUNT 0x10 /* type bit for mounted channel */ +#define QTAUTH 0x08 /* type bit for authentication file */ +#define QTFILE 0x00 /* plain file */ + +/* bits in Dir.mode */ +#define DMDIR 0x80000000 /* mode bit for directories */ +#define DMAPPEND 0x40000000 /* mode bit for append only files */ +#define DMEXCL 0x20000000 /* mode bit for exclusive use files */ +#define DMMOUNT 0x10000000 /* mode bit for mounted channel */ +#define DMAUTH 0x08000000 /* mode bit for authentication file */ +#define DMREAD 0x4 /* mode bit for read permission */ +#define DMWRITE 0x2 /* mode bit for write permission */ +#define DMEXEC 0x1 /* mode bit for execute permission */ + +typedef +struct Qid +{ + uvlong path; + ulong vers; + uchar type; +} Qid; + +typedef +struct Dir { + /* system-modified data */ + ushort type; /* server type */ + uint dev; /* server subtype */ + /* file data */ + Qid qid; /* unique id from server */ + ulong mode; /* permissions */ + ulong atime; /* last read time */ + ulong mtime; /* last write time */ + vlong length; /* file length */ + char *name; /* last element of path */ + char *uid; /* owner name */ + char *gid; /* group name */ + char *muid; /* last modifier name */ +} Dir; + +extern Dir* dirstat(char*); +extern Dir* dirfstat(int); +extern int dirwstat(char*, Dir*); +extern int dirfwstat(int, Dir*); +extern long dirread(int, Dir**); +extern void nulldir(Dir*); +extern long dirreadall(int, Dir**); + +typedef +struct Waitmsg +{ + int pid; /* of loved one */ + ulong time[3]; /* of loved one & descendants */ + char *msg; +} Waitmsg; + +extern void _exits(char*); + +extern void exits(char*); +extern int create(char*, int, int); +extern int errstr(char*, uint); + +extern void perror(const char*); +extern long readn(int, void*, long); +extern int remove(const char*); +extern void rerrstr(char*, uint); +extern vlong seek(int, vlong, int); +extern int segflush(void*, ulong); +extern void werrstr(char*, ...); + +extern char *argv0; +#define ARGBEGIN for((argv0||(argv0=*argv)),argv++,argc--;\ + argv[0] && argv[0][0]=='-' && argv[0][1];\ + argc--, argv++) {\ + char *_args, *_argt;\ + Rune _argc;\ + _args = &argv[0][1];\ + if(_args[0]=='-' && _args[1]==0){\ + argc--; argv++; break;\ + }\ + _argc = 0;\ + while(*_args && (_args += chartorune(&_argc, _args)))\ + switch(_argc) +#define ARGEND SET(_argt);USED(_argt);USED(_argc); USED(_args);}USED(argv); USED(argc); +#define ARGF() (_argt=_args, _args="",\ + (*_argt? _argt: argv[1]? (argc--, *++argv): 0)) +#define EARGF(x) (_argt=_args, _args="",\ + (*_argt? _argt: argv[1]? (argc--, *++argv): ((x), abort(), (char*)0))) + +#define ARGC() _argc + +/* + * Extensions for Inferno to basic libc.h + */ + +#define setbinmode() + +/* need the inline because the link register is not saved in a known location */ +static __inline uintptr getcallerpc(void* dummy) { + ulong lr; + __asm__( "mov %0, %%lr;" + : "=r" (lr) + ); + return lr; +} + + +/* FCR */ +#define FPINEX (1<<5) +#define FPUNFL ((1<<4)|(1<<1)) +#define FPOVFL (1<<3) +#define FPZDIV (1<<2) +#define FPINVAL (1<<0) +#define FPRNR (0<<10) +#define FPRZ (3<<10) +#define FPRPINF (2<<10) +#define FPRNINF (1<<10) +#define FPRMASK (3<<10) +#define FPPEXT (3<<8) +#define FPPSGL (0<<8) +#define FPPDBL (2<<8) +#define FPPMASK (3<<8) +/* FSR */ +#define FPAINEX FPINEX +#define FPAOVFL FPOVFL +#define FPAUNFL FPUNFL +#define FPAZDIV FPZDIV +#define FPAINVAL FPINVAL + +extern void setfcr(ulong); +extern void setfsr(ulong); +extern ulong getfcr(void); +extern ulong getfsr(void); diff --git a/emu/NetBSD/asm-arm.S b/emu/NetBSD/asm-arm.S new file mode 100644 index 00000000..02e37396 --- /dev/null +++ b/emu/NetBSD/asm-arm.S @@ -0,0 +1,78 @@ +#include + +/* + * ulong _tas(ulong*); + */ +#if __ARM_ARCH >= 6 + +#if __ARM_ARCH >= 7 +#define DMB dmb +#else +#define DMB mcr p15, 0, r0, c7, c10, 5 +#endif + +ENTRY(_tas) + @ args = 0, pretend = 0, frame = 0 + @ frame_needed = 0, uses_anonymous_args = 0 + @ link register save eliminated. + @ lr needed for prologue + DMB + mov r1, r0 + mov r2, #0xaa +tas1: + ldrex r0, [r1] + cmp r0, #0 + bne lockbusy + strex r3, r2, [r1] + cmp r3, #0 + bne tas1 + DMB + bx lr +lockbusy: + clrex + bx lr + END(_tas) + +#else /* __ARM_ARCH <= 5*/ + +ENTRY(_tas) + @ args = 0, pretend = 0, frame = 0 + @ frame_needed = 0, uses_anonymous_args = 0 + @ link register save eliminated. + @ lr needed for prologue + mov r3, #1 + mov r1, r0 + swp r0, r3, [r1] + bx lr + END(_tas) + +#endif /* __ARM_ARCH <= 5*/ + + +/* + * void FPsave(void *); + */ +ENTRY(FPsave) + @ args = 0, pretend = 0, frame = 4 + @ frame_needed = 1, uses_anonymous_args = 0 + mov ip, sp + stmfd sp!, {fp, ip, lr, pc} + sub fp, ip, #4 + sub sp, sp, #4 + str r0, [fp, #-16] + ldmea fp, {fp, sp, pc} + END(FPsave) + +/* + * void FPrestore(void *); + */ +ENTRY(FPrestore) + @ args = 0, pretend = 0, frame = 4 + @ frame_needed = 1, uses_anonymous_args = 0 + mov ip, sp + stmfd sp!, {fp, ip, lr, pc} + sub fp, ip, #4 + sub sp, sp, #4 + str r0, [fp, #-16] + ldmea fp, {fp, sp, pc} + END(FPrestore) diff --git a/emu/NetBSD/segflush-arm.c b/emu/NetBSD/segflush-arm.c new file mode 100644 index 00000000..f4529633 --- /dev/null +++ b/emu/NetBSD/segflush-arm.c @@ -0,0 +1,16 @@ +#include +#include + +#include "dat.h" + + +int +segflush(void *a, ulong n) +{ + struct arm_sync_icache_args args; + + args.addr = (uintptr_t)a; + args.len = (size_t)n; + sysarch(ARM_SYNC_ICACHE, (void *)&args); + return 0; +} diff --git a/lib9/getcallerpc-NetBSD-arm.S b/lib9/getcallerpc-NetBSD-arm.S new file mode 100644 index 00000000..2b2e74b1 --- /dev/null +++ b/lib9/getcallerpc-NetBSD-arm.S @@ -0,0 +1 @@ +/* getcallerpc for NetBSD/arm is placed in lib9.h as inline function*/ diff --git a/lib9/setfcr-NetBSD-arm.S b/lib9/setfcr-NetBSD-arm.S new file mode 100644 index 00000000..61afd843 --- /dev/null +++ b/lib9/setfcr-NetBSD-arm.S @@ -0,0 +1,38 @@ +#include + +#define ENT +#define RET bx lr + +#ifdef USEVFP + .fpu vfp +#define VMSR(f,r) vmsr f,r +#define VMRS(r,f) vmrs r,f +#else + .fpu softvfp +#define VMSR(f,r) +#define VMRS(r,f) +#endif + +ENTRY_NP(setfcr) + ENT + VMSR(fpscr, r0) + RET + END(setfcr) + +ENTRY_NP(getfcr) + ENT + VMRS(r0, fpscr) + RET + END(getfcr) + +ENTRY_NP(getfsr) + ENT + VMRS(r0, fpscr) + RET + END(getfsr) + +ENTRY_NP(setfsr) + ENT + VMSR(fpscr, r0) + RET + END(setfsr) diff --git a/mkfiles/mkfile-NetBSD-arm b/mkfiles/mkfile-NetBSD-arm new file mode 100644 index 00000000..a022c05b --- /dev/null +++ b/mkfiles/mkfile-NetBSD-arm @@ -0,0 +1,30 @@ +TARGMODEL= Posix +TARGSHTYPE= sh +CPUS= arm + +O= o +OS= o + +AR= ar +ARFLAGS= ruvs + +AS= cc -c +ASFLAGS= + +CC= cc -c +CFLAGS= -g\ + -O\ + -fno-strict-aliasing\ + -Wno-deprecated-declarations -Wuninitialized -Wunused -Wreturn-type -Wimplicit\ + -I$ROOT/NetBSD/arm/include\ + -I$ROOT/include\ + -I/usr/X11R7/include + +ANSICPP= +LD= cc +LDFLAGS= + +SYSLIBS= + +YACC= iyacc +YFLAGS= -d -- cgit v1.2.3 From c5728686379484100b7d59abf4f0b47928b1631e Mon Sep 17 00:00:00 2001 From: Valery Ushakov Date: Tue, 29 Dec 2020 20:21:00 +0300 Subject: NetBSD/asm-arm.S: use .L for local labels. --- emu/NetBSD/asm-arm.S | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/emu/NetBSD/asm-arm.S b/emu/NetBSD/asm-arm.S index 02e37396..afaa5479 100644 --- a/emu/NetBSD/asm-arm.S +++ b/emu/NetBSD/asm-arm.S @@ -19,16 +19,16 @@ ENTRY(_tas) DMB mov r1, r0 mov r2, #0xaa -tas1: +.Loop: ldrex r0, [r1] cmp r0, #0 - bne lockbusy + bne .Lockbusy strex r3, r2, [r1] cmp r3, #0 - bne tas1 + bne .Loop DMB bx lr -lockbusy: +.Lockbusy: clrex bx lr END(_tas) -- cgit v1.2.3 From 8adc601ba8dfd68676fc702cd30075643967f2fd Mon Sep 17 00:00:00 2001 From: Valery Ushakov Date: Mon, 4 Jan 2021 02:42:43 +0300 Subject: NetBSD/arm: disable pax mprotect restrictions for emu ARM has separate read and execute protection bits so after writing out JIT code we need to make it executable with mprotect(2), but PAX wouldn't let us by default. Mark the emu binary so that this restriction is lifted. On other machines where this is not an issue set PAXCTL to a no-op. --- emu/NetBSD/mkfile | 1 + mkfiles/mkfile-NetBSD-386 | 2 ++ mkfiles/mkfile-NetBSD-arm | 3 +++ mkfiles/mkfile-NetBSD-power | 2 ++ 4 files changed, 8 insertions(+) diff --git a/emu/NetBSD/mkfile b/emu/NetBSD/mkfile index 17516997..6a9b6a5c 100644 --- a/emu/NetBSD/mkfile +++ b/emu/NetBSD/mkfile @@ -40,6 +40,7 @@ default:V: $O.$CONF $O.$CONF: $OBJ $CONF.c $CONF.root.h $LIBFILES $CC $CFLAGS '-DKERNDATE='$KERNDATE $CONF.c $LD $LDFLAGS -o $target $OBJ $CONF.$O $LIBFILES $SYSLIBS + $PAXCTL $target install:V: $O.$CONF cp $O.$CONF $INSTALLDIR/$CONF diff --git a/mkfiles/mkfile-NetBSD-386 b/mkfiles/mkfile-NetBSD-386 index 99ae6687..39e8ed5d 100644 --- a/mkfiles/mkfile-NetBSD-386 +++ b/mkfiles/mkfile-NetBSD-386 @@ -26,5 +26,7 @@ LDFLAGS= SYSLIBS= +PAXCTL= : + YACC= iyacc YFLAGS= -d diff --git a/mkfiles/mkfile-NetBSD-arm b/mkfiles/mkfile-NetBSD-arm index a022c05b..581bca9d 100644 --- a/mkfiles/mkfile-NetBSD-arm +++ b/mkfiles/mkfile-NetBSD-arm @@ -26,5 +26,8 @@ LDFLAGS= SYSLIBS= +# disable PaX mprotect(2) restrictions for JIT +PAXCTL= paxctl +m + YACC= iyacc YFLAGS= -d diff --git a/mkfiles/mkfile-NetBSD-power b/mkfiles/mkfile-NetBSD-power index 1ac7e58e..ae7f86c8 100644 --- a/mkfiles/mkfile-NetBSD-power +++ b/mkfiles/mkfile-NetBSD-power @@ -26,5 +26,7 @@ LDFLAGS= SYSLIBS= +PAXCTL= : + YACC= iyacc YFLAGS= -d -- cgit v1.2.3 From e273317811820976dda632b0893960646d6e1119 Mon Sep 17 00:00:00 2001 From: Valery Ushakov Date: Mon, 4 Jan 2021 03:00:19 +0300 Subject: NetBSD/arm: segflush - use mprotect to add PROT_EXEC ARM has separate read and execute protection bits so after writing out JIT code we need to make it executable. --- emu/NetBSD/segflush-arm.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/emu/NetBSD/segflush-arm.c b/emu/NetBSD/segflush-arm.c index f4529633..a03b438b 100644 --- a/emu/NetBSD/segflush-arm.c +++ b/emu/NetBSD/segflush-arm.c @@ -1,4 +1,5 @@ #include +#include #include #include "dat.h" @@ -9,6 +10,8 @@ segflush(void *a, ulong n) { struct arm_sync_icache_args args; + mprotect(a, (size_t)n, PROT_READ | PROT_WRITE | PROT_EXEC); + args.addr = (uintptr_t)a; args.len = (size_t)n; sysarch(ARM_SYNC_ICACHE, (void *)&args); -- cgit v1.2.3