Switching windows to visual studio.

This seems to partially reduce Defender falsely identifying this
as a threat.
Abitrary things seem to matter, like using _div64 instead of 64-bit
operations.
This commit is contained in:
Brad Nelson
2021-01-20 22:35:45 -08:00
parent 445e42d56f
commit ace5d4d92e
10 changed files with 170 additions and 79 deletions

View File

@ -7,11 +7,13 @@ WINDOWS = $(OUT)/windows
ARDUINO = $(OUT)/arduino
DEPLOY = $(OUT)/deploy
CFLAGS_COMMON = -Wall -Werror \
-O2 \
CFLAGS_COMMON = -O2 -I ./ -I $(OUT)
CFLAGS_MINIMIZE = \
-s \
-ffreestanding \
-DUEFORTH_MINIMAL \
-fno-exceptions \
-ffreestanding \
-fno-stack-check \
-fno-stack-protector \
-fno-stack-protector \
@ -19,9 +21,10 @@ CFLAGS_COMMON = -Wall -Werror \
-mno-stack-arg-probe \
-fno-ident -Wl,--build-id=none \
-ffunction-sections -fdata-sections \
-fmerge-all-constants \
-I ./ -I $(OUT)
-fmerge-all-constants
CFLAGS = $(CFLAGS_COMMON) \
-Wall \
-Werror \
-Wl,--gc-sections
STRIP_ARGS = -S \
--strip-unneeded \
@ -32,39 +35,57 @@ STRIP_ARGS = -S \
--remove-section=.note.ABI-tag
LIBS=-ldl
WIN_CFLAGS = $(CFLAGS_COMMON) -mwindows -nostdlib \
WIN_CFLAGS = $(CFLAGS_COMMON) \
-I "c:/Program Files (x86)/Microsoft SDKs/Windows/v7.1A/Include" \
-I "c:/Program Files (x86)/Microsoft Visual Studio/2019/Community/VC/Tools/MSVC/14.28.29333/include" \
-I "c:/Program Files (x86)/Windows Kits/10/Include/10.0.19041.0/ucrt"
WIN_LIBS = -lkernel32
WIN_LFLAGS32 = /LIBPATH:"c:/Program Files (x86)/Microsoft SDKs/Windows/v7.1A/Lib" \
/LIBPATH:"c:/Program Files (x86)/Microsoft Visual Studio/2019/Community/VC/Tools/MSVC/14.28.29333/lib/x86" \
/LIBPATH:"c:/Program Files (x86)/Windows Kits/10/Lib/10.0.19041.0/ucrt/x86"
WIN_LFLAGS64 = /LIBPATH:"c:/Program Files (x86)/Microsoft SDKs/Windows/v7.1A/Lib/x64" \
/LIBPATH:"c:/Program Files (x86)/Microsoft Visual Studio/2019/Community/VC/Tools/MSVC/14.28.29333/lib/x64" \
/LIBPATH:"c:/Program Files (x86)/Windows Kits/10/Lib/10.0.19041.0/ucrt/x64" \
TARGETS = $(WEB)/terminal.html \
$(WEB)/ueforth.js \
$(POSIX)/ueforth \
$(ARDUINO)/ueforth/ueforth.ino
PROGFILES = /mnt/c/Program Files (x86)
CL32 = "$(shell find "${PROGFILES}/Microsoft Visual Studio" -name cl.exe | grep /Hostx86/x86/ | head -n 1)"
CL64 = "$(shell find "${PROGFILES}/Microsoft Visual Studio" -name cl.exe | grep /Hostx86/x64/ | head -n 1)"
LINK32 = "$(shell find "${PROGFILES}/Microsoft Visual Studio" -name link.exe | grep /Hostx86/x86/ | head -n 1)"
LINK64 = "$(shell find "${PROGFILES}/Microsoft Visual Studio" -name link.exe | grep /Hostx86/x64/ | head -n 1)"
RC32 = "$(shell find "${PROGFILES}/Windows Kits" -name rc.exe | grep /x86/ | head -n 1)"
RC64 = "$(shell find "${PROGFILES}/Windows Kits" -name rc.exe | grep /x64/ | head -n 1)"
# Selectively enable windows if tools available
DEPLOYABLE = 1
ifneq (, $(shell which i686-w64-mingw32-windres))
ifneq (, $(shell which i686-w64-mingw32-gcc))
ifneq (, $(CL32))
ifneq (, $(RC32))
TARGETS += $(WINDOWS)/uEforth32.exe
else
$(warning "Missing i686-w64-mingw32-gcc skipping 32-bit Windows.")
$(warning "Missing Visual Studio rc.exe skipping 32-bit Windows.")
DEPLOYABLE := 0
endif
else
$(warning "Missing i686-w64-mingw32-windres skipping 32-bit Windows.")
$(warning "Missing Visual Studio cl.exe skipping 32-bit Windows.")
DEPLOYABLE := 0
endif
ifneq (, $(shell which x86_64-w64-mingw32-windres))
ifneq (, $(shell which x86_64-w64-mingw32-gcc))
ifneq (, $(CL64))
ifneq (, $(RC64))
TARGETS += $(WINDOWS)/uEforth64.exe
else
$(warning "Missing x86_64-w64-mingw32-gcc skipping 64-bit Windows.")
$(warning "Missing Visual Studio rc.exe skipping 64-bit Windows.")
DEPLOYABLE := 0
endif
else
$(warning "Missing x86_64-w64-mingw32-windres skipping 64-bit Windows.")
$(warning "Missing Visual Studio cl.exe skipping 64-bit Windows.")
DEPLOYABLE := 0
endif
# Decide if we can deploy.
DEPLOY_TARGETS =
ifeq (1, $(DEPLOYABLE))
@ -145,11 +166,11 @@ ICON_SIZES = $(RES)/eforth256x256.png \
$(RES)/eforth.ico: $(ICON_SIZES)
convert $^ $< $@
$(RES)/ueforth_res32.o: windows/ueforth.rc $(RES)/eforth.ico
i686-w64-mingw32-windres $< $@
$(RES)/ueforth_res32.res: windows/ueforth.rc $(RES)/eforth.ico
$(RC32) /fo $@ $<
$(RES)/ueforth_res64.o: windows/ueforth.rc $(RES)/eforth.ico
x86_64-w64-mingw32-windres $< $@
$(RES)/ueforth_res64.res: windows/ueforth.rc $(RES)/eforth.ico
$(RC64) /fo $@ $<
# ---- WEB ----
@ -175,6 +196,7 @@ $(POSIX):
$(POSIX)/ueforth: \
posix/posix_main.c \
common/opcodes.h \
common/interp.h \
common/core.h \
$(GEN)/posix_boot.h | $(POSIX)
$(CC) $(CFLAGS) $< -o $@ $(LIBS)
@ -185,23 +207,31 @@ $(POSIX)/ueforth: \
$(WINDOWS):
mkdir -p $@
$(WINDOWS)/uEforth32.exe: \
$(WINDOWS)/uEforth32.obj: \
windows/windows_main.c \
common/opcodes.h \
common/core.h \
$(GEN)/windows_boot.h \
$(RES)/ueforth_res32.o | $(WINDOWS)
i686-w64-mingw32-gcc \
$(WIN_CFLAGS) $< $(RES)/ueforth_res32.o -o $@ $(WIN_LIBS)
windows/windows_interp.h \
$(GEN)/windows_boot.h | $(WINDOWS)
$(CL32) /c /Fo$@ $(WIN_CFLAGS) $<
$(WINDOWS)/uEforth32.exe: \
$(WINDOWS)/uEforth32.obj \
$(RES)/ueforth_res32.res | $(WINDOWS)
$(LINK32) /OUT:$@ $(WIN_LFLAGS32) $^
$(WINDOWS)/uEforth64.obj: \
windows/windows_main.c \
common/opcodes.h \
common/core.h \
windows/windows_interp.h \
$(GEN)/windows_boot.h | $(WINDOWS)
$(CL64) /c /Fo$@ $(WIN_CFLAGS) $<
$(WINDOWS)/uEforth64.exe: \
windows/windows_main.c \
common/opcodes.h \
common/core.h \
$(GEN)/windows_boot.h \
$(RES)/ueforth_res64.o | $(WINDOWS)
x86_64-w64-mingw32-gcc \
$(WIN_CFLAGS) $< $(RES)/ueforth_res64.o -o $@ $(WIN_LIBS)
$(WINDOWS)/uEforth64.obj \
$(RES)/ueforth_res64.res | $(WINDOWS)
$(LINK64) /OUT:$@ $(WIN_LFLAGS64) $^
# ---- ARDUINO ----
@ -213,6 +243,7 @@ $(ARDUINO)/ueforth/ueforth.ino: \
arduino/arduino.template.ino \
common/opcodes.h \
common/core.h \
common/interp.h \
$(GEN)/arduino_boot.h | $(ARDUINO)/ueforth
$^ >$@

