xref: /openbsd-src/gnu/usr.bin/binutils/gdb/testsuite/gdb.base/callfuncs.c (revision b2ea75c1b17e1a9a339660e7ed45cd24946b230e)
1 /* Support program for testing gdb's ability to call functions
2    in the inferior, pass appropriate arguments to those functions,
3    and get the returned result. */
4 
5 #ifdef NO_PROTOTYPES
6 #define PARAMS(paramlist) ()
7 #else
8 #define PARAMS(paramlist) paramlist
9 #endif
10 
11 char char_val1 = 'a';
12 char char_val2 = 'b';
13 
14 short short_val1 = 10;
15 short short_val2 = -23;
16 
17 int int_val1 = 87;
18 int int_val2 = -26;
19 
20 long long_val1 = 789;
21 long long_val2 = -321;
22 
23 float float_val1 = 3.14159;
24 float float_val2 = -2.3765;
25 
26 double double_val1 = 45.654;
27 double double_val2 = -67.66;
28 
29 #define DELTA (0.001)
30 
31 char *string_val1 = "string 1";
32 char *string_val2 = "string 2";
33 
34 char char_array_val1[] = "carray 1";
35 char char_array_val2[] = "carray 2";
36 
37 struct struct1 {
38   char c;
39   short s;
40   int i;
41   long l;
42   float f;
43   double d;
44   char a[4];
45 } struct_val1 = { 'x', 87, 76, 51, 2.1234, 9.876, "foo" };
46 
47 /* Some functions that can be passed as arguments to other test
48    functions, or called directly. */
49 
50 int add (a, b)
51 int a, b;
52 {
53   return (a + b);
54 }
55 
56 int doubleit (a)
57 int a;
58 {
59   return (a + a);
60 }
61 
62 int (*func_val1) PARAMS((int,int)) = add;
63 int (*func_val2) PARAMS((int)) = doubleit;
64 
65 /* An enumeration and functions that test for specific values. */
66 
67 enum enumtype { enumval1, enumval2, enumval3 };
68 enum enumtype enum_val1 = enumval1;
69 enum enumtype enum_val2 = enumval2;
70 enum enumtype enum_val3 = enumval3;
71 
72 t_enum_value1 (enum_arg)
73 enum enumtype enum_arg;
74 {
75   return (enum_arg == enum_val1);
76 }
77 
78 t_enum_value2 (enum_arg)
79 enum enumtype enum_arg;
80 {
81   return (enum_arg == enum_val2);
82 }
83 
84 t_enum_value3 (enum_arg)
85 enum enumtype enum_arg;
86 {
87   return (enum_arg == enum_val3);
88 }
89 
90 /* A function that takes a vector of integers (along with an explicit
91    count) and returns their sum. */
92 
93 int sum_args (argc, argv)
94 int argc;
95 int argv[];
96 {
97   int sumval = 0;
98   int idx;
99 
100   for (idx = 0; idx < argc; idx++)
101     {
102       sumval += argv[idx];
103     }
104   return (sumval);
105 }
106 
107 /* Test that we can call functions that take structs and return
108    members from that struct */
109 
110 char   t_structs_c (tstruct) struct struct1 tstruct; { return (tstruct.c); }
111 short  t_structs_s (tstruct) struct struct1 tstruct; { return (tstruct.s); }
112 int    t_structs_i (tstruct) struct struct1 tstruct; { return (tstruct.i); }
113 long   t_structs_l (tstruct) struct struct1 tstruct; { return (tstruct.l); }
114 float  t_structs_f (tstruct) struct struct1 tstruct; { return (tstruct.f); }
115 double t_structs_d (tstruct) struct struct1 tstruct; { return (tstruct.d); }
116 char  *t_structs_a (tstruct) struct struct1 tstruct; { return (tstruct.a); }
117 
118 /* Test that calling functions works if there are a lot of arguments.  */
119 int
120 sum10 (i0, i1, i2, i3, i4, i5, i6, i7, i8, i9)
121      int i0, i1, i2, i3, i4, i5, i6, i7, i8, i9;
122 {
123   return i0 + i1 + i2 + i3 + i4 + i5 + i6 + i7 + i8 + i9;
124 }
125 
126 /* Gotta have a main to be able to generate a linked, runnable
127    executable, and also provide a useful place to set a breakpoint. */
128 
129 main ()
130 {
131 #ifdef usestubs
132   set_debug_traps();
133   breakpoint();
134 #endif
135   malloc(1);
136   t_structs_c(struct_val1);
137 }
138 
139 /* Functions that expect specific values to be passed and return
140    either 0 or 1, depending upon whether the values were
141    passed incorrectly or correctly, respectively. */
142 
143 int t_char_values (char_arg1, char_arg2)
144 char char_arg1, char_arg2;
145 {
146   return ((char_arg1 == char_val1) && (char_arg2 == char_val2));
147 }
148 
149 int
150 #ifdef NO_PROTOTYPES
151 t_small_values (arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10)
152      char arg1;
153      short arg2;
154      int arg3;
155      char arg4;
156      short arg5;
157      char arg6;
158      short arg7;
159      int arg8;
160      short arg9;
161      short arg10;
162 #else
163 t_small_values (char arg1, short arg2, int arg3, char arg4, short arg5,
164 		char arg6, short arg7, int arg8, short arg9, short arg10)
165 #endif
166 {
167   return arg1 + arg2 + arg3 + arg4 + arg5 + arg6 + arg7 + arg8 + arg9 + arg10;
168 }
169 
170 int t_short_values (short_arg1, short_arg2)
171 short short_arg1, short_arg2;
172 {
173   return ((short_arg1 == short_val1) && (short_arg2 == short_val2));
174 }
175 
176 int t_int_values (int_arg1, int_arg2)
177 int int_arg1, int_arg2;
178 {
179   return ((int_arg1 == int_val1) && (int_arg2 == int_val2));
180 }
181 
182 int t_long_values (long_arg1, long_arg2)
183 long long_arg1, long_arg2;
184 {
185   return ((long_arg1 == long_val1) && (long_arg2 == long_val2));
186 }
187 
188 int t_float_values (float_arg1, float_arg2)
189 float float_arg1, float_arg2;
190 {
191   return ((float_arg1 - float_val1) < DELTA
192 	  && (float_arg1 - float_val1) > -DELTA
193 	  && (float_arg2 - float_val2) < DELTA
194 	  && (float_arg2 - float_val2) > -DELTA);
195 }
196 
197 int
198 #ifdef NO_PROTOTYPES
199 /* In this case we are just duplicating t_float_values, but that is the
200    easiest way to deal with either ANSI or non-ANSI.  */
201 t_float_values2 (float_arg1, float_arg2)
202      float float_arg1, float_arg2;
203 #else
204 t_float_values2 (float float_arg1, float float_arg2)
205 #endif
206 {
207   return ((float_arg1 - float_val1) < DELTA
208 	  && (float_arg1 - float_val1) > -DELTA
209 	  && (float_arg2 - float_val2) < DELTA
210 	  && (float_arg2 - float_val2) > -DELTA);
211 }
212 
213 int t_double_values (double_arg1, double_arg2)
214 double double_arg1, double_arg2;
215 {
216   return ((double_arg1 - double_val1) < DELTA
217 	  && (double_arg1 - double_val1) > -DELTA
218 	  && (double_arg2 - double_val2) < DELTA
219 	  && (double_arg2 - double_val2) > -DELTA);
220 }
221 
222 int t_string_values (string_arg1, string_arg2)
223 char *string_arg1, *string_arg2;
224 {
225   return (!strcmp (string_arg1, string_val1) &&
226 	  !strcmp (string_arg2, string_val2));
227 }
228 
229 int t_char_array_values (char_array_arg1, char_array_arg2)
230 char char_array_arg1[], char_array_arg2[];
231 {
232   return (!strcmp (char_array_arg1, char_array_val1) &&
233 	  !strcmp (char_array_arg2, char_array_val2));
234 }
235 
236 
237 /* This used to simply compare the function pointer arguments with
238    known values for func_val1 and func_val2.  Doing so is valid ANSI
239    code, but on some machines (RS6000, HPPA, others?) it may fail when
240    called directly by GDB.
241 
242    In a nutshell, it's not possible for GDB to determine when the address
243    of a function or the address of the function's stub/trampoline should
244    be passed.
245 
246    So, to avoid GDB lossage in the common case, we perform calls through the
247    various function pointers and compare the return values.  For the HPPA
248    at least, this allows the common case to work.
249 
250    If one wants to try something more complicated, pass the address of
251    a function accepting a "double" as one of its first 4 arguments.  Call
252    that function indirectly through the function pointer.  This would fail
253    on the HPPA.  */
254 
255 int t_func_values (func_arg1, func_arg2)
256 int (*func_arg1) PARAMS ((int, int));
257 int (*func_arg2) PARAMS ((int));
258 {
259   return ((*func_arg1) (5,5)  == (*func_val1) (5,5)
260           && (*func_arg2) (6) == (*func_val2) (6));
261 }
262 
263 int t_call_add (func_arg1, a, b)
264 int (*func_arg1) PARAMS ((int, int));
265 int a, b;
266 {
267   return ((*func_arg1)(a, b));
268 }
269