From e78f2e904bd4c48265d0f0ef236de42ec842cc89 Mon Sep 17 00:00:00 2001 From: verhaegs Date: Sun, 4 Sep 2011 16:51:52 +0000 Subject: [PATCH] Use arossupport altstack for passing libbase to shared library functions. It supports both functions using register and C stack argument passing. This is a generic framework with support for i386 and m68k. Other cpu archs will fail on #error. This generic framework should never be a final ABI for a cpu. It is meant to allow as a quick way to get AROS going on a new CPU. Libbase passing should be optimized afterwards possibly by using a CPU register to pass the libbase. Added support for debug output when SysBase == NULL in kernel.resource. kprintf won't output anything when SysBase == NULL. This patch is co-developed with Jason McMullan. git-svn-id: https://svn.aros.org/svn/aros/trunk/AROS@41079 fb15a70f-31f2-0310-bbcc-cdcc74a49acc --- arch/arm-all/include/aros/cpu.h | 1 + arch/i386-all/include/aros/cpu.h | 36 +++++++++++-- arch/m68k-all/include/aros/cpu.h | 39 ++++++++++++-- arch/ppc-all/include/aros/cpu.h | 1 + arch/x86_64-all/include/aros/cpu.h | 3 ++ compiler/arossupport/aros_relbase.c | 93 ++++++++++++++++++++++++++++++++++ compiler/arossupport/include/libcall.h | 51 +++++++++++++++++++ compiler/arossupport/kprintf.c | 8 +++ compiler/arossupport/mmakefile.src | 1 + compiler/clib/__vfork.h | 2 + compiler/clib/include/sys/syscall.def | 2 +- compiler/clib/mmakefile.src | 8 ++- rom/kernel/bug.c | 6 +++ rom/kernel/kernel_debug.h | 43 +++++++++------- tools/genmodule/writeincdefines.c | 20 +------- tools/genmodule/writeincinline.c | 3 +- tools/genmodule/writestart.c | 17 +++++++ 17 files changed, 283 insertions(+), 51 deletions(-) create mode 100644 compiler/arossupport/aros_relbase.c diff --git a/arch/arm-all/include/aros/cpu.h b/arch/arm-all/include/aros/cpu.h index 7e35e48611..8ae6c1f9cb 100644 --- a/arch/arm-all/include/aros/cpu.h +++ b/arch/arm-all/include/aros/cpu.h @@ -96,6 +96,7 @@ struct JumpVec unused junk code but otherwise we can't pass input arguments to the asm statement */ +#error the __AROS_LIBFUNCSTUB needs to be update for RELBASE handling #define __AROS_LIBFUNCSTUB(fname, libbasename, lvo) \ void __ ## fname ## _ ## libbasename ## _wrapper(void) \ { \ diff --git a/arch/i386-all/include/aros/cpu.h b/arch/i386-all/include/aros/cpu.h index dcc38fde4d..6a7c8d98d5 100644 --- a/arch/i386-all/include/aros/cpu.h +++ b/arch/i386-all/include/aros/cpu.h @@ -94,16 +94,42 @@ struct JumpVec Internals: a dummy function is used that will generate some unused junk code but otherwise we can't pass input arguments - to the asm statement + to the asm statement. + + Some asm trickery performed: + - function return address is top of stack, + leave it there to use as argument for aros_push2_relbase + - libbase is other argument to aros_push2_relbase + - call aros_push2_relbase + - put libbase back in %eax + - remove libbase and return address from stack + - Call lvo vector + - push return value on stack + - call aros_pop2_relbase, + return value will be old return address + - pull return value from stack + - jmp to old return address */ #define __AROS_LIBFUNCSTUB(fname, libbasename, lvo) \ void __ ## fname ## _ ## libbasename ## _wrapper(void) \ { \ asm volatile( \ - ".weak " #fname ";" \ - #fname " : " \ - "movl " #libbasename ",%%eax;" \ - "jmp *%c0(%%eax)" \ + ".weak " #fname "\n" \ + #fname " :\n" \ + /* return address is top of stack */ \ + /* use as 2nd argument for aros_push2_relbase */ \ + "\tmovl " #libbasename ", %%eax\n" \ + "\tpushl %%eax\n" /* libbase on stack */ \ + "\tcall aros_push2_relbase\n" \ + "\tmovl (%%esp), %%eax\n" \ + "\taddl $8,%%esp\n" /* original arguments */ \ + "\tcall *%c0(%%eax)\n" \ + "\tpushl %%eax\n" \ + "\tcall aros_pop2_relbase\n" \ + "\tmovl %%eax, %%ecx\n" \ + "\tpopl %%eax\n" \ + "\tmovl %%ecx, (%%esp)\n" \ + "\tjmp *%%ecx" \ : : "i" ((-lvo*LIB_VECTSIZE)) \ ); \ } diff --git a/arch/m68k-all/include/aros/cpu.h b/arch/m68k-all/include/aros/cpu.h index e9761de2ec..7522053ef1 100644 --- a/arch/m68k-all/include/aros/cpu.h +++ b/arch/m68k-all/include/aros/cpu.h @@ -102,22 +102,48 @@ do \ Internals: a dummy function is used that will generate some unused junk code but otherwise we can't pass input arguments to the asm statement + + Some asm trickery performed: + - function return address is top of stack, + leave it there to use as argument for aros_push2_relbase + - libbase is other argument to aros_push2_relbase + - call aros_push2_relbase + - put libbase back in %eax + - remove libbase and return address from stack + - Call lvo vector + - push return value on stack + - call aros_pop2_relbase, + return value will be old return address + - pull return value from stack + - jmp to old return address */ #define __AROS_LIBFUNCSTUB(fname, libbasename, lvo) \ void __ ## fname ## _ ## libbasename ## _wrapper(void) \ { \ asm volatile( \ - ".globl " #fname "\n" \ + ".weak " #fname "\n" \ "\t" #fname ":\n" \ - "\tmovl " #libbasename ",%%a0\n" \ - "\tlea.l %c0(%%a0),%%a0\n" \ - "\tjmp (%%a0)\n" \ + /* return address is top of stack */ \ + /* use as 2nd argument for aros_push2_relbase */ \ + "\tmove.l " #libbasename ",%%a0\n" \ + "\tmove.l %%a0,%%sp@-\n" /* libbase on stack */ \ + "\tjsr aros_push2_relbase\n" \ + "\tmove.l %%sp@,%%a0\n" \ + "\taddq.l #8, %%sp\n" /* original arguments */ \ + "\tjsr %%a0@(%c0)\n" \ + "\tmovem.l %%d0/%%d1,%%sp@-\n" \ + "\tjsr aros_pop2_relbase\n" \ + "\tmove.l %%d0,%%a0\n" \ + "\tmovem.l %%sp@+,%%d0/%%d1\n" \ + "\tjmp %%a0@\n" \ : : "i" ((-lvo*LIB_VECTSIZE)) \ + : \ ); \ } #define AROS_LIBFUNCSTUB(fname, libbasename, lvo) \ __AROS_LIBFUNCSTUB(fname, libbasename, lvo) + /* Macro: AROS_FUNCALIAS(functionname, alias) This macro will generate an alias 'alias' for function 'functionname' @@ -246,6 +272,11 @@ extern void aros_not_implemented (); /* Call a libary function which requires the libbase */ #include +#define AROS_LC_CALL(t,x,bn) ERROR IN DEFINITIONS - AROS_LC_CALL +#define AROS_LC_CALLNR(x,bn) ERROR IN DEFINITIONS - AROS_LC_CALLNR +#define AROS_LC_CALLI(t,x,bn) ERROR IN DEFINITIONS - AROS_LC_CALLI +#define AROS_LC_CALLINR(x,bn) ERROR IN DEFINITIONS - AROS_LC_CALLNR + #define AROS_LHQUAD1(t,n,a1,bt,bn,o,s) \ AROS_LH2(t,n, \ AROS_LHA(ULONG, __AROS_LTAQUAD1(a1), __AROS_LRAQUAD1(a1)), \ diff --git a/arch/ppc-all/include/aros/cpu.h b/arch/ppc-all/include/aros/cpu.h index 8ea0d86fe1..54512cf8b6 100644 --- a/arch/ppc-all/include/aros/cpu.h +++ b/arch/ppc-all/include/aros/cpu.h @@ -126,6 +126,7 @@ struct JumpVec unused junk code but otherwise we can't pass input arguments to the asm statement */ +#error the __AROS_LIBFUNCSTUB needs to be update for RELBASE handling #define __AROS_LIBFUNCSTUB(fname, libbasename, lvo) \ void __ ## fname ## _ ## libbasename ## _wrapper(void) \ { \ diff --git a/arch/x86_64-all/include/aros/cpu.h b/arch/x86_64-all/include/aros/cpu.h index fa24c3bd75..17309d8c0a 100644 --- a/arch/x86_64-all/include/aros/cpu.h +++ b/arch/x86_64-all/include/aros/cpu.h @@ -120,6 +120,9 @@ struct JumpVec unused junk code but otherwise we can't pass input arguments to the asm statement */ +#ifdef __AROS__ +#error the __AROS_LIBFUNCSTUB needs to be update for RELBASE handling +#endif #define __AROS_LIBFUNCSTUB(fname, libbasename, lvo) \ void __ ## fname ## _ ## libbasename ## _wrapper(void) \ { \ diff --git a/compiler/arossupport/aros_relbase.c b/compiler/arossupport/aros_relbase.c new file mode 100644 index 0000000000..5838d3583e --- /dev/null +++ b/compiler/arossupport/aros_relbase.c @@ -0,0 +1,93 @@ +/* + * Copyright (C) 2011, The AROS Development Team. All rights reserved. + * Author: Jason S. McMullan + * + * Licensed under the AROS PUBLIC LICENSE (APL) Version 1.1 + */ + +#include + +#include +#include + +#define DEBUG 1 +#include + +/* In order to avoid infinite recursive call of aros_set_relbase + no shared library functions may be called from these functions. + On some platforms they may call aros_set_relbase. +*/ + +void *aros_get_relbase(void) +{ + D( + if (SysBase == NULL) + bug("[aros_get_relbase]: Error! SysBase==NULL\n"); + else if (SysBase->ThisTask == NULL) + bug("[aros_get_relbase]: Error! SysBase->ThisTask==NULL\n"); + ) + + return (void *)aros_get_altstack(SysBase->ThisTask); +} + +void *aros_set_relbase(void *libbase) +{ + D( + if (SysBase == NULL) + bug("[aros_get_relbase]: Error! SysBase==NULL\n"); + else if (SysBase->ThisTask == NULL) + bug("[aros_get_relbase]: Error! SysBase->ThisTask==NULL\n"); + ) + + return (void *)aros_set_altstack(SysBase->ThisTask,(IPTR)libbase); +} + +void aros_push_relbase(void *libbase) +{ + D( + if (SysBase == NULL) + bug("[aros_get_relbase]: Error! SysBase==NULL\n"); + else if (SysBase->ThisTask == NULL) + bug("[aros_get_relbase]: Error! SysBase->ThisTask==NULL\n"); + ) + + aros_push_altstack(SysBase->ThisTask,(IPTR)libbase); +} + +void aros_push2_relbase(void *libbase, void *ptr) +{ + D( + if (SysBase == NULL) + bug("[aros_get_relbase]: Error! SysBase==NULL\n"); + else if (SysBase->ThisTask == NULL) + bug("[aros_get_relbase]: Error! SysBase->ThisTask==NULL\n"); + ) + + aros_push_altstack(SysBase->ThisTask,(IPTR)ptr); + aros_push_altstack(SysBase->ThisTask,(IPTR)libbase); +} + +void *aros_pop_relbase(void) +{ + D( + if (SysBase == NULL) + bug("[aros_get_relbase]: Error! SysBase==NULL\n"); + else if (SysBase->ThisTask == NULL) + bug("[aros_get_relbase]: Error! SysBase->ThisTask==NULL\n"); + ) + + return (void *)aros_pop_altstack(SysBase->ThisTask); +} + +void *aros_pop2_relbase(void) +{ + D( + if (SysBase == NULL) + bug("[aros_get_relbase]: Error! SysBase==NULL\n"); + else if (SysBase->ThisTask == NULL) + bug("[aros_get_relbase]: Error! SysBase->ThisTask==NULL\n"); + ) + + aros_pop_altstack(SysBase->ThisTask); + return (void *)aros_pop_altstack(SysBase->ThisTask); +} diff --git a/compiler/arossupport/include/libcall.h b/compiler/arossupport/include/libcall.h index fd0d9ec397..cbb3925d2c 100644 --- a/compiler/arossupport/include/libcall.h +++ b/compiler/arossupport/include/libcall.h @@ -82,6 +82,57 @@ typedef int (*LONG_FUNC)(); typedef unsigned int (*ULONG_FUNC)(); #endif +/* Declare relbase if asked */ +#if !defined(AROS_GET_RELBASE) || !defined(AROS_SET_RELBASE) + +#include + +/* Uncomment next define to get debug output for relbase calls + */ +//#define AROS_RELBASE_DEBUG 1 + +/* Also use debug version if we may not define global SysBase */ +#if !defined(AROS_RELBASE_DEBUG) && !defined(__NOLIBBASE__) && !defined(__EXEC_NOLIBBASE__) + +#include + +#include + +extern struct ExecBase *SysBase; + +#define AROS_GET_RELBASE ((void *)aros_get_altstack(SysBase->ThisTask)) +#define AROS_SET_RELBASE(x) ((void *)aros_set_altstack(SysBase->ThisTask,(IPTR)x)) +#define AROS_PUSH_RELBASE(x) aros_push_altstack(SysBase->ThisTask,(IPTR)x) +#define AROS_POP_RELBASE ((void *)aros_pop_altstack(SysBase->ThisTask) + +#else /* AROS_RELBASE_DEBUG || __NOLIBBASE__ || __EXEC_NOLIBBASE__ */ + +__BEGIN_DECLS +void *aros_get_relbase(void); +void *aros_set_relbase(void *libbase); +void aros_push_relbase(void *libbase); +void aros_push2_relbase(void *libbase, void *ptr); +void *aros_pop_relbase(void); +void *aros_pop2_relbase(void); +__END_DECLS + +#define AROS_GET_RELBASE aros_get_relbase() +#define AROS_SET_RELBASE(x) aros_set_relbase(x) +#define AROS_PUSH_RELBASE(x) aros_push_relbase(x) +#define AROS_POP_RELBASE aros_pop_relbase() + +#endif /* !AROS_RELBASE_DEBUG && !__NOLIBBASE__ && !__EXEC_NOLIBBASE__ */ + +#endif /* !AROS_GET_RELBASE || !AROS_SET_RELBASE */ + +/* If AROS_GET_LIBBASE/AROS_SET_LIBBASE use relbase by defining them as resp. + * AROS_GET_RELBASE/AROS_SET_RELBASE + */ +#ifndef AROS_GET_LIBBASE +#define AROS_GET_LIBBASE AROS_GET_RELBASE +#define AROS_SET_LIBBASE(x) AROS_SET_RELBASE(x) +#endif + /* Declare all macros which the systems' libcall didn't */ #ifndef __AROS_SLIB_ENTRY # define __AROS_SLIB_ENTRY(n,s,o) s ## _ ## o ## _ ## n diff --git a/compiler/arossupport/kprintf.c b/compiler/arossupport/kprintf.c index 8d8b6ac67d..e5cedea8a4 100644 --- a/compiler/arossupport/kprintf.c +++ b/compiler/arossupport/kprintf.c @@ -68,6 +68,10 @@ va_list ap; int result; + /* Don't try to call RawPutChar if SysBase is not initialized */ + if (!SysBase) + return 0; + va_start (ap, fmt); result = vkprintf (fmt, ap); va_end (ap); @@ -86,6 +90,10 @@ int vkprintf (const UBYTE * fmt, va_list args) unsigned long val; long lval = 0; + /* Don't try to call RawPutChar if SysBase is not initialized */ + if (!SysBase) + return 0; + if (!fmt) { RawPutChars ("(null)", 6); diff --git a/compiler/arossupport/mmakefile.src b/compiler/arossupport/mmakefile.src index 0908646fea..e44c17e197 100644 --- a/compiler/arossupport/mmakefile.src +++ b/compiler/arossupport/mmakefile.src @@ -6,6 +6,7 @@ include $(TOP)/config/make.cfg FILES := \ aros_altstack \ + aros_relbase \ calcchecksum \ createbstr \ createseglist \ diff --git a/compiler/clib/__vfork.h b/compiler/clib/__vfork.h index 8d0e039271..fbd5828bff 100644 --- a/compiler/clib/__vfork.h +++ b/compiler/clib/__vfork.h @@ -10,6 +10,7 @@ #include #include #include +#include #include struct vfork_data @@ -44,6 +45,7 @@ struct vfork_data APTR exec_id; }; +pid_t __vfork(jmp_buf env); void vfork_longjmp (jmp_buf env, int val); #endif /* __VFORK_H */ diff --git a/compiler/clib/include/sys/syscall.def b/compiler/clib/include/sys/syscall.def index 70dd1dd120..7945145fb4 100644 --- a/compiler/clib/include/sys/syscall.def +++ b/compiler/clib/include/sys/syscall.def @@ -255,7 +255,7 @@ SYSTEM_CALL (uname) SYSTEM_CALL (__env_get_environ) SYSTEM_CALL (execve) SYSTEM_CALL (strptime) -SYSTEM_CALL (vfork) +SYSTEM_CALL (__vfork) SYSTEM_CALL (waitpid) SYSTEM_CALL (execv) SYSTEM_CALL (execlp) diff --git a/compiler/clib/mmakefile.src b/compiler/clib/mmakefile.src index 3fd39f4a8b..c05a075ecc 100644 --- a/compiler/clib/mmakefile.src +++ b/compiler/clib/mmakefile.src @@ -400,6 +400,9 @@ SHARED_ARCH := \ vfork \ vfork_longjmp +SHARED_LINKLIB_ARCH := \ + vfork + # Note: These files are compiled differently # depending on whether -DAROSC_ROM is used # or not. @@ -496,10 +499,11 @@ DEPS := $(foreach f,$(COMMON),$(OBJDIR)/$(f).d) \ COMMON_OBJ := $(foreach f,$(COMMON),$(OBJDIR)/$(f).o) \ $(foreach f,$(COMMON_ARCH),$(OBJDIR)/arch/$(f).o) -SHARED_OBJ := $(COMMON_OBJ) $(STUBS) $(OBJDIR)/arosc_autoinit.o +SHARED_OBJ := $(COMMON_OBJ) $(STUBS) $(OBJDIR)/arosc_autoinit.o \ + $(foreach f,$(SHARED_LINKLIB_ARCH),$(OBJDIR)/shared/arch/$(f).o) MODULE_OBJ := $(foreach f, $(SHARED), $(OBJDIR)/shared/$(f).o) \ - $(foreach f,$(SHARED_ARCH),$(OBJDIR)/shared/arch/$(f).o) + $(foreach f,$(SHARED_ARCH),$(OBJDIR)/shared/arch/$(f).o) ROM_OBJ := $(foreach f,$(ROM_ONLY),$(OBJDIR)/rom/$(f).o) \ $(foreach f,$(ROM_COMMON),$(OBJDIR)/$(f).o) \ diff --git a/rom/kernel/bug.c b/rom/kernel/bug.c index 4a06158d03..9e2593b473 100644 --- a/rom/kernel/bug.c +++ b/rom/kernel/bug.c @@ -55,3 +55,9 @@ AROS_LH2(int, KrnBug, AROS_LIBFUNC_EXIT } + +/* Support for output when SysBase is not initialized */ +int __KrnBugBoot(const char *format, va_list args) +{ + return __vcformat(NULL, (int (*)(int, void *))krnPutC, format, args); +} diff --git a/rom/kernel/kernel_debug.h b/rom/kernel/kernel_debug.h index 47c8c0d52c..d1010904b9 100644 --- a/rom/kernel/kernel_debug.h +++ b/rom/kernel/kernel_debug.h @@ -19,32 +19,39 @@ AROS_LD2(int, KrnBug, AROS_LDA(va_list, args, A1), struct KernelBase *, KernelBase, 12, Kernel); +/* + * Character output function. All debug output ends up there. + * This function needs to be implemented for every supported + * architecture. + */ +int krnPutC(int chr, struct KernelBase *KernelBase); + + static inline void _bug(struct KernelBase *KernelBase, const char *format, ...) { va_list args; va_start(args, format); - /* - * We use AROS_CALL2 here, since there are files that - * include this that cannot tolerate - * Note that this is a direct call, not using an LVO. This is done - * in such a manner because this function can be user during early boot, - * while KernelBase is NULL. - */ - AROS_CALL2(int, AROS_SLIB_ENTRY(KrnBug, Kernel, 12), - AROS_LCA(const char *, format, A0), - AROS_LCA(va_list, args, A1), - struct KernelBase *, KernelBase); + if (SysBase && SysBase->ThisTask) + { + /* + * We use AROS_CALL2 here, since there are files that + * include this that cannot tolerate + * Note that this is a direct call, not using an LVO. This is done + * in such a manner because this function can be user during early boot, + * while KernelBase is NULL. + */ + AROS_CALL2(int, AROS_SLIB_ENTRY(KrnBug, Kernel, 12), + AROS_LCA(const char *, format, A0), + AROS_LCA(va_list, args, A1), + struct KernelBase *, KernelBase + ); + } + else + __KrnBugBoot(format, args); va_end(args); } #define bug(...) _bug(KernelBase, __VA_ARGS__) - -/* - * Character output function. All debug output ends up there. - * This function needs to be implemented for every supported - * architecture. - */ -int krnPutC(int chr, struct KernelBase *KernelBase); diff --git a/tools/genmodule/writeincdefines.c b/tools/genmodule/writeincdefines.c index 3e2f62a76b..00f005ee79 100644 --- a/tools/genmodule/writeincdefines.c +++ b/tools/genmodule/writeincdefines.c @@ -59,7 +59,7 @@ void writeincdefines(struct config *cfg) } else /* libcall == STACK */ { - writedefinestack(out, funclistit, cfg); + /* NOP: define can't handle libbase passing */ } writealiases(out, funclistit, cfg); @@ -383,24 +383,6 @@ writedefinevararg(FILE *out, struct functionhead *funclistit, struct config *cfg } void -writedefinestack(FILE *out, struct functionhead *funclistit, struct config *cfg) -{ - struct functionarg *arglistit; - - fprintf(out, "#define %s ((%s (*)(", funclistit->name, funclistit->type); - for (arglistit = funclistit->arguments; - arglistit != NULL; - arglistit = arglistit->next - ) - { - fprintf(out, "%s", arglistit->arg); - if (arglistit->next != NULL) - fprintf(out, ", "); - } - fprintf(out, "))__AROS_GETVECADDR(%s,%d))\n", cfg->libbase, funclistit->lvo); -} - -void writealiases(FILE *out, struct functionhead *funclistit, struct config *cfg) { struct stringlist *aliasesit; diff --git a/tools/genmodule/writeincinline.c b/tools/genmodule/writeincinline.c index 500c20850a..6e1ed9a6fe 100644 --- a/tools/genmodule/writeincinline.c +++ b/tools/genmodule/writeincinline.c @@ -57,8 +57,7 @@ void writeincinline(struct config *cfg) } else /* libcall == STACK */ { - /* This is very straightforward, reuse code from writeincdefines.c */ - writedefinestack(out, funclistit, cfg); + /* TODO: inline function with libbase passing */ } writealiases(out, funclistit, cfg); diff --git a/tools/genmodule/writestart.c b/tools/genmodule/writestart.c index c2193ae227..8237a23c7c 100644 --- a/tools/genmodule/writestart.c +++ b/tools/genmodule/writestart.c @@ -754,6 +754,10 @@ static void writeinitlib(FILE *out, struct config *cfg) } } + fprintf(out, + " void *oldbase = AROS_SET_LIBBASE(lh);\n" + ); + if (!(cfg->options & OPTION_NOEXPUNGE) && cfg->modtype!=RESOURCE && cfg->modtype != HANDLER) fprintf(out, " GM_SEGLIST_FIELD(lh) = segList;\n"); if (cfg->options & OPTION_DUPBASE) @@ -797,6 +801,7 @@ static void writeinitlib(FILE *out, struct config *cfg) fprintf(out, " set_call_libfuncs(SETNAME(CLASSESEXPUNGE), -1, 0, lh);\n"); if (!(cfg->options & OPTION_NOAUTOLIB)) fprintf(out, " set_close_libraries();\n"); + fprintf(out, " (void)AROS_SET_LIBBASE(oldbase);\n"); if (cfg->modtype != HANDLER) { @@ -848,6 +853,7 @@ static void writeinitlib(FILE *out, struct config *cfg) fprintf(out, " GM_UNIQUENAME(InitHandler)();\n"); fprintf(out, + " (void)AROS_SET_LIBBASE(oldbase);\n" " return lh;\n" " }\n" "\n" @@ -1047,11 +1053,14 @@ static void writeopenlib(FILE *out, struct config *cfg) ); fprintf(out, "\n" + " void *oldbase = AROS_SET_LIBBASE(newlib);\n" " if (!set_call_libfuncs(SETNAME(OPENLIB), 1, 1, newlib))\n" " {\n" + " (void)AROS_SET_LIBBASE(oldbase);\n" " __freebase(newlib);\n" " return NULL;\n" " }\n" + " (void)AROS_SET_LIBBASE(oldbase);\n" "\n" " ((struct Library *)lh)->lib_OpenCnt++;\n" " ((struct Library *)lh)->lib_Flags &= ~LIBF_DELEXP;\n" @@ -1109,11 +1118,14 @@ static void writecloselib(FILE *out, struct config *cfg) "{\n" " AROS_LIBFUNC_INIT\n" "\n" + " void *oldbase = AROS_SET_LIBBASE(lh);\n" + "\n" ); if (cfg->modtype == DEVICE) fprintf(out, " if (!set_call_devfuncs(SETNAME(CLOSEDEV), -1, 1, lh, ioreq, 0, 0))\n" " {\n" + " (void)AROS_SET_LIBBASE(oldbase);\n" " return BNULL;\n" " }\n" ); @@ -1160,6 +1172,7 @@ static void writecloselib(FILE *out, struct config *cfg) " && (((struct Library *)lh)->lib_Flags & LIBF_DELEXP)\n" " )\n" " {\n" + " (void)AROS_SET_LIBBASE(oldbase);\n" " return AROS_LC1(BPTR, GM_UNIQUENAME(ExpungeLib),\n" " AROS_LCA(LIBBASETYPEPTR, lh, D0),\n" " LIBBASETYPEPTR, lh, 3, %s\n" @@ -1169,6 +1182,7 @@ static void writecloselib(FILE *out, struct config *cfg) ); fprintf(out, "\n" + " (void)AROS_SET_LIBBASE(oldbase);\n" " return BNULL;\n" "\n" " AROS_LIBFUNC_EXIT\n" @@ -1200,6 +1214,8 @@ static void writeexpungelib(FILE *out, struct config *cfg) " {\n" " BPTR seglist = GM_SEGLIST_FIELD(lh);\n" "\n" + " void *oldbase = AROS_SET_LIBBASE(lh);\n" + "\n" " if(!set_call_libfuncs(SETNAME(EXPUNGELIB), -1, 1, lh))\n" " {\n" " ((struct Library *)lh)->lib_Flags |= LIBF_DELEXP;\n" @@ -1217,6 +1233,7 @@ static void writeexpungelib(FILE *out, struct config *cfg) fprintf(out, " set_close_libraries();\n"); fprintf(out, "\n" + " (void)AROS_SET_LIBBASE(oldbase);\n" " __freebase(lh);\n" "\n" " return seglist;\n" -- 2.11.4.GIT