Skip to content

Newelf #25

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Mar 1, 2025
Merged
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
4 changes: 2 additions & 2 deletions demos/rmcb/asm.S
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
#include "asm.h"

.bss
.global __ds
__ds: .long 0
.global __rmcb_ds
__rmcb_ds: .long 0
.ifndef _DJ64
/* We need emergency stack because __dpmi_int() alters SS in djgpp.
* That was eventually fixed in dj64, hence the ifdef. */
Expand Down
4 changes: 2 additions & 2 deletions demos/rmcb/asm.inc
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
.macro handler_prolog len
push %ds
mov %cs:__ds, %eax
mov %cs:__rmcb_ds, %eax
mov %eax, %ds
.ifndef _DJ64
/* djgpp needs emergency stack because of a bug in __dpmi_int() */
mov %ss, %esi
mov %esp, %edi
pushl __ds
pushl __rmcb_ds
lea _cstack+\len, %edx
push %edx
lss (%esp), %esp
Expand Down
4 changes: 2 additions & 2 deletions demos/rmcb/glob_asm.h
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
__ASM(unsigned short, _ds) SEMIC
__ASM_FUNC(my_mouse_handler) SEMIC
__ASM(unsigned short, _rmcb_ds) SEMIC
__ASM_FUNC(rmcb_mouse_handler) SEMIC
2 changes: 1 addition & 1 deletion demos/rmcb/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ int main()
int ok;

/* our rm cb needs to know DS */
_ds = _my_ds();
_rmcb_ds = _my_ds();

