From 68f469fe2cb6d5b8a47eea6fed6d32e606982f92 Mon Sep 17 00:00:00 2001 From: Stas Sergeev Date: Sun, 20 Sep 2026 23:49:46 +0300 Subject: [PATCH] move djdev64 away --- .github/workflows/ci-build.yml | 3 - ci_prereq.sh | 5 +- configure.ac | 13 - debian/control | 28 +- debian/djdev64-dev.install | 4 - dj64dev.spec.rpkg | 31 +- djdev64.pc.in | 4 - djstub64.pc.in | 4 - makefile | 45 +- src/djdev64/djdev64.c | 467 ------------------ src/djdev64/djdev_priv.h | 1 - src/djdev64/djexec.c | 165 ------- src/djdev64/elf.c | 188 ------- src/djdev64/elf_priv.h | 11 - src/djdev64/include/djdev64/dj64init.h | 107 ---- src/djdev64/include/djdev64/djdev64.h | 40 -- src/djdev64/include/djdev64/djdpmi.h | 145 ------ src/djdev64/include/djdev64/dpmi_inc.h | 146 ------ src/djdev64/include/djdev64/stub.h | 76 --- src/djdev64/makefile | 46 -- src/djdev64/stub/coff.c | 176 ------- src/djdev64/stub/coff.h | 8 - src/djdev64/stub/dos.c | 59 --- src/djdev64/stub/dos.h | 16 - src/djdev64/stub/dpmiwrp.c | 48 -- src/djdev64/stub/dpmiwrp.h | 41 -- src/djdev64/stub/elf.c | 165 ------- src/djdev64/stub/elf.h | 107 ---- src/djdev64/stub/elfp.h | 8 - src/djdev64/stub/libdjstub.version | 8 - src/djdev64/stub/makefile | 44 -- src/djdev64/stub/stub.c | 656 ------------------------- src/djdev64/stub/stub_priv.h | 14 - src/djdev64/stub/stubinfo.h | 1 - src/djdev64/stub/util.c | 45 -- src/djdev64/stub/util.h | 14 - src/libc/dj64/32/makefile | 2 +- src/libc/dj64/makefile | 2 +- 38 files changed, 13 insertions(+), 2930 deletions(-) delete mode 100644 debian/djdev64-dev.install delete mode 100644 djdev64.pc.in delete mode 100644 djstub64.pc.in delete mode 100644 src/djdev64/djdev64.c delete mode 100644 src/djdev64/djdev_priv.h delete mode 100644 src/djdev64/djexec.c delete mode 100644 src/djdev64/elf.c delete mode 100644 src/djdev64/elf_priv.h delete mode 100644 src/djdev64/include/djdev64/dj64init.h delete mode 100644 src/djdev64/include/djdev64/djdev64.h delete mode 100644 src/djdev64/include/djdev64/djdpmi.h delete mode 100644 src/djdev64/include/djdev64/dpmi_inc.h delete mode 100644 src/djdev64/include/djdev64/stub.h delete mode 100644 src/djdev64/makefile delete mode 100644 src/djdev64/stub/coff.c delete mode 100644 src/djdev64/stub/coff.h delete mode 100644 src/djdev64/stub/dos.c delete mode 100644 src/djdev64/stub/dos.h delete mode 100644 src/djdev64/stub/dpmiwrp.c delete mode 100644 src/djdev64/stub/dpmiwrp.h delete mode 100644 src/djdev64/stub/elf.c delete mode 100644 src/djdev64/stub/elf.h delete mode 100644 src/djdev64/stub/elfp.h delete mode 100644 src/djdev64/stub/libdjstub.version delete mode 100644 src/djdev64/stub/makefile delete mode 100644 src/djdev64/stub/stub.c delete mode 100644 src/djdev64/stub/stub_priv.h delete mode 120000 src/djdev64/stub/stubinfo.h delete mode 100644 src/djdev64/stub/util.c delete mode 100644 src/djdev64/stub/util.h diff --git a/.github/workflows/ci-build.yml b/.github/workflows/ci-build.yml index 9629d2fa..b4770718 100644 --- a/.github/workflows/ci-build.yml +++ b/.github/workflows/ci-build.yml @@ -29,9 +29,6 @@ jobs: make deb sudo dpkg -i ../dj32*.deb sudo dpkg -i ../dj64*.deb - sudo dpkg -i ../libdjdev64*.deb - sudo dpkg -i ../libdjstub64*.deb - sudo dpkg -i ../djdev64*.deb - name: Upload failure logs if: ${{ always() && (steps.build.outcome == 'failure') }} diff --git a/ci_prereq.sh b/ci_prereq.sh index 35b32ff6..498c739e 100755 --- a/ci_prereq.sh +++ b/ci_prereq.sh @@ -5,5 +5,8 @@ sudo apt install -y \ devscripts \ equivs -sudo add-apt-repository ppa:stsp-0/thunk-gen +sudo add-apt-repository -y --no-update ppa:stsp-0/thunk-gen +sudo add-apt-repository -y --no-update ppa:stsp-0/dj64 +sudo apt update -q + mk-build-deps --install --root-cmd sudo diff --git a/configure.ac b/configure.ac index f6d5a1d0..687d77b4 100644 --- a/configure.ac +++ b/configure.ac @@ -6,8 +6,6 @@ AC_CONFIG_FILES([ Makefile.conf dj64.pc dj64_s.pc - djdev64.pc - djstub64.pc dj32.pc ]) @@ -38,17 +36,6 @@ USE32=1 AC_ARG_ENABLE(64bit, AS_HELP_STRING([--disable-64bit], [do not build 64bit components (reduced build)])) if test "$enable_64bit" != "no"; then - PKG_CHECK_MODULES([LIBELF], [libelf],, [ - AC_CHECK_LIB(elf, elf_memory, [ - LIBELF_LIBS=-lelf - ], [ - AC_MSG_ERROR([libelf not installed]) - ]) - ]) - - AC_CHECK_FUNCS([dlmopen]) - AC_CHECK_DECLS([RTLD_DEEPBIND],,, [[#include ]]) - AC_ARG_WITH(sysroot, [AS_HELP_STRING([--with-sysroot=dir], [sysroot directory. default: ${prefix}/${ARCH_DIR}])], sysroot="$withval", [ diff --git a/debian/control b/debian/control index 8ef40be3..080f52eb 100644 --- a/debian/control +++ b/debian/control @@ -11,10 +11,10 @@ Build-Depends: autoconf, automake, pkgconf, - libelf-dev, + djdev64-dev, ncurses-bin, debhelper (>= 9~) -Homepage: https://github.com/stsp/djgpp-cvs +Homepage: https://github.com/stsp/dj64dev Description: 64-bit djgpp-compatible dev suite dj64dev is a 64-bit djgpp-compatible dev suite. @@ -52,27 +52,3 @@ Depends: ${misc:Depends}, Description: development tools and headers of dj32 This package contains tools and headers for building dj64-enabled programs for 32bit targets. - -Package: libdjdev64-0 -Replaces: djdev64 -Architecture: any -Depends: ${misc:Depends}, ${shlibs:Depends} -Description: djdev64 runtime libraries - This package contains runtime libraries for djdev64-enabled DPMI host. - -Package: libdjstub64-0 -Replaces: djdev64 -Architecture: any -Depends: ${misc:Depends}, ${shlibs:Depends} -Description: djdev64 runtime libraries - This package contains runtime libraries for djdev64-enabled DPMI host. - -Package: djdev64-dev -Architecture: any -Section: libdevel -Depends: libdjdev64-0 (= ${binary:Version}), - libdjstub64-0 (= ${binary:Version}), - ${misc:Depends} -Description: djdev64 development libraries and headers - This package contains development libraries and headers for - djdev64-enabled DPMI host. diff --git a/debian/djdev64-dev.install b/debian/djdev64-dev.install deleted file mode 100644 index e7965931..00000000 --- a/debian/djdev64-dev.install +++ /dev/null @@ -1,4 +0,0 @@ -usr/include/djdev64 -usr/lib/*/*.so -usr/lib/*/pkgconfig/djdev64.pc -usr/lib/*/pkgconfig/djstub64.pc diff --git a/dj64dev.spec.rpkg b/dj64dev.spec.rpkg index 6e92e39a..580d0b28 100644 --- a/dj64dev.spec.rpkg +++ b/dj64dev.spec.rpkg @@ -22,7 +22,7 @@ BuildRequires: gcc BuildRequires: binutils BuildRequires: gcc-x86_64-linux-gnu BuildRequires: binutils-x86_64-linux-gnu -BuildRequires: elfutils-libelf-devel +BuildRequires: djdev64-devel BuildRequires: thunk-gen BuildRequires: pkgconf-pkg-config BuildRequires: ctags @@ -133,35 +133,6 @@ for 32bit targets. %{_libdir}/pkgconfig/dj32.pc %end -%package djdev64 -Summary: djdev64 runtime libraries - -%description djdev64 -This package contains runtime libraries for djdev64-enabled DPMI host. -%end - -%files djdev64 -%defattr(-,root,root) -%{_libdir}/*.so.* -%end - -%package djdev64-devel -Summary: djdev64 development libraries and headers -Requires: dj64dev-djdev64 = {{{ git_dir_version }}} - -%description djdev64-devel -This package contains development libraries and headers for -djdev64-enabled DPMI host. -%end - -%files djdev64-devel -%defattr(-,root,root) -%{_includedir}/djdev64 -%{_libdir}/*.so -%{_libdir}/pkgconfig/djdev64.pc -%{_libdir}/pkgconfig/djstub64.pc -%end - %changelog {{{ git_dir_changelog }}} %end diff --git a/djdev64.pc.in b/djdev64.pc.in deleted file mode 100644 index 7c58506f..00000000 --- a/djdev64.pc.in +++ /dev/null @@ -1,4 +0,0 @@ -Name: djdev64 -Description: djdev64 suit -Version: @VERSION@ -Libs: -ldjdev64 diff --git a/djstub64.pc.in b/djstub64.pc.in deleted file mode 100644 index 424d4825..00000000 --- a/djstub64.pc.in +++ /dev/null @@ -1,4 +0,0 @@ -Name: djstub64 -Description: djstub64 libs -Version: @VERSION@ -Libs: -ldjstub64 diff --git a/makefile b/makefile index 319c42c1..04dbeb30 100644 --- a/makefile +++ b/makefile @@ -26,19 +26,13 @@ DJ64LIBV = $(TOP)/lib/libdj64.*.* DJ64DEVL = $(TOP)/lib/libdj64.$(SHLIB_EXT) DJ64LIBS = $(TOP)/lib/libdj64_s.a DJ32LIBS = $(TOP)/lib/libdj32_s.a -DJDEV64LIB = $(TOP)/lib/libdjdev64.*.*.* -DJDEV64LIBV = $(TOP)/lib/libdjdev64.*.* -DJDEV64DEVL = $(TOP)/lib/libdjdev64.$(SHLIB_EXT) -DJSTUB64LIB = $(TOP)/lib/libdjstub64.*.*.* -DJSTUB64LIBV = $(TOP)/lib/libdjstub64.*.* -DJSTUB64DEVL = $(TOP)/lib/libdjstub64.$(SHLIB_EXT) DJELFLOAD = $(TOP)/lib/elfload.com NC_BUILD = contrib/ncurses/build NC_BUILD32 = contrib/ncurses/build32 -.PHONY: dj64 djdev64 demos ncurses ncurses32 +.PHONY: dj64 demos ncurses ncurses32 -all: Makefile.conf dj64 djdev64 ncurses ncurses32 +all: Makefile.conf dj64 ncurses ncurses32 @echo @echo "Done building. You may need to run \"sudo make install\" now." @echo "You can first run \"sudo make uninstall\" to purge the prev install." @@ -63,9 +57,6 @@ endif %.pc: %.pc.in config.status ./config.status -djdev64: djdev64.pc djstub64.pc - $(MAKE) -C src/djdev64 - ifeq ($(USE64),1) DJ64PC = dj64.pc dj64_s.pc endif @@ -104,23 +95,8 @@ ifeq ($(NCURSES),1) endif endif -install_djdev64: - $(INSTALL) -d $(DESTDIR)$(libdir)/pkgconfig - $(INSTALL) -m 0644 djdev64.pc $(DESTDIR)$(libdir)/pkgconfig - $(INSTALL) -m 0644 djstub64.pc $(DESTDIR)$(libdir)/pkgconfig - $(INSTALL) -d $(DESTDIR)$(includedir)/djdev64 - cp -rL $(abs_top_srcdir)/src/djdev64/include/djdev64 $(DESTDIR)$(includedir) - $(INSTALL) -d $(DESTDIR)$(libdir) - $(INSTALL) -m 0755 $(DJDEV64LIB) $(DESTDIR)$(libdir) - $(CP_FP) $(DJDEV64LIBV) $(DESTDIR)$(libdir) - $(CP_FP) $(DJDEV64DEVL) $(DESTDIR)$(libdir) - $(INSTALL) -m 0755 $(DJSTUB64LIB) $(DESTDIR)$(libdir) - $(CP_FP) $(DJSTUB64LIBV) $(DESTDIR)$(libdir) - $(CP_FP) $(DJSTUB64DEVL) $(DESTDIR)$(libdir) - -install: install_dj64 install_djdev64 install_demos install32 +install: install_dj64 install_demos install32 @echo - @echo "Done installing. You may need to run \"sudo ldconfig\" now." uninstall64: ifeq ($(USE64),1) @@ -131,23 +107,11 @@ endif endif $(RM) -r $(DESTDIR)$(datadir)/dj64 $(RM) -r $(DESTDIR)$(sysroot) - $(RM) -r $(DESTDIR)$(includedir)/djdev64 $(RM) $(DESTDIR)$(libdir)/pkgconfig/dj64.pc $(RM) $(DESTDIR)$(libdir)/pkgconfig/dj64_s.pc $(MAKE) -C demos src_uninstall endif -uninstall_dev64: - $(RM) $(DESTDIR)$(libdir)/pkgconfig/djdev64.pc - $(RM) $(DESTDIR)$(libdir)/pkgconfig/djstub64.pc - $(RM) $(DESTDIR)$(libdir)/$(notdir $(DJDEV64DEVL)) - $(RM) $(DESTDIR)$(libdir)/$(notdir $(DJDEV64LIBV)) - $(RM) $(DESTDIR)$(libdir)/$(notdir $(DJDEV64LIB)) - $(RM) $(DESTDIR)$(libdir)/$(notdir $(DJSTUB64DEVL)) - $(RM) $(DESTDIR)$(libdir)/$(notdir $(DJSTUB64LIBV)) - $(RM) $(DESTDIR)$(libdir)/$(notdir $(DJSTUB64LIB)) - ldconfig - install32: ifeq ($(USE32),1) $(INSTALL) -d $(DESTDIR)$(sysroot32)/lib @@ -176,11 +140,10 @@ endif $(RM) $(DESTDIR)$(libdir)/pkgconfig/dj32.pc endif -uninstall: uninstall64 uninstall_dev64 uninstall32 +uninstall: uninstall64 uninstall32 clean: demos_clean $(MAKE) -C src clean - $(MAKE) -C src/djdev64 clean $(RM) *.pc $(RM) -r lib ifeq ($(NCURSES),1) diff --git a/src/djdev64/djdev64.c b/src/djdev64/djdev64.c deleted file mode 100644 index 282e4e62..00000000 --- a/src/djdev64/djdev64.c +++ /dev/null @@ -1,467 +0,0 @@ -/* - * dj64 - 64bit djgpp-compatible tool-chain - * Copyright (C) 2021-2024 @stsp - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#define _GNU_SOURCE -#include -#ifdef __sun__ -#include -#endif -#include -#include -#include -#include -#include -#include -#include -#include "djdev64/dj64init.h" -#include "djdev64/djdev64.h" -#include "elf_priv.h" -#include "djdev_priv.h" - -static int handles; -#define HNDL_MAX 5 -struct dj64handle { - void *dlobj; - char *estart; - char *eend; - dj64cdispatch_t *cdisp; - dj64cdispatch_t *ctrl; - dj64done_t *done; - char *path; - const struct djdev64_api *api; - int api_ver; -}; -static struct dj64handle dlhs[HNDL_MAX]; - -static pthread_mutex_t init_mtx = PTHREAD_MUTEX_INITIALIZER; - -static void *do_open_dyn(int handle, int hfd) -{ - int fd; - void *ret; - struct dj64handle *h; - if (handle >= handles) - return NULL; - h = &dlhs[handle]; - fd = h->api->uget(hfd); - if (fd == -1) - return NULL; - ret = djelf_open_dyn(fd); - close(fd); - return ret; -} - -static char *do_elfparse64(int handle, uint32_t *r_size) -{ - struct dj64handle *h; - if (handle >= handles) - return NULL; - h = &dlhs[handle]; - *r_size = h->eend - h->estart; - return h->estart; -} - -static const struct elf_ops eops = { - djelf_open, - do_open_dyn, - djelf_close, - djelf_getsymoff, - djelf_reloc, - djelf64_parse, - do_elfparse64, - djelf64_exec_self, - djelf64_run, -}; - -#define __S(x) #x -#define _S(x) __S(x) -#define FORMAT(T,A,B) __attribute__((format(T,A,B))) - -FORMAT(printf, 2, 3) -static void loudprintf(const struct dj64_api *api, const char *str, ...) -{ - va_list args; - - va_start(args, str); - api->print(DJ64_PRINT_LOG, str, args); - va_end(args); - va_start(args, str); - api->print(DJ64_PRINT_TERMINAL, str, args); - va_end(args); - va_start(args, str); - api->print(DJ64_PRINT_SCREEN, str, args); - va_end(args); -} - -static char *findmnt(const char *path) -{ - const char *tmpl = "findmnt -n -o target --target %s"; - static char buf[1024]; - FILE *f; - int rd; - - snprintf(buf, sizeof(buf), tmpl, path); - f = popen(buf, "r"); - if (!f) - return NULL; - rd = fread(buf, 1, sizeof(buf), f); - if (rd <= 0) - goto err; - if (buf[rd - 1] == '\n') - rd--; - buf[rd] = '\0'; - pclose(f); - return buf; - -err: - pclose(f); - return NULL; -} - -static const char *var_list[] = { "_crt0_startup_flags", NULL }; - -static int copy_file(const char *src, const char *dest) -{ - char buffer[4096]; - size_t bytes; - int rc = 0; - FILE *source = fopen(src, "rb"); - FILE *destination = fopen(dest, "wb"); - - if (!source || !destination) { - if (source) { - fprintf(stderr, "failed to open for writing %s\n", dest); - fclose(source); - } else { - fprintf(stderr, "failed to open for reading %s\n", src); - } - return -1; - } - - while ((bytes = fread(buffer, 1, sizeof(buffer), source)) > 0) { - size_t wr = fwrite(buffer, 1, bytes, destination); - if (wr != bytes) { - fprintf(stderr, "failed to write to %s\n", dest); - rc = -1; - break; - } - } - - fclose(source); - fclose(destination); - if (rc) - remove(dest); - return rc; -} - -static void *emu_dlmopen(int handle, const char *filename, int flags, - char **r_path) -{ - int err; - int len = strlen(filename) + 1 + 16; - char *path = malloc(len); - const char *p; - void *ret; - - /* fake soname to cheat same-lib detection */ - snprintf(path, len, "%.*s.%i", (int)strlen(filename), filename, handle); - p = strrchr(filename, '/'); - if (!p) - p = filename; - else - p++; - unlink(path); - /* glibc compares inodes from stat(), so symlinks do not help - use cp */ - err = copy_file(filename, path); - if (err) { - fprintf(stderr, "cp(%s %s) failed\n", filename, path); -#if 1 - goto err_free; -#else - free(path); - /* try as-is */ - path = strdup(filename); -#endif - } - ret = dlopen(path, flags); - if (!ret) - goto err_unlink; - - *r_path = path; - return ret; - -err_unlink: - unlink(path); -err_free: - free(path); - return NULL; -} - -#define FLG_STATIC 0x40 - -static int _djdev64_open(const char *path, const struct dj64_api *api, - int api_ver, unsigned flags, const struct djdev64_api *devapi) -{ - int rc; - dj64init_t *init; - dj64done_t *done; - dj64init_once_t *init_once; - dj64cdispatch_t **cdisp; - void *m; - void *dlh = NULL; - const char **v; - char *path2 = NULL; - struct dj64handle *h; - int use_dlm = 0; - int full; - - if (handles >= HNDL_MAX) { - fprintf(stderr, "out of handles\n"); - return -1; - } - /* RTLD_DEEPBIND has similar effect to -Wl,-Bsymbolic, but we don't - * use it with dlmopen() as asan doesn't work with that flag. - * So if we don't have dlmopen() then no asan support is possible. */ - if (flags & DJ64F_DLMOPEN) { -#ifdef HAVE_DLMOPEN - use_dlm = 1; - dlh = dlmopen(LM_ID_NEWLM, path, RTLD_LOCAL | RTLD_NOW); -#else - fprintf(stderr, "dlmopen() not supported, asan won't work\n"); - return -1; -#endif - } else if (flags & FLG_STATIC) { - dlh = emu_dlmopen(handles, path, RTLD_LOCAL | RTLD_NOW, &path2); - } else { -#if defined(__linux__) -/* On linux, versioning works and glibc is versioned. - * Add your platform here. */ -#define VERSIONING 1 -#else -#define VERSIONING 0 -#endif - -#if VERSIONING || HAVE_DECL_RTLD_DEEPBIND -#define WANT_DLMOPEN 0 -#else -#define WANT_DLMOPEN 1 -#endif - -#if WANT_DLMOPEN -#ifdef HAVE_DLMOPEN - use_dlm = 1; - dlh = dlmopen(LM_ID_NEWLM, path, RTLD_LOCAL | RTLD_NOW); -#else - fprintf(stderr, "dlmopen() not supported, use static linking\n"); -#if HAVE_DECL_RTLD_DEEPBIND - dlh = emu_dlmopen(handles, path, RTLD_LOCAL | RTLD_NOW | RTLD_DEEPBIND, - &path2); -#endif -#endif -#else - /* Can as well use RTLD_GLOBAL, as we never override libc symbols - * because libc is loaded before us. But for safety lets use - * RTLD_LOCAL. */ - int rtld_flags = RTLD_LOCAL | RTLD_NOW; -#if HAVE_DECL_RTLD_DEEPBIND - rtld_flags |= RTLD_DEEPBIND; -#else - /* - * Works only with symbol versioning in both libc and - * libdj64. Otherwise libc, which is loaded before us, - * will trap our symbols. - * - no version in libdj64: unversioned undefined - * symbols intended for libdj64, are bound to libc, - * to either its unversioned or default symbols - * - no version in libc: either versioned or unversioned - * undefined symbols intended for libdj64, are bound - * to libc - * Wish: add some feature (ELF flag? RTLD flag?) to disallow - * undefined versioned symbols binding to unversioned ones. - */ -#endif - if (flags & DJ64F_NOMANGLE) - dlh = dlopen(path, rtld_flags); - else - dlh = emu_dlmopen(handles, path, rtld_flags, &path2); -#endif - } - if (!dlh) { - char cmd[1024]; - const char *d; - fprintf(stderr, "cannot dlopen %s: %s\n", path, dlerror()); - d = findmnt(path); - if (!d) - return -1; - snprintf(cmd, sizeof(cmd), "grep %.256s /proc/mounts | grep noexec", d); - if (system(cmd) == 0) { - loudprintf(api, "\nDJ64 ERROR: Your %s is mounted with noexec option.\n" - "Please execute:\n" - "\tsudo mount -o remount,exec %s\n" - "and try running the program again.\n", - d, d - ); - } - return -1; - } - - m = dlsym(dlh, "main"); - if (!m) { - fprintf(stderr, "cannot find main\n"); - goto err_close; - } - init_once = dlsym(dlh, _S(DJ64_INIT_ONCE_FN)); - if (!init_once) { - fprintf(stderr, "cannot find " _S(DJ64_INIT_ONCE_FN) "\n"); - goto err_close; - } - init = dlsym(dlh, _S(DJ64_INIT_FN)); - if (!init) { - fprintf(stderr, "cannot find " _S(DJ64_INIT_FN) "\n"); - goto err_close; - } - done = dlsym(dlh, _S(DJ64_DONE_FN)); - if (!done) { - fprintf(stderr, "cannot find " _S(DJ64_DONE_FN) "\n"); - goto err_close; - } - - rc = init_once(api, api_ver); - if (rc == -1) { - fprintf(stderr, _S(DJ64_INIT_ONCE_FN) " failed\n"); - goto err_close; - } - full = (use_dlm || (flags & FLG_STATIC) || !handles); - cdisp = init(handles, &eops, m, full); - if (!cdisp) { - fprintf(stderr, _S(DJ64_INIT_FN) " failed\n"); - goto err_close; - } - - for (v = var_list; *v; v++) { - char buf[256]; - int *vh1, *vh2; - - snprintf(buf, sizeof(buf), "____%s", *v); - vh1 = dlsym(dlh, *v); - vh2 = dlsym(dlh, buf); - if (vh1 && vh2) - *vh2 = *vh1; - } - - h = &dlhs[handles]; - h->dlobj = dlh; - h->estart = dlsym(dlh, "_binary_tmp_o_elf_start"); - h->eend = dlsym(dlh, "_binary_tmp_o_elf_end"); - h->cdisp = cdisp[0]; - h->ctrl = cdisp[1]; - h->done = done; - h->path = path2; - h->api = devapi; - h->api_ver = api_ver; - return handles++; - -err_close: - dlclose(dlh); - if (path2) { - int err = unlink(path2); - if (err) - perror("unlink()"); - free(path2); - } - return -1; -} - -int djdev64_open(const char *path, const struct dj64_api *api, int api_ver, - unsigned flags, const struct djdev64_api *devapi) -{ - int ret; - - /* Init sequence is inherently thread-unsafe: at dlmopen() the ctors - * register the dispatch fn, which is stored in a global pointer until - * init() is called. Also we increment handles non-atomically. */ - pthread_mutex_lock(&init_mtx); - ret = _djdev64_open(path, api, api_ver, flags, devapi); - pthread_mutex_unlock(&init_mtx); - return ret; -} - -int djdev64_call(int handle, int libid, int fn, unsigned esi, - unsigned char *sp) -{ - if (handle >= handles || !dlhs[handle].dlobj) - return -1; - return dlhs[handle].cdisp(handle, libid, fn, esi, sp); -} - -int djdev64_ctrl(int handle, int libid, int fn, unsigned esi, - unsigned char *sp) -{ - if (handle >= handles || !dlhs[handle].dlobj) - return -1; - return dlhs[handle].ctrl(handle, libid, fn, esi, sp); -} - -void djdev64_close(int handle) -{ - struct dj64handle *h; - int err; - - if (handle >= handles) - return; - h = &dlhs[handle]; - h->done(handle); - dlclose(h->dlobj); - h->dlobj = NULL; - if (h->path) { - err = unlink(h->path); - if (err) - perror("unlink()"); - free(h->path); - } - while (handles > 0 && !dlhs[handles - 1].dlobj) - handles--; -} - -void djdevprintf(int handle, int prio, const char *format, ...) -{ - struct dj64handle *h; - va_list vl, cpy; - - assert(handle < HNDL_MAX); - h = &dlhs[handle]; - if (h->api_ver < 24) - return; - va_start(vl, format); - if (prio & DJDEV64_PRINT_LOG) { - va_copy(cpy, vl); - h->api->print(DJ64_PRINT_LOG, format, cpy); - va_end(cpy); - } - if (prio & DJDEV64_PRINT_TERMINAL) { - va_copy(cpy, vl); - h->api->print(DJ64_PRINT_TERMINAL, format, cpy); - va_end(cpy); - } - if (prio & DJDEV64_PRINT_SCREEN) { - va_copy(cpy, vl); - h->api->print(DJ64_PRINT_SCREEN, format, cpy); - va_end(cpy); - } - va_end(vl); -} diff --git a/src/djdev64/djdev_priv.h b/src/djdev64/djdev_priv.h deleted file mode 100644 index c397a4cf..00000000 --- a/src/djdev64/djdev_priv.h +++ /dev/null @@ -1 +0,0 @@ -void djdevprintf(int handle, int prio, const char *format, ...); diff --git a/src/djdev64/djexec.c b/src/djdev64/djexec.c deleted file mode 100644 index 11daf243..00000000 --- a/src/djdev64/djexec.c +++ /dev/null @@ -1,165 +0,0 @@ -/* - * dj64 - 64bit djgpp-compatible tool-chain - * Copyright (C) 2021-2024 @stsp - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -#define _GNU_SOURCE -#include -#include -#include -#include "djdev64/djdev64.h" -#include "elf_priv.h" -#include "djdev_priv.h" - -#define DJ64_ELFEXEC_VERSION 2 - -struct exec_info { - /* volatile because of longjmp() vs auto storage */ - /* unsigned char to not clash with go64/dj64 errors */ - volatile unsigned char exit_code; - jmp_buf exit_jmp; -}; - -struct exec_handle { - void *dlobj; - int (*m)(int, char **); - int (*ae2)(void(*)(void*,int),void*); - char *estart; - char *eend; -}; -static struct exec_handle ehands[1]; // expand if more than 1 ever needed - -static void exit_exec(void *handle, int rc); - -int djdev64_exec(const char *path, int handle, int libid, unsigned flags) -{ - struct exec_handle *eh = &ehands[0]; - int rtld_flags = RTLD_LOCAL | RTLD_NOW; - dj64init2_t *i2; - int err; - - eh->dlobj = NULL; -#if HAVE_DECL_RTLD_DEEPBIND - rtld_flags |= RTLD_DEEPBIND; -#endif - eh->dlobj = dlopen(path, rtld_flags); - if (!eh->dlobj) { - printf("error loading %s: %s\n", path, dlerror()); - return -1; - } - eh->estart = dlsym(eh->dlobj, "_binary_tmp_o_elf_start"); - eh->eend = dlsym(eh->dlobj, "_binary_tmp_o_elf_end"); - eh->m = dlsym(eh->dlobj, "main"); - if (!eh->m) { - printf("error: can't find \"main\"\n"); - goto out; - } - eh->ae2 = dlsym(eh->dlobj, "atexit2"); - if (!eh->ae2) { - printf("error: can't find \"atexit2\"\n"); - goto out; - } - i2 = dlsym(eh->dlobj, "dj64init2"); - if (!i2) { - printf("error: can't find \"dj64init2\"\n"); - goto out; - } - - err = i2(handle, libid); - if (err) { - djdevprintf(handle, DJDEV64_PRINT_TERMINAL | DJDEV64_PRINT_SCREEN, - "error: statically linked ELF unsupported by this loader\n"); - goto out; - } - return 0; -out: - dlclose(eh->dlobj); - return -1; -} - -int djelf64_exec_self(void) -{ -#ifdef RTLD_DEFAULT - struct exec_handle *eh = &ehands[0]; - void **dlh = dlsym(RTLD_DEFAULT, "dj64_dl_handle_self"); - int *ee_ver = dlsym(RTLD_DEFAULT, "dj64_elfexec_version"); - - if (!dlh || !ee_ver) - return -1; - if (*ee_ver != DJ64_ELFEXEC_VERSION) { - fprintf(stderr, "wrong elfexec version, want %i got %i\n", - DJ64_ELFEXEC_VERSION, *ee_ver); - } - eh->dlobj = NULL; - eh->estart = dlsym(RTLD_DEFAULT, "_binary_tmp_o_elf_start"); - eh->eend = dlsym(RTLD_DEFAULT, "_binary_tmp_o_elf_end"); - eh->m = dlsym(RTLD_DEFAULT, "dj64_startup_hook"); - if (!eh->m) { - printf("error: can't find \"dj64_startup_hook\"\n"); - return -1; - } - eh->ae2 = dlsym(*dlh, "atexit2"); - if (!eh->ae2) { - printf("error: can't find \"atexit2\"\n"); - return -1; - } - return 0; -#else - return -1; -#endif -} - -char *djelf64_parse(int eid, uint32_t *r_size) -{ - struct exec_handle *eh; - - if (eid != 0) - return NULL; - eh = &ehands[eid]; - *r_size = eh->eend - eh->estart; - return eh->estart; -} - -int djelf64_run(int eid, int argc, char **argv) -{ - struct exec_handle *eh; - struct exec_info ei; - int ret = -1, rc; - - if (eid != 0) - return -1; - eh = &ehands[eid]; - rc = eh->ae2(exit_exec, &ei); - if (rc == -1) { - printf("error: atexit2() failed\n"); - goto out; - } - if (setjmp(ei.exit_jmp)) - ret = ei.exit_code; - else - ret = (unsigned char)eh->m(argc, argv); - eh->ae2(NULL, NULL); -out: - if (eh->dlobj) - dlclose(eh->dlobj); - return ret; -} - -static void exit_exec(void *handle, int rc) -{ - struct exec_info *ei = handle; - ei->exit_code = rc; - longjmp(ei->exit_jmp, 1); -} diff --git a/src/djdev64/elf.c b/src/djdev64/elf.c deleted file mode 100644 index fc43838c..00000000 --- a/src/djdev64/elf.c +++ /dev/null @@ -1,188 +0,0 @@ -/* - * FDPP - freedos port to modern C++ - * Copyright (C) 2021 Stas Sergeev (stsp) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "djdev64/djdev64.h" -#include "elf_priv.h" - -struct elfstate { - size_t mapsize; - Elf *elf; - Elf_Scn *symtab_scn; - GElf_Shdr symtab_shdr; - char *addr; - int need_unmap; -}; - -static int do_getsym(struct elfstate *state, const char *name, GElf_Sym *r_sym) -{ - Elf_Data *data; - int count, i; - - data = elf_getdata(state->symtab_scn, NULL); - count = state->symtab_shdr.sh_size / state->symtab_shdr.sh_entsize; - - for (i = 0; i < count; i++) { - GElf_Sym sym; - gelf_getsym(data, i, &sym); - if (strcmp(elf_strptr(state->elf, state->symtab_shdr.sh_link, - sym.st_name), name) == 0) { - *r_sym = sym; - return 0; - } - } - - return -1; -} - -static int do_elf_open(char *addr, uint32_t size, struct elfstate *ret) -{ - Elf *elf; - Elf_Scn *scn = NULL; - GElf_Shdr shdr; - - elf_version(EV_CURRENT); - - elf = elf_memory(addr, size); - if (!elf) { - fprintf(stderr, "elf_memory() failed\n"); - return -1; - } - - while ((scn = elf_nextscn(elf, scn)) != NULL) { - gelf_getshdr(scn, &shdr); - if (shdr.sh_type == SHT_SYMTAB) { - /* found a symbol table, go print it. */ - break; - } - } - if (!scn) { - fprintf(stderr, "elf: not found SHT_SYMTAB\n"); - goto err; - } - - ret->mapsize = size; - ret->elf = elf; - ret->symtab_scn = scn; - ret->symtab_shdr = shdr; - ret->addr = addr; - return 0; - -err: - elf_end(elf); - return -1; -} - -void *djelf_open(char *addr, uint32_t size) -{ - struct elfstate es = {}, *ret; - int err = do_elf_open(addr, size, &es); - if (err) - return NULL; - ret = (struct elfstate *)malloc(sizeof(*ret)); - *ret = es; - return ret; -} - -void *djelf_open_dyn(int fd) -{ - struct elfstate es = {}, *ret; - int err; - char *addr; - struct stat st; - - fstat(fd, &st); - addr = (char *)mmap(NULL, st.st_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, - fd, 0); - if (addr == MAP_FAILED) { - perror("mmap()"); - return NULL; - } - err = do_elf_open(addr, st.st_size, &es); - if (err) - return NULL; - ret = (struct elfstate *)malloc(sizeof(*ret)); - *ret = es; - ret->need_unmap = 1; - return ret; -} - -void djelf_close(void *arg) -{ - struct elfstate *state = (struct elfstate *)arg; - - elf_end(state->elf); - if (state->need_unmap) - munmap(state->addr, state->mapsize); - free(state); -} - -static uint32_t do_getsymoff(struct elfstate *state, const char *name) -{ - GElf_Sym sym; - int err = do_getsym(state, name, &sym); - assert(err || sym.st_value); // make sure st_value!=0 - return (err ? 0 : sym.st_value); -} - -uint32_t djelf_getsymoff(void *arg, const char *name) -{ - struct elfstate *state = (struct elfstate *)arg; - return do_getsymoff(state, name); -} - -int djelf_reloc(void *arg, uint8_t *addr, uint32_t size, uint32_t va, - uint32_t *r_entry) -{ - struct elfstate *state = (struct elfstate *)arg; - GElf_Ehdr ehdr; - GElf_Phdr phdr; - int offs; - int i; - - if (elf_kind(state->elf) != ELF_K_ELF) - return -1; - gelf_getehdr(state->elf, &ehdr); - if (ehdr.e_ident[EI_CLASS] != ELFCLASS32) { - fprintf(stderr, "unsupported ELF class %i\n", ehdr.e_ident[EI_CLASS]); - return -1; - } - for (i = 0; i < ehdr.e_phnum; i++) { - gelf_getphdr(state->elf, i, &phdr); - if (phdr.p_type != PT_LOAD) - continue; - offs = phdr.p_vaddr - va; - if (offs < 0 || offs + phdr.p_memsz > size) - return -1; - memcpy(addr + offs, state->addr + phdr.p_offset, phdr.p_filesz); - if (phdr.p_memsz > phdr.p_filesz) - memset(addr + offs + phdr.p_filesz, 0, phdr.p_memsz - - phdr.p_filesz); - } - *r_entry = ehdr.e_entry; - return 0; -} diff --git a/src/djdev64/elf_priv.h b/src/djdev64/elf_priv.h deleted file mode 100644 index 8b5c7ae5..00000000 --- a/src/djdev64/elf_priv.h +++ /dev/null @@ -1,11 +0,0 @@ -#include - -void *djelf_open_dyn(int fd); -uint32_t djelf_getsymoff(void *arg, const char *name); -void *djelf_open(char *addr, uint32_t size); -void djelf_close(void *arg); -int djelf_reloc(void *arg, uint8_t *addr, uint32_t size, uint32_t va, - uint32_t *r_entry); - -char *djelf64_parse(int eid, uint32_t *r_size); -int djelf64_exec_self(void); diff --git a/src/djdev64/include/djdev64/dj64init.h b/src/djdev64/include/djdev64/dj64init.h deleted file mode 100644 index e2ce1acb..00000000 --- a/src/djdev64/include/djdev64/dj64init.h +++ /dev/null @@ -1,107 +0,0 @@ -/* - * dj64 - 64bit djgpp-compatible tool-chain - * Copyright (C) 2021-2024 @stsp - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#ifndef DJ64INIT_H -#define DJ64INIT_H - -#include -#include -#include - -typedef int (dj64cdispatch_t)(int handle, int libid, int fn, unsigned esi, - uint8_t *sp); -#define DJ64_API_VER 25 -#define DJ64_API_MIN_VER 19 -enum { DJ64_PRINT_LOG, DJ64_PRINT_TERMINAL, DJ64_PRINT_SCREEN }; -#define DJDEV64_PRINT_LOG (1 << DJ64_PRINT_LOG) -#define DJDEV64_PRINT_TERMINAL (1 << DJ64_PRINT_TERMINAL) -#define DJDEV64_PRINT_SCREEN (1 << DJ64_PRINT_SCREEN) - -/* pushal */ -typedef struct { - uint32_t edi; - uint32_t esi; - uint32_t ebp; - uint32_t esp; - uint32_t ebx; - uint32_t edx; - uint32_t ecx; - uint32_t eax; -} __attribute__((packed)) dpmi_regs; - -typedef struct { - uint32_t offset32; - unsigned short selector; -} dpmi_paddr; - -enum { ASM_CALL_OK, ASM_CALL_ABORT }; -enum { DJ64_RET_ABORT = -1, DJ64_RET_OK, DJ64_RET_NORET }; - -struct dj64_api { - uint8_t *(*addr2ptr)(uint32_t addr); - uint8_t *(*addr2ptr2)(uint32_t addr, uint32_t len); - uint32_t (*ptr2addr)(const uint8_t *ptr); - void (*print)(int prio, const char *format, va_list ap); - int (*asm_call)(dpmi_regs *regs, dpmi_paddr pma, uint8_t *sp, uint8_t len); - void (*asm_noret)(dpmi_regs *regs, dpmi_paddr pma, uint8_t *sp, - uint8_t len); - uint8_t *(*inc_esp)(uint32_t len); - int (*is_dos_ptr)(const uint8_t *ptr); - int (*get_handle)(void); - void (*exit)(int rc); - void *(*malloc)(size_t size); - void (*free)(void *ptr); - int (*elfload)(int num, int handle, int libid); -}; - -struct djdev64_api { - int (*uget)(int handle); - void (*print)(int prio, const char *format, va_list ap); -}; - -#define DJ64_INIT_ONCE_FN dj64init_once -typedef int (dj64init_once_t)(const struct dj64_api *api, int api_ver); -int DJ64_INIT_ONCE_FN(const struct dj64_api *api, int api_ver); - -struct elf_ops { - void *(*open)(char *addr, uint32_t size); - void *(*open_dyn)(int handle, int fd); - void (*close)(void *arg); - uint32_t (*getsym)(void *arg, const char *name); - int (*reloc)(void *arg, uint8_t *addr, uint32_t size, uint32_t va, - uint32_t *r_entry); - char *(*elfparse64)(int eid, uint32_t *r_size); - char *(*elfparse64_h)(int handle, uint32_t *r_size); - int (*exec_self)(void); - int (*exec64)(int eid, int argc, char **argv); -}; - -typedef dj64cdispatch_t **(dj64init_t)(int handle, const struct elf_ops *ops, - void *main, int full_init); -#define DJ64_INIT_FN dj64init -dj64init_t DJ64_INIT_FN; - -typedef int (dj64init2_t)(int handle, int disp_id); -#define DJ64_INIT2_FN dj64init2 -dj64init2_t DJ64_INIT2_FN; - -#define DJ64_DONE_FN dj64done -typedef void (dj64done_t)(int handle); -void DJ64_DONE_FN(int handle); - -#endif diff --git a/src/djdev64/include/djdev64/djdev64.h b/src/djdev64/include/djdev64/djdev64.h deleted file mode 100644 index 3ee99f87..00000000 --- a/src/djdev64/include/djdev64/djdev64.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * dj64 - 64bit djgpp-compatible tool-chain - * Copyright (C) 2021-2024 @stsp - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#ifndef DJDEV64_H -#define DJDEV64_H - -#include "djdev64/dj64init.h" - -/* first 16 bits are for internal use */ -#define DJ64F_DLMOPEN (1 << 16) -#define DJ64F_NOMANGLE (1 << 17) - -int djdev64_open(const char *path, const struct dj64_api *api, int api_ver, - unsigned flags, const struct djdev64_api *devapi); -int djdev64_call(int handle, int libid, int fn, unsigned esi, - unsigned char *sp); -int djdev64_ctrl(int handle, int libid, int fn, unsigned esi, - unsigned char *sp); -void djdev64_close(int handle); - -int djdev64_exec(const char *path, int handle, int libid, unsigned flags); - -int djelf64_run(int eid, int argc, char **argv); - -#endif diff --git a/src/djdev64/include/djdev64/djdpmi.h b/src/djdev64/include/djdev64/djdpmi.h deleted file mode 100644 index 16d32bc5..00000000 --- a/src/djdev64/include/djdev64/djdpmi.h +++ /dev/null @@ -1,145 +0,0 @@ -/* - * dj64 - 64bit djgpp-compatible tool-chain - * Copyright (C) 2021-2024 @stsp - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#ifndef DJDPMI_H -#define DJDPMI_H -/* ripped from djgpp's dpmi.h */ - -#include -#define LONG int32_t -#define ULONG uint32_t - -typedef struct { - unsigned short offset16; - unsigned short segment; -} __dpmi_raddr; - -typedef struct { - ULONG offset32; - unsigned short selector; -} __dpmi_paddr; - -typedef struct { - ULONG handle; /* 0, 2 */ - ULONG size; /* or count */ /* 4, 6 */ - ULONG address; /* 8, 10 */ -} __dpmi_meminfo; - -typedef union { - struct { - ULONG edi; - ULONG esi; - ULONG ebp; - ULONG res; - ULONG ebx; - ULONG edx; - ULONG ecx; - ULONG eax; - } d; - struct { - unsigned short di, di_hi; - unsigned short si, si_hi; - unsigned short bp, bp_hi; - unsigned short res, res_hi; - unsigned short bx, bx_hi; - unsigned short dx, dx_hi; - unsigned short cx, cx_hi; - unsigned short ax, ax_hi; - unsigned short flags; - unsigned short es; - unsigned short ds; - unsigned short fs; - unsigned short gs; - unsigned short ip; - unsigned short cs; - unsigned short sp; - unsigned short ss; - } x; - struct { - unsigned char edi[4]; - unsigned char esi[4]; - unsigned char ebp[4]; - unsigned char res[4]; - unsigned char bl, bh, ebx_b2, ebx_b3; - unsigned char dl, dh, edx_b2, edx_b3; - unsigned char cl, ch, ecx_b2, ecx_b3; - unsigned char al, ah, eax_b2, eax_b3; - } h; -} __attribute__((packed)) __dpmi_regs; - -typedef struct { - unsigned char major; - unsigned char minor; - unsigned short flags; - unsigned char cpu; - unsigned char master_pic; - unsigned char slave_pic; -} __dpmi_version_ret; - -typedef struct { - ULONG largest_available_free_block_in_bytes; - ULONG maximum_unlocked_page_allocation_in_pages; - ULONG maximum_locked_page_allocation_in_pages; - ULONG linear_address_space_size_in_pages; - ULONG total_number_of_unlocked_pages; - ULONG total_number_of_free_pages; - ULONG total_number_of_physical_pages; - ULONG free_linear_address_space_in_pages; - ULONG size_of_paging_file_partition_in_pages; - ULONG reserved[3]; -} __dpmi_free_mem_info; - -typedef struct { - ULONG total_allocated_bytes_of_physical_memory_host; - ULONG total_allocated_bytes_of_virtual_memory_host; - ULONG total_available_bytes_of_virtual_memory_host; - ULONG total_allocated_bytes_of_virtual_memory_vcpu; - ULONG total_available_bytes_of_virtual_memory_vcpu; - ULONG total_allocated_bytes_of_virtual_memory_client; - ULONG total_available_bytes_of_virtual_memory_client; - ULONG total_locked_bytes_of_memory_client; - ULONG max_locked_bytes_of_memory_client; - ULONG highest_linear_address_available_to_client; - ULONG size_in_bytes_of_largest_free_memory_block; - ULONG size_of_minimum_allocation_unit_in_bytes; - ULONG size_of_allocation_alignment_unit_in_bytes; - ULONG reserved[19]; -} __dpmi_memory_info; - -typedef struct { - ULONG data16[2]; - ULONG code16[2]; - unsigned short ip; - unsigned short reserved; - ULONG data32[2]; - ULONG code32[2]; - ULONG eip; -} __dpmi_callback_info; - -typedef struct { - ULONG size_requested; - ULONG size; - ULONG handle; - ULONG address; - ULONG name_offset; - unsigned short name_selector; - unsigned short reserved1; - ULONG reserved2; -} __dpmi_shminfo; - -#endif diff --git a/src/djdev64/include/djdev64/dpmi_inc.h b/src/djdev64/include/djdev64/dpmi_inc.h deleted file mode 100644 index 8e3247be..00000000 --- a/src/djdev64/include/djdev64/dpmi_inc.h +++ /dev/null @@ -1,146 +0,0 @@ -/* - * dj64 - 64bit djgpp-compatible tool-chain - * Copyright (C) 2021-2024 @stsp - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -vDDv(dpmi_yield) - -DD(int, dpmi_allocate_ldt_descriptors, (int _count), _count) -DD(int, dpmi_free_ldt_descriptor, (int _descriptor), _descriptor) -DD(int, dpmi_segment_to_descriptor, (int _segment), _segment) -DDv(int, dpmi_get_selector_increment_value) -DD(int, dpmi_get_segment_base_address, (int _selector, ULONG *_addr), _selector, _addr) -DD(int, dpmi_set_segment_base_address, (int _selector, ULONG _address), _selector, _address) -DD(ULONG, dpmi_get_segment_limit, (int _selector), _selector) -DD(int, dpmi_set_segment_limit, (int _selector, ULONG _limit), _selector, _limit) -DD(int, dpmi_get_descriptor_access_rights, (int _selector), _selector) -DD(int, dpmi_set_descriptor_access_rights, (int _selector, int _rights), _selector, _rights) -DD(int, dpmi_create_alias_descriptor, (int _selector), _selector) -DD(int, dpmi_get_descriptor, (int _selector, void *_buffer), _selector, _buffer) -DD(int, dpmi_set_descriptor, (int _selector, void *_buffer), _selector, _buffer) -DD(int, dpmi_allocate_specific_ldt_descriptor, (int _selector), _selector) - -DD(int, dpmi_get_multiple_descriptors, (int _count, void *_buffer), _count, _buffer) /* DPMI 1.0 AX=000e */ -DD(int, dpmi_set_multiple_descriptors, (int _count, void *_buffer), _count, _buffer) - -DD(int, dpmi_allocate_dos_memory, (int _paragraphs, int *_ret_selector_or_max), - _paragraphs, _ret_selector_or_max) -DD(int, dpmi_free_dos_memory, (int _selector), _selector) -DD(int, dpmi_resize_dos_memory, (int _selector, int _newpara, int *_ret_max), - _selector, _newpara, _ret_max) - -DD(int, dpmi_get_real_mode_interrupt_vector, (int _vector, __dpmi_raddr *_address), - _vector, _address) -DD(int, dpmi_set_real_mode_interrupt_vector, (int _vector, __dpmi_raddr *_address), - _vector, _address) -DD(int, dpmi_get_processor_exception_handler_vector, (int _vector, __dpmi_paddr *_address), - _vector, _address) -DD(int, dpmi_set_processor_exception_handler_vector, (int _vector, __dpmi_paddr *_address), - _vector, _address) -DD(int, dpmi_get_protected_mode_interrupt_vector, (int _vector, __dpmi_paddr *_address), - _vector, _address) -DD(int, dpmi_set_protected_mode_interrupt_vector, (int _vector, __dpmi_paddr *_address), - _vector, _address) - -DD(int, dpmi_get_extended_exception_handler_vector_pm, (int _vector, __dpmi_paddr *_address), - _vector, _address) -DD(int, dpmi_get_extended_exception_handler_vector_rm, (int _vector, __dpmi_paddr *_address), - _vector, _address) -DD(int, dpmi_set_extended_exception_handler_vector_pm, (int _vector, __dpmi_paddr *_address), - _vector, _address) -DD(int, dpmi_set_extended_exception_handler_vector_rm, (int _vector, __dpmi_paddr *_address), - _vector, _address) - -DD(int, dpmi_simulate_real_mode_interrupt, (int _vector, __dpmi_regs *__regs), - _vector, __regs) -DD(int, dpmi_int, (int _vector, __dpmi_regs *__regs), - _vector, __regs) - -DD(int, dpmi_simulate_real_mode_procedure_retf, (__dpmi_regs *__regs), __regs) -DD(int, dpmi_simulate_real_mode_procedure_retf_stack, (__dpmi_regs *__regs, int stack_words_to_copy, const void *stack_data), - __regs, stack_words_to_copy, stack_data) -DD(int, dpmi_simulate_real_mode_procedure_iret, (__dpmi_regs *__regs), __regs) -DD(int, dpmi_allocate_real_mode_callback, (void (*_handler)(void), __dpmi_regs *__regs, __dpmi_raddr *_ret), - _handler, __regs, _ret) -DD(int, dpmi_free_real_mode_callback, (__dpmi_raddr *_addr), _addr) -DD(int, dpmi_get_state_save_restore_addr, (__dpmi_raddr *_rm, __dpmi_paddr *_pm), _rm, _pm) -DD(int, dpmi_get_raw_mode_switch_addr, (__dpmi_raddr *_rm, __dpmi_paddr *_pm), _rm, _pm) - -DD(int, dpmi_get_version, (__dpmi_version_ret *_ret), _ret) - -DD(int, dpmi_get_capabilities, (int *_flags, char *vendor_info), - _flags, vendor_info) - -DD(int, dpmi_get_free_memory_information, (__dpmi_free_mem_info *_info), _info) -DD(int, dpmi_allocate_memory, (__dpmi_meminfo *_info), _info) -DD(int, dpmi_free_memory, (ULONG _handle), _handle) -DD(int, dpmi_resize_memory, (__dpmi_meminfo *_info), _info) - -DD(int, dpmi_allocate_linear_memory, (__dpmi_meminfo *_info, int _commit), - _info, _commit) -DD(int, dpmi_resize_linear_memory, (__dpmi_meminfo *_info, int _commit), - _info, _commit) -DD(int, dpmi_get_page_attributes, (__dpmi_meminfo *_info, short *_buffer), - _info, _buffer) -DD(int, dpmi_set_page_attributes, (__dpmi_meminfo *_info, short *_buffer), - _info, _buffer) -DD(int, dpmi_map_device_in_memory_block, (__dpmi_meminfo *_info, ULONG _physaddr), - _info, _physaddr) -DD(int, dpmi_map_conventional_memory_in_memory_block, (__dpmi_meminfo *_info, ULONG _physaddr), - _info, _physaddr) -DD(int, dpmi_get_memory_block_size_and_base, (__dpmi_meminfo *_info), _info) -DD(int, dpmi_get_memory_information, (__dpmi_memory_info *_buffer), _buffer) - -DD(int, dpmi_lock_linear_region, (__dpmi_meminfo *_info), _info) -DD(int, dpmi_unlock_linear_region, (__dpmi_meminfo *_info), _info) -DD(int, dpmi_mark_real_mode_region_as_pageable, (__dpmi_meminfo *_info), _info) -DD(int, dpmi_relock_real_mode_region, (__dpmi_meminfo *_info), _info) -DD(int, dpmi_get_page_size, (ULONG *_size), _size) - -DD(int, dpmi_mark_page_as_demand_paging_candidate, (__dpmi_meminfo *_info), _info) -DD(int, dpmi_discard_page_contents, (__dpmi_meminfo *_info), _info) - -DD(int, dpmi_physical_address_mapping, (__dpmi_meminfo *_info), _info) -DD(int, dpmi_free_physical_address_mapping, (__dpmi_meminfo *_info), _info) - -DDv(int, dpmi_get_and_disable_virtual_interrupt_state) -DDv(int, dpmi_get_and_enable_virtual_interrupt_state) -DD(int, dpmi_get_and_set_virtual_interrupt_state, (int _old_state), _old_state) -DDv(int, dpmi_get_virtual_interrupt_state) - -DD(int, dpmi_get_vendor_specific_api_entry_point, (char *_id, __dpmi_paddr *_api), - _id, _api) - -DD(int, dpmi_set_debug_watchpoint, (__dpmi_meminfo *_info, int _type), _info, _type) -DD(int, dpmi_clear_debug_watchpoint, (ULONG _handle), _handle) -DD(int, dpmi_get_state_of_debug_watchpoint, (ULONG _handle, int *_status), - _handle, _status) -DD(int, dpmi_reset_debug_watchpoint, (ULONG _handle), _handle) - -DD(int, dpmi_install_resident_service_provider_callback, (__dpmi_callback_info *_info), - _info) -DD(int, dpmi_terminate_and_stay_resident, (int return_code, int paragraphs_to_keep), - return_code, paragraphs_to_keep) - -DD(int, dpmi_allocate_shared_memory, (__dpmi_shminfo *_info), _info) -DD(int, dpmi_free_shared_memory, (LONG _handle), _handle) -DD(int, dpmi_serialize_on_shared_memory, (ULONG _handle, int _flags), - _handle, _flags) -DD(int, dpmi_free_serialization_on_shared_memory, (ULONG _handle, int _flags), - _handle, _flags) - -DDv(int, dpmi_get_coprocessor_status) -DD(int, dpmi_set_coprocessor_emulation, (int _flags), _flags) diff --git a/src/djdev64/include/djdev64/stub.h b/src/djdev64/include/djdev64/stub.h deleted file mode 100644 index 42cde21e..00000000 --- a/src/djdev64/include/djdev64/stub.h +++ /dev/null @@ -1,76 +0,0 @@ -/* - * dj64 - 64bit djgpp-compatible tool-chain - * Copyright (C) 2021-2024 @stsp - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#ifndef STUB_H -#define STUB_H - -#include -#include "djdpmi.h" - -struct dos_ops { - unsigned (*_dos_open)(const char *pathname, unsigned mode, int *handle); - unsigned (*_dos_read)(int handle, void *buffer, unsigned count, unsigned *numread); - unsigned (*_dos_write)(int handle, const void *buffer, unsigned count, unsigned *numwrt); - unsigned long (*_dos_seek)(int handle, unsigned long offset, int origin); - int (*_dos_close)(int handle); - int (*_dos_link_umb)(int on); -}; - -#define DD(r, n, a, ...) \ - r (*__##n) a; -#define DDv(r, n) \ - r (*__##n)(void); -#define vDD(n, a, ...) \ - void (*__##n) a; -#define vDDv(n) \ - void (*__##n)(void); - -struct dpmi_ops { -#include "dpmi_inc.h" -}; - -#undef DD -#undef DDv -#undef vDD -#undef vDDv - -struct stub_ret_regs { - uint16_t fs; - uint16_t ds; - uint16_t cs; - uint32_t eip; -}; - -struct djstub_api { - unsigned psp_sel; - int ifile; - int ver; - struct stub_ret_regs *regs; - char *(*lin2ptr)(unsigned lin); - struct dos_ops *dosops; - struct dpmi_ops *dpmiops; - void (*do_printf)(int prio, const char *fmt, va_list ap); - int (*uput)(int); - int (*elf32_open)(int); - const char *dyn; -}; - -int djstub_main(int argc, char *argv[], char *envp[], int api_ver, - struct djstub_api api); - -#endif diff --git a/src/djdev64/makefile b/src/djdev64/makefile deleted file mode 100644 index 6df42df5..00000000 --- a/src/djdev64/makefile +++ /dev/null @@ -1,46 +0,0 @@ -TOP = ../.. -include $(TOP)/Makefile.conf -SOURCES = djdev64.c elf.c djexec.c -OBJECTS = $(SOURCES:.c=.o) -CFLAGS += -iquote $(srcdir)/include -fpic -ggdb3 -Wall -Wmissing-prototypes -Og -MD \ - $(LIBELF_CFLAGS) - -%.o: %.c - $(CC) $(CFLAGS) -imacros $(TOP)/config.hh -c -o $@ $< - -LIBDIR = $(TOP)/lib -OS = $(shell uname -s) -ifeq ($(OS),Darwin) -LIBN = libdjdev64.0.2.dylib -LIBNS = libdjdev64.dylib -SHARED_LDFLAGS = $(LDFLAGS) -dynamiclib -install_name $(libdir)/$(LIBN) -compatibility_version 0.2 -current_version 0.2 -else -LIBN = libdjdev64.so.0.2 -LIBNV = libdjdev64.so.0 -LIBNS = libdjdev64.so -SHARED_LDFLAGS = $(LDFLAGS) -shared -Wl,-soname=$(LIBNV) -endif -LIB = $(LIBDIR)/$(LIBN) - -.PHONY: subs - -all: $(LIBDIR)/$(LIBNS) $(LIBDIR)/$(LIBNV) subs - -subs: - $(MAKE) -C stub - -clean: - $(MAKE) -C stub clean - $(RM) *.o *.d $(LIBDIR)/libdjdev64.so* $(LIBDIR)/libdjdev64.*dylib - -$(LIBDIR): - mkdir $@ - -$(LIB): $(OBJECTS) | $(LIBDIR) - $(CC) $(SHARED_LDFLAGS) -o $@ $^ \ - $(LIBELF_LIBS) - -$(LIBDIR)/$(LIBNS) $(LIBDIR)/$(LIBNV): $(LIB) - ln -sf $(LIBN) $@ - --include $(wildcard *.d) diff --git a/src/djdev64/stub/coff.c b/src/djdev64/stub/coff.c deleted file mode 100644 index 62884c8d..00000000 --- a/src/djdev64/stub/coff.c +++ /dev/null @@ -1,176 +0,0 @@ -/* - * COFF loader. - * Copyright (C) 2023, stsp2@yandex.ru - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#include -#include -#include -#include -#include -#include -#include "dos.h" -#include "util.h" -#include "coff.h" - -#define STUB_DEBUG 0 -#if STUB_DEBUG -#define stub_debug(...) printf(__VA_ARGS__) -#else -#define stub_debug(...) -#endif - -struct coff_header { - unsigned short f_magic; /* Magic number */ - unsigned short f_nscns; /* Number of Sections */ - int32_t f_timdat; /* Time & date stamp */ - int32_t f_symptr; /* File pointer to Symbol Table */ - int32_t f_nsyms; /* Number of Symbols */ - unsigned short f_opthdr; /* sizeof(Optional Header) */ - unsigned short f_flags; /* Flags */ -}; - -struct opt_header { - unsigned short magic; /* Magic Number */ - unsigned short vstamp; /* Version stamp */ - uint32_t tsize; /* Text size in bytes */ - uint32_t dsize; /* Initialised data size */ - uint32_t bsize; /* Uninitialised data size */ - uint32_t entry; /* Entry point */ - uint32_t text_start; /* Base of Text used for this file */ - uint32_t data_start; /* Base of Data used for this file */ -}; - -struct scn_header { - char s_name[8]; /* Section Name */ - int32_t s_paddr; /* Physical Address */ - int32_t s_vaddr; /* Virtual Address */ - int32_t s_size; /* Section Size in Bytes */ - int32_t s_scnptr; /* File offset to the Section data */ - int32_t s_relptr; /* File offset to the Relocation table for this Section */ - int32_t s_lnnoptr; /* File offset to the Line Number table for this Section */ - unsigned short s_nreloc; /* Number of Relocation table entries */ - unsigned short s_nlnno; /* Number of Line Number table entries */ - int32_t s_flags; /* Flags for this section */ -}; - -enum { SCT_TEXT, SCT_DATA, SCT_BSS, SCT_MAX }; - -static struct scn_header scns[SCT_MAX]; - -struct coff_h { - uint32_t length; - uint32_t entry; -}; - -static void read_section(char *buf, uint32_t va, int ifile, long coffset, int sc) -{ - long bytes; - __dos_seek(ifile, coffset + scns[sc].s_scnptr, SEEK_SET); - bytes = _long_read(ifile, buf, scns[sc].s_vaddr - va, - scns[sc].s_size); - stub_debug("read returned %li\n", bytes); - if (bytes != scns[sc].s_size) { - fprintf(stderr, "err reading %i bytes, got %li\n", - scns[sc].s_size, bytes); -// _exit(EXIT_FAILURE); - } -} - -static void *read_coff_headers(int ifile) -{ - struct coff_header chdr; - struct opt_header ohdr; - struct coff_h *h; - int rc; - unsigned rd; - - rc = __dos_read(ifile, &chdr, sizeof(chdr), &rd); /* get the COFF header */ - if (rc || rd != sizeof(chdr)) { - fprintf(stderr, "bad COFF header\n"); - return NULL; - } - if (chdr.f_opthdr < sizeof(ohdr)) { - fprintf(stderr, "opt header size mismatch: %i %zi\n", - chdr.f_opthdr, sizeof(ohdr)); - return NULL; - } - rc = __dos_read(ifile, &ohdr, sizeof(ohdr), &rd); /* get the COFF opt header */ - if (rc || rd != sizeof(ohdr)) { - fprintf(stderr, "bad COFF opt header\n"); - return NULL; - } - if (chdr.f_opthdr > sizeof(ohdr)) - __dos_seek(ifile, chdr.f_opthdr - sizeof(ohdr), SEEK_CUR); - rc = __dos_read(ifile, scns, sizeof(scns[0]) * SCT_MAX, &rd); - if (rc || rd != sizeof(scns[0]) * SCT_MAX) { - fprintf(stderr, "failed to read section headers\n"); - return NULL; - } -#if STUB_DEBUG - for (int i = 0; i < SCT_MAX; i++) { - struct scn_header *h = &scns[i]; - stub_debug("Section %s pa 0x%lx va 0x%lx size 0x%lx foffs 0x%lx\n", - h->s_name, h->s_paddr, h->s_vaddr, h->s_size, h->s_scnptr); - } -#endif - h = malloc(sizeof(*h)); - assert(h); - h->entry = ohdr.entry; - h->length = scns[SCT_BSS].s_vaddr + scns[SCT_BSS].s_size; - return h; -} - -static uint32_t get_coff_va(void *handle) -{ - return 0; // ??? -} - -static uint32_t get_coff_length(void *handle) -{ - struct coff_h *h = handle; - return h->length; -} - -static uint32_t get_coff_entry(void *handle) -{ - struct coff_h *h = handle; - return h->entry; -} - -static void read_coff_sections(void *handle, char *ptr, uint32_t va, int ifile, - uint32_t offset) -{ - struct coff_h *h = handle; - read_section(ptr, va, ifile, offset, SCT_TEXT); - read_section(ptr, va, ifile, offset, SCT_DATA); - memset(ptr + scns[SCT_BSS].s_vaddr, 0, scns[SCT_BSS].s_size + - (scns[SCT_BSS].s_size & 1)); - free(h); -} - -static void coff_close(void *handle) -{ -} - -struct ldops coff_ops = { - read_coff_headers, - get_coff_va, - get_coff_length, - get_coff_entry, - read_coff_sections, - coff_close, -}; diff --git a/src/djdev64/stub/coff.h b/src/djdev64/stub/coff.h deleted file mode 100644 index 42b23259..00000000 --- a/src/djdev64/stub/coff.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef COFF_H -#define COFF_H - -#include "stub_priv.h" - -extern struct ldops coff_ops; - -#endif diff --git a/src/djdev64/stub/dos.c b/src/djdev64/stub/dos.c deleted file mode 100644 index 5f22c5b1..00000000 --- a/src/djdev64/stub/dos.c +++ /dev/null @@ -1,59 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ -#include -#include "dos.h" - -static struct dos_ops *dosops; - -unsigned __dos_open(const char *pathname, unsigned mode, int *handle) -{ - return dosops->_dos_open(pathname, mode, handle); -} - -unsigned __dos_read(int handle, void *buffer, unsigned count, unsigned *numread) -{ - return dosops->_dos_read(handle, buffer, count, numread); -} - -unsigned __dos_write(int handle, const void *buffer, unsigned count, unsigned *numwrt) -{ - return dosops->_dos_write(handle, buffer, count, numwrt); -} - -unsigned long __dos_seek(int handle, unsigned long offset, int origin) -{ - return dosops->_dos_seek(handle, offset, origin); -} - -int __dos_close(int handle) -{ - return dosops->_dos_close(handle); -} - -int __dos_link_umb(int on) -{ - return dosops->_dos_link_umb(on); -} - -void register_dosops(struct dos_ops *dops) -{ - dosops = dops; -} - -void unregister_dosops(void) -{ - dosops = NULL; -} diff --git a/src/djdev64/stub/dos.h b/src/djdev64/stub/dos.h deleted file mode 100644 index 02603938..00000000 --- a/src/djdev64/stub/dos.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef DOS_H -#define DOS_H - -#include "djdev64/stub.h" - -unsigned __dos_open(const char *pathname, unsigned mode, int *handle); -unsigned __dos_read(int handle, void *buffer, unsigned count, unsigned *numread); -unsigned __dos_write(int handle, const void *buffer, unsigned count, unsigned *numwrt); -unsigned long __dos_seek(int handle, unsigned long offset, int origin); -int __dos_close(int handle); -int __dos_link_umb(int on); - -void register_dosops(struct dos_ops *dops); -void unregister_dosops(void); - -#endif diff --git a/src/djdev64/stub/dpmiwrp.c b/src/djdev64/stub/dpmiwrp.c deleted file mode 100644 index c539f149..00000000 --- a/src/djdev64/stub/dpmiwrp.c +++ /dev/null @@ -1,48 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ -#include -#include "dpmiwrp.h" - -static struct dpmi_ops *dpmiops; - -#define DD(r, n, a, ...) \ -r __##n a { \ - return dpmiops->__##n(__VA_ARGS__); \ -} -#define DDv(r, n) \ -r __##n(void) { \ - return dpmiops->__##n(); \ -} -#define vDD(n, a, ...) \ -void __##n a { \ - dpmiops->__##n(__VA_ARGS__); \ -} -#define vDDv(n) \ -void __##n(void) { \ - dpmiops->__##n(); \ -} - -#include "djdev64/dpmi_inc.h" - -void register_dpmiops(struct dpmi_ops *dops) -{ - dpmiops = dops; -} - -void unregister_dpmiops(void) -{ - dpmiops = NULL; -} diff --git a/src/djdev64/stub/dpmiwrp.h b/src/djdev64/stub/dpmiwrp.h deleted file mode 100644 index f008479e..00000000 --- a/src/djdev64/stub/dpmiwrp.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifndef DPMIWRP_H -#define DPMIWRP_H - -#include "djdev64/stub.h" - -#define DD(r, n, a, ...) \ -r __##n a; -#define DDv(r, n) \ -r __##n(void); -#define vDD(n, a, ...) \ -void __##n a; -#define vDDv(n) \ -void __##n(void); - -#include "djdev64/dpmi_inc.h" - -#undef DD -#undef DDv -#undef vDD -#undef vDDv - -void register_dpmiops(struct dpmi_ops *dops); -void unregister_dpmiops(void); - -#endif diff --git a/src/djdev64/stub/elf.c b/src/djdev64/stub/elf.c deleted file mode 100644 index 20021eea..00000000 --- a/src/djdev64/stub/elf.c +++ /dev/null @@ -1,165 +0,0 @@ -/* - * ELF loader. - * Copyright (C) 2023, @stsp - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#include -#include -#include -#include -#include -#include -#include "dos.h" -#include "util.h" -#include "stub_priv.h" -#include "elf.h" -#include "elfp.h" - -#define STUB_DEBUG 0 -#if STUB_DEBUG -#define stub_debug(...) printf(__VA_ARGS__) -#else -#define stub_debug(...) -#endif - -struct elf_h { - uint32_t va; - uint32_t length; - uint32_t entry; - int phnum; - Elf32_Phdr phdr[0]; -}; - -static void *read_elf_headers(int ifile) -{ - Elf32_Ehdr ehdr; - struct elf_h *h; - int i, rc; - unsigned rd; - long beg = 0, end = 0; - - rc = __dos_read(ifile, &ehdr, sizeof(ehdr), &rd); /* get the ELF header */ - if (rc || rd != sizeof(ehdr)) { - fprintf(stderr, "cant read ELF header\n"); - return NULL; - } - if (memcmp(&ehdr.e_ident, ELFMAG, SELFMAG)) { - fprintf(stderr, "not an ELF\n"); - return NULL; - } - if (ehdr.e_ident[EI_CLASS] != ELFCLASS32) { - fprintf(stderr, "unsupported ELF class %i\n", ehdr.e_ident[EI_CLASS]); - return NULL; - } - if (ehdr.e_ehsize != sizeof(ehdr) || - ehdr.e_phentsize != sizeof(Elf32_Phdr)) { - fprintf(stderr, "bad ELF header\n"); - return NULL; - } - if (ehdr.e_phoff > sizeof(ehdr)) - __dos_seek(ifile, ehdr.e_phoff - sizeof(ehdr), SEEK_CUR); - h = malloc(sizeof(*h) + sizeof(Elf32_Phdr) * ehdr.e_phnum); - assert(h); - rc = __dos_read(ifile, h->phdr, sizeof(Elf32_Phdr) * ehdr.e_phnum, &rd); - if (rc || rd != sizeof(Elf32_Phdr) * ehdr.e_phnum) { - fprintf(stderr, "can't read phdr\n"); - return NULL; - } - h->phnum = ehdr.e_phnum; - for (i = 0; i < ehdr.e_phnum; i++) { - Elf32_Phdr *phdr = &h->phdr[i]; - if (phdr->p_type != PT_LOAD) - continue; - if (phdr->p_align != 4096) { - fprintf(stderr, "unsupported ELF alignment %i\n", phdr->p_align); - return NULL; - } - if (phdr->p_vaddr < beg || !beg) - beg = phdr->p_vaddr; - if (phdr->p_vaddr + phdr->p_memsz > end) - end = phdr->p_vaddr + phdr->p_memsz; -#if STUB_DEBUG - stub_debug("PHDR pa 0x%lx va 0x%lx size 0x%lx foffs 0x%lx\n", - phdr->p_paddr, phdr->p_vaddr, phdr->p_filesz, phdr->p_offset); -#endif - } - h->entry = ehdr.e_entry; - h->va = beg; - h->length = end - beg; - return h; -} - -static uint32_t get_elf_length(void *handle) -{ - struct elf_h *h = handle; - return h->length; -} - -static uint32_t get_elf_entry(void *handle) -{ - struct elf_h *h = handle; - return h->entry; -} - -static uint32_t get_elf_va(void *handle) -{ - struct elf_h *h = handle; - return h->va; -} - -static void read_elf_sections(void *handle, char *ptr, uint32_t va, int ifile, - uint32_t offset) -{ - struct elf_h *h = handle; - int i; - - for (i = 0; i < h->phnum; i++) { - Elf32_Phdr *phdr = &h->phdr[i]; - long bytes; - - if (phdr->p_type != PT_LOAD) - continue; - __dos_seek(ifile, offset + phdr->p_offset, SEEK_SET); - bytes = _long_read(ifile, ptr, phdr->p_vaddr - va, phdr->p_filesz); - stub_debug("read returned %li\n", bytes); - if (bytes != phdr->p_filesz) { - fprintf(stderr, "err reading %i bytes, got %li\n", - phdr->p_filesz, bytes); -// _exit(EXIT_FAILURE); - goto fr; - } - if (phdr->p_memsz > phdr->p_filesz) { - uint32_t len = phdr->p_memsz - phdr->p_filesz; - len += len & 1; // word-align - memset(ptr + phdr->p_vaddr - va + phdr->p_filesz, 0, len); - } - } -fr:; -} - -static void elf_close(void *handle) -{ - free(handle); -} - -struct ldops elf_ops = { - read_elf_headers, - get_elf_va, - get_elf_length, - get_elf_entry, - read_elf_sections, - elf_close, -}; diff --git a/src/djdev64/stub/elf.h b/src/djdev64/stub/elf.h deleted file mode 100644 index 2dded08f..00000000 --- a/src/djdev64/stub/elf.h +++ /dev/null @@ -1,107 +0,0 @@ -/* This file defines standard ELF types, structures, and macros. - Copyright (C) 1995-2023 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - . */ - -#ifndef _ELF_H -#define _ELF_H 1 - -/* Standard ELF types. */ - -#include - -/* Type for a 16-bit quantity. */ -typedef uint16_t Elf32_Half; - -/* Types for signed and unsigned 32-bit quantities. */ -typedef uint32_t Elf32_Word; - -/* Type of addresses. */ -typedef uint32_t Elf32_Addr; - -/* Type of file offsets. */ -typedef uint32_t Elf32_Off; - -/* The ELF file header. This appears at the start of every ELF file. */ - -#define EI_NIDENT (16) - -typedef struct -{ - unsigned char e_ident[EI_NIDENT]; /* Magic number and other info */ - Elf32_Half e_type; /* Object file type */ - Elf32_Half e_machine; /* Architecture */ - Elf32_Word e_version; /* Object file version */ - Elf32_Addr e_entry; /* Entry point virtual address */ - Elf32_Off e_phoff; /* Program header table file offset */ - Elf32_Off e_shoff; /* Section header table file offset */ - Elf32_Word e_flags; /* Processor-specific flags */ - Elf32_Half e_ehsize; /* ELF header size in bytes */ - Elf32_Half e_phentsize; /* Program header table entry size */ - Elf32_Half e_phnum; /* Program header table entry count */ - Elf32_Half e_shentsize; /* Section header table entry size */ - Elf32_Half e_shnum; /* Section header table entry count */ - Elf32_Half e_shstrndx; /* Section header string table index */ -} Elf32_Ehdr; - -/* Fields in the e_ident array. The EI_* macros are indices into the - array. The macros under each EI_* macro are the values the byte - may have. */ - -#define EI_MAG0 0 /* File identification byte 0 index */ -#define ELFMAG0 0x7f /* Magic number byte 0 */ - -#define EI_MAG1 1 /* File identification byte 1 index */ -#define ELFMAG1 'E' /* Magic number byte 1 */ - -#define EI_MAG2 2 /* File identification byte 2 index */ -#define ELFMAG2 'L' /* Magic number byte 2 */ - -#define EI_MAG3 3 /* File identification byte 3 index */ -#define ELFMAG3 'F' /* Magic number byte 3 */ - -/* Conglomeration of the identification bytes, for easy testing as a word. */ -#define ELFMAG "\177ELF" -#define SELFMAG 4 - -#define EI_CLASS 4 /* File class byte index */ -#define ELFCLASSNONE 0 /* Invalid class */ -#define ELFCLASS32 1 /* 32-bit objects */ -#define ELFCLASS64 2 /* 64-bit objects */ -#define ELFCLASSNUM 3 - -/* Program segment header. */ - -typedef struct -{ - Elf32_Word p_type; /* Segment type */ - Elf32_Off p_offset; /* Segment file offset */ - Elf32_Addr p_vaddr; /* Segment virtual address */ - Elf32_Addr p_paddr; /* Segment physical address */ - Elf32_Word p_filesz; /* Segment size in file */ - Elf32_Word p_memsz; /* Segment size in memory */ - Elf32_Word p_flags; /* Segment flags */ - Elf32_Word p_align; /* Segment alignment */ -} Elf32_Phdr; - -/* Legal values for p_type (segment type). */ - -#define PT_NULL 0 /* Program header table entry unused */ -#define PT_LOAD 1 /* Loadable program segment */ - -/* rest of the file is removed by @stsp */ - -#endif /* elf.h */ diff --git a/src/djdev64/stub/elfp.h b/src/djdev64/stub/elfp.h deleted file mode 100644 index 136f12b4..00000000 --- a/src/djdev64/stub/elfp.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef ELFP_H -#define ELFP_H - -#include "stub_priv.h" - -extern struct ldops elf_ops; - -#endif diff --git a/src/djdev64/stub/libdjstub.version b/src/djdev64/stub/libdjstub.version deleted file mode 100644 index 9e68b62b..00000000 --- a/src/djdev64/stub/libdjstub.version +++ /dev/null @@ -1,8 +0,0 @@ -DJSTUB_0.5 { - global: djstub_main; - local: *; -}; - -DJSTUB_0.6 { - global: djstub_main; -} DJSTUB_0.5; diff --git a/src/djdev64/stub/makefile b/src/djdev64/stub/makefile deleted file mode 100644 index e8032845..00000000 --- a/src/djdev64/stub/makefile +++ /dev/null @@ -1,44 +0,0 @@ -TOP = ../../.. -include $(TOP)/Makefile.conf -SOURCES = coff.c elf.c util.c stub.c dpmiwrp.c dos.c -OBJECTS = $(SOURCES:.c=.o) -CFLAGS += -iquote $(srcdir)/../include -fpic -ggdb3 -Wall -Og -MD - -%.o: %.c - $(CC) $(CFLAGS) -c -o $@ $< - -LIBDIR = $(TOP)/lib -OS = $(shell uname -s) -ifeq ($(OS),Darwin) -LIBN = libdjstub64.0.2.dylib -LIBNS = libdjstub64.dylib -SHARED_LDFLAGS = $(LDFLAGS) -dynamiclib -install_name $(libdir)/$(LIBN) -compatibility_version 0.2 -current_version 0.2 -else -LIBN = libdjstub64.so.0.2 -LIBNV = libdjstub64.so.0 -LIBNS = libdjstub64.so -ifeq ($(HOST),SunOS) -SHARED_LDFLAGS = $(LDFLAGS) -shared -Wl,-soname=$(LIBNV) -else -SHARED_LDFLAGS = $(LDFLAGS) -shared -Wl,-soname=$(LIBNV) \ - -Wl,--version-script=$(srcdir)/libdjstub.version -endif -endif -LIB = $(LIBDIR)/$(LIBN) - -all: $(LIBDIR)/$(LIBNS) $(LIBDIR)/$(LIBNV) - -clean: - $(RM) *.o *.d $(LIBDIR)/libdjstub64.so* $(LIBDIR)/libdjstub64.*dylib - -$(LIBDIR): - mkdir $@ - -$(LIB): $(OBJECTS) $(srcdir)/libdjstub.version | $(LIBDIR) - $(CC) $(SHARED_LDFLAGS) \ - -o $@ $(OBJECTS) - -$(LIBDIR)/$(LIBNS) $(LIBDIR)/$(LIBNV): $(LIB) - ln -sf $(LIBN) $@ - --include $(wildcard *.d) diff --git a/src/djdev64/stub/stub.c b/src/djdev64/stub/stub.c deleted file mode 100644 index f9262bab..00000000 --- a/src/djdev64/stub/stub.c +++ /dev/null @@ -1,656 +0,0 @@ -/* - * go32-compatible COFF, PE32 and ELF loader stub. - * Copyright (C) 2022, stsp - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#include -#include -#include -#include -#include -#include -#include -#include "stubinfo.h" -#include "dpmiwrp.h" -#include "dos.h" -#include "dpmiwrp.h" -#include "coff.h" -#include "elfp.h" -#include "util.h" -#include "stub_priv.h" -#include "djdev64/dj64init.h" -#include "djdev64/stub.h" - -#define DJSTUB_VERSION 8 -#define DJSTUB_API_VERSION 5 - -#define STUB_DEBUG 1 -#if STUB_DEBUG -#define stub_debug(f, ...) J_printf(api.do_printf, DJ64_PRINT_LOG, "stub: " f, ##__VA_ARGS__) -#else -#define stub_debug(...) -#endif - -#define FLG1_OFF STFLAGS_OFF -#define FLG2_OFF (STFLAGS_OFF + 1) - -#define STFLG1_rsv2 0x20 // compact 32bit VA layout - pre-v7 stubs -#define STFLG1_STATIC SIFLG_STATIC // 0x40 - static linking -#define STFLG1_ELF 0x80 // ELF payload (since stub-v8) -#define STFLG2_DJ32 0x20 // dj32 payload -#define STFLG2_C32PL 0x40 // have core 32bit payload -#define STFLG2_EMBOV 0x80 // embedded overlay layout - -#define HAS_32PL(buf) (buf[FLG2_OFF] & STFLG2_EMBOV) - -static const int STFLAGS_OFF = 0x38; - -#define MB (1024 * 1024) -#define VA_SZ (2*MB) - -typedef struct -{ - uint32_t offset32; - unsigned short selector; -} DPMI_FP; - -typedef struct -{ - uint16_t rm; - int pm; -} dpmi_dos_block; - -static DPMI_FP clnt_entry; - -static const char *_basename(const char *name) -{ - const char *p; - p = strrchr(name, '\\'); - if (!p) - p = name; - else - p++; - return p; -} - -#if 0 -static char *_fname(char *name) -{ - char *p, *p1; - p = strrchr(name, '\\'); - if (!p) - p = name; - else - p++; - p1 = strrchr(p, '.'); - if (p1) - p1[0] = '\0'; - return p; -} -#endif - -static unsigned _host_open(const char *pathname, unsigned mode, int *handle) -{ - int fd = open(pathname, mode | O_CLOEXEC); - if (fd == -1) - return 1; - *handle = fd; - return 0; -} - -static unsigned _host_read(int handle, void *buffer, unsigned count, - unsigned *numread) -{ - int rd = read(handle, buffer, count); - if (rd == -1) - return 1; - *numread = rd; - return 0; -} - -static unsigned long _host_seek(int handle, unsigned long offset, int origin) -{ - return lseek(handle, offset, origin); -} - -static int _host_close(int handle) -{ - return close(handle); -} - -static struct dos_ops hops = { - ._dos_open = _host_open, - ._dos_read = _host_read, - ._dos_seek = _host_seek, - ._dos_close = _host_close, -}; - -__attribute__((format(printf, 3, 4))) -static void J_printf(void (*do_printf)(int prio, const char *fmt, va_list ap), - int prio, const char *fmt, ...) -{ - va_list val; - - va_start(val, fmt); - do_printf(prio, fmt, val); - va_end(val); -} - -#define IS_ELF(buf) (buf[0] == 0x7f && buf[1] == 0x45 && \ - buf[2] == 0x4c && buf[3] == 0x46) - -#define EI_CLASS 4 -#define ELFCLASS32 1 -#define ELFCLASS64 2 -#define ELF_IS64(buf) (buf[EI_CLASS] == ELFCLASS64) - -#define SHM_NOEXEC 1 -#define SHM_EXCL 2 -#define SHM_NEW_NS 4 -#define SHM_NS 8 - -#define SHM_FLAGS0 (SHM_NOEXEC | SHM_EXCL | SHM_NEW_NS) -#define SHM_FLAGS1 (SHM_NOEXEC | SHM_EXCL | SHM_NS) -#define SHM_FLAGS (SHM_FLAGS0 | (SHM_FLAGS1 << 8)) - -static int open_dyn(int32_t *cpl_fd, struct dos_ops **ioops, - struct ldops **ops, int (*uput)(int), const char *dyn) -{ - int pfile = open(dyn, O_RDONLY | O_CLOEXEC); - if (pfile == -1) - return -1; - *cpl_fd = uput(pfile); - *ioops = &hops; - *ops = &elf_ops; - return pfile; -} - -#define OPEN_DYN() do { \ - assert(pfile < 0); \ - pfile = open_dyn(&stubinfo.cpl_fd, &ioops, &ops, api.uput, api.dyn); \ - if (pfile == -1) { \ - error("unable to open %s\n", api.dyn); \ - return -1; \ - } \ -} while(0) - -enum { OT_COFF, OT_DJ32, OT_E32, OT_E64, OT_D64, OT_D32, OT_MAX }; - -static int find_idx(int type, char *buf) -{ - uint16_t type_map; - int cnt = 0; - memcpy(&type_map, &buf[0x36], sizeof(type_map)); - if (type == 0 && type_map == 0) - return 0; - while (type_map) { - uint8_t t = type_map & 0xf; - if (t == type) - return cnt; - type_map >>= 4; - cnt++; - } - return -1; -} - -static int find_size(int type, char *buf) -{ - uint32_t size; - int idx = find_idx(type, buf); - if (idx == -1) - return -1; - memcpy(&size, &buf[0x1c + idx * 4], sizeof(size)); - return size; -} - -static int find_offs(int type, char *buf) -{ - uint16_t type_map; - int offs = 0, cnt = 0; - memcpy(&type_map, &buf[0x36], sizeof(type_map)); - if (type == 0 && type_map == 0) - return 0; - while (type_map) { - uint32_t off; - uint8_t t = type_map & 0xf; - if (t == type) - return offs; - memcpy(&off, &buf[0x1c + cnt * 4], sizeof(off)); - offs += off; - type_map >>= 4; - cnt++; - } - return -1; -} - -static int get_type0(char *buf) -{ - if (!(buf[FLG1_OFF] & STFLG1_ELF)) - return OT_COFF; - if (buf[FLG2_OFF] & STFLG2_DJ32) - return OT_DJ32; - return OT_E32; -} - -#define exit(x) return -(x) -#define error(...) J_printf(api.do_printf, DJ64_PRINT_TERMINAL, __VA_ARGS__) -__attribute__((symver("djstub_main@@DJSTUB_0.6"))) -int djstub_main_v6(int argc, char *argv[], char *envp[], int api_ver, - struct djstub_api api) -{ - int pfile = -1; - off_t coffset = 0; - uint32_t coffsize = 0; - uint32_t noffset = 0; - uint32_t nsize = 0; - uint32_t noffset2 = 0; - uint32_t nsize2 = 0; - int rc, i; -#define BUF_SIZE 0x40 - char buf[BUF_SIZE]; - int done = 0; - int dyn = 0; - int pl32 = 0; - uint32_t va; - uint32_t va_size; - uint32_t mem_lin; - uint32_t mem_base; - unsigned short clnt_ds; - unsigned short stubinfo_fs; - __dpmi_meminfo info; - dpmi_dos_block db; - void *handle; - _GO32_StubInfo stubinfo = {0}; - _GO32_StubInfo *stubinfo_p; - struct ldops *ops = NULL; - int dj32 = 0; - struct dos_ops *ioops = api.dosops; - uint8_t stub_ver = 0; - int ifile = api.ifile; - - if ((api.ver & 0xff) != DJSTUB_API_VERSION) { - error("Stub version mismatch: want 0x%x got 0x%x\n", DJSTUB_API_VERSION, api.ver); -// exit(1); - } - - register_dpmiops(api.dpmiops); - stubinfo.cpl_fd = -1; - for (i = 0; envp && envp[i]; i++) { - const char *s = "ELFLOAD="; - int l = strlen(s); - int el = 0, ee = 0; - - if (strncmp(envp[i], s, l) == 0) { - el++; - } else { - s = "ELFEXEC="; - l = strlen(s); - if (strncmp(envp[i], s, l) == 0) - ee++; - } - if (el) { - if (api_ver >= 23) - pfile = api.elf32_open(atoi(envp[i] + l)); - if (pfile < 0) { - /* 64bit elf */ - OPEN_DYN(); - stubinfo.elfload_arg = atoi(envp[i] + l); - dyn = 1; - /* Not setting emb_ov flags: pfile closed, no payload, - * second loader will re-check everything anyway. - * But we set pl32 below to reserve space for upl. */ - } else { - /* 32bit elf */ - dj32 = 1; - ioops = &hops; - ops = &elf_ops; - } - api.dosops->_dos_close(ifile); - ifile = -1; // load dynamically via API - } - if (ee) { - unsigned rd; - - api.dosops->_dos_close(ifile); - ifile = -1; - rc = api.dosops->_dos_open(envp[i] + l, O_RDONLY, &pfile); - if (rc || pfile < 0) { - error("cannot open %s\n", envp[i] + l); - exit(EXIT_FAILURE); - } - rc = api.dosops->_dos_read(pfile, buf, BUF_SIZE, &rd); - if (rc) { - api.dosops->_dos_close(pfile); - error("stub: read() failure\n"); - exit(EXIT_FAILURE); - } - if (rd != BUF_SIZE) { - api.dosops->_dos_close(pfile); - error("stub: read(%i)=%i, wrong exe file\n", BUF_SIZE, rd); - exit(EXIT_FAILURE); - } - if (!IS_ELF(buf)) { - api.dosops->_dos_close(pfile); - error("stub: not an ELF: %s\n", envp[i] + l); - exit(EXIT_FAILURE); - } - api.dosops->_dos_seek(pfile, 0, SEEK_SET); - if (ELF_IS64(buf)) { - ifile = pfile; - pfile = -1; - OPEN_DYN(); - stubinfo.elfload_arg = atoi(envp[i] + l); - dyn = 1; - - /* calling second ldr */ - stubinfo.flags = ((STFLG2_EMBOV) << 8); - stubinfo.flags |= SHM_FLAGS; - nsize = api.dosops->_dos_seek(ifile, 0, SEEK_END); - } else { - dj32 = 1; - ops = &elf_ops; - } - } - if (el || ee) { - pl32 = 1; // even for ELFLOAD we reserve space for pl32 - done = 1; - stubinfo.flags |= SIFLG_ELFEXEC; - break; - } - } - while (!done) { - unsigned rd; -#if STUB_DEBUG - int cnt = 0; -#endif - - stub_debug("Expecting header at 0x%lx\n", coffset); - rc = api.dosops->_dos_read(ifile, buf, BUF_SIZE, &rd); - if (rc) { - error("stub: read() failure\n"); - exit(EXIT_FAILURE); - } - if (rd != BUF_SIZE) { - error("stub: read(%i)=%i, wrong exe file\n", BUF_SIZE, rd); - exit(EXIT_FAILURE); - } - if (buf[0] == 'M' && buf[1] == 'Z' && buf[8] == 4 && buf[9] == 0) { - /* lfanew */ - uint32_t offs; - int moff, sz; - - stub_ver = buf[0x3b]; -#if STUB_DEBUG - cnt++; -#endif - stubinfo.stubinfo_ver |= stub_ver << 16; - if (stub_ver >= 7) - stubinfo.flags |= SIFLG_SPLITPL; - stub_debug("Found exe header %i at 0x%lx\n", cnt, coffset); - memcpy(&offs, &buf[0x3c], sizeof(offs)); - if (!(buf[FLG2_OFF] & STFLG2_C32PL) && (stub_ver < 8 || - (buf[FLG1_OFF] & STFLG1_ELF))) - dyn++; - else - pfile = ifile; - if (HAS_32PL(buf)) - pl32++; - if (buf[FLG2_OFF] & STFLG2_DJ32) { - done = 1; - dj32 = 1; - ops = &elf_ops; - } - if (stub_ver >= 8 && (buf[FLG1_OFF] & STFLG1_ELF)) { - done = 1; - if (dyn) - OPEN_DYN(); - else - ops = &elf_ops; - } - - coffset = offs; - if (stub_ver <= 7) { - noffset = offs; - if (!dyn) { - memcpy(&coffsize, &buf[0x1c], sizeof(coffsize)); - noffset += coffsize; - } - memcpy(&nsize, &buf[0x20 - dyn * 4], sizeof(nsize)); - } else { - if ((sz = find_size(get_type0(buf), buf)) != -1) - coffsize = sz; - if ((moff = find_offs(OT_E64, buf)) != -1) - noffset = offs + moff; - if ((sz = find_size(OT_E64, buf)) != -1) - nsize = sz; - if ((moff = find_offs(OT_D64, buf)) != -1) - noffset2 = offs + moff; - if ((sz = find_size(OT_D64, buf)) != -1) - nsize2 = sz; - if ((!(buf[FLG1_OFF] & STFLG1_ELF) || !dyn) && !coffsize) - exit(EXIT_FAILURE); - } - - memcpy(&stubinfo.flags, &buf[STFLAGS_OFF], 2); - if (stub_ver >= 6) { - uint32_t nmoffs; - memcpy(&nmoffs, &buf[0x28], sizeof(nmoffs)); - if (nmoffs) { - api.dosops->_dos_seek(ifile, noffset + nmoffs, SEEK_SET); - rc = api.dosops->_dos_read(ifile, stubinfo.payload2_name, - 16, &rd); - stubinfo.payload2_name[rd] = '\0'; - } - } else { - error("unsupported stub version %i\n", stub_ver); - return -1; - } - stub_debug("suppl name %s\n", stubinfo.payload2_name[0] ? - stubinfo.payload2_name : ""); - } else if (buf[0] == 0x4c && buf[1] == 0x01) { /* it's a COFF */ - if (dyn) { - /* undo mistake: no dyn with COFF */ - assert(stub_ver < 8); // no such mistake for v8+ - dyn = 0; - pl32 = 1; - pfile = ifile; - } - done = 1; - ops = &coff_ops; - } else if (IS_ELF(buf)) { /* it's an ELF */ - int is_64 = ELF_IS64(buf); - if (!coffset) { - assert(!dyn); - if (is_64) { - dyn++; - OPEN_DYN(); - stubinfo.flags = (STFLG2_EMBOV) << 8; - stubinfo.flags |= SHM_FLAGS; - nsize = api.dosops->_dos_seek(ifile, 0, SEEK_END); - } else { - stubinfo.flags = ((STFLG2_DJ32) << 8); - dj32 = 1; - pfile = ifile; - ops = &elf_ops; - } - pl32 = 1; - } else if (stub_ver >= 8) { - error("djstub: ELF at position %lx (expected COFF)\n", coffset); - return -1; - } else if (is_64 && (stub_ver < 7 || !dyn)) { - error("djstub: 64bit ELF at position %lx\n", coffset); - return -1; - } else if (!dyn) { - ops = &elf_ops; - } - done = 1; - } else { - error("not an exe %s at %lx\n", argv[0], coffset); - exit(EXIT_FAILURE); - } - api.dosops->_dos_seek(ifile, coffset, SEEK_SET); - } - if (dyn && coffset && stub_ver < 8) - OPEN_DYN(); - assert(ops); - assert(pfile != -1); - - if (dj32) - strncpy(stubinfo.magic, "dj32 (C) stsp", sizeof(stubinfo.magic)); - else - strncpy(stubinfo.magic, "dj64 (C) stsp", sizeof(stubinfo.magic)); - stubinfo.size = sizeof(stubinfo); - i = 3; - while(envp && *envp) { - i += strlen(*envp) + 1; - envp++; - } - if (argv && argv[0]) - i += strlen(argv[0]) + 1; - stub_debug("env size %i\n", i); - stubinfo.env_size = i; - stubinfo.minstack = 0x80000; - stubinfo.minkeep = 0x4000; - if (argv) { - strncpy(stubinfo.argv0, _basename(argv[0]), sizeof(stubinfo.argv0)); - stubinfo.argv0[sizeof(stubinfo.argv0) - 1] = '\0'; - } else { - stubinfo.argv0[0] = '\0'; - } - /* basename seems unused and produces warning about missing 0-terminator */ -// strncpy(stubinfo.basename, _fname(argv0), sizeof(stubinfo.basename)); -// stubinfo.basename[sizeof(stubinfo.basename) - 1] = '\0'; - strncpy(stubinfo.dpmi_server, "CWSDPMI.EXE", sizeof(stubinfo.dpmi_server)); -#define max(a, b) ((a) > (b) ? (a) : (b)) - stubinfo.psp_selector = api.psp_sel; - /* DJGPP relies on ds_selector, cs_selector and ds_segment all mapping - * the same real-mode memory block. */ - api.dosops->_dos_link_umb(1); - db.rm = __dpmi_allocate_dos_memory(stubinfo.minkeep >> 4, &db.pm); - api.dosops->_dos_link_umb(0); - stub_debug("rm seg 0x%x\n", db.rm); - stubinfo.ds_selector = db.pm; - stubinfo.ds_segment = db.rm; - /* create alias */ - stubinfo.cs_selector = __dpmi_create_alias_descriptor(db.pm); - /* set descriptor access rights */ - __dpmi_set_descriptor_access_rights(stubinfo.cs_selector, 0x00fb); - - clnt_entry.selector = __dpmi_allocate_ldt_descriptors(1); - clnt_ds = __dpmi_allocate_ldt_descriptors(1); - - register_dosops(ioops); - handle = ops->read_headers(pfile); - if (!handle) - exit(EXIT_FAILURE); - va = ops->get_va(handle); - va_size = ops->get_length(handle); - clnt_entry.offset32 = ops->get_entry(handle); - stub_debug("va 0x%x va_size 0x%x entry 0x%x\n", - va, va_size, clnt_entry.offset32); - if (!dj32 && va_size > MB) - exit(EXIT_FAILURE); - /* if we load 2 payloads, use larger estimate */ - if (pl32) { - stubinfo.initial_size = VA_SZ; - stubinfo.upl_base = va; - stubinfo.upl_size = VA_SZ; - } else { - stubinfo.initial_size = max(va_size, 0x10000); - } - info.size = PAGE_ALIGN(stubinfo.initial_size); - /* allocate mem */ - rc = __dpmi_allocate_memory(&info); - if (rc) - exit(EXIT_FAILURE); - stubinfo.memory_handle = info.handle; - mem_lin = info.address; - mem_base = mem_lin - va; - stubinfo.mem_base = mem_base; - stub_debug("mem_lin 0x%x mem_base 0x%x\n", mem_lin, mem_base); - ops->read_sections(handle, api.lin2ptr(mem_lin), va, pfile, dyn ? 0 : coffset); - ops->close(handle); - /* host fd can clash with DOS fd, so check also ioops */ - if (dj32 && (pfile != ifile || ioops == &hops)) - __dos_close(pfile); - unregister_dosops(); - - /* set base */ - __dpmi_set_segment_base_address(clnt_entry.selector, mem_base); - /* set descriptor access rights */ - __dpmi_set_descriptor_access_rights(clnt_entry.selector, 0xc0fb); - /* set limit */ - __dpmi_set_segment_limit(clnt_entry.selector, 0xffffffff); - /* set base */ - __dpmi_set_segment_base_address(clnt_ds, mem_base); - /* set descriptor access rights */ - __dpmi_set_descriptor_access_rights(clnt_ds, 0xc0f3); - /* set limit */ - __dpmi_set_segment_limit(clnt_ds, 0xffffffff); - - stubinfo_fs = __dpmi_allocate_ldt_descriptors(1); - info.size = PAGE_ALIGN(sizeof(_GO32_StubInfo)); - __dpmi_allocate_memory(&info); - __dpmi_set_segment_base_address(stubinfo_fs, info.address); - __dpmi_set_segment_limit(stubinfo_fs, sizeof(_GO32_StubInfo) - 1); - stubinfo_p = (_GO32_StubInfo *)api.lin2ptr(info.address); - - stubinfo.self_fd = ifile; - stubinfo.self_offs = coffset; - stubinfo.self_size = coffsize; - stubinfo.payload_offs = noffset; - stubinfo.payload_size = nsize; - stubinfo.payload2_offs = noffset2; - stubinfo.payload2_size = nsize2; - api.dosops->_dos_seek(ifile, noffset, SEEK_SET); - if (nsize > 0) - stub_debug("Found payload of size %i at 0x%x\n", nsize, noffset); - stubinfo.stubinfo_ver |= DJSTUB_VERSION | ((api.ver & 0xff00) << 16); - - unregister_dpmiops(); - - memcpy(stubinfo_p, &stubinfo, sizeof(stubinfo)); - stub_debug("Jump to entry...\n"); - api.regs->fs = stubinfo_fs; - api.regs->ds = clnt_ds; - api.regs->cs = clnt_entry.selector; - api.regs->eip = clnt_entry.offset32; - return 0; -} - -__attribute__((symver("djstub_main@DJSTUB_0.5"))) -int djstub_main_v5(int argc, char *argv[], char *envp[], - unsigned psp_sel, int ifile, int ver, - struct stub_ret_regs *regs, char *(*lin2ptr)(unsigned lin), - struct dos_ops *dosops, struct dpmi_ops *dpmiops, - void (*do_printf)(int prio, const char *fmt, va_list ap), - int (*uput)(int), int (*elf32_open)(int), int api_ver) -{ - struct djstub_api sapi = { - .psp_sel = psp_sel, - .ifile = ifile, - .ver = ver, - .regs = regs, - .lin2ptr = lin2ptr, - .dosops = dosops, - .dpmiops = dpmiops, - .do_printf = do_printf, - .uput = uput, - .elf32_open = elf32_open, - .dyn = "/usr/share/dj64/crt0.elf", // hardcoded, backward-compat - }; - return djstub_main_v6(argc, argv, envp, api_ver, sapi); -} diff --git a/src/djdev64/stub/stub_priv.h b/src/djdev64/stub/stub_priv.h deleted file mode 100644 index 43a35dee..00000000 --- a/src/djdev64/stub/stub_priv.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef STUB_PRIV_H -#define STUB_PRIV_H - -struct ldops { - void *(*read_headers)(int ifile); - uint32_t (*get_va)(void *handle); - uint32_t (*get_length)(void *handle); - uint32_t (*get_entry)(void *handle); - void (*read_sections)(void *handle, char *ptr, uint32_t va, int ifile, - uint32_t offset); - void (*close)(void *handle); -}; - -#endif diff --git a/src/djdev64/stub/stubinfo.h b/src/djdev64/stub/stubinfo.h deleted file mode 120000 index a0c4d905..00000000 --- a/src/djdev64/stub/stubinfo.h +++ /dev/null @@ -1 +0,0 @@ -../../../include/libc/stubinfo.h \ No newline at end of file diff --git a/src/djdev64/stub/util.c b/src/djdev64/stub/util.c deleted file mode 100644 index b37c9855..00000000 --- a/src/djdev64/stub/util.c +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (C) 2023, stsp2@yandex.ru - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#include -#include -#include -#include -#include "dos.h" -#include "util.h" - -long _long_read(int file, char *buf, unsigned long offset, unsigned long size) -{ - char tmp[PAGE_SIZE]; - unsigned long done = 0; - -#define min(a, b) ((a) < (b) ? (a) : (b)) - while (size) { - unsigned todo = min(size, sizeof(tmp)); - unsigned rd; - int err = __dos_read(file, tmp, todo, &rd); - if (!err) { - /* word-align memcpy */ - memcpy(buf + offset + done, tmp, rd + (rd & 1)); - done += rd; - size -= rd; - } - if (rd < todo) - break; - } - return done; -} diff --git a/src/djdev64/stub/util.h b/src/djdev64/stub/util.h deleted file mode 100644 index db6ee6f0..00000000 --- a/src/djdev64/stub/util.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef UTIL_H -#define UTIL_H - -#ifndef PAGE_SIZE -#define PAGE_SIZE 4096 -#endif -#define _PAGE_MASK (~(PAGE_SIZE-1)) -/* to align the pointer to the (next) page boundary */ -#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&_PAGE_MASK) - -long _long_read(int file, char *buf, unsigned long offset, - unsigned long size); - -#endif diff --git a/src/libc/dj64/32/makefile b/src/libc/dj64/32/makefile index e145e9b4..eb29d310 100644 --- a/src/libc/dj64/32/makefile +++ b/src/libc/dj64/32/makefile @@ -3,7 +3,7 @@ TOP = ../.. include $(TOP)/../../Makefile.conf include $(srcdir)/$(TOP)/../makefile.inc # cur dir must be searched before .. -CPPFLAGS += -I $(srcdir)/$(TOP)/../djdev64/include -I. -I $(srcdir)/.. +CPPFLAGS += -I $(includedir) -I. -I $(srcdir)/.. P = $(srcdir)/../parsers MP = $(P)/mkproto.sh diff --git a/src/libc/dj64/makefile b/src/libc/dj64/makefile index f4817273..ffad9ee3 100644 --- a/src/libc/dj64/makefile +++ b/src/libc/dj64/makefile @@ -2,7 +2,7 @@ TOP = .. include $(TOP)/../../Makefile.conf include $(srcdir)/$(TOP)/../makefile.inc -CPPFLAGS += -I $(srcdir)/$(TOP)/../djdev64/include +CPPFLAGS += -I $(includedir) P = $(srcdir)/parsers MP = $(P)/mkproto.sh