View File

@ -214,6 +214,7 @@ static char filename[PATH_MAX];
static String string_value;
{{core}}
{{interp}}
{{boot}}
static IPAddress ToIP(cell_t ip) {

View File

@ -5,10 +5,12 @@ var fs = require('fs');
var code = fs.readFileSync(process.argv[2]).toString();
var opcodes = fs.readFileSync(process.argv[3]).toString();
var core = fs.readFileSync(process.argv[4]).toString();
var boot = fs.readFileSync(process.argv[5]).toString();
var interp = fs.readFileSync(process.argv[5]).toString();
var boot = fs.readFileSync(process.argv[6]).toString();
code = code.replace('{{opcodes}}', function() { return opcodes; });
code = code.replace('{{boot}}', function() { return boot; });
code = code.replace('{{core}}', function() { return core; });
code = code.replace('{{interp}}', function() { return interp; });
process.stdout.write(code);

View File

@ -1,7 +1,7 @@
#ifndef CALLTYPE
# define CALLTYPE
#endif
typedef CALLTYPE cell_t (*call_t)();
typedef cell_t (CALLTYPE *call_t)();
#define CALLING_OPCODE_LIST \
X("CALL0", OP_CALL0, tos = ((call_t) tos)()) \

View File

@ -1,6 +1,5 @@
#define PRINT_ERRORS 0
#define NEXT w = *ip++; goto **(void **) w
#define CELL_LEN(n) (((n) + sizeof(cell_t) - 1) / sizeof(cell_t))
#define FIND(name) find(name, sizeof(name) - 1)
#define LOWER(ch) ((ch) & 0x5F)
@ -120,25 +119,7 @@ static cell_t *evaluate1(cell_t *sp) {
return sp;
}
static void ueforth_run() {
if (!g_sys.ip) {
#define X(name, op, code) create(name, sizeof(name) - 1, name[0] == ';', && OP_ ## op);
PLATFORM_OPCODE_LIST
OPCODE_LIST
#undef X
return;
}
register cell_t *ip = g_sys.ip, *rp = g_sys.rp, *sp = g_sys.sp, tos, w;
DROP; NEXT;
#define X(name, op, code) OP_ ## op: { code; } NEXT;
PLATFORM_OPCODE_LIST
OPCODE_LIST
#undef X
OP_DOCOLON: ++rp; *rp = (cell_t) ip; ip = (cell_t *) (w + sizeof(cell_t)); NEXT;
OP_DOCREATE: DUP; tos = w + sizeof(cell_t) * 2; NEXT;
OP_DODOES: DUP; tos = w + sizeof(cell_t) * 2;
++rp; *rp = (cell_t) ip; ip = (cell_t *) *(cell_t *) (w + sizeof(cell_t)); NEXT;
}
static void ueforth_run(void);
static void ueforth(int argc, char *argv[], void *heap,
const char *src, cell_t src_len) {

25
ueforth/common/interp.h Normal file
View File

@ -0,0 +1,25 @@
#define JMPW goto **(void **) w
#define NEXT w = *ip++; JMPW
#define ADDR_DOCOLON && OP_DOCOLON
#define ADDR_DOCREATE && OP_DOCREATE
#define ADDR_DODOES && OP_DODOES
static void ueforth_run(void) {
if (!g_sys.ip) {
#define X(name, op, code) create(name, sizeof(name) - 1, name[0] == ';', && OP_ ## op);
PLATFORM_OPCODE_LIST
OPCODE_LIST
#undef X
return;
}
register cell_t *ip = g_sys.ip, *rp = g_sys.rp, *sp = g_sys.sp, tos, w;
DROP; NEXT;
#define X(name, op, code) OP_ ## op: { code; } NEXT;
PLATFORM_OPCODE_LIST
OPCODE_LIST
#undef X
OP_DOCOLON: ++rp; *rp = (cell_t) ip; ip = (cell_t *) (w + sizeof(cell_t)); NEXT;
OP_DOCREATE: DUP; tos = w + sizeof(cell_t) * 2; NEXT;
OP_DODOES: DUP; tos = w + sizeof(cell_t) * 2;
++rp; *rp = (cell_t) ip; ip = (cell_t *) *(cell_t *) (w + sizeof(cell_t)); NEXT;
}

View File

@ -5,28 +5,29 @@
typedef intptr_t cell_t;
typedef uintptr_t ucell_t;
#if __SIZEOF_POINTER__ == 8
typedef __int128_t dcell_t;
typedef __uint128_t udcell_t;
#elif __SIZEOF_POINTER__ == 4
typedef int64_t dcell_t;
typedef uint64_t udcell_t;
#else
# error "unsupported cell size"
#endif
#define DUP *++sp = tos
#define DROP tos = *sp--
#define COMMA(n) *g_sys.heap++ = (n)
#define IMMEDIATE() g_sys.last[-1] |= 1
#define DOES(ip) *g_sys.last = (cell_t) && OP_DODOES; g_sys.last[1] = (cell_t) ip
#ifndef SSMOD_FUNC
#define SSMOD_FUNC dcell_t d = (dcell_t) *sp * (dcell_t) sp[-1]; \
--sp; *sp = (cell_t) (((udcell_t) d) % tos); \
tos = (cell_t) (d < 0 ? ~(~d / tos) : d / tos)
#endif
#define DOES(ip) *g_sys.last = (cell_t) ADDR_DODOES; g_sys.last[1] = (cell_t) ip
#define PARK DUP; g_sys.ip = ip; g_sys.rp = rp; g_sys.sp = sp
#ifndef SSMOD_FUNC
# if __SIZEOF_POINTER__ == 8
typedef __int128_t dcell_t;
typedef __uint128_t udcell_t;
# elif __SIZEOF_POINTER__ == 4 || defined(_M_IX86)
typedef int64_t dcell_t;
typedef uint64_t udcell_t;
# else
# error "unsupported cell size"
# endif
# define SSMOD_FUNC dcell_t d = (dcell_t) *sp * (dcell_t) sp[-1]; \
--sp; *sp = (cell_t) (((udcell_t) d) % tos); \
tos = (cell_t) (d < 0 ? ~(~d / tos) : d / tos)
#endif
#define OPCODE_LIST \
X("0=", ZEQUAL, tos = !tos ? -1 : 0) \
X("0<", ZLESS, tos = (tos|0) < 0 ? -1 : 0) \
@ -54,7 +55,7 @@ typedef uint64_t udcell_t;
X(">R", TOR, *++rp = tos; DROP) \
X("R>", FROMR, DUP; tos = *rp; --rp) \
X("R@", RAT, DUP; tos = *rp) \
X("EXECUTE", EXECUTE, w = tos; DROP; goto **(void **) w) \
X("EXECUTE", EXECUTE, w = tos; DROP; JMPW) \
X("BRANCH", BRANCH, ip = (cell_t *) *ip) \
X("0BRANCH", ZBRANCH, if (!tos) ip = (cell_t *) *ip; else ++ip; DROP) \
X("DONEXT", DONEXT, *rp = *rp - 1; \
@ -67,17 +68,17 @@ typedef uint64_t udcell_t;
X("S>NUMBER?", CONVERT, tos = convert((const char *) *sp, tos, sp); \
if (!tos) --sp) \
X("CREATE", CREATE, DUP; DUP; tos = parse(32, sp); \
create((const char *) *sp, tos, 0, && OP_DOCREATE); \
create((const char *) *sp, tos, 0, ADDR_DOCREATE); \
COMMA(0); --sp; DROP) \
X("DOES>", DOES, DOES(ip); ip = (cell_t *) *rp; --rp) \
X("IMMEDIATE", IMMEDIATE, IMMEDIATE()) \
X("'SYS", SYS, DUP; tos = (cell_t) &g_sys) \
X("YIELD", YIELD, PARK; return) \
X(":", COLON, DUP; DUP; tos = parse(32, sp); \
create((const char *) *sp, tos, 0, && OP_DOCOLON); \
create((const char *) *sp, tos, 0, ADDR_DOCOLON); \
g_sys.state = -1; --sp; DROP) \
X("EVALUATE1", EVALUATE1, DUP; sp = evaluate1(sp); w = *sp--; DROP; \
if (w) goto **(void **) w) \
if (w) JMPW) \
X("EXIT", EXIT, ip = (cell_t *) *rp--) \
X(";", SEMICOLON, COMMA(g_sys.DOEXIT_XT); g_sys.state = 0) \

View File

@ -12,6 +12,7 @@
CALLING_OPCODE_LIST \
#include "common/core.h"
#include "common/interp.h"
#include "gen/posix_boot.h"

View File

@ -0,0 +1,44 @@
#define NEXT goto next
#define JMPW goto work
#define ADDR_DOCOLON ((void *) OP_DOCOLON)
#define ADDR_DOCREATE ((void *) OP_DOCREATE)
#define ADDR_DODOES ((void *) OP_DODOES)
enum {
OP_DOCOLON = 0,
OP_DOCREATE,
OP_DODOES,
#define X(name, op, code) OP_ ## op,
PLATFORM_OPCODE_LIST
OPCODE_LIST
#undef X
};
static void ueforth_run(void) {
if (!g_sys.ip) {
#define X(name, op, code) \
create(name, sizeof(name) - 1, name[0] == ';', (void *) OP_ ## op);
PLATFORM_OPCODE_LIST
OPCODE_LIST
#undef X
return;
}
register cell_t *ip = g_sys.ip, *rp = g_sys.rp, *sp = g_sys.sp, tos, w;
DROP;
for (;;) {
next:
w = *ip++;
work:
switch (*(cell_t *) w & 0xff) {
#define X(name, op, code) case OP_ ## op: { code; } NEXT;
PLATFORM_OPCODE_LIST
OPCODE_LIST
#undef X
case OP_DOCOLON: ++rp; *rp = (cell_t) ip; ip = (cell_t *) (w + sizeof(cell_t)); NEXT;
case OP_DOCREATE: DUP; tos = w + sizeof(cell_t) * 2; NEXT;
case OP_DODOES: DUP; tos = w + sizeof(cell_t) * 2;
++rp; *rp = (cell_t) ip;
ip = (cell_t *) *(cell_t *) (w + sizeof(cell_t)); NEXT;
}
}
}

View File

@ -1,12 +1,13 @@
#define _USING_V110_SDK71_ 1
#include "windows.h"
#include <immintrin.h>
#define CALLTYPE WINAPI
# define SSMOD_FUNC \
w = tos; asm("imul %4\n\t" \
"idiv %2" \
: "=a" (tos), "=d" (sp[-1]) \
: "r" (w), "a" (sp[-1]), "d" (*sp)); --sp; if (*sp < 0) { *sp += w; --tos; }
#if defined(_M_X64)
# define SSMOD_FUNC --sp; cell_t b, a = _mul128(*sp, sp[1], &b); tos = _div128(b, a, tos, sp)
#elif defined(_M_IX86)
# define SSMOD_FUNC --sp; __int64 a = (__int64) *sp * (__int64) sp[1]; tos = _div64(a, tos, sp)
#endif
#include "common/opcodes.h"
#include "common/calling.h"
@ -22,13 +23,17 @@
CALLING_OPCODE_LIST \
#include "common/core.h"
#include "windows/windows_interp.h"
#include "gen/windows_boot.h"
#ifdef UEFORTH_MINIMAL
int WINAPI WinMainCRTStartup(void) {
#else
int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmd, int show) {
#endif
void *heap = VirtualAlloc(
NULL, HEAP_SIZE, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);
ueforth(0, 0, heap, boot, sizeof(boot));
return 1;
}