mirror of
https://github.com/LIV2/libnix.git
synced 2025-12-06 00:23:08 +00:00
add support for simple shared libraries
This commit is contained in:
parent
b00180b09b
commit
88a4f42dca
@ -113,6 +113,7 @@ one: $(LIBS_TO_BUILD)
|
||||
# install all kinds into the prefix
|
||||
.PHONY: install_lib install_libb install_libm020 install_libm020bb install_libm020bb32 install_libm881 install_libm020bb881 install_libm020bb32881
|
||||
install: install_lib install_libb install_libm020 install_libm020bb install_libm020bb32 install_libm881 install_libm020bb881 install_libm020bb32881
|
||||
cp $(root)/mkstub $(PREFIX)/bin
|
||||
|
||||
install_lib:
|
||||
$(MAKE) install_one kind=lib to=""
|
||||
|
||||
128
mkstub
Executable file
128
mkstub
Executable file
@ -0,0 +1,128 @@
|
||||
#!/bin/bash
|
||||
out=$1
|
||||
dir=$out-support
|
||||
|
||||
shift
|
||||
|
||||
echo creating support files in $dir
|
||||
|
||||
rm -rf $dir
|
||||
mkdir -p $dir
|
||||
|
||||
echo >$dir/init-stub-${out}.c "// STUB to load and init the so file
|
||||
#include <proto/dos.h>
|
||||
#include <proto/exec.h>
|
||||
#include <stabs.h>
|
||||
|
||||
void * ${out}Base = 0;
|
||||
void * __${out}_sp = 0;
|
||||
void * __${out}_a4[3] = {0};
|
||||
|
||||
// linked first stub
|
||||
__attribute__((section(\".dlist_so_${out}\")))
|
||||
static long __so_${out}_start[1] = {0};
|
||||
|
||||
// init all references by name
|
||||
void __so_${out}_open() {
|
||||
${out}Base = OldOpenLibrary(\"$out.library\");
|
||||
if (!${out}Base) {
|
||||
FPuts(Output(), \"failed to load $out.library\n\");
|
||||
exit(10);
|
||||
}
|
||||
register long * a0 asm(\"a0\") = &__so_${out}_start[1];
|
||||
register void * a6 asm(\"a6\") = ${out}Base;
|
||||
asm volatile(\"jsr (-30,a6)\"::\"r\"(a0), \"r\"(a6));
|
||||
}
|
||||
|
||||
void __so_${out}_close() {
|
||||
if (${out}Base)
|
||||
CloseLibrary(${out}Base);
|
||||
}
|
||||
|
||||
ADD2INIT(__so_${out}_open, -78); // one less than __initlibraries
|
||||
ADD2EXIT(__so_${out}_close, -78);
|
||||
"
|
||||
|
||||
# get last word = var name of exported functions
|
||||
m68k-amigaos-objdump -t $* | grep "0000 01 " | while read line; do
|
||||
|
||||
n=$(echo $line | awk '{ print $NF }' | grep -v "___")
|
||||
n=${n:1}
|
||||
|
||||
if [[ "$n" == "" ]]; then
|
||||
continue;
|
||||
fi
|
||||
|
||||
# only normal variables
|
||||
|
||||
echo >>$dir/export-$out.c "
|
||||
|
||||
extern void * $n;
|
||||
__attribute__((section(\".dlist_so_export_$n\")))
|
||||
char const * __name_$n = \"$n\";
|
||||
__attribute__((section(\".dlist_so_export_$n\")))
|
||||
void ** __ptr_to_$n = (void**)&$n;
|
||||
"
|
||||
|
||||
echo creating $dir/stub-$n.c
|
||||
|
||||
text=${line##*.text}
|
||||
# text segment -> function with stub
|
||||
if [[ "$text" != "$line" ]]; then
|
||||
echo >$dir/stub-$n.c "//=== BEGIN stubs for $n
|
||||
extern void * ${out}Base;
|
||||
extern void * __${out}_sp;
|
||||
extern void * __${out}_a4[2];
|
||||
|
||||
__attribute__((section(\".data.${out}_$n\")))
|
||||
long (*__ptr_$n)();
|
||||
__attribute__((section(\".text.${out_}$n\")))
|
||||
void $n() {
|
||||
asm volatile(\"move.l (sp)+,%0\" : \"=m\"(__${out}_sp));
|
||||
asm volatile(\"movem.l a4-a6,%0\" : \"=m\"(__${out}_a4));
|
||||
asm volatile(\"move.l %0,a4;\nmove.l a4,a6;\nadd.l #32766,a4\" :: \"m\"(${out}Base));
|
||||
asm volatile(\"move.l %0,a5;jsr (a5)\" :: \"m\"(__ptr_$n));
|
||||
asm volatile(\"movem.l %0,a4-a6\" :: \"m\"(__${out}_a4));
|
||||
asm volatile(\"move.l %0,-(sp)\" :: \"m\"(__${out}_sp));
|
||||
}
|
||||
|
||||
__attribute__((section(\".dlist_so_${out}z_$n\")))
|
||||
char const * __name_$n = \"$n\";
|
||||
__attribute__((section(\".dlist_so_${out}z_$n\")))
|
||||
void ** __to_ptr_$n = (void**)&__ptr_$n;
|
||||
//=== END
|
||||
|
||||
"
|
||||
else
|
||||
echo >$dir/stub-$n.c "//=== BEGIN stubs for $n
|
||||
extern void *__${out}_sp;
|
||||
|
||||
__attribute__((section(\".data.${out}_$n\")))
|
||||
void * $n = (void *)&__${out}_sp;
|
||||
|
||||
__attribute__((section(\".dlist_so_${out}z_$n\")))
|
||||
char const * __name_$n = \"$n\";
|
||||
__attribute__((section(\".dlist_so_${out}z_$n\")))
|
||||
void ** __to_ptr_$n = &$n;
|
||||
//=== END
|
||||
"
|
||||
fi
|
||||
|
||||
done
|
||||
|
||||
pushd $dir >/dev/null
|
||||
echo compiling stubs
|
||||
echo m68k-amigaos-gcc -Os -fomit-frame-pointer *stub*.c -c
|
||||
m68k-amigaos-gcc -Os -fomit-frame-pointer *stub*.c -c
|
||||
|
||||
echo create link lib $out.a
|
||||
rm -f ../$out.a
|
||||
echo m68k-amigaos-ar rcs ../$out.a *stub*.o
|
||||
m68k-amigaos-ar rcs ../$out.a *stub*.o
|
||||
|
||||
echo m68k-amigaos-gcc -resident -Os -fomit-frame-pointer export*.c -c
|
||||
m68k-amigaos-gcc -resident -Os -fomit-frame-pointer export*.c -c
|
||||
|
||||
popd >/dev/null
|
||||
|
||||
|
||||
16
sources/headers/dlfcn.h
Normal file
16
sources/headers/dlfcn.h
Normal file
@ -0,0 +1,16 @@
|
||||
#ifndef __DLFCN_H__
|
||||
#define __DLFCN_H__
|
||||
|
||||
/*
|
||||
* To be used withlibraries created with -noixemul -shared
|
||||
*/
|
||||
|
||||
void * __stdargs dlopen (__const char *__file, int __mode);
|
||||
int __stdargs dlclose (void *__handle);
|
||||
void * __stdargs dlvsym (void *__restrict __handle,
|
||||
__const char *__restrict __name,
|
||||
__const char *__restrict __version);
|
||||
void * __stdargs dlsym (void *__restrict __handle,
|
||||
__const char *__restrict __name);
|
||||
|
||||
#endif //__DLFCN_H__
|
||||
57
sources/nix/misc/dlfcn.c
Normal file
57
sources/nix/misc/dlfcn.c
Normal file
@ -0,0 +1,57 @@
|
||||
#include <amistdio.h>
|
||||
#include <string.h>
|
||||
#include <proto/dos.h>
|
||||
#include <proto/exec.h>
|
||||
|
||||
// the linker inserts this id behind the idString
|
||||
static char id[3] = {0x0b, 0xeb, 0xb0};
|
||||
void *dlopen (__const char *__file, int __mode) {
|
||||
struct Library * lib = OldOpenLibrary(__file);
|
||||
if (lib) {
|
||||
// only one exported function -> neg size == 32, magic marker "bebb0" behind id string!
|
||||
if (32 != lib->lib_NegSize || !lib->lib_IdString || memcmp(id, lib->lib_IdString + strlen(lib->lib_IdString) + 1, 3)) {
|
||||
#ifndef __KICK13__
|
||||
Printf("%s is not suitable for dlopen", __file);
|
||||
#endif
|
||||
CloseLibrary(lib);
|
||||
lib = 0;
|
||||
}
|
||||
}
|
||||
return lib;
|
||||
}
|
||||
|
||||
/* Unmap and close a shared object opened by `dlopen'.
|
||||
The handle cannot be used again after calling `dlclose'. */
|
||||
int dlclose (void *__handle) {
|
||||
if (!__handle)
|
||||
return -1;
|
||||
CloseLibrary((struct Library *)__handle);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Find the run-time address in the shared object HANDLE refers to
|
||||
of the symbol called NAME with VERSION. */
|
||||
void *dlvsym (void *__restrict __handle,
|
||||
__const char *__restrict __name,
|
||||
__const char *__restrict __version) {
|
||||
if (!__handle)
|
||||
return 0;
|
||||
|
||||
void * r = 0;
|
||||
static void const * p[3];
|
||||
p[0] = __name;
|
||||
p[1] = &r;
|
||||
|
||||
register void * a0 asm("a0") = p;
|
||||
register struct Library * a6 asm("a6") = (struct Library *)__handle;
|
||||
asm volatile("jsr (-30,a6)" : "=m"(r) : "r"(a0), "r"(a6));
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
/* Find the run-time address in the shared object HANDLE refers to
|
||||
of the symbol called NAME. */
|
||||
void *dlsym (void *__restrict __handle,
|
||||
__const char *__restrict __name) {
|
||||
return dlvsym(__handle, __name, 0);
|
||||
}
|
||||
@ -1,8 +1,12 @@
|
||||
#include <amistdio.h>
|
||||
#include <string.h>
|
||||
#include <exec/execbase.h>
|
||||
#include <exec/resident.h>
|
||||
#include <proto/dos.h>
|
||||
#include <proto/exec.h>
|
||||
|
||||
extern void exit(int);
|
||||
|
||||
#pragma GCC push_options
|
||||
#pragma GCC optimize ("-Os")
|
||||
#pragma GCC optimize ("-fno-toplevel-reorder")
|
||||
@ -19,13 +23,12 @@ const struct Resident __RomTag;
|
||||
|
||||
// place into data segment -> init with zero
|
||||
__attribute__((section(".data")))
|
||||
struct Library __lib = {0};
|
||||
struct Library __lib = { 0 };
|
||||
// track all instantiated libs, the lib_Sum fields is used to track the opening Task
|
||||
__attribute__((section(".data")))
|
||||
struct List __libList = {0};
|
||||
struct List __libList = { 0 };
|
||||
|
||||
const char __libName[32] = {0};
|
||||
const char __libIdString[64] = {0};
|
||||
const char __libName[64] = { 0 };
|
||||
const APTR __FuncTable__[];
|
||||
|
||||
struct ExecBase *SysBase = 0;
|
||||
@ -37,75 +40,85 @@ long __initFailed = 0;
|
||||
unsigned short __cleanupflag = 0;
|
||||
|
||||
__attribute__((section(".list___INIT_LIST__")))
|
||||
const int __INIT_LIST__[1] = {0};
|
||||
const int __INIT_LIST__[1] = { 0 };
|
||||
__attribute__((section(".list___EXIT_LIST__")))
|
||||
const int __EXIT_LIST__[1] = {0};
|
||||
const int __EXIT_LIST__[1] = { 0 };
|
||||
|
||||
__attribute__((section(".dlist___LIB_LIST__")))
|
||||
int __LIB_LIST__[1] = {0};
|
||||
int __LIB_LIST__[1] = { 0 };
|
||||
|
||||
__attribute__((section(".list___CTOR_LIST__")))
|
||||
const int __CTOR_LIST__[1] = {0};
|
||||
const int __CTOR_LIST__[1] = { 0 };
|
||||
|
||||
__attribute__((section(".list___DTOR_LIST__")))
|
||||
const int __DTOR_LIST__[1] = {0};
|
||||
const int __DTOR_LIST__[1] = { 0 };
|
||||
|
||||
// the section for the exported functions
|
||||
__attribute__((section(".dlist_so_export")))
|
||||
long __so_xlib_export[1] = {0};
|
||||
long __so_xlib_export[1] = { 0 };
|
||||
|
||||
__attribute__((section(".end_of_lists")))
|
||||
const int __ZZZ_LIST__[1] = {0};
|
||||
const int __ZZZ_LIST__[1] = { 0 };
|
||||
__attribute__((section(".end_of_dlists")))
|
||||
int __ZZZ_DLIST__[1] = {0};
|
||||
int __ZZZ_DLIST__[1] = { 0 };
|
||||
|
||||
long __LibClose(struct Library * childLib asm("a6"));
|
||||
void __callfuncs(const int * p asm("a2"), unsigned short prioo asm("d2"));
|
||||
long __LibClose(struct Library *childLib asm("a6"));
|
||||
void __callfuncs(const int *p asm("a2"), unsigned short prioo asm("d2"));
|
||||
|
||||
void __restore_a4() {
|
||||
asm volatile("lea 32766(a6),a4");
|
||||
}
|
||||
|
||||
static inline VOID __NewList(struct List *_NewList_list)
|
||||
{
|
||||
_NewList_list->lh_TailPred = (struct Node *) _NewList_list;
|
||||
_NewList_list->lh_Head = (struct Node *) &_NewList_list->lh_Tail;
|
||||
static inline VOID __NewList(struct List *_NewList_list) {
|
||||
_NewList_list->lh_TailPred = (struct Node*) _NewList_list;
|
||||
_NewList_list->lh_Head = (struct Node*) &_NewList_list->lh_Tail;
|
||||
_NewList_list->lh_Tail = 0;
|
||||
}
|
||||
|
||||
// init the library. defer real init stuff to LibOpen!
|
||||
APTR __LibInit(long __segListIn asm("a0"), struct Library *_masterlib asm("d0"), struct ExecBase *__sysBase asm("a6")) {
|
||||
// get access to the data
|
||||
register long * a4 asm("a4");
|
||||
register long *a4 asm("a4");
|
||||
asm volatile("move.l a4,-(a7)" :: "r"(a4));
|
||||
asm volatile("lea ___a4_init,%0;\n" : "=r"(a4));
|
||||
|
||||
struct Library *masterlib = _masterlib;
|
||||
|
||||
#if 0
|
||||
{
|
||||
struct DosLibrary * DOSBase = (struct DosLibrary *)OldOpenLibrary("dos.library");
|
||||
Printf("neg=%ld, pos=%ld\n", masterlib->lib_NegSize, masterlib->lib_PosSize);
|
||||
Flush(Output());
|
||||
CloseLibrary(&DOSBase->dl_lib);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* setup private data */
|
||||
SysBase = __sysBase;
|
||||
__theMasterLib = masterlib;
|
||||
__segList = __segListIn;
|
||||
|
||||
|
||||
/* set up header data */
|
||||
masterlib->lib_Node.ln_Type = NT_LIBRARY;
|
||||
masterlib->lib_Node.ln_Name = (char*) __libName;
|
||||
masterlib->lib_Flags = LIBF_CHANGED | LIBF_SUMUSED;
|
||||
masterlib->lib_Version = __lib.lib_Version;
|
||||
masterlib->lib_Revision = __lib.lib_Revision;
|
||||
masterlib->lib_IdString = (char*) __libIdString;
|
||||
// /* set up header data */
|
||||
// masterlib->lib_Node.ln_Type = NT_LIBRARY;
|
||||
// masterlib->lib_Node.ln_Name = (char*) __libName;
|
||||
// masterlib->lib_Flags = LIBF_CHANGED | LIBF_SUMUSED;
|
||||
// masterlib->lib_Version = __lib.lib_Version;
|
||||
// masterlib->lib_Revision = __lib.lib_Revision;
|
||||
// masterlib->lib_IdString = (char*) __libName + strlen((char*) __libName) + 1;
|
||||
|
||||
CopyMem(masterlib, &__lib, sizeof(__lib));
|
||||
|
||||
__NewList(&__libList);
|
||||
|
||||
/* this will be added to SysBase->LibList or NULL (init error) */
|
||||
asm volatile("move.l (a7)+,a4" : "=r"(a4));
|
||||
return masterlib;
|
||||
}
|
||||
|
||||
// bye bye library
|
||||
long __LibExpunge(struct Library *_masterlib asm("a6")) {
|
||||
register long * a4 asm("a4");
|
||||
register long *a4 asm("a4");
|
||||
asm volatile("move.l a4,-(a7)" :: "r"(a4));
|
||||
asm volatile("lea ___a4_init,%0;\n" : "=r"(a4));
|
||||
|
||||
struct Library *masterlib = _masterlib;
|
||||
@ -113,26 +126,26 @@ long __LibExpunge(struct Library *_masterlib asm("a6")) {
|
||||
/* set delayed expunge flag */
|
||||
masterlib->lib_Flags |= LIBF_DELEXP;
|
||||
|
||||
/* still in use? */
|
||||
if (masterlib->lib_OpenCnt)
|
||||
return 0;
|
||||
|
||||
/* remove lib from SysBase->LibList */
|
||||
Remove(&masterlib->lib_Node);
|
||||
|
||||
long sl = __segList;
|
||||
// free the allocated ram of the lib's struct
|
||||
int neg = masterlib->lib_NegSize;
|
||||
FreeMem((-neg + (char* )masterlib), neg + masterlib->lib_PosSize);
|
||||
/* still in use? */
|
||||
if (!masterlib->lib_OpenCnt) {
|
||||
/* remove lib from SysBase->LibList */
|
||||
Remove(&masterlib->lib_Node);
|
||||
|
||||
// free the allocated ram of the lib's struct
|
||||
int neg = masterlib->lib_NegSize;
|
||||
FreeMem((-neg + (char* )masterlib), neg + masterlib->lib_PosSize);
|
||||
}
|
||||
/* return the seglist for UnLoadSeg() */
|
||||
asm volatile("move.l (a7)+,a4" : "=r"(a4));
|
||||
return sl;
|
||||
}
|
||||
|
||||
// open the library
|
||||
struct Library*
|
||||
__LibOpen(struct Library *_masterlib asm("a6")) {
|
||||
register long * a4 asm("a4");
|
||||
register long *a4 asm("a4");
|
||||
asm volatile("move.l a4,-(a7)" :: "r"(a4));
|
||||
asm volatile("lea ___a4_init,%0;\n" : "=r"(a4));
|
||||
|
||||
struct Library *masterlib = _masterlib;
|
||||
@ -143,43 +156,43 @@ __LibOpen(struct Library *_masterlib asm("a6")) {
|
||||
/* clear delayed expunge flag */
|
||||
masterlib->lib_Flags &= ~LIBF_DELEXP;
|
||||
|
||||
struct Task * task = SysBase->ThisTask;
|
||||
struct Task *task = SysBase->ThisTask;
|
||||
// search the List if the task already opened this library.
|
||||
for (struct Node * node = __libList.lh_Head; node != (struct Node *)&__libList.lh_Tail; node = node->ln_Succ) {
|
||||
struct Library * childLib = (struct Library *)node->ln_Name;
|
||||
if (childLib->lib_Sum == (ULONG)task) {
|
||||
for (struct Node *node = __libList.lh_Head; node != (struct Node*) &__libList.lh_Tail; node = node->ln_Succ) {
|
||||
struct Library *childLib = (struct Library*) node->ln_Name;
|
||||
if (childLib->lib_Sum == (ULONG) task) {
|
||||
++childLib->lib_OpenCnt;
|
||||
asm volatile("move.l (a7)+,a4" : "=r"(a4));
|
||||
return childLib;
|
||||
}
|
||||
}
|
||||
|
||||
// get memory per lib
|
||||
unsigned sz = masterlib->lib_PosSize + masterlib->lib_NegSize;
|
||||
char * to = (char *)AllocVec(sz, MEMF_PUBLIC);
|
||||
char *to = (char*) AllocVec(sz, MEMF_PUBLIC);
|
||||
|
||||
// copy jump table
|
||||
CopyMemQuick(((char *)masterlib) - masterlib->lib_NegSize, to, masterlib->lib_NegSize);
|
||||
CopyMemQuick(((char* )masterlib) - masterlib->lib_NegSize, to, masterlib->lib_NegSize);
|
||||
|
||||
to += masterlib->lib_NegSize;
|
||||
|
||||
|
||||
// copy data segment
|
||||
CopyMemQuick (&__lib, to, masterlib->lib_PosSize);
|
||||
CopyMemQuick(&__lib, to, masterlib->lib_PosSize);
|
||||
|
||||
struct Library * childLib = (struct Library*)to;
|
||||
childLib->lib_Sum = (ULONG)task;
|
||||
struct Library *childLib = (struct Library*) to;
|
||||
childLib->lib_Sum = (ULONG) task;
|
||||
childLib->lib_OpenCnt = 1;
|
||||
AddHead(&__libList, (struct Node *)&childLib[1]); // the child's libList as node...
|
||||
AddHead(&__libList, (struct Node* )&childLib[1]); // the child's libList as node...
|
||||
|
||||
// apply datadata relocs
|
||||
long * p;
|
||||
long *p;
|
||||
asm volatile("lea ___datadata_relocs,%0" : "=r"(p));
|
||||
asm volatile("lea __etext,%0" : "=r"(a4));
|
||||
if (p < a4) {
|
||||
long count = *p++;
|
||||
long diff = (char *)&__lib - to;
|
||||
long diff = (char*) &__lib - to;
|
||||
while (count > 0) {
|
||||
long * t = (long *)*p++;
|
||||
long *t = (long*) *p++;
|
||||
*t -= diff;
|
||||
--count;
|
||||
}
|
||||
@ -196,78 +209,87 @@ __LibOpen(struct Library *_masterlib asm("a6")) {
|
||||
|
||||
if (__initFailed) {
|
||||
__LibClose(childLib);
|
||||
return 0;
|
||||
childLib = 0;
|
||||
}
|
||||
|
||||
asm volatile("move.l (a7)+,a4" : "=r"(a4));
|
||||
return childLib;
|
||||
}
|
||||
|
||||
// close the library
|
||||
long __LibClose(struct Library * childLib asm("a6")) {
|
||||
register long * a4 asm("a4");
|
||||
long __LibClose(struct Library *childLib asm("a6")) {
|
||||
register long *a4 asm("a4");
|
||||
asm volatile("move.l a4,-(a7)" :: "r"(a4));
|
||||
asm volatile("lea 32766(a6),%0;\n" : "=r"(a4));
|
||||
|
||||
Forbid();
|
||||
--__theMasterLib->lib_OpenCnt;
|
||||
// still in user
|
||||
if (--childLib->lib_OpenCnt) {
|
||||
long r = 0;
|
||||
if (!--childLib->lib_OpenCnt) {
|
||||
// disable forbid during cleanup
|
||||
Permit();
|
||||
return 0;
|
||||
|
||||
// run exit
|
||||
__cleanupflag ^= -1;
|
||||
__callfuncs(&__EXIT_LIST__[1], -1);
|
||||
|
||||
// forbid again
|
||||
Forbid();
|
||||
// free the instance
|
||||
Remove((struct Node* )&childLib[1]);
|
||||
FreeVec(((char* )childLib) - childLib->lib_NegSize);
|
||||
|
||||
/* one less user */
|
||||
if (!__theMasterLib->lib_OpenCnt && (__theMasterLib->lib_Flags & LIBF_DELEXP))
|
||||
r = __LibExpunge(__theMasterLib);
|
||||
|
||||
}
|
||||
Permit();
|
||||
|
||||
// run exit
|
||||
__cleanupflag ^= -1;
|
||||
__callfuncs(&__EXIT_LIST__[1], -1);
|
||||
|
||||
Forbid();
|
||||
// free the instance
|
||||
Remove((struct Node *)&childLib[1]);
|
||||
FreeVec(((char *)childLib) - childLib->lib_NegSize);
|
||||
|
||||
/* one less user */
|
||||
long r = 0;
|
||||
if (!__theMasterLib->lib_OpenCnt && (__theMasterLib->lib_Flags & LIBF_DELEXP))
|
||||
r = __LibExpunge(__theMasterLib);
|
||||
|
||||
Permit();
|
||||
asm volatile("move.l (a7)+,a4" : "=r"(a4));
|
||||
return r;
|
||||
}
|
||||
|
||||
__regargs
|
||||
void __so_xlib_init(char const * name, void **to) {
|
||||
long * p = &__so_xlib_export[1];
|
||||
void __so_xlib_init(char const *name, void **to) {
|
||||
long *p = &__so_xlib_export[1];
|
||||
while (*p) {
|
||||
char const * oname = (char const *)*p++;
|
||||
void * v = (void *)*p++;
|
||||
char const *oname = (char const*) *p++;
|
||||
// {
|
||||
// struct DosLibrary * DOSBase = (struct DosLibrary *)OldOpenLibrary("dos.library");
|
||||
// Printf("%s==%s\n", name, oname);
|
||||
// Flush(Output());
|
||||
// CloseLibrary(&DOSBase->dl_lib);
|
||||
// }
|
||||
void *v = (void*) *p++;
|
||||
if (0 == strcmp(name, oname)) {
|
||||
*to = v;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!*to)
|
||||
exit(10);
|
||||
}
|
||||
|
||||
void __ResolveSymbols(long * p asm("a0"), struct Library * childLib asm("a6")) {
|
||||
register long * a4 asm("a4");
|
||||
void __ResolveSymbols(long *p asm("a0"), struct Library *childLib asm("a6")) {
|
||||
register long *a4 asm("a4");
|
||||
asm volatile("move.l a4,-(a7)" :: "r"(a4));
|
||||
asm volatile("lea 32766(a6),%0;\n" : "=r"(a4));
|
||||
while (*p) {
|
||||
char const * name = (char const *)*p++;
|
||||
void ** to = (void **)*p++;
|
||||
char const *name = (char const*) *p++;
|
||||
void **to = (void**) *p++;
|
||||
__so_xlib_init(name, to);
|
||||
}
|
||||
asm volatile("move.l (a7)+,a4" : "=r"(a4));
|
||||
}
|
||||
|
||||
extern void __initlibraries();
|
||||
extern void __initcpp();
|
||||
|
||||
// the function table
|
||||
const APTR __FuncTable__[] = { __LibOpen, __LibClose, __LibExpunge, NULL,
|
||||
__ResolveSymbols,
|
||||
(APTR) -1,
|
||||
const APTR __FuncTable__[] = { __LibOpen, __LibClose, __LibExpunge, NULL, __ResolveSymbols, (APTR) -1,
|
||||
// link __initlibraries and __initcpp behind end marker^
|
||||
__initlibraries,
|
||||
__initcpp
|
||||
};
|
||||
__initlibraries, __initcpp };
|
||||
|
||||
// the libraries init table
|
||||
extern long __data_size;
|
||||
@ -276,16 +298,18 @@ const APTR __InitTab[4] = { (APTR) &__data_size, (APTR) &__FuncTable__[0], (APTR
|
||||
// that's what the library loader is looking for: the rom tag with references to the remaining data.
|
||||
const struct Resident __RomTag = { RTC_MATCHWORD, (struct Resident*) &__RomTag, (struct Resident*) &__RomTag + 1,
|
||||
RTF_AUTOINIT, 1,
|
||||
NT_LIBRARY, 0, (char*) __libName, (char*) __libIdString, (APTR) &__InitTab };
|
||||
NT_LIBRARY, 0, (char*) __libName,
|
||||
(char*) __libName, // the linker will fix this!
|
||||
(APTR) &__InitTab };
|
||||
|
||||
void __callfuncs(const int * q asm("a2"), unsigned short order asm("d2")) {
|
||||
void __callfuncs(const int *q asm("a2"), unsigned short order asm("d2")) {
|
||||
for (;;) {
|
||||
const int * p = q;
|
||||
const int *p = q;
|
||||
unsigned short curprio = __cleanupflag;
|
||||
unsigned short nextprio = -1;
|
||||
|
||||
while (*p) {
|
||||
unsigned short prio = *((unsigned short *) p + 3) ^ order;
|
||||
unsigned short prio = *((unsigned short*) p + 3) ^ order;
|
||||
|
||||
// invoke
|
||||
if (prio == curprio)
|
||||
@ -304,6 +328,7 @@ void __callfuncs(const int * q asm("a2"), unsigned short order asm("d2")) {
|
||||
}
|
||||
}
|
||||
|
||||
// just in case callfunc calls something which calls exit
|
||||
void exit(int x) {
|
||||
__initFailed = -1;
|
||||
__initFailed = x;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user