Skip to content

Commit

Permalink
Merge remote-tracking branch 'osvm/Cog' into Issue3571
Browse files Browse the repository at this point in the history
  • Loading branch information
akgrant43 committed Feb 4, 2020
2 parents 021fc79 + bd898a7 commit 4868d1e
Show file tree
Hide file tree
Showing 28 changed files with 537 additions and 195 deletions.
2 changes: 1 addition & 1 deletion build.macos64x64/gdbarm64/conf.COG
Expand Up @@ -10,5 +10,5 @@ done
for d in sim/common sim/aarch64; do
(cd $d;
../$S/$d/configure COG=1 CFLAGS="$CFLAGS" $CONFFLAGS \
--disable-sim-trace --without-profile)
--disable-sim-trace)
done
20 changes: 19 additions & 1 deletion platforms/Cross/plugins/SqueakFFIPrims/sqFFITestFuncs.c
Expand Up @@ -51,7 +51,7 @@ typedef struct Si2 {int a,b;} ffiTestSi2;
typedef struct Ss2 {short a,b;} ffiTestSs2;
typedef struct Ssi {short a; int b;} ffiTestSsi;
typedef struct Sfi {float a; int b;} ffiTestSfi;
typedef struct Sfd {float a; double b} ffiTestSfd;
typedef struct Sfd {float a; double b;} ffiTestSfd;
typedef struct Sdi {double a; int b;} ffiTestSdi;
typedef struct Ssf {short a; float b;} ffiTestSsf;
typedef struct SsSsi {short a; struct Ssi b;} ffiTestSsSsi;
Expand All @@ -66,6 +66,13 @@ typedef struct Sf4 {float a,b,c,d;} ffiTestSf4;
typedef struct Ss4 {short a,b,c,d;} ffiTestSs4;
typedef struct SSdi5 {struct Sdi a,b,c,d,e;} ffiTestSSdi5; /* a structure longer than 8 eightBytes */

typedef union Ufi {float a; int b;} ffiTestUfi;
typedef union Ufd {float a; double b;} ffiTestUfd;
typedef union UdSi2 {double a; struct Si2 b;} ffiTestUdSi2;

typedef struct SUfdUfi {union Ufd a; union Ufi b;} ffiTestSUfdUfi;
typedef struct SUfdUdSi2 {union Ufd a; union UdSi2 b;} ffiTestSUfdUdSi2;

#pragma export on

EXPORT(ffiTestSd2) ffiTestInitSd2 (double a,double b) { ffiTestSd2 v = {a,b}; return v; }
Expand All @@ -90,6 +97,15 @@ EXPORT(ffiTestSf4) ffiTestInitSf4 (float a,float b, float c,float d)
EXPORT(ffiTestSs4) ffiTestInitSs4 (short a,short b, short c,short d) { ffiTestSs4 v = {a,b,c,d}; return v; }
EXPORT(ffiTestSSdi5)ffiTestInitSSdi5(struct Sdi a,struct Sdi b,struct Sdi c, struct Sdi d,struct Sdi e) { ffiTestSSdi5 v = {a,b,c,d,e}; return v; }

EXPORT(ffiTestUfi) ffiTestInitUfi_f(float a) { ffiTestUfi v; v.a=a; return v; }
EXPORT(ffiTestUfi) ffiTestInitUfi_i(int b) { ffiTestUfi v; v.b=b; return v; }
EXPORT(ffiTestUfd) ffiTestInitUfd_f(float a) { ffiTestUfd v; v.a=a; return v; }
EXPORT(ffiTestUfd) ffiTestInitUfd_d(double b) { ffiTestUfd v; v.b=b; return v; }
EXPORT(ffiTestUdSi2) ffiTestInitUdSi2_d(double a) { ffiTestUdSi2 v; v.a=a; return v; }
EXPORT(ffiTestUdSi2) ffiTestInitUdSi2_ii(int a,int b) { ffiTestUdSi2 v; v.b.a=a; v.b.b=b; return v; }
EXPORT(ffiTestSUfdUfi) ffiTestInitSUfdUfi (union Ufd a,union Ufi b) { ffiTestSUfdUfi v = {a,b}; return v; }
EXPORT(ffiTestSUfdUdSi2) ffiTestInitSUfdUdSi2 (union Ufd a,union UdSi2 b) { ffiTestSUfdUdSi2 v = {a,b}; return v; }

