1
0
mirror of https://github.com/deadw00d/AROS.git synced 2025-12-10 00:14:36 +00:00

Add code for implementing dynamic module support in executables (primarily game ports). Implements the interface between executable & module, management code, and API calls to resolve symbols.

This commit is contained in:
Kalamatee
2025-08-09 03:20:25 +01:00
committed by deadwood
parent 8597caa655
commit 86ae9fc7fe
13 changed files with 985 additions and 0 deletions

View File

@ -0,0 +1,40 @@
/*
* This file implements the runtime module function, Export.
*/
//#define DEBUG 1
#include <aros/debug.h>
#include "dynmodule_modules.h"
#include <dynmod/dynmodstack.h>
#include <stdlib.h>
#include <string.h>
// module provided symbols...
extern dynmod_export_t DYNMODULE_Exports[];
BOOL dynmodule__InternalMatchSymbol(const char *sym1, const char *sym2)
{
return (strcmp(sym1, sym2) == 0);
}
int dynmoduleExport(dynmod_sym_t *sym)
{
D(bug("[DynLink] %s(0x%p)\n", __func__, sym));
if (sym->SymPtr) {
dynmod_export_t *symtable = DYNMODULE_Exports;
while (symtable->ExportAddress) {
if(dynmodule__InternalMatchSymbol(symtable->ExportName, sym->SymName)) {
*sym->SymPtr = symtable->ExportAddress;
return 1;
}
symtable++;
}
*sym->SymPtr = NULL;
}
return 0;
}

View File

@ -0,0 +1,82 @@
/*
* This file implements the runtime module function, FreeModule.
*/
//#define DEBUG 1
#include <aros/debug.h>
#include "dynmodule_modules.h"
#include <proto/dos.h>
#include <proto/exec.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
void dynmodule__InternalFreeModule(int slotid)
{
__dynmodulemsg_t msg,*reply;
struct MsgPort *replyport, *dmmport;
__dynmoduleinstance_t *dynmod = (__dynmoduleinstance_t *) dynmoduleslots[slotid].mhandle;
D(bug("[DynLink] %s(%u)\n", __func__, slotid));
if (!dynmod)
return;
if (!(replyport = CreateMsgPort()))
DYNMODULE_Exit(0);
memset(&msg.Message, 0, sizeof(struct Message));
msg.Message.mn_ReplyPort = replyport;
msg.IFMsgType = DMIFMSG_Close;
if ((dmmport = FindPort((CONST_STRPTR)dynmoduleslots[slotid].pnam)) == dynmod->dmi_IFMsgPort) {
D(bug("[DynLink] %s: Sending IF Close Msg to Port @ 0x%p\n", __func__, dmmport));
PutMsg(dmmport, (struct Message *)&msg);
while ((reply = (__dynmodulemsg_t *)GetMsg(replyport)) == NULL) {
Delay(2);
if (FindPort((CONST_STRPTR)dynmoduleslots[slotid].pnam) != dynmod->dmi_IFMsgPort)
break;
}
}
D(bug("[DynLink] %s: deleting module\n", __func__, slotid));
dynmodule__InternalDestroyDynModEntry(dynmod, replyport);
memset((APTR)&dynmoduleslots[slotid], 0, sizeof(__dynmoduleentry_t));
dynmodopncnt--;
return;
}
void dynmodule__InternalCleanup()
{
int slotid;
D(bug("[DynLink] %s()\n", __func__));
for (slotid = 0; slotid< DYNMODULE_MAX; slotid++)
if (dynmoduleslots[slotid].mhandle)
dynmodule__InternalFreeModule(slotid);
D(bug("[DynLink] %s: done\n", __func__));
}
void dynmoduleFreeModule(void *mhandle)
{
int slotid;
D(bug("[DynLink] %s(0x%p)\n", __func__, mhandle));
for (slotid = 0; slotid < DYNMODULE_MAX; slotid++)
if (dynmoduleslots[slotid].mhandle == mhandle)
break;
if (slotid < DYNMODULE_MAX) {
dynmoduleslots[slotid].opencnt--;
if (dynmoduleslots[slotid].opencnt <= 0)
dynmodule__InternalFreeModule(slotid);
}
}

