Skip to content
Merged

v8 #81

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 14 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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`
Expand All @@ -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
Expand All @@ -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.<br/>
`-T 3 -D 4` is a content of `DJ64_LINKARGS`.<br/>
`libtmp.so` arg is an expansion of `DJ64_XLIB` variable set by dj64 for us.<br/>
`-o` specifies the output file.<br/>
`-f 0x80` arg is an expansion of `DJ64_XLDFLAGS` variable set by dj64.
Expand All @@ -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
Expand Down
2 changes: 1 addition & 1 deletion demos/asmsimp/32/makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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) $@
2 changes: 1 addition & 1 deletion demos/asmsimp/makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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/%:
Expand Down
2 changes: 1 addition & 1 deletion demos/file/32/makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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) $@
2 changes: 1 addition & 1 deletion demos/file/makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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/%:
Expand Down
2 changes: 1 addition & 1 deletion demos/helloasm/32/makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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) $@
2 changes: 1 addition & 1 deletion demos/helloasm/makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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/%:
Expand Down
2 changes: 1 addition & 1 deletion demos/int86/32/makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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) $@
2 changes: 1 addition & 1 deletion demos/int86/makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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/%:
Expand Down
2 changes: 1 addition & 1 deletion demos/rmcb/32/makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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) $@
2 changes: 1 addition & 1 deletion demos/rmcb/makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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/%:
Expand Down
3 changes: 3 additions & 0 deletions dj32.mk
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ DJ64ASCPPFLAGS = $(DJASCPPFLAGS) $(shell pkg-config --variable=cppflags dj32)
LOADADDR = 0x08148000
# static
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)),)
Expand Down
9 changes: 4 additions & 5 deletions dj64.mk
Original file line number Diff line number Diff line change
Expand Up @@ -189,13 +189,12 @@ S2 := $(shell pkg-config --variable=crt0 dj64_s)
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
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 $@

Expand Down
119 changes: 98 additions & 21 deletions src/djdev64/stub/stub.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -182,13 +178,71 @@ 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)

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)
Expand Down Expand Up @@ -348,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
Expand All @@ -359,30 +413,49 @@ 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;
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) {
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(&nsize, &buf[0x20 - moff], sizeof(nsize));
if (nsize)
noffset2 = noffset + nsize;
memcpy(&nsize2, &buf[0x24 - moff], sizeof(nsize2));
memcpy(&stubinfo.flags, &buf[STFLAGS_OFF], 2);
if (stub_ver >= 6) {
uint32_t nmoffs;
Expand All @@ -402,6 +475,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;
Expand All @@ -425,6 +499,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;
Expand All @@ -438,7 +515,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);
Expand Down
Loading