2 Copyright © 1995-2014, The AROS Development Team. All rights reserved.
5 Function to write module stubs. Part of genmodule.
7 Stubs are agregated differently into objects files based on STACK vs REG
10 Linker will always put a whole object file from archive into
11 executable. If all stubs are in one object file, all stubs are present
12 in executable, inflating its size, even if they are not used.
14 In majority of cases REG call function stubs will be handled be inlines
15 or defines while STACK call function stubs will be linked from linklib.
17 Based on above paragraphs, putting stubs of STACK functions into separate
18 object files will allow for linker to only include required function stubs.
21 #include "genmodule.h"
23 static void writeheader(struct config
*cfg
, int is_rel
, FILE *out
);
24 static void writefuncstub(struct config
*cfg
, int is_rel
, FILE *out
, struct functionhead
*funclistit
);
26 void writestubs(struct config
*cfg
, int is_rel
)
30 struct functionhead
*funclistit
;
32 /* Build STACKCALL - each stub in separate object file */
33 for (funclistit
= cfg
->funclist
;
35 funclistit
= funclistit
->next
38 if (funclistit
->lvo
>= cfg
->firstlvo
&& funclistit
->libcall
== STACK
)
41 snprintf(line
, 255, "%s/%s_%s_%sstub.c", cfg
->gendir
, cfg
->modulename
, funclistit
->name
, is_rel
? "rel" : "");
42 out
= fopen(line
, "w");
50 writeheader(cfg
, is_rel
, out
);
51 writefuncstub(cfg
, is_rel
, out
, funclistit
);
57 /* Build REGCALL - all stusb in one object file */
58 snprintf(line
, 255, "%s/%s_regcall_%sstubs.c", cfg
->gendir
, cfg
->modulename
, is_rel
? "rel" : "");
59 out
= fopen(line
, "w");
67 writeheader(cfg
, is_rel
, out
);
69 for (funclistit
= cfg
->funclist
;
71 funclistit
= funclistit
->next
74 if (funclistit
->lvo
>= cfg
->firstlvo
&& funclistit
->libcall
!= STACK
)
76 writefuncstub(cfg
, is_rel
, out
, funclistit
);
83 static void writeheader(struct config
*cfg
, int is_rel
, FILE *out
)
85 struct stringlist
*linelistit
;
88 banner
= getBanner(cfg
);
94 "#undef NOLIBINLINE\n"
95 "#undef NOLIBDEFINES\n"
96 "#define NOLIBINLINE\n"
97 "#define NOLIBDEFINES\n"
98 "char *__aros_getoffsettable(void);\n"
99 "#ifndef __%s_NOLIBBASE__\n"
100 "/* Do not include the libbase */\n"
101 "#define __%s_NOLIBBASE__\n"
103 banner
, cfg
->modulenameupper
, cfg
->modulenameupper
110 "#undef NOLIBINLINE\n"
111 "#undef NOLIBDEFINES\n"
112 "#define NOLIBINLINE\n"
113 "#define NOLIBDEFINES\n"
114 "/* Be sure that the libbases are included in the stubs file */\n"
115 "#undef __NOLIBBASE__\n"
116 "#undef __%s_NOLIBBASE__\n",
117 banner
, cfg
->modulenameupper
122 if (!(cfg
->options
& OPTION_NOINCLUDES
))
125 fprintf(out
, "#define __%s_RELLIBBASE__\n", cfg
->modulenameupper
);
126 fprintf(out
, "#include <proto/%s.h>\n", cfg
->modulename
);
131 "#include <exec/types.h>\n"
132 "#include <aros/system.h>\n\n"
135 for (linelistit
= cfg
->cdefprivatelines
; linelistit
!=NULL
; linelistit
= linelistit
->next
)
136 fprintf(out
, "%s\n", linelistit
->s
);
140 "%s__aros_getbase_%s(void);\n"
142 cfg
->libbasetypeptrextern
, cfg
->libbase
149 "#include <stddef.h>\n"
151 "#include <aros/cpu.h>\n"
152 "#include <aros/genmodule.h>\n"
153 "#include <aros/libcall.h>\n"
158 static void writefuncstub(struct config
*cfg
, int is_rel
, FILE *out
, struct functionhead
*funclistit
)
160 struct stringlist
*aliasesit
;
161 struct functionarg
*arglistit
;
164 if (funclistit
->libcall
!= STACK
)
166 int nargs
= 0, nquad
= 0;
167 int isvoid
= strcmp(funclistit
->type
, "void") == 0
168 || strcmp(funclistit
->type
, "VOID") == 0;
173 funclistit
->type
, funclistit
->name
175 for (arglistit
= funclistit
->arguments
;
177 arglistit
= arglistit
->next
180 if (arglistit
!= funclistit
->arguments
)
182 fprintf(out
, "%s", arglistit
->arg
);
183 if (strchr(arglistit
->reg
, '/')) {
196 " %sAROS_LC%d%s(%s, %s,\n",
197 (isvoid
) ? "" : "return ",
198 funclistit
->argcount
, (isvoid
) ? "NR" : "",
199 funclistit
->type
, funclistit
->name
202 for (arglistit
= funclistit
->arguments
;
204 arglistit
= arglistit
->next
207 type
= getargtype(arglistit
);
208 name
= getargname(arglistit
);
209 assert(type
!= NULL
&& name
!= NULL
);
211 fprintf(out
, " AROS_LCA(%s,%s,%s),\n",
212 type
, name
, arglistit
->reg
218 else /* nquad != 0 */
222 " %sAROS_LCQUAD%d%s(%s, %s, \\\n",
223 (isvoid
) ? "" : "return ",
224 funclistit
->argcount
, (isvoid
) ? "NR" : "",
225 funclistit
->type
, funclistit
->name
231 " %sAROS_LC%dQUAD%d%s(%s, %s, \\\n",
232 (isvoid
) ? "" : "return ",
233 nargs
, nquad
, (isvoid
) ? "NR" : "",
234 funclistit
->type
, funclistit
->name
238 for (arglistit
= funclistit
->arguments
;
240 arglistit
= arglistit
->next
243 char *quad2
= strchr(arglistit
->reg
, '/');
245 type
= getargtype(arglistit
);
246 name
= getargname(arglistit
);
247 assert(type
!= NULL
&& name
!= NULL
);
252 " AROS_LCAQUAD(%s, %s, %s, %s), \\\n",
253 type
, name
, arglistit
->reg
, quad2
+1
260 " AROS_LCA(%s, %s, %s), \\\n",
261 type
, name
, arglistit
->reg
269 fprintf(out
, " %s, __aros_getbase_%s(), %u, %s);\n}\n",
270 cfg
->libbasetypeptrextern
, cfg
->libbase
, funclistit
->lvo
, cfg
->basename
273 else /* libcall==STACK */
275 fprintf(out
, "AROS_GM_%sLIBFUNCSTUB(%s, %s, %d)\n",
277 funclistit
->name
, cfg
->libbase
, funclistit
->lvo
281 for (aliasesit
= funclistit
->aliases
;
283 aliasesit
= aliasesit
->next
286 fprintf(out
, "AROS_GM_LIBFUNCALIAS(%s, %s)\n",
287 funclistit
->name
, aliasesit
->s