View File

@ -0,0 +1,47 @@
/*
* This file implements the runtime module function, GetProcAddress.
*/
//#define DEBUG 1
#include <aros/debug.h>
#include "dynmodule_modules.h"
#include <dos/dos.h>
#include <dos/dostags.h>
#include <proto/exec.h>
#include <string.h>
void *dynmoduleGetProcAddress(void *mhandle, const char *name)
{
void *sym = NULL;
__dynmoduleinstance_t *dynmod;
D(bug("[DynLink] %s(0x%p, '%s')\n", __func__, mhandle, name));
if((dynmod = (__dynmoduleinstance_t *) mhandle) != NULL) {
struct MsgPort *replyport;
if((replyport = CreateMsgPort())) {
__dynmodulemsg_t msg, *reply;
memset(&msg.Message, 0, sizeof(struct Message));
msg.Message.mn_ReplyPort = replyport;
msg.IFMsgType = DMIFMSG_Resolve;
msg.IFResolveRequest.StackFType = dynmod->dmi_StackFType;
msg.IFResolveRequest.SymName = name;
msg.IFResolveRequest.SymPtr = &sym;
PutMsg(dynmod->dmi_IFMsgPort, (struct Message *)&msg);
WaitPort(replyport);
reply = (__dynmodulemsg_t *)GetMsg(replyport);
DeleteMsgPort(replyport);
if (!reply)
sym = NULL;
}
}
return sym;
}

View File

