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