#!/bin/bash out=$1 dir=$out-support shift if [[ "$1" == "" ]] || [[ "$out" == "" ]]; then echo "USAGE mkstub " echo "USAGE mkstub " 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 #include #include #include 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