@ -0,0 +1,176 @@
/*
* This file contains glue linked into the dynamic-module
*/
//#define DEBUG 1
#include <aros/debug.h>
#include <exec/exec.h>
#include <proto/exec.h>
#include <proto/dos.h>
#include <string.h>
#include "dynmodule_intern.h"
/*
* symbols provided by the linked module ...
*/
__attribute__((weak)) const char *DYNMODULE_Name = NULL;
extern int DYNMODULE_Setup(APTR);
extern void DYNMODULE_Cleanup(void);
/*
* glue function implementations ...
*/
APTR __dynglue_FindResource(int id, const char *pType)
{
return NULL;
}
APTR __dynglue_LoadResource(APTR handle)
{
return NULL;
}
void __dynglue_FreeResource(APTR handle)
{
return;
}
/*
* internal glue functions ...
*/
struct MsgPort *__dynglue_InitIFPort(char *name)
{
struct MsgPort *ifMPort = NULL;
ifMPort = CreatePort(name, 0);
return ifMPort;
}
__dynmodulemsg_t *__dynglue_GetIFMSg(struct MsgPort *dmmport, BOOL inuse)
{
__dynmodulemsg_t *ifMsg = NULL;
if (inuse) {
WaitPort(dmmport);
ifMsg = (__dynmodulemsg_t *)GetMsg(dmmport);
}
return ifMsg;
}
__dynmodulemsg_t *__dynglue_DisposeIFPort(struct MsgPort *dmmport)
{
__dynmodulemsg_t *ifMsg;
while((ifMsg = (__dynmodulemsg_t *)GetMsg(dmmport))) {
ifMsg->IFOpenRequest.Error = DMIFERR_Closing;
ReplyMsg((struct Message *)ifMsg);
}
DeletePort(dmmport);
}
/*
* Module entry point ...
*/
#define ARG_TEMPLATE "PORT/A"
enum
{
ARG_PORT = 0,
NOOFARGS
};
int main(int argc, char **argv)
{
IPTR args[NOOFARGS + 1] = { (IPTR)NULL, (IPTR)0 };
struct RDArgs *rda;
struct MsgPort *dmmport;
__dynmodulemsg_t *ifMsg;
char *pname;
int opencnt = 0;
BOOL inuse = TRUE;
D(
const char *dbgname;
if ((&DYNMODULE_Name == NULL) || (DYNMODULE_Name == NULL))
dbgname = argv[0];
else
dbgname = DYNMODULE_Name;
bug("[%s] %s('%s')\n", dbgname, __func__, argv[0]);
)
if ((rda = ReadArgs(ARG_TEMPLATE, args, NULL)) != NULL) {
char *argpname = (char *)args[ARG_PORT];
if (*argpname == '"') {
char prttmp[255];
int prtlen = strlen(argpname) - 2;
strncpy(prttmp, &argpname[1], prtlen);
prttmp[prtlen] = 0;
pname = StrDup((CONST_STRPTR)prttmp);
}
else
pname = StrDup((CONST_STRPTR)args[ARG_PORT]);
FreeArgs(rda);
}
if (!pname) {
if ((&DYNMODULE_Name == NULL) || (DYNMODULE_Name == NULL))
pname = StrDup((CONST_STRPTR)argv[0]);
else
pname = StrDup(DYNMODULE_Name);
}
dmmport = __dynglue_InitIFPort(pname);
FreeVec(pname);
if (!dmmport)
DYNMODULE_Exit(0);
D(bug("[%s] %s: port @ 0x%p\n", dbgname, __func__, dmmport));
if(!DYNMODULE_Setup(dmmport)) {
__dynglue_DisposeIFPort(dmmport);
DYNMODULE_Exit(0);
}
D(bug("[%s] %s: initialised\n", dbgname, __func__));
while((ifMsg = __dynglue_GetIFMSg(dmmport, inuse))) {
if (ifMsg) {
switch(ifMsg->IFMsgType) {
case DMIFMSG_Open:
D(bug("[%s] %s: DMIFMSG_Open\n", dbgname, __func__));
if (++opencnt > 0)
inuse = TRUE;
ifMsg->IFOpenRequest.Error = DMIFERR_Ok;
break;
case DMIFMSG_Close:
D(bug("[%s] %s: DMIFMSG_Close\n", dbgname, __func__));
if (--opencnt <= 0)
inuse = FALSE;
break;
case DMIFMSG_Dispose:
D(bug("[%s] %s: DMIFMSG_Dispose\n", dbgname, __func__));
inuse = FALSE;
break;
case DMIFMSG_Resolve:
D(bug("[%s] %s: DMIFMSG_Resolve\n", dbgname, __func__));
dynmoduleExport(&ifMsg->IFResolveRequest);
break;
default:
D(bug("[%s] %s: Unknown Msg type received!\n", dbgname, __func__));
break;
}
ReplyMsg((struct Message *)ifMsg);
}
}
__dynglue_DisposeIFPort(dmmport);
DYNMODULE_Cleanup();
return 0;
}

View File

@ -0,0 +1,41 @@
/*
* This file implements the runtime module function, Import.
*/
//#define DEBUG 1
#include <aros/debug.h>
#include "dynmodule_modules.h"
#include <dynmod/dynmodstack.h>
#include <stdlib.h>
#include <string.h>
// module needed symbols...
extern dynmod_import_t DYNMODULE_Imports[];
int dynmoduleImport()
{
int cnt = 0;
dynmod_import_t *symtable = DYNMODULE_Imports;
D(bug("[DynLink] %s()\n", __func__));
while (symtable->ImportPtr) {
void *mhandle;
void *ptr;
if (((mhandle = dynmodule__InternalLoadModule(symtable->ImportModule.Name, symtable->ImportModule.Port, 0)) == NULL) ||
((ptr = dynmoduleGetProcAddress(mhandle, symtable->ImportName)) == NULL))
return 0;
*symtable->ImportPtr = ptr;
symtable++;
cnt++;
}
D(bug("[DynLink] %s: imported %u symbols\n", __func__, cnt));
return cnt;
}

View File

