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
159 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,125 @@ | ||
/* | ||
* dj64 - 64bit djgpp-compatible tool-chain | ||
* Copyright (C) 2021-2024 @stsp | ||
* | ||
* This program is free software: you can redistribute it and/or modify | ||
* it under the terms of the GNU Lesser General Public License as published | ||
* by the Free Software Foundation, either version 3 of the License, or | ||
* (at your option) any later version. | ||
* | ||
* This program is distributed in the hope that it will be useful, | ||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
* GNU Lesser General Public License for more details. | ||
* | ||
* You should have received a copy of the GNU Lesser General Public License | ||
* along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
*/ | ||
|
||
#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); | ||
free32(fname); | ||
if (err) { | ||
close(fd); | ||
fprintf(stderr, "Can't allocate shmem for %s\n", p); | ||
return -1; | ||
} | ||
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 |