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