@ -0,0 +1,68 @@
#ifndef __DYNMODULE_INTERN_H
#define __DYNMODULE_INTERN_H
/*
* Internal definitions used to implement the dynamic module support
*/
#include <exec/exec.h>
#include <dynmod/dynmodule.h>
typedef enum
{
DMIFERR_Ok = 0,
DMIFERR_Closing,
DMIFERR_StackNotSupported,
DMIFERR_OutOfMemory
} __dynmoduleiferror_t;
typedef enum
{
DMIFMSG_Open = 0,
DMIFMSG_Close,
DMIFMSG_Dispose,
DMIFMSG_Resolve,
DMIFMSG_TYPEMAX
} __dynmodulemsgtype_t;
typedef struct {
dynmod_stackf_t StackType;
__dynmoduleiferror_t Error;
} dynmodi_ifopenmsg_t;
typedef struct {
} dynmodi_ifclosemsg_t;
/*
*/
typedef struct
{
struct Message Message;
__dynmodulemsgtype_t IFMsgType;
union
{
dynmodi_ifopenmsg_t IFOpenRequest;
dynmodi_ifclosemsg_t IFCloseRequest;
dynmod_sym_t IFResolveRequest;
};
// ... Might grow
} __dynmodulemsg_t;
typedef struct
{
struct MsgPort *dmi_IFMsgPort;
dynmod_stackf_t dmi_StackFType;
dynmoduleLoadResourceFn_t dmi_LoadResFunc;
dynmoduleFreeResourceFn_t dmi_FreeResFunc;
dynmoduleFindResourceFn_t dmi_FindResFunc;
} __dynmoduleinstance_t;
/************************************************************
* Misc
************************************************************/
extern void *dynmodule__InternalLoadModule(const char *, const char *, BOOL);
extern void dynmodule__InternalFreeModule(int);
extern void dynmodule__InternalCleanup();
#endif

View File

