1VACALL(3) Library Functions Manual VACALL(3)
2
3
4
6 vacall - C functions called with variable arguments
7
9 #include <vacall.h>
10
11 extern void* vacall_function;
12
13 void function (alist)
14 va_alist alist;
15 {
16 va_start_type(alist[, return_type]);
17 arg = va_arg_type(alist[, arg_type]);
18 va_return_type(alist[[, return_type], return_value]);
19 }
20
21 vacall_function = &function;
22
23 val = ((return_type (*) ()) vacall) (arg1,arg2,...);
24
26 This set of macros permit a C function function to be called with vari‐
27 able arguments and to return variable return values. This is much like
28 the varargs(3) facility, but also allows the return value to be speci‐
29 fied at run time.
30
31 Function calling conventions differ considerably on different machines,
32 and vacall attempts to provide some degree of isolation from such
33 architecture dependencies.
34
35 The function that can be called with any number and type of arguments
36 and which will return any type of return value is vacall. It will do
37 some magic and call the function stored in the variable vacall_func‐
38 tion. If you want to make more than one use of vacall, use the trampo‐
39 line(3) facility to store &function into vacall_function just before
40 calling vacall.
41
42 Within function, the following macros can be used to walk through the
43 argument list and specify a return value:
44
45 va_start_type(alist[, return_type]);
46 starts the walk through the argument list and specifies the
47 return type.
48
49 arg = va_arg_type(alist[, arg_type]);
50 fetches the next argument from the argument list.
51
52 va_return_type(alist[[, return_type], return_value]);
53 ends the walk through the argument list and specifies the return
54 value.
55
56 The type in va_start_type and va_return_type shall be one of void, int,
57 uint, long, ulong, longlong, ulonglong, double, struct, ptr or (for
58 ANSI C calling conventions only) char, schar, uchar, short, ushort,
59 float, depending on the class of return_type.
60
61 The type specifiers in va_start_type and va_return_type must be the
62 same. The return_type specifiers passed to va_start_type and
63 va_return_type must be the same.
64
65 The type in va_arg_type shall be one of int, uint, long, ulong, long‐
66 long, ulonglong, double, struct, ptr or (for ANSI C calling conventions
67 only) char, schar, uchar, short, ushort, float, depending on the class
68 of arg_type.
69
70 In va_start_struct(alist, return_type, splittable); the splittable flag
71 specifies whether the struct return_type can be returned in registers
72 such that every struct field fits entirely in a single register. This
73 needs to be specified for structs of size 2*sizeof(long). For structs
74 of size <= sizeof(long), splittable is ignored and assumed to be 1. For
75 structs of size > 2*sizeof(long), splittable is ignored and assumed to
76 be 0. There are some handy macros for this:
77 va_word_splittable_1 (type1)
78 va_word_splittable_2 (type1, type2)
79 va_word_splittable_3 (type1, type2, type3)
80 va_word_splittable_4 (type1, type2, type3, type4)
81 For a struct with three slots
82 struct { type1 id1; type2 id2; type3 id3; }
83 you can specify splittable as va_word_splittable_3 (type1, type2,
84 type3) .
85
86
88 Functions which want to emulate Kernighan & Ritchie style functions
89 (i.e., in ANSI C, functions without a typed argument list) cannot use
90 the type values char, schar, uchar, short, ushort, float. As pre‐
91 scribed by the default K&R C expression promotions, they have to use
92 int instead of char, schar, uchar, short, ushort and double instead of
93 float.
94
95 The macros va_start_longlong(), va_start_ulonglong(), va_return_long‐
96 long(), va_return_ulonglong(), va_arg_longlong() and va_arg_ulonglong()
97 work only if the C compiler has a working long long 64-bit integer
98 type.
99
100 The struct types used in va_start_struct() and va_struct() must only
101 contain (signed or unsigned) int, long, long long or pointer fields.
102 Struct types containing (signed or unsigned) char, short, float, double
103 or other structs are not supported.
104
105
107 This example, a possible implementation of execl(3) on top of execv(2)
108 using varargs(3),
109
110 #include <varargs.h>
111 #define MAXARGS 100
112 /* execl is called by execl(file, arg1, arg2, ..., (char *)0); */
113 int execl (va_alist)
114 va_dcl
115 {
116 va_list ap;
117 char* file;
118 char* args[MAXARGS];
119 int argno = 0;
120 va_start (ap);
121 file = va_arg(ap, char*);
122 while ((args[argno] = va_arg(ap, char*)) != (char *)0)
123 argno++;
124 va_end (ap);
125 return execv(file, args);
126 }
127
128 looks like this using vacall(3):
129
130 #include <vacall.h>
131 #define MAXARGS 100
132 /* execl is called by vacall(file, arg1, arg2, ..., (char *)0); */
133 void execl (ap)
134 va_alist ap;
135 {
136 char* file;
137 char* args[MAXARGS];
138 int argno = 0;
139 int retval;
140 va_start_int (ap);
141 file = va_arg_ptr(ap, char*);
142 while ((args[argno] = va_arg_ptr(ap, char*)) != (char *)0)
143 argno++;
144 retval = execv(file, args);
145 va_return_int (ap, retval);
146 }
147 vacall_function = &execl;
148
149
151 varargs(3), trampoline(3), callback(3).
152
153
155 The current implementations have been tested on a selection of common
156 cases but there are probably still many bugs.
157
158 There are typically built-in limits on the size of the argument-list,
159 which may also include the size of any structure arguments.
160
161 The decision whether a struct is to be returned in registers or in mem‐
162 ory considers only the struct's size and alignment. This is inaccurate:
163 for example, gcc on m68k-next returns struct { char a,b,c; } in regis‐
164 ters and struct { char a[3]; } in memory, although both types have the
165 same size and the same alignment.
166
167 <vacall.h> cannot be included when <varargs.h> or <stdarg.h> is
168 included. (Name clash for va_alist.)
169
170 The argument list can only be walked once.
171
172 The use of the global variable vacall_function is not reentrant. This
173 is fixed in the callback(3) package.
174
175
177 Knowledge about argument passing conventions can be found in the gcc
178 source, file gcc-2.6.3/config/cpu/cpu.h, section "Stack layout; func‐
179 tion entry, exit and calling."
180
181 The implementation of varargs for gcc can be found in the gcc source,
182 files gcc-2.6.3/ginclude/va*.h.
183
184 gcc's __builtin_saveregs() function is defined in the gcc source, file
185 gcc-2.6.3/libgcc2.c.
186
187
189 Bruno Haible <bruno@clisp.org>
190
191
193 Many ideas and a lot of code were cribbed from the gcc source.
194
195
196
197
198 14 January 2001 VACALL(3)