Compare commits

...

9 Commits

Author SHA1 Message Date
deadwood 4015166e29 Implement functions needed for __showerror
This is first triggered when required library cannot be oped.
2024-03-11 19:15:40 +01:00
deadwood 664362b0a3 LibOpen of crt.library completed 2024-03-11 19:14:24 +01:00
deadwood 056b53536a LibOpen of crt.library up to __init_clock 2024-03-11 18:16:53 +01:00
deadwood 1549ec8c73 Load dos.library binary from disk and run SysBase_autoinit
InitResident cannot be run, because DOS's rt_Init vector is quite
special and part of boot procedure.
2024-03-11 18:01:14 +01:00
deadwood 4e46269f63 Be more selective before running strcmp 2024-03-11 17:59:42 +01:00
deadwood 907933667b Implement call to rt_Init 2024-03-11 16:50:38 +01:00
deadwood cbd93faa88 Fix structure size 2024-03-11 16:50:10 +01:00
deadwood f3b50d5053 Remember to set ds segment when entering 32-bit mode
Otherwise it leads to crash when doing mov from/to memory
2024-03-11 16:01:58 +01:00
deadwood e89e1d98a9 Introduce 1-line proxy macros 2024-03-11 14:29:43 +01:00
9 changed files with 258 additions and 199 deletions

View File