@ -0,0 +1,144 @@
/*
* This file implements the runtime module function, LoadModule.
*/
//#define DEBUG 1
#include <aros/debug.h>
#include "dynmodule_modules.h"
#include <dos/dos.h>
#include <dos/dostags.h>
#include <string.h>
#include <proto/exec.h>
#include <proto/dos.h>
extern const char *DYNMODULE_EntryPoint_Sym;
extern const char *DYNMODULE_FindResource_Sym;
extern const char *DYNMODULE_LoadResource_Sym;
extern const char *DYNMODULE_FreeResource_Sym;
void *dynmoduleLoadModule(const char *modname, const char *port)
{
int (*EntryPFn)(void *, long, void *);
void *mhandle;
D(bug("[DynLink] %s('%s','%s')\n", __func__, modname, port));
if ((mhandle = dynmodule__InternalLoadModule(modname, port, TRUE)) != NULL) {
EntryPFn = dynmoduleGetProcAddress(mhandle, DYNMODULE_EntryPoint_Sym);
if (EntryPFn) {
if (!EntryPFn(mhandle, 0, NULL)) {
dynmoduleFreeModule(mhandle);
mhandle = NULL;
}
}
}
return mhandle;
}
BOOL dynmodule__InternalHandleOpenMsg(__dynmoduleinstance_t *dynmod, int slotid, __dynmodulemsg_t *msg)
{
D(bug("[DynLink] %s()\n", __func__));
if (msg->IFOpenRequest.Error != DMIFERR_Ok) {
D(bug("[DynLink] %s: Open error %08x\n", __func__, msg->IFOpenRequest.Error));
dynmodule__InternalDestroyDynModEntry(dynmod, NULL);
return FALSE;
}
if ((dynmod->dmi_FindResFunc = dynmoduleGetProcAddress(dynmod, DYNMODULE_FindResource_Sym)) != NULL)
if ((dynmod->dmi_LoadResFunc = dynmoduleGetProcAddress(dynmod, DYNMODULE_LoadResource_Sym)) != NULL)
if ((dynmod->dmi_FreeResFunc = dynmoduleGetProcAddress(dynmod, DYNMODULE_FreeResource_Sym)) != NULL)
return TRUE;
dynmoduleslots[slotid].mhandle = dynmod;
dynmodule__InternalFreeModule(slotid);
return FALSE;
}
BOOL dynmodule__InternalValidModuleFile(const char *modname)
{
BPTR modf;
if ((!modname) || !(modf = Open(modname, MODE_OLDFILE)))
return FALSE;
Close(modf);
return TRUE;
}
void *dynmodule__InternalLoadModule(const char *modname, const char *port, BOOL registeropen)
{
__dynmoduleinstance_t *dynmod;
struct MsgPort *dmodport;
struct MsgPort *replyport;
__dynmodulemsg_t msg,*reply;
int slotid;
D(bug("[DynLink] %s('%s','%s')\n", __func__, modname, port));
if (!DYNMODULE_Init(&dynmoduleslots,
sizeof(__dynmoduleentry_t) * DYNMODULE_MAX,
(stdexitfunc_t)dynmodule__InternalCleanup))
return NULL;
if (!dynmodule__InternalValidModuleFile(modname))
return NULL;
if (!port)
port = modname;
if ((dynmod = dynmodule__InternalOpenPortEntry(port, registeropen)) != NULL)
return dynmod;
D(bug("[DynLink] %s: first open ..\n", __func__));
if (!dynmodule__InternalFindFreeSlot(&slotid))
return NULL;
D(bug("[DynLink] %s: using slot %u\n", __func__, slotid));
if ((dynmod = dynmodule__InternalAllocDynModEntry(&replyport)) == NULL)
return NULL;
D(bug("[DynLink] %s: dynamicmodule instance @ 0x%p\n", __func__, dynmod));
D(bug("[DynLink] %s: ifport @ 0x%p\n", __func__, replyport));
if (!(dmodport = FindPort(port)))
dmodport = dynmodule__InternalBootstrapDynMod(modname, port, 10);
if (!dmodport) {
dynmodule__InternalDestroyDynModEntry(dynmod, replyport);
return NULL;
}
D(bug("[DynLink] %s: found port for '%s' @ 0x%p\n", __func__, port, dmodport));
memset(&msg.Message, 0, sizeof(struct Message));
msg.Message.mn_ReplyPort = replyport;
msg.IFMsgType = DMIFMSG_Open;
msg.IFOpenRequest.Error = DMIFERR_Ok;
msg.IFOpenRequest.StackType = DYNMOD_STACKF_DEFAULT;
dynmod->dmi_StackFType = DYNMOD_STACKF_DEFAULT;
dynmod->dmi_IFMsgPort = dmodport;
PutMsg(dynmod->dmi_IFMsgPort, (struct Message *)&msg);
WaitPort(replyport);
if (((reply = (__dynmodulemsg_t *)GetMsg(replyport)) != NULL) &&
(reply->IFMsgType == DMIFMSG_Open)) {
D(bug("[DynLink] %s: Open reply @ 0x%p\n", __func__, reply));
if (!dynmodule__InternalHandleOpenMsg(dynmod, slotid, reply)) {
dynmod = NULL;
}
} else {
D(bug("[DynLink] %s: no reply from IF port\n", __func__));
dynmodule__InternalDestroyDynModEntry(dynmod, NULL);
dynmod = NULL;
}
DeleteMsgPort(replyport);
if (dynmod)
dynmodule__InternalInitDynModEntry(slotid, dynmod, port);
D(bug("[DynLink] %s: returning 0x%p\n", __func__, dynmod));
return dynmod;
}

View File

