📄 loadprg.c
字号:
/*****************************************************************************
* FILE: loadprg.c *
* *
* DESC: *
* - loader for coff/a.out programs *
* - set args,environment *
* - load text,data (if not DPMI 1.0) *
* *
* Copyright (C) 1993,1994 *
* Rainer Schnitker, Heeper Str. 283, 33607 Bielefeld *
* email: rainer@mathematik.uni-bielefeld.de *
* *
*****************************************************************************/
#include <string.h>
#include "DPMI.H"
#include "DPMI10.H"
#include "PRINTF.H"
#include "RMLIB.H"
#include "PROCESS.H"
#include "FS.H"
#include "GNUAOUT.H"
#include "LOADPRG.H"
#include "COPY32.H"
#include "START32.H"
#include "CDOSX32.H"
#include "RSX.H"
#include "DOSERRNO.H"
static int skip_exe_hdr(int filehandle, DWORD * headoff, NEWPROCESS *p)
{
struct exe_hdr exehdr;
struct emx_hdr2 emxhdr;
rm_read(filehandle, &exehdr, sizeof(struct exe_hdr));
if (exehdr.signatur == 0x5a4d) { /* falls exe-kopf */
*headoff = ((DWORD) exehdr.hdr_para) * 16;
rm_lseek(filehandle, *headoff, SEEK_SET);
rm_read(filehandle, &emxhdr, sizeof(emxhdr));
if (memcmp(emxhdr.sig, "emx", 3) == 0) {
*headoff = *(DWORD *) emxhdr.next_hdr;
if (emxhdr.option[0]) {
char *s = emxhdr.option;
for (; *s != '\0'; ++s) {
while (*s == ' ')
++s;
if (*s == '-') {
s = scan_for_option(++s, p);
} else
break;
}
}
}
else if (memcmp(emxhdr.sig, "rsx", 3) == 0)
goto fail; /* prevent loading rsx32.exe as a.out */
else { /* not a emx file */
long new_off;
rm_lseek(filehandle, 0x3C, SEEK_SET);
rm_read(filehandle, &new_off, sizeof(long));
if (new_off) {
char pe_sig[4];
rm_lseek(filehandle, new_off, SEEK_SET);
rm_read(filehandle, pe_sig, sizeof(pe_sig));
if (pe_sig[0])
*headoff = new_off + 4;
}
else { /* djgpp */
*headoff = (DWORD) exehdr.high * 512L;
if (exehdr.low)
*headoff += (DWORD) exehdr.low - 512L;
}
}
} /* exe files */
if (rm_lseek(filehandle, *headoff, SEEK_SET) == -1L)
goto fail;
return 0;
fail:
*headoff = 0;
rm_lseek(filehandle, 0, SEEK_SET);
return -1;
}
/*
** arguments and environment at process start
**
** environment and argument strings
** argv[]
** envp[]
** pointer to env[0]
** pointer to argv[0]
** int argc
** <- ESP
*/
int argvenv(int argc, char **argv, int envc, char **env, NEWPROCESS * proc)
{
int i;
DWORD len, stkp;
DWORD *vectors;
UINT count = 3; /* 0=argc 1=argv 2=env */
vectors = (DWORD *) iobuf;
stkp = proc->stackp32;
/* store env strings in user stack, built vectors */
for (i = 0; i < envc; i++) {
len = (DWORD) (UINT) strlen(env[i]) + 1;
stkp -= len;
stkp &= ~3L; /* align4 */
cpy16_32(proc->data32sel, stkp, env[i], len);
vectors[count++] = stkp;
}
vectors[count++] = 0; /* last is a NULL pointer */
/* store arg strings in user stack, built vectors */
for (i = 0; i < argc; i++) {
len = (DWORD) (UINT) strlen(argv[i]) + 1;
stkp -= len;
stkp &= ~3L;
cpy16_32(proc->data32sel, stkp, argv[i], len);
vectors[count] = stkp;
count++;
/* for emx: add flag */
stkp -= 1;
put_user_byte(proc->data32sel, stkp, 0x80);
}
vectors[count++] = 0; /* last is a NULL pointer */
stkp &= ~3L;
len = (DWORD) (count * sizeof(long));
stkp -= len;
vectors[0] = argc;
vectors[1] = stkp + (4L + envc) * sizeof(long); /* & vectors[3+nenvp+1] */
vectors[2] = stkp + 3 * sizeof(long); /* & vectors[3] */
cpy16_32(proc->data32sel, stkp, vectors, len);
if (proc->p_flags & PF_EMX_FILE)
stkp += 3 * 4;
proc->stackp32 = stkp;
return 0;
}
void cpy_exename_to_stack(NEWPROCESS *proc, char *name)
{
int len = strlen(name) + 1;
long name_pos = proc->stackp32 - (long) (len + 2 * sizeof(DWORD));
proc->stackp32 -= sizeof(DWORD);
store32(proc->data32sel, proc->stackp32, name_pos);
proc->stackp32 -= sizeof(DWORD);
store32(proc->data32sel, proc->stackp32, (long) len);
proc->stackp32 -= (long) len;
cpy16_32(proc->data32sel, proc->stackp32, name, (long) len);
}
int readin_file(short handle, short r_ds, long r_edx, long count)
{
long bytes;
int rc;
while (count > 0) {
bytes = (count <= IOBUF_SIZE) ? count : (DWORD) IOBUF_SIZE;
rc = rm_read(handle, iobuf, (short) bytes);
cpy16_32(r_ds, r_edx, iobuf, rc);
if (bytes != rc)
break;
count -= bytes;
r_edx += bytes;
}
return 0;
}
/*
**
** RSX program layout:
**
**
** DPMI 0.9 : fixed stack
** never ending heap
**
** emx style
** |--------------------------------------------------------------
** |stack| code | data/bss | stack,if>64KB | heap -> ...
** |--------------------------------------------------------------
** 0 ^64 KB ^(n x 64KB)
**
**
** old djgpp style
** |--------------------------------------------------------------
** | | code | stack | data/bss | heap -> ...
** |--------------------------------------------------------------
** 0 ^4K ^0x400000
**
** djgpp style 1.11
** |--------------------------------------------------------------
** | code | data/bss | stack | heap -> ...
** |--------------------------------------------------------------
** 0 ^ 4 Kb align ^
**
**
**
** DPMI 1.0 : address room = 64 MegaBytes
**
** |--------------------------------------------...-----------------------|
** | | code | | data/bss | heap -> <- stack | mappings |
** | | | | | | DOS 1MB |
** |--------------------------------------------...-----------------------|
** 0 ^60 64
**
*/
#define SHORT_EMX_STACK (0x10000L-0x1000L) /* 64 KB - one R/O page */
#define DEFAULT_STACK (0x40000L) /* 256 KB */
#define TEXT 0
#define DATA 1
#define BSS 2
int load_protected_program(char *filename, NEWPROCESS * proc)
{
FILEHDR file_hdr;
AOUTHDR aout_hdr;
SCNHDR scnd_hdr[3];
DWORD tdbsegm, stacksegm;
DWORD headoff;
UINT stack32sel;
int fhandle;
int use_dpmi10;
if ((fhandle = rm_open(filename, RM_O_RDONLY | RM_O_DENYWR)) == -1)
return doserror_to_errno(_doserrno);
/* skip exe-header, return correct offset in file */
headoff = 0;
skip_exe_hdr(fhandle, &headoff, proc);
/* read file header */
rm_read(fhandle, &file_hdr, sizeof(file_hdr));
if (file_hdr.f_magic == 0x14C) { /* COFF header */
rm_read(fhandle, &aout_hdr, sizeof(aout_hdr));
rm_lseek(fhandle, headoff + sizeof(file_hdr) + file_hdr.f_opthdr, 0);
rm_read(fhandle, scnd_hdr, sizeof(scnd_hdr));
if ((scnd_hdr[TEXT].s_scnptr & 0xFF) == 0xA8) { /* DJGPP */
scnd_hdr[TEXT].s_vaddr &= ~0xFFL;
scnd_hdr[TEXT].s_scnptr &= ~0xFFL; /* align */
scnd_hdr[TEXT].s_size += 0xa8L;
proc->p_flags |= PF_DJGPP_FILE;
}
else {
DWORD image_base;
rm_lseek(fhandle, headoff + sizeof(file_hdr) + file_hdr.f_opthdr, 0);
rm_read(fhandle, &image_base, 4);
if (image_base == 0x400000L)
proc->p_flags |= PF_TNT_FILE;
printf("image base %lX\n", image_base);
}
}
else if (file_hdr.f_magic == 0x10B) {
GNUOUT gnu_hdr;
rm_lseek(fhandle, headoff, 0);
rm_read(fhandle, &gnu_hdr, sizeof(gnu_hdr));
aout_hdr.magic = 0x10B;
aout_hdr.tsize = gnu_hdr.a_text;
aout_hdr.dsize = gnu_hdr.a_data;
aout_hdr.bsize = gnu_hdr.a_bss;
aout_hdr.entry = gnu_hdr.a_entry;
scnd_hdr[TEXT].s_size = gnu_hdr.a_text;
scnd_hdr[DATA].s_size = gnu_hdr.a_data;
scnd_hdr[BSS].s_size = gnu_hdr.a_bss;
if (gnu_hdr.a_entry == 0x10000L) { /* EMX STYLE */
scnd_hdr[TEXT].s_vaddr = 0x10000L;
scnd_hdr[DATA].s_vaddr =
0x10000L + ((gnu_hdr.a_text + 0xFFFFL) & ~0xFFFFL);
scnd_hdr[BSS].s_vaddr =
scnd_hdr[DATA].s_vaddr + gnu_hdr.a_data;
scnd_hdr[TEXT].s_scnptr = 1024;
scnd_hdr[DATA].s_scnptr = 1024 + gnu_hdr.a_text;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -