Skip to content

Commit

Permalink
started adding dynamic linking
Browse files Browse the repository at this point in the history
  • Loading branch information
stsp committed Oct 1, 2024
1 parent dfd974e commit 841e4db
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 7 deletions.
10 changes: 8 additions & 2 deletions dj64.mk
Original file line number Diff line number Diff line change
Expand Up @@ -61,11 +61,17 @@ endif
endif

ifneq ($(AS_OBJECTS),)
XLDFLAGS = $(shell pkg-config --static --libs dj64static) -melf_i386 -static
XLDFLAGS = -melf_i386
ifeq ($(DJ64STATIC),1)
XLDFLAGS += $(shell pkg-config --static --libs dj64static) -static
DJ64_XLDFLAGS += -f 0x4000
else
XLDFLAGS += -shared -z notext
endif
$(XELF): $(AS_OBJECTS) $(PLT_O)
$(XLD) $^ $(XLDFLAGS) -o $@
$(XSTRIP) $@
DJ64_XLDFLAGS += -l $(XELF) -f 0x4000
DJ64_XLDFLAGS += -l $(XELF)
else
ifeq ($(DJ64STATIC),1)
DJ64_XLDFLAGS += -l $(shell pkg-config --variable=crt0 dj64_s) -f 0x4000
Expand Down
44 changes: 39 additions & 5 deletions src/djdev64/stub/stub.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,9 @@
#define STFLG1_NO32PL 0x80 // no 32bit payload
#define STFLG2_C32PL 0x40 // have core 32bit payload

#define MB (1024 * 1024)
#define VA_SZ (2*MB)

typedef struct
{
uint32_t offset32;
Expand Down Expand Up @@ -162,6 +165,7 @@ int djstub_main(int argc, char *argv[], char *envp[], unsigned psp_sel,
char buf[BUF_SIZE];
int done = 0;
int dyn = 0;
int pl32 = 0;
uint32_t va;
uint32_t va_size;
uint32_t mem_lin;
Expand Down Expand Up @@ -217,17 +221,21 @@ int djstub_main(int argc, char *argv[], char *envp[], unsigned psp_sel,

if (!(buf[FLG2_OFF] & STFLG2_C32PL)) {
dyn++;
noffset = offs;
moff = 4;
pfile = open(CRT0, O_RDONLY | O_CLOEXEC);
ops = &elf_ops;
} else {
pfile = ifile;
}
if (buf[FLG1_OFF] & STFLG1_NO32PL) {
noffset = offs;
moff = 4;
done = 1;
} else {
pl32++;
coffset = offs;
memcpy(&coffsize, &buf[0x1c], sizeof(coffsize));
if (coffsize)
noffset = coffset + coffsize;
pfile = ifile;
}
memcpy(&nsize, &buf[0x20 - moff], sizeof(nsize));
if (nsize)
Expand Down Expand Up @@ -303,7 +311,13 @@ int djstub_main(int argc, char *argv[], char *envp[], unsigned psp_sel,
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);
stubinfo.initial_size = max(va_size, 0x10000);
if (va_size > MB)
exit(EXIT_FAILURE);
/* if we load 2 payloads, use larger estimate */
if (dyn && pl32)
stubinfo.initial_size = VA_SZ;
else
stubinfo.initial_size = max(va_size, 0x10000);
info.size = PAGE_ALIGN(stubinfo.initial_size);
/* allocate mem */
__dpmi_allocate_memory(&info);
Expand All @@ -312,11 +326,31 @@ int djstub_main(int argc, char *argv[], char *envp[], unsigned psp_sel,
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, lin2ptr(mem_base), pfile, coffset);
ops->read_sections(handle, lin2ptr(mem_base), pfile, dyn ? 0 : coffset);
ops->close(handle);
if (dyn)
close(pfile);
unregister_dosops();
if (dyn && pl32) {
uint32_t va2;
uint32_t va_size2;

/* dyn loaded, now pl32 */
register_dosops(dosops);
handle = ops->read_headers(ifile);
if (!handle)
exit(EXIT_FAILURE);
va2 = ops->get_va(handle);
va_size2 = ops->get_length(handle);
stub_debug("va 0x%x va_size 0x%x\n", va2, va_size2);
if (va_size2 > MB)
exit(EXIT_FAILURE);
if (va2 < va + va_size || va2 + va_size2 - va > VA_SZ)
exit(EXIT_FAILURE);
ops->read_sections(handle, lin2ptr(mem_base), ifile, coffset);
ops->close(handle);
unregister_dosops();
}

/* set base */
__dpmi_set_segment_base_address(clnt_entry.selector, mem_base);
Expand Down

0 comments on commit 841e4db

Please sign in to comment.