forked from jwt27/djgpp-cvs
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
started implementing go64 [closes #12]
It can load elf files directly.
- Loading branch information
Showing
4 changed files
with
137 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
#ifndef GO64_H | ||
#define GO64_H | ||
|
||
void pltcall32(__dpmi_regs *regs, __dpmi_paddr addr); | ||
int elfexec(const char *path, int argc, char **argv); | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
#include <stdio.h> | ||
#include <string.h> | ||
#include <stdlib.h> | ||
#include <unistd.h> | ||
#include <fcntl.h> | ||
#include <assert.h> | ||
#include <errno.h> | ||
#include <sys/segments.h> | ||
#include <io.h> | ||
#include <dpmi.h> | ||
#include <crt0.h> | ||
#include <go64.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) | ||
|
||
// https://github.com/vonj/snippets.org/blob/master/strrpbrk.c | ||
static char *strrpbrk(const char *szString, const char *szChars) | ||
{ | ||
const char *p; | ||
char *p0, *p1; | ||
|
||
for (p = szChars, p0 = p1 = NULL; p && *p; ++p) | ||
{ | ||
p1 = strrchr(szString, *p); | ||
if (p1 && p1 > p0) | ||
p0 = p1; | ||
} | ||
return p0; | ||
} | ||
|
||
int elfexec(const char *path, int argc, char **argv) | ||
{ | ||
int err, fd, len, errn; | ||
const char *p; | ||
unsigned fname; | ||
__dpmi_paddr api; | ||
__dpmi_shminfo shmi; | ||
__dpmi_meminfo dm; | ||
__dpmi_regs regs; | ||
int en_dis = !(_crt0_startup_flags & _CRT0_FLAG_NEARPTR); | ||
|
||
err = __dpmi_get_vendor_specific_api_entry_point("DJ64", &api); | ||
if (err) { | ||
fprintf(stderr, "DJ64 support missing\n"); | ||
return -1; | ||
} | ||
memset(®s, 0, sizeof(regs)); | ||
regs.d.ebx = 3; // get version | ||
pltcall32(®s, api); | ||
if (regs.d.eax < 2) { | ||
fprintf(stderr, "unsupported DJ64 version %i\n", regs.d.eax); | ||
return -1; | ||
} | ||
fd = open(path, O_RDONLY | O_BINARY); | ||
if (fd == -1) { | ||
fprintf(stderr, "failed to open %s: %s\n", path, strerror(errno)); | ||
return -1; | ||
} | ||
len = filelength(fd); | ||
p = strrpbrk(path, "/\\"); | ||
if (!p) | ||
p = path; | ||
fname = malloc32(strlen(p) + 1); | ||
strcpy(DATA_PTR(fname), p); | ||
shmi.size_requested = len; | ||
shmi.name_offset = fname; | ||
shmi.name_selector = _my_ds(); | ||
err = __dpmi_allocate_shared_memory(&shmi); | ||
assert(!err); | ||
free32(fname); | ||
if (en_dis) | ||
__djgpp_nearptr_enable(); | ||
err = read(fd, djaddr2ptr(shmi.address), len); | ||
errn = errno; | ||
if (en_dis) | ||
__djgpp_nearptr_disable(); | ||
close(fd); | ||
if (err == -1) { | ||
fprintf(stderr, "error reading %s: %s\n", path, strerror(errn)); | ||
return -1; | ||
} | ||
if (err != len) { | ||
fprintf(stderr, "read returned %i, need %i\n", err, len); | ||
return -1; | ||
} | ||
dm.handle = shmi.handle; | ||
dm.address = shmi.address; | ||
dm.size = shmi.size; | ||
err = __dpmi_free_physical_address_mapping(&dm); | ||
assert(!err); | ||
memset(®s, 0, sizeof(regs)); | ||
regs.d.ebx = 2; // exec | ||
regs.x.di = shmi.handle & 0xffff; | ||
regs.x.si = shmi.handle >> 16; | ||
pltcall32(®s, api); | ||
__dpmi_free_shared_memory(shmi.handle); | ||
return regs.d.eax; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
# Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details | ||
TOP=../.. | ||
|
||
AS_SRC += pltcall32.S | ||
SRC += elfexec.c | ||
|
||
include $(TOP)/../makefile.inc |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
#include <libc/asmdefs.h> | ||
|
||
FUNC(_pltcall32) | ||
ENTER | ||
pushal | ||
movl ARG1, %ebx | ||
.irpc i,76543210 | ||
pushl \i*4(%ebx) | ||
.endr | ||
movl %ebp, 8(%esp) // keep ebp untouched | ||
popal | ||
movl __plt_handle, %eax | ||
lcalll *ARG2 | ||
pushal | ||
movl ARG1, %ebx | ||
.irpc i,01234567 | ||
popl \i*4(%ebx) | ||
.endr | ||
popal | ||
LEAVE |