mirror of
https://github.com/LIV2/libnix.git
synced 2025-12-06 00:23:08 +00:00
202 lines
4.5 KiB
Bash
Executable File
202 lines
4.5 KiB
Bash
Executable File
#!/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
|