From 61b152159b8f56f3d3780aa423be2d93c8383920 Mon Sep 17 00:00:00 2001 From: Stas Sergeev Date: Wed, 15 Jul 2026 17:27:35 +0300 Subject: [PATCH 1/6] dj[64|32].mk: re-purpose unused flag 0x80 [#79] It was meant to say "no 32pl" in <=v6, and is unused in v7. Lets re-purpose it for the meaning of ELF. Needs to explicitly request stub v8, as both values of that flag denote existing (and not new) functionality. --- dj32.mk | 2 ++ dj64.mk | 6 ++---- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/dj32.mk b/dj32.mk index cd3adf27..18eb8cb8 100644 --- a/dj32.mk +++ b/dj32.mk @@ -41,6 +41,8 @@ DJ64ASCPPFLAGS = $(DJASCPPFLAGS) $(shell pkg-config --variable=cppflags dj32) LOADADDR = 0x08148000 # static DJ64_XLDFLAGS += -f 0x40 +# ELF +DJ64_XLDFLAGS += -f 0x80 -V 8 XELF = tmp.elf ifeq ($(filter clean install,$(MAKECMDGOALS)),) diff --git a/dj64.mk b/dj64.mk index a9f5f0a2..c849d244 100644 --- a/dj64.mk +++ b/dj64.mk @@ -190,12 +190,10 @@ ifneq ($(.SHELLSTATUS),0) $(error dj64-dev-static not installed) endif DJ64_XLDFLAGS += -l $(S2) -f 0x4000 -else -ifeq ($(AS_OBJECTS),) -DJ64_XLDFLAGS += -f 0x80 -endif endif +DJ64_XLDFLAGS += -f 0x80 -V 8 + $(DJ64_XLIB): $(OBJECTS) $(XELF) $(LD) $^ $(DJLDFLAGS) -o $@ From c09ec0fcb538cd950b6e2b4d93f981c14cdc259a Mon Sep 17 00:00:00 2001 From: Stas Sergeev Date: Wed, 15 Jul 2026 19:59:54 +0300 Subject: [PATCH 2/6] stub: use new flag of v8 [#79] --- src/djdev64/stub/stub.c | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/src/djdev64/stub/stub.c b/src/djdev64/stub/stub.c index 9fb9d510..7ae4a6da 100644 --- a/src/djdev64/stub/stub.c +++ b/src/djdev64/stub/stub.c @@ -49,11 +49,7 @@ #define STFLG1_rsv2 0x20 // compact 32bit VA layout - pre-v7 stubs #define STFLG1_STATIC SIFLG_STATIC // 0x40 - static linking -/* 2 flags below are chosen for compatibility between v4 and v5 stubs. - * They can't be set together, and as such, when we have a core payload, - * there is no indication of whether or not the user payload is also - * present. */ -#define STFLG1_rsv 0x80 // no 32bit payload - pre-v7 stubs +#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 @@ -182,14 +178,14 @@ static int open_dyn(int32_t *cpl_fd, struct dos_ops **ioops, return pfile; } -#define OPEN_DYN() { \ +#define OPEN_DYN() do { \ assert(pfile < 0); \ pfile = open_dyn(&stubinfo.cpl_fd, &ioops, &ops, uput); \ if (pfile == -1) { \ error("unable to open %s\n", CRT0); \ return -1; \ } \ -} +} while(0) #define exit(x) return -(x) #define error(...) J_printf(do_printf, DJ64_PRINT_TERMINAL, __VA_ARGS__) @@ -359,7 +355,8 @@ int djstub_main(int argc, char *argv[], char *envp[], 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)) + if (!(buf[FLG2_OFF] & STFLG2_C32PL) && (stub_ver < 8 || + (buf[FLG1_OFF] & STFLG1_ELF))) dyn++; else pfile = ifile; @@ -378,6 +375,13 @@ int djstub_main(int argc, char *argv[], char *envp[], dj32 = 1; ops = &elf_ops; } + if (stub_ver >= 8 && (buf[FLG1_OFF] & STFLG1_ELF)) { + done = 1; + if (dyn) + OPEN_DYN(); + else + ops = &elf_ops; + } memcpy(&nsize, &buf[0x20 - moff], sizeof(nsize)); if (nsize) @@ -402,6 +406,7 @@ int djstub_main(int argc, char *argv[], char *envp[], } 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; @@ -425,6 +430,9 @@ int djstub_main(int argc, char *argv[], char *envp[], 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; @@ -438,7 +446,7 @@ int djstub_main(int argc, char *argv[], char *envp[], } dosops->_dos_seek(ifile, coffset, SEEK_SET); } - if (dyn && coffset) + if (dyn && coffset && stub_ver < 8) OPEN_DYN(); assert(ops); assert(pfile != -1); From 5ed2297405779668daeaf2320eb1c97ff7fe9ee9 Mon Sep 17 00:00:00 2001 From: Stas Sergeev Date: Thu, 16 Jul 2026 01:08:28 +0300 Subject: [PATCH 3/6] dj[32|64].mk: generate type table for stub-v8 [#79] --- dj32.mk | 1 + dj64.mk | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/dj32.mk b/dj32.mk index 18eb8cb8..ecd7e49d 100644 --- a/dj32.mk +++ b/dj32.mk @@ -43,6 +43,7 @@ LOADADDR = 0x08148000 DJ64_XLDFLAGS += -f 0x40 # ELF DJ64_XLDFLAGS += -f 0x80 -V 8 +DJ64_LINKARGS += -T 1 -D 5 XELF = tmp.elf ifeq ($(filter clean install,$(MAKECMDGOALS)),) diff --git a/dj64.mk b/dj64.mk index c849d244..f2d1c8ad 100644 --- a/dj64.mk +++ b/dj64.mk @@ -189,10 +189,11 @@ S2 := $(shell pkg-config --variable=crt0 dj64_s) ifneq ($(.SHELLSTATUS),0) $(error dj64-dev-static not installed) endif -DJ64_XLDFLAGS += -l $(S2) -f 0x4000 +DJ64_XLDFLAGS += -t 2 -l $(S2) -f 0x4000 endif DJ64_XLDFLAGS += -f 0x80 -V 8 +DJ64_LINKARGS += -T 3 -D 4 $(DJ64_XLIB): $(OBJECTS) $(XELF) $(LD) $^ $(DJLDFLAGS) -o $@ From fabfe288069b47c5787d1ab8e7d052dd0e732f2e Mon Sep 17 00:00:00 2001 From: Stas Sergeev Date: Thu, 16 Jul 2026 01:09:51 +0300 Subject: [PATCH 4/6] stub: use type table of v8 [closes #79] --- src/djdev64/stub/stub.c | 95 +++++++++++++++++++++++++++++++++++------ 1 file changed, 82 insertions(+), 13 deletions(-) diff --git a/src/djdev64/stub/stub.c b/src/djdev64/stub/stub.c index 7ae4a6da..66b1ad9c 100644 --- a/src/djdev64/stub/stub.c +++ b/src/djdev64/stub/stub.c @@ -187,6 +187,64 @@ static int open_dyn(int32_t *cpl_fd, struct dos_ops **ioops, } \ } 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(do_printf, DJ64_PRINT_TERMINAL, __VA_ARGS__) int djstub_main(int argc, char *argv[], char *envp[], @@ -344,7 +402,7 @@ int djstub_main(int argc, char *argv[], char *envp[], if (buf[0] == 'M' && buf[1] == 'Z' && buf[8] == 4 && buf[9] == 0) { /* lfanew */ uint32_t offs; - int moff = 0; + int moff, sz; stub_ver = buf[0x3b]; #if STUB_DEBUG @@ -360,14 +418,6 @@ int djstub_main(int argc, char *argv[], char *envp[], dyn++; else pfile = ifile; - if (stub_ver >= 7 && dyn) - moff = 4; - coffset = offs; - noffset = offs; - if (stub_ver >= 7 && !dyn) { - memcpy(&coffsize, &buf[0x1c], sizeof(coffsize)); - noffset += coffsize; - } if (HAS_32PL(buf)) pl32++; if (buf[FLG2_OFF] & STFLG2_DJ32) { @@ -383,10 +433,29 @@ int djstub_main(int argc, char *argv[], char *envp[], ops = &elf_ops; } - memcpy(&nsize, &buf[0x20 - moff], sizeof(nsize)); - if (nsize) - noffset2 = noffset + nsize; - memcpy(&nsize2, &buf[0x24 - moff], sizeof(nsize2)); + 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; From 04d7d1371be6bb20b38cdd512ebe2210210521aa Mon Sep 17 00:00:00 2001 From: Stas Sergeev Date: Thu, 16 Jul 2026 20:59:59 +0300 Subject: [PATCH 5/6] demos: add DJ64_LINKARGS to makefiles [#79] --- demos/asmsimp/32/makefile | 2 +- demos/asmsimp/makefile | 2 +- demos/file/32/makefile | 2 +- demos/file/makefile | 2 +- demos/helloasm/32/makefile | 2 +- demos/helloasm/makefile | 2 +- demos/int86/32/makefile | 2 +- demos/int86/makefile | 2 +- demos/rmcb/32/makefile | 2 +- demos/rmcb/makefile | 2 +- 10 files changed, 10 insertions(+), 10 deletions(-) diff --git a/demos/asmsimp/32/makefile b/demos/asmsimp/32/makefile index 55e4e7d5..36743c56 100644 --- a/demos/asmsimp/32/makefile +++ b/demos/asmsimp/32/makefile @@ -55,5 +55,5 @@ endif # dj64 sets `DJ64_XOBJS`, `DJ64_XLIB`, `DJ64_XLDFLAGS` $(TGT): $(DJ64_XLIB) - $(LINK) -d $@.dbg $^ -o $@ $(DJ64_XLDFLAGS) + $(LINK) -d $@.dbg $(DJ64_LINKARGS) $^ -o $@ $(DJ64_XLDFLAGS) $(DJSTRIP) $@ diff --git a/demos/asmsimp/makefile b/demos/asmsimp/makefile index 15109600..7c723fd7 100644 --- a/demos/asmsimp/makefile +++ b/demos/asmsimp/makefile @@ -44,7 +44,7 @@ endif # dj64 sets `DJ64_XOBJS`, `DJ64_XLIB`, `DJ64_XLDFLAGS` $(TGT): $(DJ64_XLIB) - $(LINK) -d $@.dbg $^ -o $@ $(DJ64_XLDFLAGS) + $(LINK) -d $@.dbg $(DJ64_LINKARGS) $^ -o $@ $(DJ64_XLDFLAGS) $(DJSTRIP) $@ djgpp/%: diff --git a/demos/file/32/makefile b/demos/file/32/makefile index 7e860d8a..acbe9d86 100644 --- a/demos/file/32/makefile +++ b/demos/file/32/makefile @@ -50,5 +50,5 @@ endif # dj64 sets `DJ64_XOBJS`, `DJ64_XLIB`, `DJ64_XLDFLAGS` $(TGT): $(DJ64_XLIB) - $(LINK) -d $@.dbg $^ -o $@ $(DJ64_XLDFLAGS) + $(LINK) -d $@.dbg $(DJ64_LINKARGS) $^ -o $@ $(DJ64_XLDFLAGS) $(DJSTRIP) $@ diff --git a/demos/file/makefile b/demos/file/makefile index 8afa57e6..92af6396 100644 --- a/demos/file/makefile +++ b/demos/file/makefile @@ -41,7 +41,7 @@ endif # dj64 sets `DJ64_XOBJS`, `DJ64_XLIB`, `DJ64_XLDFLAGS` $(TGT): $(DJ64_XLIB) - $(LINK) -d $@.dbg $^ -o $@ $(DJ64_XLDFLAGS) + $(LINK) -d $@.dbg $(DJ64_LINKARGS) $^ -o $@ $(DJ64_XLDFLAGS) $(DJSTRIP) $@ djgpp/%: diff --git a/demos/helloasm/32/makefile b/demos/helloasm/32/makefile index ec7d9a94..cddca68e 100644 --- a/demos/helloasm/32/makefile +++ b/demos/helloasm/32/makefile @@ -57,5 +57,5 @@ endif # dj64 sets `DJ64_XOBJS`, `DJ64_XLIB`, `DJ64_XLDFLAGS` $(TGT): $(DJ64_XLIB) - $(LINK) -d $@.dbg $^ -o $@ $(DJ64_XLDFLAGS) + $(LINK) -d $@.dbg $(DJ64_LINKARGS) $^ -o $@ $(DJ64_XLDFLAGS) $(DJSTRIP) $@ diff --git a/demos/helloasm/makefile b/demos/helloasm/makefile index 8b6a7f22..2b360db7 100644 --- a/demos/helloasm/makefile +++ b/demos/helloasm/makefile @@ -45,7 +45,7 @@ endif # dj64 sets `DJ64_XOBJS`, `DJ64_XLIB`, `DJ64_XLDFLAGS` $(TGT): $(DJ64_XLIB) - $(LINK) -d $@.dbg $^ -o $@ $(DJ64_XLDFLAGS) + $(LINK) -d $@.dbg $(DJ64_LINKARGS) $^ -o $@ $(DJ64_XLDFLAGS) $(DJSTRIP) $@ djgpp/%: diff --git a/demos/int86/32/makefile b/demos/int86/32/makefile index 7e860d8a..acbe9d86 100644 --- a/demos/int86/32/makefile +++ b/demos/int86/32/makefile @@ -50,5 +50,5 @@ endif # dj64 sets `DJ64_XOBJS`, `DJ64_XLIB`, `DJ64_XLDFLAGS` $(TGT): $(DJ64_XLIB) - $(LINK) -d $@.dbg $^ -o $@ $(DJ64_XLDFLAGS) + $(LINK) -d $@.dbg $(DJ64_LINKARGS) $^ -o $@ $(DJ64_XLDFLAGS) $(DJSTRIP) $@ diff --git a/demos/int86/makefile b/demos/int86/makefile index 8afa57e6..92af6396 100644 --- a/demos/int86/makefile +++ b/demos/int86/makefile @@ -41,7 +41,7 @@ endif # dj64 sets `DJ64_XOBJS`, `DJ64_XLIB`, `DJ64_XLDFLAGS` $(TGT): $(DJ64_XLIB) - $(LINK) -d $@.dbg $^ -o $@ $(DJ64_XLDFLAGS) + $(LINK) -d $@.dbg $(DJ64_LINKARGS) $^ -o $@ $(DJ64_XLDFLAGS) $(DJSTRIP) $@ djgpp/%: diff --git a/demos/rmcb/32/makefile b/demos/rmcb/32/makefile index 9165f494..988330e0 100644 --- a/demos/rmcb/32/makefile +++ b/demos/rmcb/32/makefile @@ -59,5 +59,5 @@ endif # dj64 sets `DJ64_XOBJS`, `DJ64_XLIB`, `DJ64_XLDFLAGS` $(TGT): $(DJ64_XLIB) - $(LINK) -d $@.dbg $^ -o $@ $(DJ64_XLDFLAGS) + $(LINK) -d $@.dbg $(DJ64_LINKARGS) $^ -o $@ $(DJ64_XLDFLAGS) $(DJSTRIP) $@ diff --git a/demos/rmcb/makefile b/demos/rmcb/makefile index 3d6dcfd3..abf865ca 100644 --- a/demos/rmcb/makefile +++ b/demos/rmcb/makefile @@ -46,7 +46,7 @@ endif # dj64 sets `DJ64_XOBJS`, `DJ64_XLIB`, `DJ64_XLDFLAGS` $(TGT): $(DJ64_XLIB) - $(LINK) -d $@.dbg $^ -o $@ $(DJ64_XLDFLAGS) + $(LINK) -d $@.dbg $(DJ64_LINKARGS) $^ -o $@ $(DJ64_XLDFLAGS) $(DJSTRIP) $@ djgpp/%: From d2233dfa002d1c75ea536c643e04d65d90449d53 Mon Sep 17 00:00:00 2001 From: Stas Sergeev Date: Thu, 16 Jul 2026 21:00:22 +0300 Subject: [PATCH 6/6] README: add DJ64_LINKARGS [#79] --- README.md | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index cbe380b0..95d196a8 100644 --- a/README.md +++ b/README.md @@ -241,7 +241,7 @@ clean: clean_dj64 ``` As soon as the dj64's makefile is hooked in, it takes care of compiling the object files and sets the following variables as the result: -`DJ64_XLIB`, `DJ64_XLDFLAGS` and `LINK`. +`DJ64_XLIB`, `DJ64_XLDFLAGS`, `LINK` and DJ64_LINKARGS. You only need to pass those to `djlink` as described below. Another important variable is `DJ64STATIC`. You can set it to `1` @@ -253,14 +253,16 @@ itself on the platforms where dj64 does not support dynamic linking so you may want to strip them with `djstrip`. You can check if the executable is statically linked, by inspecting `bit 6` in `Stub flags`: ``` -$ djstubify -i hello.exe +$ djstubify -i file.exe dj64 file format -Overlay 0 (i386/ELF DOS payload) at 23368, size 30220 -Overlay 1 (x86_64/ELF host payload) at 53588, size 186376 -Overlay 2 (x86_64/ELF host debug info) at 239964, size 347000 -Overlay name: hello.exe -Stub version: 4 -Stub flags: 0x0040 +Overlay 0 (i386/ELF (dj64) DOS payload) + at 32920, size 31468 +Overlay 1 (x86_64/ELF host payload) + at 64388, size 205744 +Overlay 2 (x86_64/ELF debug info for file.exe.dbg) + at 270132, size 848752 +Stub version: 8 +Stub flags: 0x40c0 ``` `0x0040` means that `bit 6` is set, so this is a statically linked executable. It doesn't need `dj64` package to be installed on a host system, as @@ -273,14 +275,15 @@ STRIP = @true # or use `STRIP = djstrip` for non-debug build ... $(TGT): $(DJ64_XLIB) - $(LINK) -d $@.dbg $^ -o $@ $(DJ64_XLDFLAGS) + $(LINK) -d $@.dbg $(DJ64_LINKARGS) $^ -o $@ $(DJ64_XLDFLAGS) $(STRIP) $@ ``` Lets consider this command line, which we get from the above recipe: ``` -djlink -d hello.exe.dbg libtmp.so -o hello.exe -f 0x80 +djlink -d file.exe.dbg -T 3 -D 4 libtmp.so -o file.exe -f 0x80 -V 8 ``` `-d` option sets the debuglink name.
+`-T 3 -D 4` is a content of `DJ64_LINKARGS`.
`libtmp.so` arg is an expansion of `DJ64_XLIB` variable set by dj64 for us.
`-o` specifies the output file.
`-f 0x80` arg is an expansion of `DJ64_XLDFLAGS` variable set by dj64. @@ -292,7 +295,7 @@ For example if you don't need to use debugger, then you can just do: ``` $(TGT): $(DJ64_LIB) strip $^ - djlink $^ -o $@ $(DJ64_XLDFLAGS) + djlink $(DJ64_LINKARGS) $^ -o $@ $(DJ64_XLDFLAGS) ``` to get an executable without debug info. Note the use of `strip` instead of `djstrip` in this example. This is because we strip an intermediate