Commit | Line | Data |
---|---|---|
ef44eed1 SS |
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 __STDC__ | |
6 | #define PARAMS(paramlist) paramlist | |
7 | #else | |
8 | #define PARAMS(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 | int x; | |
39 | long y; | |
40 | } struct_val1 = { 76, 51 }; | |
41 | ||
42 | /* Some functions that can be passed as arguments to other test | |
43 | functions, or called directly. */ | |
44 | ||
45 | int add (a, b) | |
46 | int a, b; | |
47 | { | |
48 | return (a + b); | |
49 | } | |
50 | ||
51 | int doubleit (a) | |
52 | int a; | |
53 | { | |
54 | return (a + a); | |
55 | } | |
56 | ||
57 | int (*func_val1) PARAMS((int,int)) = add; | |
58 | int (*func_val2) PARAMS((int)) = doubleit; | |
59 | ||
60 | /* An enumeration and functions that test for specific values. */ | |
61 | ||
62 | enum enumtype { enumval1, enumval2, enumval3 }; | |
63 | enum enumtype enum_val1 = enumval1; | |
64 | enum enumtype enum_val2 = enumval2; | |
65 | enum enumtype enum_val3 = enumval3; | |
66 | ||
67 | t_enum_value1 (enum_arg) | |
68 | enum enumtype enum_arg; | |
69 | { | |
70 | return (enum_arg == enum_val1); | |
71 | } | |
72 | ||
73 | t_enum_value2 (enum_arg) | |
74 | enum enumtype enum_arg; | |
75 | { | |
76 | return (enum_arg == enum_val2); | |
77 | } | |
78 | ||
79 | t_enum_value3 (enum_arg) | |
80 | enum enumtype enum_arg; | |
81 | { | |
82 | return (enum_arg == enum_val3); | |
83 | } | |
84 | ||
85 | /* A function that takes a vector of integers (along with an explicit | |
86 | count) and returns their sum. */ | |
87 | ||
88 | int sum_args (argc, argv) | |
89 | int argc; | |
90 | int argv[]; | |
91 | { | |
92 | int sumval = 0; | |
93 | int idx; | |
94 | ||
95 | for (idx = 0; idx < argc; idx++) | |
96 | { | |
97 | sumval += argv[idx]; | |
98 | } | |
99 | return (sumval); | |
100 | } | |
101 | ||
102 | /* Test that calling functions works if there are a lot of arguments. */ | |
103 | int | |
104 | sum10 (i0, i1, i2, i3, i4, i5, i6, i7, i8, i9) | |
105 | int i0, i1, i2, i3, i4, i5, i6, i7, i8, i9; | |
106 | { | |
107 | return i0 + i1 + i2 + i3 + i4 + i5 + i6 + i7 + i8 + i9; | |
108 | } | |
109 | ||
110 | /* Gotta have a main to be able to generate a linked, runnable | |
111 | executable, and also provide a useful place to set a breakpoint. */ | |
112 | ||
113 | main () | |
114 | { | |
115 | malloc(1); | |
116 | } | |
117 | ||
118 | /* Functions that expect specific values to be passed and return | |
119 | either 0 or 1, depending upon whether the values were | |
120 | passed incorrectly or correctly, respectively. */ | |
121 | ||
122 | int t_char_values (char_arg1, char_arg2) | |
123 | char char_arg1, char_arg2; | |
124 | { | |
125 | return ((char_arg1 == char_val1) && (char_arg2 == char_val2)); | |
126 | } | |
127 | ||
128 | int t_short_values (short_arg1, short_arg2) | |
129 | short short_arg1, short_arg2; | |
130 | { | |
131 | return ((short_arg1 == short_val1) && (short_arg2 == short_val2)); | |
132 | } | |
133 | ||
134 | int t_int_values (int_arg1, int_arg2) | |
135 | int int_arg1, int_arg2; | |
136 | { | |
137 | return ((int_arg1 == int_val1) && (int_arg2 == int_val2)); | |
138 | } | |
139 | ||
140 | int t_long_values (long_arg1, long_arg2) | |
141 | long long_arg1, long_arg2; | |
142 | { | |
143 | return ((long_arg1 == long_val1) && (long_arg2 == long_val2)); | |
144 | } | |
145 | ||
146 | int t_float_values (float_arg1, float_arg2) | |
147 | float float_arg1, float_arg2; | |
148 | { | |
149 | return (((float_arg1 - float_val1) < DELTA) && | |
150 | ((float_arg2 - float_val2) < DELTA)); | |
151 | } | |
152 | ||
153 | int t_double_values (double_arg1, double_arg2) | |
154 | double double_arg1, double_arg2; | |
155 | { | |
156 | return (((double_arg1 - double_val1) < DELTA) && | |
157 | ((double_arg2 - double_val2) < DELTA)); | |
158 | } | |
159 | ||
160 | int t_string_values (string_arg1, string_arg2) | |
161 | char *string_arg1, *string_arg2; | |
162 | { | |
163 | return (!strcmp (string_arg1, string_val1) && | |
164 | !strcmp (string_arg2, string_val2)); | |
165 | } | |
166 | ||
167 | int t_char_array_values (char_array_arg1, char_array_arg2) | |
168 | char char_array_arg1[], char_array_arg2[]; | |
169 | { | |
170 | return (!strcmp (char_array_arg1, char_array_val1) && | |
171 | !strcmp (char_array_arg2, char_array_val2)); | |
172 | } | |
173 | ||
174 | ||
175 | /* This used to simply compare the function pointer arguments with | |
176 | known values for func_val1 and func_val2. Doing so is valid ANSI | |
177 | code, but on some machines (RS6000, HPPA, others?) it may fail when | |
178 | called directly by GDB. | |
179 | ||
180 | In a nutshell, it's not possible for GDB to determine when the address | |
181 | of a function or the address of the function's stub/trampoline should | |
182 | be passed. | |
183 | ||
184 | So, to avoid GDB lossage in the common case, we perform calls through the | |
185 | various function pointers and compare the return values. For the HPPA | |
186 | at least, this allows the common case to work. | |
187 | ||
188 | If one wants to try something more complicated, pass the address of | |
189 | a function accepting a "double" as one of its first 4 arguments. Call | |
190 | that function indirectly through the function pointer. This would fail | |
191 | on the HPPA. */ | |
192 | ||
193 | int t_func_values (func_arg1, func_arg2) | |
194 | int (*func_arg1) PARAMS ((int, int)); | |
195 | int (*func_arg2) PARAMS ((int)); | |
196 | { | |
197 | return ((*func_arg1) (5,5) == (*func_val1) (5,5) | |
198 | && (*func_arg2) (6) == (*func_val2) (6)); | |
199 | } | |
200 | ||
201 | int t_call_add (func_arg1, a, b) | |
202 | int (*func_arg1) PARAMS ((int, int)); | |
203 | int a, b; | |
204 | { | |
205 | return ((*func_arg1)(a, b)); | |
206 | } |