EXPORT(ffiTestSd2) ffiTestReturnSd2 () { return ffiTestInitSd2(1.0 ,2.0 ); }
EXPORT(ffiTestSf2) ffiTestReturnSf2 () { return ffiTestInitSf2(1.0f,2.0f); }
EXPORT(ffiTestSl2) ffiTestReturnSl2 () { return ffiTestInitSl2(1LL,2LL); }
Expand Down Expand Up @@ -131,6 +147,8 @@ EXPORT(double) ffiTestSumSslf(ffiTestSslf x) { return (double) x.a + (double) x.
EXPORT(double) ffiTestSumSslf_2(ffiTestSslf x,ffiTestSslf y) { return ffiTestSumSslf(x) + ffiTestSumSslf(y); }
EXPORT(double) ffiTestSumSslf_4(ffiTestSslf x,ffiTestSslf y,ffiTestSslf z,ffiTestSslf t) { return ffiTestSumSslf_2(x,y) + ffiTestSumSslf_2(z,t); }

EXPORT(double) ffiTestSumSUfdUfi_f(ffiTestSUfdUfi x) {return (double) x.a.a + (double) x.b.a; }; /* sum the float parts */
EXPORT(double) ffiTestSumSUfdUdSi2_d(ffiTestSUfdUdSi2 x) {return x.a.b + x.b.a; }; /* sum the double parts */

EXPORT(char) ffiTestChars(char c1, char c2, char c3, char c4);
EXPORT(short) ffiTestShorts(short c1, short c2, short c3, short c4);
Expand Down
2 changes: 1 addition & 1 deletion platforms/Cross/vm/sq.h
Expand Up @@ -102,7 +102,7 @@ extern void sqDeallocateMemorySegmentAtOfSize(void *addr, sqInt sz);
#endif /* SPURVM */
#if COGVM
extern void sqMakeMemoryExecutableFromToCodeToDataDelta(usqInt, usqInt, sqInt*);
extern void sqMakeMemoryNotExecutableFromTo(unsigned long, unsigned long);
extern void sqMakeMemoryNotExecutableFromTo(usqInt, usqInt);
#endif

/* Platform-dependent memory size adjustment macro. */
Expand Down
2 changes: 1 addition & 1 deletion platforms/Cross/vm/sqCogStackAlignment.h
Expand Up @@ -92,7 +92,7 @@
# define setsp(spval) __asm volatile ("mov sp, %0" : : "r"(spval))

# endif
# elif defined(__arm32__) || defined(ARM32)
# elif defined(__arm__) || defined(__arm32__) || defined(ARM32)
/* http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0041c/Cegbidie.html
* ARM DUI 0041C Page 9-7
*/
Expand Down
73 changes: 68 additions & 5 deletions platforms/Mac OS/vm/sqMacMemory.c
Expand Up @@ -121,26 +121,89 @@ sqMacMemoryFree()
}

#if COGVM
# if DUAL_MAPPED_CODE_ZONE
/* We are indebted to Chris Wellons who designed this elegant API for dual
* mapping which we depend on for fine-grained code modification (classical
* Deutsch/Schiffman style inline cacheing and derivatives). Chris's code is:
https://nullprogram.com/blog/2016/04/10/
*
* To cope with modern OSs that disallow executing code in writable memory we
* dual-map the code zone, one mapping with read/write permissions and the other
* with read/execute permissions. In such a configuration the code zone has
* already been alloated and is not included in (what is no longer) the initial
* alloc.
*/
static void
memory_alias_map(size_t size, size_t naddr, void **addrs)
{
extern char *exeName;
char path[128];
snprintf(path, sizeof(path), "/%s(%lu,%p)",
exeName ? exeName : __FUNCTION__, (long)getpid(), addrs);
int fd = shm_open(path, O_RDWR | O_CREAT | O_EXCL, 0600);
if (fd == -1) {
perror("memory_alias_map: shm_open");
exit(0666);
}
shm_unlink(path);
ftruncate(fd, size);
for (size_t i = 0; i < naddr; i++) {
addrs[i] = mmap(addrs[i], size, PROT_READ | PROT_WRITE,
addrs[i] ? MAP_FIXED | MAP_SHARED : MAP_SHARED,
fd, 0);
if (addrs[i] == MAP_FAILED) {
perror("memory_alias_map: mmap(addrs[i]...");
exit(0667);
}
}
close(fd);
return;
}
# endif /* DUAL_MAPPED_CODE_ZONE */
void
sqMakeMemoryExecutableFromTo(unsigned long startAddr, unsigned long endAddr)
sqMakeMemoryExecutableFromToCodeToDataDelta(usqInt startAddr,
usqInt endAddr,
sqInt *codeToDataDelta)
{
unsigned long firstPage = roundDownToPage(startAddr);
usqInt firstPage = roundDownToPage(startAddr);
usqInt size = endAddr - firstPage;

# if DUAL_MAPPED_CODE_ZONE
usqInt mappings[2];

mappings[0] = firstPage;
mappings[1] = 0;

memory_alias_map(size, 2, (void **)mappings);
assert(mappings[0] == firstPage);
*codeToDataDelta = mappings[1] - startAddr;

if (mprotect((void *)firstPage,
endAddr - firstPage + 1,
size,
PROT_READ | PROT_EXEC) < 0)
perror("mprotect(x,y,PROT_READ | PROT_EXEC)");

# else /* DUAL_MAPPED_CODE_ZONE */

if (mprotect((void *)firstPage,
size,
PROT_READ | PROT_WRITE | PROT_EXEC) < 0)
perror("mprotect(x,y,PROT_READ | PROT_WRITE | PROT_EXEC)");

*codeToDataDelta = 0;
# endif
}