@ -0,0 +1,146 @@
/*
* Suppport functions and structures for the internal module entries
*/
//#define DEBUG 1
#include <aros/debug.h>
#include "dynmodule_modules.h"
#include <dos/dos.h>
#include <dos/dostags.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <proto/exec.h>
#include <proto/dos.h>
struct dynmodulesupport {
int dms_opencnt;
int dms_flags;
__dynmoduleentry_t *dms_modules;
};
int dynmodopncnt = 0;
__dynmoduleentry_t dynmoduleslots[DYNMODULE_MAX];
static const char *dynmodule_output_str = "CON:0/0/800/600/%s/AUTO/CLOSE/WAIT";
static const char *dynmodule_cmd_template = "\"%s\" \"%s\"";
void dynmodule__InternalInitDynModEntry(int slotid, __dynmoduleinstance_t *dynmod, const char *port)
{
dynmodopncnt++;
dynmoduleslots[slotid].mhandle = dynmod;
dynmoduleslots[slotid].opencnt = 1;
strcpy((char *)dynmoduleslots[slotid].pnam, port);
}
int dynmodule__InternalFindFreeSlot(int *slotid)
{
int slotcur;
for (slotcur = 0; slotcur < DYNMODULE_MAX; slotcur++)
if(!dynmoduleslots[slotcur].mhandle)
break;
if (slotcur == DYNMODULE_MAX)
return 0;
*slotid = slotcur;
return 1;
}
__dynmoduleinstance_t *dynmodule__InternalAllocDynModEntry(struct MsgPort **dmifport)
{
__dynmoduleinstance_t *dynmod;
if ((!dmifport) || ((dynmod = malloc(sizeof(__dynmoduleinstance_t))) == NULL))
return NULL;
D(bug("[DynLink] %s: entry @ 0x%p\n", __func__, dynmod));
if (!(*dmifport = CreateMsgPort())) {
free(dynmod);
return NULL;
}
return dynmod;
}
__dynmoduleinstance_t *dynmodule__InternalOpenPortEntry(const char *port, BOOL registeropen)
{
int slotcur;
for (slotcur = 0; slotcur < DYNMODULE_MAX; slotcur++) {
if(dynmoduleslots[slotcur].mhandle) {
if(strcmp((const char *)dynmoduleslots[slotcur].pnam, port) == 0) {
if(registeropen)
dynmoduleslots[slotcur].opencnt++;
return dynmoduleslots[slotcur].mhandle;
}
}
}
return NULL;
}
struct MsgPort *dynmodule__InternalBootstrapDynMod(const char *modname, const char *port, int timeout)
{
char *outputfmt;
char *commandline;
BPTR input = BNULL, output = BNULL;
if ((outputfmt = AllocVec(strlen(port) + strlen(dynmodule_output_str) - 1, MEMF_PUBLIC)) != NULL) {
sprintf(outputfmt, dynmodule_output_str, port);
output = Open(outputfmt, MODE_NEWFILE);
}
commandline = AllocVec(strlen(modname) + strlen(port) + 6, MEMF_PUBLIC);
if (commandline) {
struct TagItem cmdTags[] = {
{ NP_StackSize, AROS_STACKSIZE },
{ SYS_Input, (IPTR)input },
{ SYS_Output, (IPTR)output },
{ SYS_Asynch, TRUE },
{ TAG_DONE, 0 }
};
struct MsgPort *dmifport = NULL;
#if !defined(__AMIGA__)
#define TICKSPERSEC 50
#else
int TICKSPERSEC;
if ((SysBase->AttnFlags & AFB_NTSC) != 0)
TICKSPERSEC = 60;
else
TICKSPERSEC = 50;
#endif
int iter, itermax, to = TICKSPERSEC/2;
if (timeout > 1)
itermax = (timeout * TICKSPERSEC) / to;
else
itermax = 1;
sprintf(commandline, dynmodule_cmd_template, modname, port);
D(
bug("[DynLink] %s: bootstrapping '%s'\n", __func__, commandline);
bug("[DynLink] %s: input @ 0x%p\n", __func__, commandline, input);
bug("[DynLink] %s: output @ 0x%p\n", __func__, commandline, output);
)
SystemTagList(commandline, cmdTags);
D(bug("[DynLink] %s: waiting %usecs for module to load ...\n", __func__, ((itermax * to)/TICKSPERSEC)));
for (iter = 0; iter < itermax; iter++) {
if ((dmifport = FindPort(port)) != NULL)
break;
Delay(to);
}
FreeVec(commandline);
D(bug("[DynLink] %s: returning 0x%p\n", __func__, dmifport));
return dmifport;
}
return NULL;
}
void dynmodule__InternalDestroyDynModEntry(__dynmoduleinstance_t *dynmod, struct MsgPort *dmifport)
{
if (dmifport)
DeleteMsgPort(dmifport);
free(dynmod);
}

