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