ABI: Use a different symbol to pass library base to functions in headers

Prior to this change, __aros_getbase_XXXX was used and was re-defined in
proto/xxxx.h to either library base of relative offset. However
__aros_getbase_XXXX was an actual function often used inside of library.
The effect was that if proto/xxxx.h was included in the library xxxx
itself, the __aros_getbase_XXXX was redefined, for example in per opener
library instead of reading R12 (x86_64 ABI) it was reading (local)
library base, causing struct Library *ABase = __aros__getbase_ABase() to
become struct Library *ABase = ABase and a "silent" NO-OP

This change changes the symbol used in library call to __LIB_LIBBASE and
__aros_getbase_XXXX is no longer re-defined in proto/xxxx.h

Additionally for cases there inline/xxxx.h or defines/xxxx.h is included
instead of proto/xxxx.h, __LIB_LIBBASE is defined to __aros_getbase_XXXX
so that proper implementation from linklib is pulled in. Same goes for
stub functions in "noincludes" case.

Note: this commit does not change client-side behavior as documented in
ABI_SPECIFICATION. It only changes the name of the symbol used.
This commit is contained in:
deadwood 2024-04-22 15:10:29 +02:00
parent 77cc2e7f64
commit 9513d8ca08
5 changed files with 80 additions and 39 deletions

View File

