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