void
sqMakeMemoryNotExecutableFromTo(unsigned long startAddr, unsigned long endAddr)
sqMakeMemoryNotExecutableFromTo(usqInt startAddr, usqInt endAddr)
{
# if 0
/* We get EACCESS on 10.6.3 when trying to disable exec perm; Why? */
/* Arguably this is pointless since allocated memory always does include
* write permission. Annoyingly the mprotect call fails on both linux &
* mac os x. So make the whole thing a nop.
*/
unsigned long firstPage = roundDownToPage(startAddr);
usqInt firstPage = roundDownToPage(startAddr);
if (mprotect((void *)firstPage,
endAddr - firstPage + 1,
PROT_READ | PROT_WRITE) < 0
Expand Down
9 changes: 5 additions & 4 deletions platforms/iOS/vm/Common/sqMacV2Memory.c
Expand Up @@ -188,19 +188,20 @@ sqImageFileReadEntireImage(void *ptr, size_t elementSize, size_t count, sqImageF
# define roundUpToPage(v) (((v)+pageSize-1)&pageMask)
#if COGVM || defined(HAVE_NATIVEBOOST)
void
sqMakeMemoryExecutableFromTo(unsigned long startAddr, unsigned long endAddr)
sqMakeMemoryExecutableFromToCodeToDataDelta(usqInt startAddr, usqInt endAddr, sqInt *codeToDataDelta)
{
unsigned long firstPage = roundDownToPage(startAddr);
usqInt firstPage = roundDownToPage(startAddr);
if (mprotect((void *)firstPage,
roundUpToPage(endAddr - firstPage),
PROT_READ | PROT_WRITE | PROT_EXEC) < 0)
perror("mprotect(x,y,PROT_READ | PROT_WRITE | PROT_EXEC)");
*codeToDataDelta = 0;
}

void
sqMakeMemoryNotExecutableFromTo(unsigned long startAddr, unsigned long endAddr)
sqMakeMemoryNotExecutableFromTo(usqInt startAddr, usqInt endAddr)
{
unsigned long firstPage = roundDownToPage(startAddr);
usqInt firstPage = roundDownToPage(startAddr);
if (mprotect((void *)firstPage,
roundUpToPage(endAddr - firstPage),
PROT_READ | PROT_WRITE) < 0)
Expand Down
3 changes: 0 additions & 3 deletions platforms/minheadless/unix/sqPlatformSpecific-Unix.h
Expand Up @@ -42,9 +42,6 @@ extern sqInt sqGrowMemoryBy(sqInt oldLimit, sqInt delta);
extern sqInt sqShrinkMemoryBy(sqInt oldLimit, sqInt delta);
extern sqInt sqMemoryExtraBytesLeft(sqInt includingSwap);
#if COGVM
extern void sqMakeMemoryExecutableFromTo(unsigned long, unsigned long);
extern void sqMakeMemoryNotExecutableFromTo(unsigned long, unsigned long);

extern int osCogStackPageHeadroom(void);
extern void reportMinimumUnusedHeadroom(void);
#endif
Expand Down
9 changes: 6 additions & 3 deletions platforms/minheadless/unix/sqUnixMemory.c
Expand Up @@ -322,17 +322,20 @@ sqInt sqMemoryExtraBytesLeft(sqInt includingSwap) { return uxMemoryExtraBytesL
#define roundUpToPage(v) (((v)+pageSize-1)&pageMask)
#if COGVM
void
sqMakeMemoryExecutableFromTo(unsigned long startAddr, unsigned long endAddr)
sqMakeMemoryExecutableFromToCodeToDataDelta(usqInt startAddr,
usqInt endAddr,
sqInt *codeToDataDelta)
{
unsigned long firstPage = roundDownToPage(startAddr);
usqInt firstPage = roundDownToPage(startAddr);
if (mprotect((void *)firstPage,
endAddr - firstPage + 1,
PROT_READ | PROT_WRITE | PROT_EXEC) < 0)
perror("mprotect(x,y,PROT_READ | PROT_WRITE | PROT_EXEC)");
*codeToDataDelta = 0;
}

void
sqMakeMemoryNotExecutableFromTo(unsigned long startAddr, unsigned long endAddr)
sqMakeMemoryNotExecutableFromTo(usqInt startAddr, usqInt endAddr)
{
# if 0
unsigned long firstPage = roundDownToPage(startAddr);
Expand Down
6 changes: 3 additions & 3 deletions platforms/minheadless/unix/sqUnixSpurMemory.c
Expand Up @@ -240,10 +240,10 @@ sqMakeMemoryExecutableFromToCodeToDataDelta(usqInt startAddr,
}

void
sqMakeMemoryNotExecutableFromTo(unsigned long startAddr, unsigned long endAddr)
sqMakeMemoryNotExecutableFromTo(usqInt startAddr, usqInt endAddr)
{
unsigned long firstPage = roundDownToPage(startAddr);
unsigned long size = endAddr - firstPage;
usqInt firstPage = roundDownToPage(startAddr);
usqInt size = endAddr - firstPage;
/* Arguably this is pointless since allocated memory always includes write
* permission by default. Annoyingly the mprotect call fails on both linux
* and mac os x. So make the whole thing a nop.
Expand Down
3 changes: 0 additions & 3 deletions platforms/minheadless/windows/sqPlatformSpecific-Win32.h
Expand Up @@ -134,9 +134,6 @@ sqInt ioSetCursorARGB(sqInt bitsIndex, sqInt w, sqInt h, sqInt x, sqInt y);
#define PROF_THREAD_PRIORITY THREAD_PRIORITY_TIME_CRITICAL

#if COGVM
extern void sqMakeMemoryExecutableFromTo(usqIntptr_t, usqIntptr_t);
extern void sqMakeMemoryNotExecutableFromTo(usqIntptr_t, usqIntptr_t);

extern int osCogStackPageHeadroom(void);
extern void reportMinimumUnusedHeadroom(void);
#endif
Expand Down
5 changes: 3 additions & 2 deletions platforms/minheadless/windows/sqWin32Alloc.c
Expand Up @@ -181,7 +181,7 @@ sqMemoryExtraBytesLeft(int includingSwap) {

# if COGVM
void
sqMakeMemoryExecutableFromTo(usqIntptr_t startAddr, usqIntptr_t endAddr)
sqMakeMemoryExecutableFromToCodeToDataDelta(usqInt startAddr, usqInt endAddr, sqInt *codeToDataDelta)
{
DWORD previous;

Expand All @@ -190,10 +190,11 @@ sqMakeMemoryExecutableFromTo(usqIntptr_t startAddr, usqIntptr_t endAddr)
PAGE_EXECUTE_READWRITE,
&previous))
sqWin32PrintLastError("VirtualProtect(x,y,PAGE_EXECUTE_READWRITE)");
*codeToDataDelta = 0;
}

void
sqMakeMemoryNotExecutableFromTo(usqIntptr_t startAddr, usqIntptr_t endAddr)
sqMakeMemoryNotExecutableFromTo(usqInt startAddr, usqInt endAddr)
{
DWORD previous;

Expand Down
2 changes: 1 addition & 1 deletion platforms/minheadless/windows/sqWin32SpurAlloc.c
Expand Up @@ -214,7 +214,7 @@ sqMakeMemoryExecutableFromToCodeToDataDelta(usqInt startAddr,
}

void
sqMakeMemoryNotExecutableFromTo(usqIntptr_t startAddr, usqIntptr_t endAddr)
sqMakeMemoryNotExecutableFromTo(usqInt startAddr, usqInt endAddr)
{
DWORD previous;
SIZE_T size;
Expand Down
6 changes: 3 additions & 3 deletions platforms/unix/vm/sqUnixMain.c
Expand Up @@ -942,12 +942,12 @@ reportStackState(char *msg, char *date, int printAll, ucontext_t *uap)
# elif __sun__ && __i386__
void *fp = (void *)(uap ? uap->uc_mcontext.gregs[REG_FP] : 0);
void *sp = (void *)(uap ? uap->uc_mcontext.gregs[REG_SP] : 0);
# elif defined(__arm32__) || defined(ARM32)
void *fp = (void *)(uap ? uap->uc_mcontext.arm_fp : 0);
void *sp = (void *)(uap ? uap->uc_mcontext.arm_sp : 0);
# elif defined(__arm64__) || defined(__aarch64__) || defined(ARM64)
void *fp = (void *)(uap ? uap->uc_mcontext.regs[29] : 0);
void *sp = (void *)(uap ? uap->uc_mcontext.sp : 0);
# elif defined(__arm__) || defined(__arm32__) || defined(ARM32)
void *fp = (void *)(uap ? uap->uc_mcontext.arm_fp : 0);
void *sp = (void *)(uap ? uap->uc_mcontext.arm_sp : 0);
# else
# error need to implement extracting pc from a ucontext_t on this system
# endif
Expand Down

0 comments on commit 4868d1e

Please sign in to comment.