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