@ -12,26 +12,26 @@ Caller-side (Regular caller: program or library storing called library base in v
Type of call How base is fetched at caller ==> How base and arguments are passed to library
REGCALL
inline
regular Passed to inline function as result of __aros_getbase_LibBase() R12 for base / SysV x86_64 ABI for arguments
regular Passed to inline function as value of __LIB_LIBBASE R12 for base / SysV x86_64 ABI for arguments
defined by default to (LibBase) global or local variable.
(LibBase) can be re-defined by caller.
define
regular Passed to macro as result of __aros_getbase_LibBase() R12 for base / SysV x86_64 ABI for arguments
regular Passed to macro as value of __LIB_LIBBASE R12 for base / SysV x86_64 ABI for arguments
defined by default to (LibBase) global or local variable.
(LibBase) cab be re-defined by caller.
linklib
regular Fetched in stub function as results of R12 for base / SysV x86_64 ABI for arguments
__aros_getbase_LibBase() which is compiled as (LibBase) global
regular Fetched in stub function as value of __LIB_LIBBASE R12 for base / SysV x86_64 ABI for arguments
which is compiled as (LibBase) global
variable. Re-defining (LibBase) by caller has no effect, as
stub function is already compiled.
STACKCALL
linklib
non-varargs
regular Fetched in stub function as results of R12 for base / SysV x86_64 ABI for arguments
__aros_getbase_LibBase() which is compiled as (LibBase) global
regular Fetched in stub function as value of __LIB_LIBBASE R12 for base / SysV x86_64 ABI for arguments
which is compiled as (LibBase) global
variable. Re-defining (LibBase) by caller has no effect, as
stub function is already compiled.
@ -102,15 +102,15 @@ REGCALL
base-relative Disabled Disabled
define
base-relative Passed to macro as result of __aros_getbase_LibBase() R12 for base / SysV x86_64 ABI for arguments
base-relative Passed to macro as value of __LIB_LIBBASE R12 for base / SysV x86_64 ABI for arguments
defined by default as result of __aros_getoffsettable() offsetted
by __aros_rellib_offset_LibBase global constant. Caller must
implement or define __aros_getoffsettable() returning
caller's library base.
linklib
base-relative Fetched in stub function as results of R12 for base / SysV x86_64 ABI for arguments
__aros_getbase_LibBase() which is compiled as result of
base-relative Fetched in stub function as value of __LIB_LIBBASE R12 for base / SysV x86_64 ABI for arguments
which is compiled as result of
__aros_getoffsettable() offsetted by __aros_rellib_offset_LibBase
global constant. Caller must implement __aros_getoffsettable()
returning caller's library base.
@ -118,8 +118,8 @@ REGCALL
STACKCALL
linklib
non-varargs
base-relative Fetched in stub function as results of R12 for base / SysV x86_64 ABI for arguments
__aros_getbase_LibBase() which is compiled as result of
base-relative Fetched in stub function as value of __LIB_LIBBASE R12 for base / SysV x86_64 ABI for arguments
which is compiled as result of
__aros_getoffsettable() offsetted by __aros_rellib_offset_LibBase
global constant. Caller must implement __aros_getoffsettable()
returning caller's library base.

View File

@ -1,5 +1,5 @@
/*
Copyright (C) 1995-2017, The AROS Development Team. All rights reserved.
Copyright (C) 1995-2020, The AROS Development Team. All rights reserved.
Function to write defines/modulename.h. Part of genmodule.
*/
@ -42,6 +42,19 @@ void writeincdefines(struct config *cfg)
"\n",
cfg->includenameupper, cfg->includenameupper, banner, cfg->modulename
);
fprintf(out,
"#if !defined(__%s_LIBBASE)\n"
"#define __%s_LIBBASE __aros_getbase_%s()\n"
"#endif\n"
"#ifndef __aros_getbase_%s\n"
"extern %s__aros_getbase_%s(void);\n"
"#endif\n"
"\n",
cfg->includenameupper,
cfg->includenameupper, cfg->libbase,
cfg->libbase,
cfg->libbasetypeptrextern, cfg->libbase
);
fprintf(out,
"__BEGIN_DECLS\n"
"\n"
@ -293,8 +306,8 @@ writedefineregister(FILE *out, struct functionhead *funclistit, struct config *c
fprintf(out, ", ");
fprintf(out, "arg%d", count);
}
fprintf(out, ") \\\n __%s_WB(__aros_getbase_%s()",
funclistit->name, cfg->libbase
fprintf(out, ") \\\n __%s_WB(__%s_LIBBASE",
funclistit->name, cfg->includenameupper
);
for (arglistit = funclistit->arguments, count = 1;
arglistit != NULL;
@ -428,9 +441,9 @@ writedefinevararg(FILE *out, struct functionhead *funclistit, struct config *cfg
"...) __%s_WB(",
varargname
);
fprintf(out, "(%s)__aros_getbase_%s(), ",
fprintf(out, "(%s)__%s_LIBBASE, ",
cfg->libbasetypeptrextern,
cfg->libbase);
cfg->includenameupper);
for (arglistit = funclistit->arguments, count = 1;
arglistit != NULL && arglistit->next != NULL && arglistit->next->next != NULL;
arglistit = arglistit->next, count++
@ -506,9 +519,9 @@ writedefinevararg(FILE *out, struct functionhead *funclistit, struct config *cfg
" __inline_%s_%s(",
cfg->basename, varargname
);
fprintf(out, "(%s)__aros_getbase_%s(), ",
fprintf(out, "(%s)__%s_LIBBASE, ",
cfg->libbasetypeptrextern,
cfg->libbase);
cfg->includenameupper);
for (arglistit = funclistit->arguments, count = 1;
arglistit != NULL && arglistit->next != NULL && arglistit->next->next != NULL;
arglistit = arglistit->next, count++

View File

@ -43,6 +43,19 @@ void writeincinline(struct config *cfg)
"\n",
cfg->includenameupper, cfg->includenameupper, banner, cfg->modulename
);
fprintf(out,
"#if !defined(__%s_LIBBASE)\n"
"#define __%s_LIBBASE __aros_getbase_%s()\n"
"#endif\n"
"#ifndef __aros_getbase_%s\n"
"extern %s__aros_getbase_%s(void);\n"
"#endif\n"
"\n",
cfg->includenameupper,
cfg->includenameupper, cfg->libbase,
cfg->libbase,
cfg->libbasetypeptrextern, cfg->libbase
);
freeBanner(banner);
for (funclistit = cfg->funclist; funclistit!=NULL; funclistit = funclistit->next)
@ -309,7 +322,7 @@ writeinlineregister(FILE *out, struct functionhead *funclistit, struct config *c
arglistit = arglistit->next, count++
)
fprintf(out, "(arg%d), ", count);
fprintf(out, "__aros_getbase_%s())\n", cfg->libbase);
fprintf(out, "__%s_LIBBASE)\n", cfg->includenameupper);
}
void
@ -436,9 +449,9 @@ writeinlinevararg(FILE *out, struct functionhead *funclistit, struct config *cfg
" __inline_%s_%s(",
cfg->basename, varargname
);
fprintf(out, "(%s)__aros_getbase_%s(), ",
fprintf(out, "(%s)__%s_LIBBASE, ",
cfg->libbasetypeptrextern,
cfg->libbase);
cfg->includenameupper);
for (arglistit = funclistit->arguments, count = 1;
arglistit != NULL && arglistit->next != NULL && arglistit->next->next != NULL;
arglistit = arglistit->next, count++
@ -515,9 +528,9 @@ writeinlinevararg(FILE *out, struct functionhead *funclistit, struct config *cfg
" __inline_%s_%s(",
cfg->basename, varargname
);
fprintf(out, "(%s)__aros_getbase_%s(), ",
fprintf(out, "(%s)__%s_LIBBASE, ",
cfg->libbasetypeptrextern,
cfg->libbase);
cfg->includenameupper);
for (arglistit = funclistit->arguments, count = 1;
arglistit != NULL && arglistit->next != NULL && arglistit->next->next != NULL;
arglistit = arglistit->next, count++

View File

@ -80,11 +80,11 @@ void writeincproto(struct config *cfg)
fprintf(out,
" #endif\n"
" #endif\n"
" #ifndef __aros_getbase_%s\n"
" #define __aros_getbase_%s() (%s)\n"
" #ifndef __%s_LIBBASE\n"
" #define __%s_LIBBASE (%s)\n"
" #endif\n",
cfg->libbase,
cfg->libbase, cfg->libbase
cfg->includenameupper,
cfg->includenameupper, cfg->libbase
);
if (cfg->options & OPTION_RELLINKLIB)
@ -93,23 +93,29 @@ void writeincproto(struct config *cfg)
" extern const IPTR __aros_rellib_offset_%s;\n"
" #define AROS_RELLIB_OFFSET_%s __aros_rellib_offset_%s\n"
" #define AROS_RELLIB_BASE_%s __aros_rellib_base_%s\n"
" #ifndef __aros_getbase_%s\n"
" #ifndef __%s_LIBBASE\n"
" #ifndef __aros_getoffsettable\n"
" char *__aros_getoffsettable(void);\n"
" #endif\n"
" #define __aros_getbase_%s() (*(%s*)(__aros_getoffsettable()+__aros_rellib_offset_%s))\n"
" #define __%s_LIBBASE (*(%s*)(__aros_getoffsettable()+__aros_rellib_offset_%s))\n"
" #endif\n"
"#endif\n",
cfg->includenameupper,
cfg->libbase,
cfg->includenameupper, cfg->libbase,
cfg->includenameupper, cfg->libbase,
cfg->libbase,
cfg->libbase, cfg->libbasetypeptrextern, cfg->libbase
cfg->includenameupper,
cfg->includenameupper, cfg->libbasetypeptrextern, cfg->libbase
);
fprintf(out, "\n");
fprintf(out,
"#ifndef __aros_getbase_%s\n"
"extern %s__aros_getbase_%s(void);\n"
"#endif\n"
"\n",
cfg->libbase,
cfg->libbasetypeptrextern, cfg->libbase
);
// define name must not start with a digit
// this solves a problem with proto/8svx.h
if (isdigit(cfg->includenameupper[0]))

View File

@ -149,10 +149,19 @@ static void writeheader(struct config *cfg, int is_rel, FILE *out)
for (linelistit = cfg->cdefprivatelines; linelistit!=NULL; linelistit = linelistit->next)
fprintf(out, "%s\n", linelistit->s);
fprintf(out, "\n");
fprintf(out,
"\n"
"%s__aros_getbase_%s(void);\n"
"#if !defined(__%s_LIBBASE)\n"
"#define __%s_LIBBASE __aros_getbase_%s()\n"
"#endif\n"
"#ifndef __aros_getbase_%s\n"
"extern %s__aros_getbase_%s(void);\n"
"#endif\n"
"\n",
cfg->includenameupper,
cfg->includenameupper, cfg->libbase,
cfg->libbase,
cfg->libbasetypeptrextern, cfg->libbase
);
}
@ -272,8 +281,8 @@ static void writefuncstub(struct config *cfg, int is_rel, FILE *out, struct func
}
}
fprintf(out, " %s, __aros_getbase_%s(), %u, %s);\n}\n",
cfg->libbasetypeptrextern, cfg->libbase, funclistit->lvo, cfg->basename
fprintf(out, " %s, __%s_LIBBASE, %u, %s);\n}\n",
cfg->libbasetypeptrextern, cfg->includenameupper, funclistit->lvo, cfg->basename
);
}
else /* libcall==STACK */
@ -336,9 +345,9 @@ static void writefuncstub(struct config *cfg, int is_rel, FILE *out, struct func
fprintf(out,
"%s"
" ({\n"
" AROS_LIBCALL_INIT(__aros_getbase_%s(), %d)\n",
" AROS_LIBCALL_INIT(__%s_LIBBASE, %d)\n",
isvoid ? "" : " return\n",
cfg->libbase, funclistit->lvo
cfg->includenameupper, funclistit->lvo
);
fprintf(out,