From e2fd343dd924756bd7a3a916603fbf39ba7dde87 Mon Sep 17 00:00:00 2001 From: bebbo Date: Tue, 11 Jun 2024 10:05:34 +0200 Subject: [PATCH] various fixes: - fix datadata reloc handling - __ResolveSymbols returns now 0 on success or the missing symbol name - only for function stubs using a4 that value is store - support direct calls - support pointers pointing to *__data --- mkstub | 56 ++++++++++++++++++++++++++++------- sources/startup/init_shared.c | 40 ++++++++++++++----------- 2 files changed, 68 insertions(+), 28 deletions(-) diff --git a/mkstub b/mkstub index 87308c9..32fe430 100755 --- a/mkstub +++ b/mkstub @@ -5,7 +5,7 @@ dir=$out-support shift if [[ "$1" == "" ]] || [[ "$out" == "" ]]; then - echo "USAGE mkstub " + echo "USAGE mkstub " echo "USAGE mkstub " exit 1 fi @@ -13,6 +13,8 @@ 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 @@ -39,12 +41,20 @@ static long __so_${out}_start[1] = {0}; void __so_${out}_open() { ${out}Base = OldOpenLibrary(\"$out.library\"); if (!${out}Base) { - FPuts(Output(), \"failed to load $out.library\n\"); + 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)); + register long d0 asm(\"d0\"); + asm volatile(\"jsr (-30,a6)\": \"=r\"(d0): \"r\"(a0), \"r\"(a6)); + if (d0) { + BPTR out = Output(); + FPuts(out, \"can't resolve \"); + FPuts(out, (char const *)d0); + FPuts(out, \"\\n\"); + exit(10); + } } void __so_${out}_close() { @@ -56,8 +66,16 @@ 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}" != "$1" ]]; then cat $1; else m68k-amigaos-objdump -t $* | grep "0000 01 "; fi) | while read line; do +(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 "___") n=${n:1} @@ -67,8 +85,11 @@ if [[ "${n}" == "" ]]; then fi text=${line##*.text} + direct=${line##*.direct} # text segment -> function with stub - if [[ "$text" != "$line" ]]; then + if [[ "$text" != "$line" ]] || [[ "$direct" != "$line" ]] ; then + + if [[ "$text" != "$line" ]] ; then echo "create export function for ${n}" echo >>$dir/export-$out.c " @@ -86,7 +107,7 @@ fi \" 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}\"; @@ -94,7 +115,18 @@ __attribute__((section(\".dlist_so_export_${n}\"))) void ** __ptr_to_${n} = &__export_${n}; " - + else + + echo >>$dir/export-$out.c " + +__attribute__((section(\".dlist_so_export_${n}\"))) +char const * __name_${n} = \"${n}\"; +__attribute__((section(\".dlist_so_export_${n}\"))) +void ** __ptr_to_${n} = &${n}; +" + + fi + echo creating $dir/stub-${n}.s echo >$dir/stub-${n}.s "| stub for ${n} @@ -119,11 +151,11 @@ else echo "create export variable for ${n}" echo >>$dir/export-$out.c " -extern void * ${n}; +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}; +void ** __ptr_to_${n} = (void**)&${n}__data; " echo creating $dir/stub-${n}.s @@ -145,8 +177,10 @@ 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 @@ -160,4 +194,6 @@ m68k-amigaos-gcc -resident -Os -fomit-frame-pointer export*.c -c popd >/dev/null - +if [[ "$*" != "" ]]; then + m68k-amigaos-gcc -shared -noixemul $* $dir/export-$out.o -o ${out}.library +fi diff --git a/sources/startup/init_shared.c b/sources/startup/init_shared.c index 0d6ccdb..9da5baf 100644 --- a/sources/startup/init_shared.c +++ b/sources/startup/init_shared.c @@ -190,15 +190,12 @@ __LibOpen(struct Library *_masterlib asm("a6")) { // apply datadata relocs 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; - while (count > 0) { - long *t = (long*) *p++; - *t -= diff; - --count; - } + long count = *p++; + long diff = (char*) &__lib - to; + while (count > 0) { + long t = (long) *p++; + *(long*)(t + to) -= diff; + --count; } // reload a4 for the child library @@ -255,8 +252,12 @@ long __LibClose(struct Library *childLib asm("a6")) { return r; } + +extern char __export_stubs_start; +extern char __export_stubs_end; + __regargs -void __so_xlib_init(char const *name, void **to) { +char const * __so_xlib_init(char const *name, void **to) { long *p = &__so_xlib_export[1]; while (*p) { char const *oname = (char const*) *p++; @@ -269,25 +270,28 @@ void __so_xlib_init(char const *name, void **to) { void *v = (void*) *p++; if (0 == strcmp(name, oname)) { *to = v; - register long * l asm("a2") = (long *)v - 1; - asm volatile("move.l a4,(%0)" :: "r"(l)); - break; + if ((char *)v > &__export_stubs_start && (char *)v < &__export_stubs_end) { + register long * l asm("a2") = (long *)v - 1; + asm volatile("move.l a4,(%0)" :: "r"(l)); + } + return 0; } } - if (!*to) - exit(10); + return name; } -void __ResolveSymbols(long *p asm("a0"), struct Library *childLib asm("a6")) { +char const * __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 * r = 0; + while (!r && *p) { char const *name = (char const*) *p++; void **to = (void**) *p++; - __so_xlib_init(name, to); + r = __so_xlib_init(name, to); } asm volatile("move.l (a7)+,a4" : "=r"(a4)); + return r; } extern void __initlibraries();