View File

@ -0,0 +1,29 @@
#ifndef __DYNMODULE_MODULES_H
#define __DYNMODULE_MODULES_H
/*
* Definitions for the internal module entries
*/
#include "dynmodule_intern.h"
#define DYNMODULE_MAX 20
typedef struct dynModuleEntry
{
__dynmoduleinstance_t *mhandle;
int opencnt;
char pnam[100];
} __dynmoduleentry_t;
extern __dynmoduleentry_t dynmoduleslots[];
extern int dynmodopncnt;
int dynmodule__InternalFindFreeSlot(int *);
__dynmoduleinstance_t *dynmodule__InternalAllocDynModEntry(struct MsgPort **);
void dynmodule__InternalInitDynModEntry(int, __dynmoduleinstance_t *, const char *);
void dynmodule__InternalDestroyDynModEntry(__dynmoduleinstance_t *, struct MsgPort *);
__dynmoduleinstance_t *dynmodule__InternalOpenPortEntry(const char *, BOOL);
struct MsgPort *dynmodule__InternalBootstrapDynMod(const char *, const char *, int);
#endif

View File

@ -0,0 +1,45 @@
/*
* This file implements the runtime module function, RemoveModule.
*/
//#define DEBUG 1
#include <aros/debug.h>
#include "dynmodule_modules.h"
#include <proto/dos.h>
#include <proto/exec.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
int dynmoduleRemoveModule(const char *ifport)
{
struct MsgPort *replyport;
struct MsgPort *dmmport;
D(bug("[DynLink] %s('%s')\n", __func__, ifport));
if (!(replyport = CreateMsgPort())) {
if ((dmmport = FindPort(ifport))) {
__dynmodulemsg_t msg, *reply;
memset(&msg.Message, 0, sizeof(struct Message));
msg.Message.mn_ReplyPort = replyport;
msg.IFMsgType = DMIFMSG_Dispose;
PutMsg(dmmport, (struct Message *)&msg);
while ((reply = (__dynmodulemsg_t *)GetMsg(replyport)) == NULL) {
Delay(2);
if(FindPort(ifport) != dmmport)
break;
}
}
DeleteMsgPort(replyport);
}
else
DYNMODULE_Exit(0);
return (dmmport ? 1 : 0);
}

View File

@ -0,0 +1,55 @@
#ifndef DYNMODULE_DYNMODSTACK_H
#define DYNMODULE_DYNMODSTACK_H
/*
* Definitions used to handle the correct stack frame format
* on supported targets/toolchains. These are to define the stack
* used by the module opener.
*
* the glue code will patch in the correct function pointer based
* the requested stack frame type.
*/
// "Generic" Targets.
#define DYNMOD_STACKB_GCC 0
#define DYNMOD_STACKB_SYSV 1
// M68k Targets
#define DYNMOD_STACKB_EGCS DYNMOD_STACKB_GCC
#define DYNMOD_STACKB_VBCC 2 /* vbcc */
#define DYNMOD_STACKB_STORM 3 /* StormC */
#define DYNMOD_STACKB_SAS 4 /* SAS/C */
// PPC targets
#define DYNMOD_STACKB_EGCSPPC DYNMOD_STACKB_SYSV
#define DYNMOD_STACKB_POWEROPEN 5 /* StormC/vbcc */
typedef enum
{
DYNMOD_STACKF_STORM = (1 << DYNMOD_STACKB_STORM),
DYNMOD_STACKF_GCC = (1 << DYNMOD_STACKB_GCC),
DYNMOD_STACKF_SAS = (1 << DYNMOD_STACKB_SAS),
DYNMOD_STACKF_VBCC = (1 << DYNMOD_STACKB_VBCC),
DYNMOD_STACKF_POWEROPEN = (1 << DYNMOD_STACKB_POWEROPEN),
DYNMOD_STACKF_SYSV = (1 << DYNMOD_STACKB_SYSV)
} dynmod_stackf_t;
#ifdef __PPC
#if (defined __STORM__) || (defined __VBCC__)
# define DYNMOD_STACKF_DEFAULT DYNMOD_STACKF_POWEROPEN
#elif (defined __GNUC__)
# define DYNMOD_STACKF_DEFAULT DYNMOD_STACKF_SYSV
#endif
#else
#if (defined __VBCC__)
# define DYNMOD_STACKF_DEFAULT DYNMOD_STACKF_VBCC
#elif (defined __STORM__)
# define DYNMOD_STACKF_DEFAULT DYNMOD_STACKF_STORM
#elif (defined __SASC__)
# define DYNMOD_STACKF_DEFAULT DYNMOD_STACKF_SAS
#elif (defined __GNUC__)
# define DYNMOD_STACKF_DEFAULT DYNMOD_STACKF_GCC
#endif
#endif
#endif