@ -3,14 +3,16 @@
#include <proto/dos.h>
#include <proto/exec.h>
#include <aros/debug.h>
#include <proto/timer.h>
#include <stdio.h>
#include <string.h>
#include "abiv0/include/exec/functions.h"
#include "abiv0/include/aros/asm.h"
#include "abiv0/include/aros/proxy.h"
#include "abiv0/include/aros/cpu.h"
#include "abiv0/include/dos/structures.h"
#include "abiv0/include/timer/structures.h"
BPTR LoadSeg32 (CONST_STRPTR name, struct DosLibrary *DOSBase);
@ -22,73 +24,31 @@ APTR abiv0_AllocMem(ULONG byteSize, ULONG requirements, struct ExecBaseV0 *SysBa
{
return AllocMem(byteSize, requirements | MEMF_31BIT);
}
void proxy_AllocMem();
void dummy_AllocMem()
{
EXTER_PROXY(AllocMem)
ENTER64
COPY_ARG_1
COPY_ARG_2
COPY_ARG_3
CALL_IMPL64(AllocMem)
ENTER32
LEAVE_PROXY
}
MAKE_PROXY_ARG_3(AllocMem)
APTR abiv0_AllocVec(ULONG byteSize, ULONG requirements, struct ExecBaseV0 *SysBaseV0)
{
asm("int3");
return AllocVec(byteSize, requirements | MEMF_31BIT);
}
void proxy_AllocVec();
void dummy_AllocVec()
{
EXTER_PROXY(AllocVec)
ENTER64
COPY_ARG_1
COPY_ARG_2
COPY_ARG_3
CALL_IMPL64(AllocVec)
ENTER32
LEAVE_PROXY
}
MAKE_PROXY_ARG_3(AllocVec)
APTR abiv0_CreatePool(ULONG requirements, ULONG puddleSize, ULONG threshSize, struct ExecBaseV0 *SysBaseV0)
{
return CreatePool(requirements | MEMF_31BIT, puddleSize, threshSize);
}
void proxy_CreatePool();
void dummy_CreatePool()
{
EXTER_PROXY(CreatePool)
ENTER64
COPY_ARG_1
COPY_ARG_2
COPY_ARG_3
CALL_IMPL64(CreatePool)
ENTER32
LEAVE_PROXY
}
MAKE_PROXY_ARG_4(CreatePool)
APTR abiv0_AllocPooled(APTR poolHeader, ULONG memSize, struct ExecBaseV0 *SysBaseV0)
{
return AllocPooled(poolHeader, memSize);
}
MAKE_PROXY_ARG_3(AllocPooled)
void proxy_AllocPooled();
void dummy_AllocPooled()
ULONG abiv0_TypeOfMem(APTR address, struct ExecBaseV0 *SysBaseV0)
{
EXTER_PROXY(AllocPooled)
ENTER64
COPY_ARG_1
COPY_ARG_2
CALL_IMPL64(AllocPooled)
ENTER32
LEAVE_PROXY
return TypeOfMem(address);
}
MAKE_PROXY_ARG_2(TypeOfMem)
struct ResidentV0 * findResident(BPTR seg, CONST_STRPTR name)
{
@ -141,6 +101,9 @@ APTR abiv0_DOS_OpenLibrary(CONST_STRPTR name, ULONG version, struct ExecBaseV0 *
BPTR seglist = LoadSeg32(buff, DOSBase);
if (seglist == BNULL)
return NULL;
struct ResidentV0 *res = findResident(seglist, NULL);
if (res)
@ -183,81 +146,30 @@ void abiv0_PutStr(CONST_STRPTR text)
{
PutStr(text);
}
void proxy_PutStr();
void dummy_PutStr()
{
EXTER_PROXY(PutStr)
ENTER64
COPY_ARG_1
CALL_IMPL64(PutStr)
ENTER32
LEAVE_PROXY
}
MAKE_PROXY_ARG_2(PutStr)
void abiv0_CloseLibrary()
{
}
void proxy_CloseLibrary();
void dummy_CloseLibrary()
{
EXTER_PROXY(CloseLibrary)
ENTER64
COPY_ARG_1
CALL_IMPL64(CloseLibrary)
ENTER32
LEAVE_PROXY
}
MAKE_PROXY_ARG_2(CloseLibrary)
ULONG abiv0_AllocTaskStorageSlot()
{
return AllocTaskStorageSlot();
}
void proxy_AllocTaskStorageSlot();
void dummy_AllocTaskStorageSlot()
{
EXTER_PROXY(AllocTaskStorageSlot)
ENTER64
COPY_ARG_1
CALL_IMPL64(AllocTaskStorageSlot)
ENTER32
LEAVE_PROXY
}
MAKE_PROXY_ARG_2(AllocTaskStorageSlot)
BOOL abiv0_SetTaskStorageSlot(LONG slot, ULONG value)
{
return SetTaskStorageSlot(slot, value);
}
void proxy_SetTaskStorageSlot();
void dummy_SetTaskStorageSlot()
{
EXTER_PROXY(SetTaskStorageSlot)
ENTER64
COPY_ARG_1
COPY_ARG_2
CALL_IMPL64(SetTaskStorageSlot)
ENTER32
LEAVE_PROXY
}
MAKE_PROXY_ARG_3(SetTaskStorageSlot)
ULONG abiv0_GetTaskStorageSlot(LONG id)
{
return GetTaskStorageSlot(id);
}
void proxy_GetTaskStorageSlot();
void dummy_GetTaskStorageSlot()
{
EXTER_PROXY(GetTaskStorageSlot)
ENTER64
COPY_ARG_1
CALL_IMPL64(GetTaskStorageSlot)
ENTER32
LEAVE_PROXY
}
MAKE_PROXY_ARG_2(GetTaskStorageSlot)
APTR abiv0_OpenResource(CONST_STRPTR resName)
{
@ -267,18 +179,7 @@ APTR abiv0_OpenResource(CONST_STRPTR resName)
asm("int3");
return (APTR)0x1;
}
void proxy_OpenResource();
void dummy_OpenResource()
{
EXTER_PROXY(OpenResource)
ENTER64
COPY_ARG_1
COPY_ARG_2
CALL_IMPL64(OpenResource)
ENTER32
LEAVE_PROXY
}
MAKE_PROXY_ARG_2(OpenResource)
LONG abiv0_OpenDevice(CONST_STRPTR devName, ULONG unitNumber, struct IORequestV0 *iORequest)
{
@ -291,75 +192,58 @@ LONG abiv0_OpenDevice(CONST_STRPTR devName, ULONG unitNumber, struct IORequestV0
asm("int3");
return 0;
}
MAKE_PROXY_ARG_4(OpenDevice)
void proxy_OpenDevice();
void dummy_OpenDevice()
{
EXTER_PROXY(OpenDevice)
ENTER64
COPY_ARG_1
COPY_ARG_2
COPY_ARG_3
CALL_IMPL64(OpenDevice)
ENTER32
LEAVE_PROXY
}
void proxy_MakeLibrary();
void dummy_MakeLibrary()
{
EXTER_PROXY(MakeLibrary)
ENTER64
COPY_ARG_1
COPY_ARG_2
COPY_ARG_3
COPY_ARG_4
COPY_ARG_5
COPY_ARG_6
CALL_IMPL64(MakeLibrary)
ENTER32
LEAVE_PROXY
}
MAKE_PROXY_ARG_6(MakeLibrary)
void abiv0_CopyMem(APTR source, APTR dest, ULONG size)
{
return CopyMem(source, dest, size);
}
void proxy_CopyMem();
void dummy_CopyMem()
{
EXTER_PROXY(CopyMem)
ENTER64
COPY_ARG_1
COPY_ARG_2
COPY_ARG_3
CALL_IMPL64(CopyMem)
ENTER32
LEAVE_PROXY
}
MAKE_PROXY_ARG_4(CopyMem)
struct TaskV0 *abiv0_FindTask(CONST_STRPTR name, struct ExecBaseV0 *SysBaseV0)
{
static struct ProcessV0 *dummy = NULL;
if (dummy == NULL) dummy = abiv0_AllocMem(sizeof(struct ProcessV0), MEMF_CLEAR, SysBaseV0);
dummy->pr_Task.tc_Node.ln_Type = NT_PROCESS;
dummy->pr_Task.tc_Node.ln_Name = (APTR32)(IPTR)abiv0_AllocMem(10, MEMF_CLEAR, SysBaseV0);
strcpy((char *)(IPTR)dummy->pr_Task.tc_Node.ln_Name, "emulator");
dummy->pr_CLI = 0x1; //fake
dummy->pr_CIS = 0x1; //fake
dummy->pr_CES = 0x1; //fake
dummy->pr_COS = 0x1; //fake
return (struct TaskV0 *)dummy;
}
MAKE_PROXY_ARG_2(FindTask)
void proxy_FindTask();
void dummy_FindTask()
LONG abiv0_SetVBuf()
{
EXTER_PROXY(FindTask)
ENTER64
COPY_ARG_1
COPY_ARG_2
CALL_IMPL64(FindTask)
ENTER32
LEAVE_PROXY
return 0;
}
MAKE_PROXY_ARG_5(SetVBuf)
void abiv0_GetSysTime(struct timeval *dest, struct LibraryV0 *TimerBaseV0)
{
return GetSysTime(dest);
}
MAKE_PROXY_ARG_2(GetSysTime)
LONG abiv0_FPutC(BPTR file, LONG character, struct DosLibraryV0 DOSBaseV0)
{
if ((IPTR)file == 0x1)
{
return FPutC(Output(), character);
}
asm("int3");
}
MAKE_PROXY_ARG_3(FPutC)
ULONG *execfunctable;
ULONG *dosfunctable;
ULONG *dosinitlist;
LONG_FUNC run_emulation()
{
@ -372,7 +256,8 @@ LONG_FUNC run_emulation()
APTR tmp;
BPTR kernelseg = LoadSeg32("SYS:Libs32/exec/kernel", DOSBase);
/* Keep it! This fills global variable */
LoadSeg32("SYS:Libs32/exec/kernel", DOSBase);
tmp = AllocMem(2048, MEMF_31BIT | MEMF_CLEAR);
struct ExecBaseV0 *sysbase = (tmp + 1024);
@ -386,7 +271,7 @@ LONG_FUNC run_emulation()
__AROS_SETVECADDRV0(sysbase,184, (APTR32)(IPTR)proxy_SetTaskStorageSlot);
__AROS_SETVECADDRV0(sysbase,185, (APTR32)(IPTR)proxy_GetTaskStorageSlot);
__AROS_SETVECADDRV0(sysbase, 83, (APTR32)(IPTR)proxy_OpenResource);
__AROS_SETVECADDRV0(sysbase, 93, execfunctable[92]); // InitSemaphore
__AROS_SETVECADDRV0(sysbase, 93, execfunctable[92]); // InitSemaphore
__AROS_SETVECADDRV0(sysbase, 33, (APTR32)(IPTR)proxy_AllocMem);
__AROS_SETVECADDRV0(sysbase, 14, (APTR32)(IPTR)proxy_MakeLibrary);
__AROS_SETVECADDRV0(sysbase,104, (APTR32)(IPTR)proxy_CopyMem);
@ -394,12 +279,45 @@ LONG_FUNC run_emulation()
__AROS_SETVECADDRV0(sysbase, 74, (APTR32)(IPTR)proxy_OpenDevice);
__AROS_SETVECADDRV0(sysbase,118, (APTR32)(IPTR)proxy_AllocPooled);
__AROS_SETVECADDRV0(sysbase,114, (APTR32)(IPTR)proxy_AllocVec);
__AROS_SETVECADDRV0(sysbase, 46, execfunctable[45]); // FindName
__AROS_SETVECADDRV0(sysbase,135, execfunctable[134]); // TaggedOpenLibrary
__AROS_SETVECADDRV0(sysbase, 89, (APTR32)(IPTR)proxy_TypeOfMem);
__AROS_SETVECADDRV0(sysbase, 41, execfunctable[40]); // AddTail
__AROS_SETVECADDRV0(sysbase, 87, execfunctable[86]); // RawDoFmt
tmp = AllocMem(1024, MEMF_31BIT | MEMF_CLEAR);
struct LibraryV0 *abiv0TimerBase = (tmp + 512);
__AROS_SETVECADDRV0(abiv0TimerBase, 11, (APTR32)(IPTR)proxy_GetSysTime);
/* Keep it! This fills global variable */
LoadSeg32("SYS:Libs32/dos.library", DOSBase);
tmp = AllocMem(2048, MEMF_31BIT | MEMF_CLEAR);
abiv0DOSBase = (tmp + 1024);
abiv0DOSBase->dl_lib.lib_Version = DOSBase->dl_lib.lib_Version;
abiv0DOSBase->dl_TimeReq = (APTR32)(IPTR)AllocMem(sizeof(struct timerequestV0), MEMF_31BIT | MEMF_CLEAR);
((struct timerequestV0 *)(IPTR)abiv0DOSBase->dl_TimeReq)->tr_node.io_Device = (APTR32)(IPTR)abiv0TimerBase;
__asm__ volatile (
"subq $4, %%rsp\n"
"movl %0, %%eax\n"
"movl %%eax, (%%rsp)\n"
"movl %1, %%eax\n"
ENTER32
"call *%%eax\n"
ENTER64
"addq $4, %%rsp\n"
::"m"(sysbase), "m"(dosinitlist[1]) : "%rax", "%rcx");
__AROS_SETVECADDRV0(abiv0DOSBase, 158, (APTR32)(IPTR)proxy_PutStr);
__AROS_SETVECADDRV0(abiv0DOSBase, 9, dosfunctable[8]); // Input
__AROS_SETVECADDRV0(abiv0DOSBase, 10, dosfunctable[9]); // Output
__AROS_SETVECADDRV0(abiv0DOSBase, 61, (APTR32)(IPTR)proxy_SetVBuf);
__AROS_SETVECADDRV0(abiv0DOSBase, 32, dosfunctable[31]); // DateStamp
__AROS_SETVECADDRV0(abiv0DOSBase, 82, dosfunctable[81]); // Cli
__AROS_SETVECADDRV0(abiv0DOSBase, 159, dosfunctable[158]); // VPrintf
__AROS_SETVECADDRV0(abiv0DOSBase, 52, (APTR32)(IPTR)proxy_FPutC);
/* Switch to CS = 0x23 during FAR call. This switches 32-bit emulation mode.
Next, load 0x2B to DS (needed under 32-bit) and NEAR jump to 32-bit code */
@ -432,8 +350,14 @@ LONG_FUNC run_emulation()
:: "m"(start), "m" (sysbase) :);
}
struct timerequest tr;
struct Device *TimerBase;
int main()
{
OpenDevice("timer.device", UNIT_VBLANK, &tr.tr_node, 0);
TimerBase = tr.tr_node.io_Device;
/* Run emulation code with stack allocated in 31-bit memory */
APTR stack31bit = AllocMem(64 * 1024, MEMF_CLEAR | MEMF_31BIT);
struct StackSwapStruct sss;

View File

@ -121,11 +121,24 @@ APTR abiv0_InitResident(struct ResidentV0 *resident, BPTR segList, struct ExecBa
else
{
D(bug("InitResident !RTF_AUTOINIT"));
asm("int3");
// /* ...or let the library do it. */
// if (resident->rt_Init) {
// ExecDoInitResident(library, resident->rt_Init, segList);
// }
/* ...or let the library do it. */
if (resident->rt_Init) {
__asm__ volatile (
"subq $12, %%rsp\n"
"movl %2, %%eax\n"
"movl %%eax, 8(%%rsp)\n"
"movl %3, %%eax\n"
"movl %%eax, 4(%%rsp)\n"
"movl $0, %%eax\n"
"movl %%eax, (%%rsp)\n"
"movl %1, %%eax\n"
ENTER32
"call *%%eax\n"
ENTER64
"addq $12, %%rsp\n"
"movl %%eax, %0\n"
:"=m" (library):"m"(resident->rt_Init), "m"(SysBaseV0), "m"(segList): "%rax", "%rcx");
}
}
D(bug("InitResident end 0x%p (\"%s\"), result 0x%p", resident, resident->rt_Name, library));

View File

@ -1,15 +1,5 @@
#ifndef _AROS_ASM_H
#define _AROS_ASM_H
#define EXTER_PROXY(name) \
__asm__ volatile( \
" .code32\n" \
"proxy_" #name ":\n"
#define LEAVE_PROXY \
" ret\n" \
" .code64\n" \
:::"%ecx");
#ifndef ABIV0_AROS_ASM_H
#define ABIV0_AROS_ASM_H
#define ENTER64 \
" subl $8, %%esp\n" \
@ -27,10 +17,9 @@ __asm__ volatile( \
" movl %%ecx, (%%rsp)\n" \
" lret\n" \
" .code32\n" \
"2:\n"
#define CALL_IMPL64(name) \
" call abiv0_" #name "\n"
"2:\n" \
" push $0x2b\n" \
" pop %%ds\n"
#define COPY_ARG_1 \
" movl 4(%%rsp), %%edi\n"

View File

@ -1,5 +1,5 @@
#ifndef _AROS_CPU_H
#define _AROS_CPU_H
#ifndef ABIV0_AROS_CPU_H
#define ABIV0_AROS_CPU_H
struct JumpVecV0
{

View File

@ -0,0 +1,94 @@
#ifndef ABIV0_AROS_PROXY_H
#define ABIV0_AROS_PROXY_H
#include "./asm.h"
#define EXTER_PROXY(name) \
__asm__ volatile( \
" .code32\n" \
"proxy_" #name ":\n"
#define LEAVE_PROXY \
" ret\n" \
" .code64\n" \
:::"%ecx");
#define CALL_IMPL64(name) \
" call abiv0_" #name "\n"
#define MAKE_PROXY_ARG_2(fname) \
void proxy_##fname(); \
void dummy_##fname() \
{ \
EXTER_PROXY(fname) \
ENTER64 \
COPY_ARG_1 \
COPY_ARG_2 \
CALL_IMPL64(fname) \
ENTER32 \
LEAVE_PROXY \
}
#define MAKE_PROXY_ARG_3(fname) \
void proxy_##fname(); \
void dummy_##fname() \
{ \
EXTER_PROXY(fname) \
ENTER64 \
COPY_ARG_1 \
COPY_ARG_2 \
COPY_ARG_3 \
CALL_IMPL64(fname) \
ENTER32 \
LEAVE_PROXY \
}
#define MAKE_PROXY_ARG_4(fname) \
void proxy_##fname(); \
void dummy_##fname() \
{ \
EXTER_PROXY(fname) \
ENTER64 \
COPY_ARG_1 \
COPY_ARG_2 \
COPY_ARG_3 \
COPY_ARG_4 \
CALL_IMPL64(fname) \
ENTER32 \
LEAVE_PROXY \
}
#define MAKE_PROXY_ARG_5(fname) \
void proxy_##fname(); \
void dummy_##fname() \
{ \
EXTER_PROXY(fname) \
ENTER64 \
COPY_ARG_1 \
COPY_ARG_2 \
COPY_ARG_3 \
COPY_ARG_4 \
COPY_ARG_5 \
CALL_IMPL64(fname) \
ENTER32 \
LEAVE_PROXY \
}
#define MAKE_PROXY_ARG_6(fname) \
void proxy_##fname(); \
void dummy_##fname() \
{ \
EXTER_PROXY(fname) \
ENTER64 \
COPY_ARG_1 \
COPY_ARG_2 \
COPY_ARG_3 \
COPY_ARG_4 \
COPY_ARG_5 \
COPY_ARG_6 \
CALL_IMPL64(fname) \
ENTER32 \
LEAVE_PROXY \
}
#endif

View File

@ -72,6 +72,19 @@ struct DosLibraryV0
{
/* A normal library-base as defined in <exec/libraries.h>. */
struct LibraryV0 dl_lib;
};
#endif
APTR32 dl_Root;
/* private BCPL fields. Do not use. */
APTR32 dl_GV;
APTR32 dl_A2;
APTR32 dl_A5;
APTR32 dl_A6;
/* The following fields are PRIVATE! */
APTR32 dl_Errors;
APTR32 dl_TimeReq;
APTR32 dl_UtilityBase;
APTR32 dl_IntuitionBase;
};
#endif

View File

@ -125,7 +125,7 @@ struct ResidentV0
struct IntVectorV0
{
APTR32 iv_Data;
APTR32 (* iv_Code)();
APTR32 iv_Code;
APTR32 iv_Node;
};

View File

@ -0,0 +1,14 @@
#ifndef ABIV0_TIMER_STRUCTURES_H
#define ABIV0_TIMER_STRUCTURES_H
#include <aros/types/timeval_s.h> /* get struct timeval */
#include "../exec/structures.h"
/* Request used with 32-bit commands */
struct timerequestV0
{
struct IORequestV0 tr_node;
struct timeval32 tr_time;
};
#endif

View File

@ -345,6 +345,7 @@ static int relocate
sym = &symtab[ELF_R_SYM(rel->info)];
p = (APTR)(IPTR)toreloc->addr + rel->offset;
STRPTR name = (STRPTR)(APTR)(IPTR)sh[shsymtab->link].addr + sym->name;
DB2(bug("[ELF Loader] Processing symbol %s\n", sh[shsymtab->link].addr + sym->name));
@ -362,7 +363,6 @@ static int relocate
case SHN_UNDEF:
if (ELF_R_TYPE(rel->info) != 0) {
STRPTR name = (STRPTR)(APTR)(IPTR)sh[shsymtab->link].addr + sym->name;
if (!(name[0] == 'S' && name[3] == 'B')) // SysBase is known undef symbol in 'kernel'
{
bug("[ELF Loader] Undefined symbol '%s'\n",
@ -386,13 +386,25 @@ static int relocate
}
s = (IPTR)sh[shindex].addr + sym->value;
/* UGLY HACK TO GET FUNC TABLE OF EXEC */
if (strcmp((STRPTR)(APTR)(IPTR)sh[shsymtab->link].addr + sym->name, "Exec_FuncTable") == 0)
/* UGLY HACK TO GET FUNC TABLE OF EXEC AND DOS*/
if ((name[0] == 'E') && (strcmp(name, "Exec_FuncTable") == 0))
{
extern ULONG *execfunctable;
execfunctable = (APTR)(IPTR)s;
}
if ((name[0] == 'D') && (strcmp(name, "Dos_FuncTable") == 0))
{
extern ULONG *dosfunctable;
dosfunctable = (APTR)(IPTR)s;
}
if ((name[0] == '_') && (strcmp(name, "__INIT_LIST__") == 0))
{
extern ULONG* dosinitlist;
dosinitlist = (APTR)(IPTR)s;
}
}
switch (ELF_R_TYPE(rel->info))