ok = mouse_init();
if (!ok)
Expand Down
2 changes: 1 addition & 1 deletion demos/rmcb/mouse.c
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ int mouse_init(void)
#else
mouse_regs = (__dpmi_regs *) malloc(sizeof(__dpmi_regs));
#endif
__dpmi_allocate_real_mode_callback(my_mouse_handler, mouse_regs,
__dpmi_allocate_real_mode_callback(rmcb_mouse_handler, mouse_regs,
&newm);
r.x.ax = 0x14;
r.x.cx = MEV_MASK;
Expand Down
4 changes: 2 additions & 2 deletions demos/rmcb/ms.S
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
.include "asm.inc"

.text
.global _my_mouse_handler
_my_mouse_handler:
.global _rmcb_mouse_handler
_rmcb_mouse_handler:
pusha
handler_prolog SIGSTK_LEN
call _do_mouse
Expand Down
12 changes: 9 additions & 3 deletions dj64.mk
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,14 @@ XCPPFLAGS = $(shell pkg-config --variable=xcppflags dj64)
ASCPPFLAGS = $(shell pkg-config --variable=cppflags dj64)

LD = $(CC)
# stub version 5
#DJ64_XLDFLAGS = -V 5

ifeq ($(DJ64COMPACT_VA),)
LOADADDR = 0x08148000
else
LOADADDR = 0x08068000
DJ64_XLDFLAGS += -f 0x20
endif

# freebsd's dlopen() ignores link order and binds to libc the symbols
# defined in libdj64.so. Use static linking as a work-around.
ifneq ($(filter freebsd%,$(MACH)),)
Expand Down Expand Up @@ -99,7 +105,7 @@ ifeq ($(DJ64STATIC),1)
XLDFLAGS += $(shell pkg-config --static --libs dj64static)
DJ64_XLDFLAGS += -f 0x4000
else
XLDFLAGS += $(shell pkg-config --variable=crt0 dj64) $(XLD_IMB)=0x08148000
XLDFLAGS += $(shell pkg-config --variable=crt0 dj64) $(XLD_IMB)=$(LOADADDR)
endif
$(XELF).elf: $(AS_OBJECTS) $(PLT_O)
$(XLD) $^ $(XLDFLAGS) -o $@
Expand Down
2 changes: 1 addition & 1 deletion include/dj64/thunks_a.inc
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,6 @@ STATIC struct athunks asm_thunks = {
__attribute__((constructor))
static void init(void)
{
register_athunks(&asm_thunks);
register_athunks(&asm_thunks, DJ64_DYNAPI_VER);
}
#endif
2 changes: 1 addition & 1 deletion include/dj64/thunks_c.inc
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ static dj64dispatch_t DJ64_DISPATCH_FN;
__attribute__((constructor))
static void init(void)
{
register_dispatch_fn(DJ64_DISPATCH_FN);
register_dispatch_fn(DJ64_DISPATCH_FN, DJ64_DYNAPI_VER);
}
#endif

Expand Down
4 changes: 2 additions & 2 deletions include/dj64/thunks_p.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@

uint64_t dj64_asm_call(int num, uint8_t *sp, uint8_t len,
int flags);
uint64_t dj64_asm_call_u(int handle, int num, uint8_t *sp, uint8_t len,
int flags);
uint64_t dj64_asm_call_u(int handle, int libid, int num, uint8_t *sp,
uint8_t len, int flags);
uint8_t *dj64_clean_stk(size_t len);
uint32_t dj64_obj_init(const void *data, uint16_t len);
uint32_t dj64_obj_oinit(const void *data, uint16_t len);
Expand Down
5 changes: 3 additions & 2 deletions include/dj64/thunks_p.inc
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
#ifdef _IN_DJ64
#define __CALL(n, s, l, f) dj64_asm_call(n, s, l, f)
#else
#define __CALL(n, s, l, f) dj64_asm_call_u(_handle, n, s, l, f)
#define __CALL(n, s, l, f) dj64_asm_call_u(_handle, _libid, n, s, l, f)
#endif
#define __CSTK(l) dj64_clean_stk(l)

Expand Down Expand Up @@ -82,6 +82,7 @@

#ifndef _IN_DJ64
static int _handle;
static int _libid;
#define STATIC static
#else
#define STATIC
Expand Down Expand Up @@ -109,6 +110,6 @@ STATIC struct athunks pthunks = {
__attribute__((constructor))
static void init(void)
{
register_pthunks(&pthunks, &_handle);
register_pthunks(&pthunks, &_handle, &_libid, DJ64_DYNAPI_VER);
}
#endif
9 changes: 6 additions & 3 deletions include/dj64/util.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,15 @@
#include <stdint.h>
#include <stdarg.h>

#define DJ64_DYNAPI_VER 2

#define PRINTF(n) __attribute__((format(printf, n, n + 1)))
void djloudprintf(const char *format, ...) PRINTF(1);
void djlogprintf(const char *format, ...) PRINTF(1);
void djloudvprintf(const char *format, va_list vl);

typedef uint32_t (dj64dispatch_t)(int fn, uint8_t *sp, int *r_len);
void register_dispatch_fn(dj64dispatch_t *fn);
void register_dispatch_fn(dj64dispatch_t *fn, int ver);

struct athunk {
const char *name;
Expand All @@ -38,8 +40,9 @@ struct athunks {
int num;
uint32_t *tab;
};
void register_athunks(struct athunks *at);
void register_pthunks(struct athunks *pt, int *handle_p);
void register_athunks(struct athunks *at, int ver);
void register_pthunks(struct athunks *pt, int *handle_p, int *libid_p,
int ver);

#define _countof(array) (sizeof(array) / sizeof(array[0]))

Expand Down
4 changes: 4 additions & 0 deletions include/go64.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,11 @@
#define GO64_H

void pltcall32(__dpmi_regs *regs, __dpmi_paddr addr);
void pltctrl32(__dpmi_regs *regs, int fn, int arg);
void upltinit32(__dpmi_regs *regs);
int elfexec(const char *path, int argc, char **argv);
int elfload(int num);

#define ELFEXEC_LIBID 2

#endif
2 changes: 2 additions & 0 deletions include/libc/djthunks.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,5 +29,7 @@ uint32_t djptr2addr(const uint8_t *ptr);
uint32_t djthunk_get(const char *name);
uint32_t djthunk_get_h(int handle, const char *name);
void *djsbrk(int increment);
int djelf_run(int eid);
int djelf_load(int num, int libid, int *r_fd);

#endif
44 changes: 40 additions & 4 deletions src/djdev64/djdev64.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,17 +39,52 @@ struct dj64handle {
dj64cdispatch_t *ctrl;
dj64done_t *done;
char *path;
const struct djdev64_api *api;
};
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, int hfd, uint32_t *r_size)
{
int fd;
char *ret;
struct dj64handle *h;
if (handle >= handles)
return NULL;
h = &dlhs[handle];
fd = h->api->uget(hfd);
if (fd == -1)
return NULL;
ret = djelf64_parse_fd(fd, r_size);
close(fd);
return ret;
}

static const struct elf_ops eops = {
djelf_open,
djelf_open_dyn,
do_open_dyn,
djelf_close,
djelf_getsymoff,
djelf_reloc,
do_elfparse64,
djelf64_run,
};

#define __S(x) #x
Expand Down Expand Up @@ -137,7 +172,7 @@ static void *emu_dlmopen(int handle, const char *filename, int flags,
#define FLG_STATIC 0x40

static int _djdev64_open(const char *path, const struct dj64_api *api,
int api_ver, unsigned flags)
int api_ver, unsigned flags, const struct djdev64_api *devapi)
{
int rc;
dj64init_t *init;
Expand Down Expand Up @@ -262,6 +297,7 @@ static int _djdev64_open(const char *path, const struct dj64_api *api,
h->ctrl = cdisp[1];
h->done = done;
h->path = path2;
h->api = devapi;
return handles++;

err_close:
Expand All @@ -276,15 +312,15 @@ static int _djdev64_open(const char *path, const struct dj64_api *api,
}

int djdev64_open(const char *path, const struct dj64_api *api, int api_ver,
unsigned flags)
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);
ret = _djdev64_open(path, api, api_ver, flags, devapi);
pthread_mutex_unlock(&init_mtx);
return ret;
}
Expand Down
63 changes: 47 additions & 16 deletions src/djdev64/djexec.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include <setjmp.h>
#include <dlfcn.h>
#include "djdev64/djdev64.h"
#include "elf_priv.h"

struct exec_info {
/* volatile because of longjmp() vs auto storage */
Expand All @@ -28,46 +29,76 @@ struct exec_info {
jmp_buf exit_jmp;
};

struct exec_handle {
void *dlobj;
int (*m)(int, char **);
int (*ae2)(void(*)(void*,int),void*);
int argc;
char **argv;
};
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, unsigned flags, int argc, char **argv)
int djdev64_exec(const char *path, int handle, int libid, unsigned flags,
int argc, char **argv)
{
void *dlobj = NULL;
int (*m)(int, char **);
int (*ae2)(void(*)(void*,int),void*);
struct exec_info ei;
int ret = -1, rc;
struct exec_handle *eh = &ehands[0];
dj64init2_t *i2;

#ifdef RTLD_DEEPBIND
dlobj = dlopen(path, RTLD_LOCAL | RTLD_NOW | RTLD_DEEPBIND);
eh->dlobj = dlopen(path, RTLD_LOCAL | RTLD_NOW | RTLD_DEEPBIND);
#endif
if (!dlobj) {
if (!eh->dlobj) {
printf("error loading %s: %s\n", path, dlerror());
return -1;
}
m = dlsym(dlobj, "main");
if (!m) {
eh->m = dlsym(eh->dlobj, "main");
if (!eh->m) {
printf("error: can't find \"main\"\n");
goto out;
}
ae2 = dlsym(dlobj, "atexit2");
if (!ae2) {
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;
}

rc = ae2(exit_exec, &ei);
i2(handle, libid);
eh->argc = argc;
eh->argv = argv;
return 0;
out:
dlclose(eh->dlobj);
return -1;
}

int djelf64_run(int eid)
{
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)m(argc, argv);
ae2(NULL, NULL);
ret = (unsigned char)eh->m(eh->argc, eh->argv);
eh->ae2(NULL, NULL);
out:
dlclose(dlobj);
dlclose(eh->dlobj);
return ret;
}

Expand Down
1 change: 0 additions & 1 deletion src/djdev64/elf.c
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,6 @@ void *djelf_open_dyn(int fd)
fstat(fd, &st);
addr = (char *)mmap(NULL, st.st_size, PROT_READ | PROT_WRITE, MAP_PRIVATE,
fd, 0);
close(fd);
if (addr == MAP_FAILED) {
perror("mmap()");
return NULL;
Expand Down
Loading