View File

@ -0,0 +1,79 @@
#ifndef DYNMODULE_DYNMODULE_H
#define DYNMODULE_DYNMODULE_H
/*
* Public definitions for dynmodule support
*/
#include <dynmod/dynmodstack.h>
typedef struct dynmodModule
{
const char *Name;
const char *Port;
} dynmod_mod_t;
typedef struct dynmodSymbol
{
dynmod_stackf_t StackFType;
const char * SymName;
void ** SymPtr;
} dynmod_sym_t;
typedef struct dynmodImport
{
void **ImportPtr;
const char *ImportName;
dynmod_mod_t ImportModule;
} dynmod_import_t;
typedef struct dynmodExport
{
void *ExportAddress;
const char *ExportName;
} dynmod_export_t;
/*
* Typedefs for standard function vectors, implemented in module.
*/
typedef void *(*dynmoduleFindResourceFn_t)(int, const char *);
typedef void *(*dynmoduleLoadResourceFn_t)(void *);
typedef void (*dynmoduleFreeResourceFn_t)(void *);
typedef void (*stdexitfunc_t)(void);
#ifdef __cplusplus
extern "C" {
#endif
void *dynmoduleLoadModule(const char *, const char *);
void dynmoduleFreeModule(void *);
int dynmoduleImport(void);
int dynmoduleExport(dynmod_sym_t *);
void *dynmoduleGetProcAddress(void *, const char *);
int dynmoduleRemoveModule(const char *);
/*
* Prototypes for module provided structures/implementations
*/
extern const char *DYNMODULE_Name;
extern dynmod_export_t DYNMODULE_Exports[];
extern dynmod_import_t DYNMODULE_Imports[];
extern int DYNMODULE_Init(void *, unsigned long int, stdexitfunc_t);
extern int DYNMODULE_Setup(void *);
extern void DYNMODULE_Cleanup(void);
extern void DYNMODULE_Exit(int);
/*
* Prototypes for standard implementations exposed by the glue
*/
extern void *__dynglue_FindResource(int, const char *);
extern void *__dynglue_LoadResource(void *);
extern void __dynglue_FreeResource(void *);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,33 @@
include $(SRCDIR)/config/aros.cfg
#MM- core-linklibs : linklibs-dynmod linklibs-dynmodglue
#MM linklibs-dynmod : includes
#MM linklibs-dynmodglue : includes
#MM- includes-copy : dynmod-includes-copy
#MM- compiler-includes : dynmod-includes-copy
%copy_includes mmake=dynmod-includes-copy dir=include path=dynmod includes="dynmodule.h dynmodstack.h"
DYNMODULEGLUEFILES := \
dynmodule_glue
DYNMODULEFILES := \
dynmodule_modules \
dynmodule_loadmodule \
dynmodule_freemodule \
dynmodule_removemodule \
dynmodule_export \
dynmodule_import \
dynmodule_getprocaddr
OLD := \
dynmodule
%build_linklib mmake=linklibs-dynmod \
libname=dynmod \
files="$(DYNMODULEFILES)"
%build_linklib mmake=linklibs-dynmodglue \
libname=dynmodglue \
files="$(DYNMODULEGLUEFILES)"