Admin Panel
#!/bin/bash
out=$1
dir=$out-support
shift
if [[ "$1" == "" ]] || [[ "$out" == "" ]]; then
echo "USAGE mkstub <libname> <def file> <object files...>"
echo "USAGE mkstub <libname> <object files...>"
exit 1
fi
if [[ "${1%%.def}" != "$1" ]]; then
if [ -f "$1" ]; then
echo "Using DEF file $1"
deffile=$1
shift
else
echo "$1 not found"
exit 1
fi
fi
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>
#include <stdlib.h>
void * ${out}Base = 0;
// linked first stub
__attribute__((section(\".dlist_so_${out}\")))
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;
char const * s;
asm volatile(\"jsr (-30,a6); move.l d0,%0\": \"=r\"(s): \"r\"(a0), \"r\"(a6));
if (s) {
BPTR out = Output();
FPuts(out, \"can't resolve \");
FPuts(out, s);
FPuts(out, \"\\n\");
exit(10);
}
}
void __so_${out}_close() {
if (${out}Base)
CloseLibrary(${out}Base);
}
ADD2INIT(__so_${out}_open, -78); // priority one less than __initlibraries
ADD2EXIT(__so_${out}_close, -78);
"
echo >$dir/export-$out.c "
__attribute__((section(\".data.export~\")))
short __export_stubs_end = -1;
__attribute__((section(\".data.export@\")))
short __export_stubs_start = -1;
"
# get last word = var name of exported functions
(if [[ "${1%%.def}" != "$deffile" ]]; then cat $deffile; else m68k-amigaos-objdump -t $* | grep "0000 01 "; fi) | while read line; do
n=$(echo $line | awk '{ print $NF }' | grep -v __initlibraries | grep -v __initcpp )
n=${n:1}
if [[ "${n}" == "" ]]; then
continue;
fi
text=${line##*.text}
direct=${line##*.direct}
# text segment -> function with stub
if [[ "$text" != "$line" ]] || [[ "$direct" != "$line" ]] ; then
if [[ "$text" != "$line" ]] ; then
echo "create export function for ${n}"
echo >>$dir/export-$out.c "
asm(\"\"
\".section .data.export_${n} \n\"
\"___export_${n}_a4: \n\"
\" .long 0 | <-- contains the a4 value to use \n\"
\"___export_${n}: \n\"
\" move.l a4,-(sp) \n\"
\" move.l -8(pc),a4 | <-- read the correct a4 value \n\"
\" move.l (sp)+,(___save_a4:W,a4) \n\"
\" move.l (sp)+,(___save_sp:W,a4) \n\"
\" jsr _${n} \n\"
\" move.l (___save_sp:W,a4),-(sp) \n\"
\" move.l (___save_a4:W,a4),a4 \n\"
\" rts \n\");
extern void * __export_${n};
__attribute__((section(\".dlist_so_export_${n}\")))
char const * __name_${n} = \"${n}\";
__attribute__((section(\".dlist_so_export_${n}\")))
void ** __ptr_to_${n} = &__export_${n};
"
else
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};
"
fi
echo creating $dir/stub-${n}.s
echo >$dir/stub-${n}.s "| stub for ${n}
.data
_${n}: .globl _${n}
.short 0x4ef9 | jmp
___ptr_${n}:
.long _${out}Base
.text
__name_${n}:
.asciz \"${n}\"
.section .dlist_so_${out}z_${n}
.long __name_${n}
.long ___ptr_${n}
"
else
# only normal variables
echo "create export variable for ${n}"
echo >>$dir/export-$out.c "
extern void * ${n}__data;
__attribute__((section(\".dlist_so_export_${n}\")))
char const * __name_${n} = \"${n}\";
__attribute__((section(\".dlist_so_export_${n}\")))
void ** __ptr_to_${n} = (void**)&${n}__data;
"
echo creating $dir/stub-${n}.s
echo >$dir/stub-${n}.s "| stub for ${n}
.data
_${n}: .globl _${n}
___ptr_${n}:
.long _${out}Base
.text
__name_${n}:
.asciz \"${n}\"
.section .dlist_so_${out}z_${n}
.long __name_${n}
.long ___ptr_${n}
"
fi
done
pushd $dir >/dev/null
echo compiling stubs
echo m68k-amigaos-gcc ${LIB_MODE} -Os -fomit-frame-pointer *stub*.s *stub*.c -c
m68k-amigaos-gcc ${LIB_MODE} -Os -fomit-frame-pointer *stub*.s *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
if [[ "$*" != "" ]]; then
echo m68k-amigaos-gcc -shared -noixemul $* $dir/export-$out.o -o ${out}.library
m68k-amigaos-gcc -shared -noixemul $* $dir/export-$out.o -o ${out}.library
fi