diff --git a/gdb/testsuite/gdb.base/call-array-struct.c b/gdb/testsuite/gdb.base/call-array-struct.c new file mode 100644 index 0000000000..da5015b189 --- /dev/null +++ b/gdb/testsuite/gdb.base/call-array-struct.c @@ -0,0 +1,1137 @@ + +#include +#include +#include + +/************************************************************************** + * TESTS : + * -- function arguments that are enumerated types + * -- small structure arguments ( <= 64 bits ) + * -- stored in registers + * -- stored on the stack + * -- large structure arguments ( > 64 bits ) + * -- stored in registers + * -- stored on the stack + * -- array arguments + * -- caller is a leaf routine : + * -- use the call command from within an init routine (i.e. + * init_bit_flags, init_bit_flags_combo, init_array_rep) + * -- caller doesn't have enough space for all the function arguments : + * -- call print_long_arg_list from inside print_small_structs + ***************************************************************************/ + +/* Some enumerated types -- used to test that the structureal data type is + * retrieved for function arguments with typedef data types. + */ +typedef int id_int; + +typedef enum { + BLACK, + BLUE, + BROWN, + ECRUE, + GOLD, + GRAY, + GREEN, + IVORY, + MAUVE, + ORANGE, + PINK, + PURPLE, + RED, + SILVER, + TAN, + VIOLET, + WHITE, + YELLOW} colors; + +/* A large structure (> 64 bits) used to test passing large structures as + * parameters + */ + +struct array_rep_info_t { + int next_index[10]; + int values[10]; + int head; +}; + +/***************************************************************************** + * Small structures ( <= 64 bits). These are used to test passing small + * structures as parameters and test argument size promotion. + *****************************************************************************/ + + /* 64 bits + */ +struct small_rep_info_t { + int value; + int head; +}; + +/* 6 bits : really fits in 8 bits and is promoted to 32 bits + */ +struct bit_flags_t { + unsigned alpha :1; + unsigned beta :1; + unsigned gamma :1; + unsigned delta :1; + unsigned epsilon :1; + unsigned omega :1; +}; + +/* 22 bits : really fits in 40 bits and is promoted to 64 bits + */ +struct bit_flags_combo_t { + unsigned alpha :1; + unsigned beta :1; + char ch1; + unsigned gamma :1; + unsigned delta :1; + char ch2; + unsigned epsilon :1; + unsigned omega :1; +}; + +/* 64 bits + */ +struct one_double_t { + double double1; +}; + +/* 64 bits + */ +struct two_floats_t { + float float1; + float float2; +}; + +/* 16 bits : promoted to 32 bits + */ +struct two_char_t { + char ch1; + char ch2; +}; + +/* 24 bits : promoted to 32 bits + */ +struct three_char_t { + char ch1; + char ch2; + char ch3; +}; + +/* 40 bits : promoted to 64 bits + */ +struct five_char_t { + char ch1; + char ch2; + char ch3; + char ch4; + char ch5; +}; + +/* 40 bits : promoted to 64 bits + */ +struct int_char_combo_t { + int int1; + char ch1; +}; + +/***************************************************************** + * PRINT_STUDENT_ID_SHIRT_COLOR : + * IN id_int student -- enumerated type + * IN colors shirt -- enumerated type + *****************************************************************/ +void print_student_id_shirt_color ( student, shirt ) + id_int student; + colors shirt; +{ + + printf("student id : %d\t", student); + printf("shirt color : "); + switch (shirt) { + case BLACK : printf("BLACK\n"); + break; + case BLUE : printf("BLUE\n"); + break; + case BROWN : printf("BROWN\n"); + break; + case ECRUE : printf("ECRUE\n"); + break; + case GOLD : printf("GOLD\n"); + break; + case GRAY : printf("GRAY\n"); + break; + case GREEN : printf("GREEN\n"); + break; + case IVORY : printf("IVORY\n"); + break; + case MAUVE : printf("MAUVE\n"); + break; + case ORANGE : printf("ORANGE\n"); + break; + case PINK : printf("PINK\n"); + break; + case PURPLE : printf("PURPLE\n"); + break; + case RED : printf("RED\n"); + break; + case SILVER : printf("SILVER\n"); + break; + case TAN : printf("TAN\n"); + break; + case VIOLET : printf("VIOLET\n"); + break; + case WHITE : printf("WHITE\n"); + break; + case YELLOW : printf("YELLOW\n"); + break; + } +} + +/***************************************************************** + * PRINT_CHAR_ARRAY : + * IN char array_c[] -- character array + *****************************************************************/ +void print_char_array ( array_c ) + char array_c[]; + +{ + + int index; + + printf("array_c :\n"); + printf("=========\n\n"); + for (index = 0; index < 120; index++) { + printf("%1c", array_c[index]); + if ((index%50) == 0) printf("\n"); + } + printf("\n\n"); +} + +/***************************************************************** + * PRINT_DOUBLE_ARRAY : + * IN double array_d[] -- array of doubles + *****************************************************************/ +void print_double_array (array_d) + double array_d[]; + +{ + + int index; + + printf("array_d :\n"); + printf("=========\n\n"); + for (index = 0; index < 100; index++) { + printf("%f ", array_d[index]); + if ((index%8) == 0) printf("\n"); + } + printf("\n\n"); +} + +/***************************************************************** + * PRINT_FLOAT_ARRAY: + * IN float array_f[] -- array of floats + *****************************************************************/ +void print_float_array ( array_f ) + float array_f[]; + +{ + + int index; + + printf("array_f :\n"); + printf("=========\n\n"); + for (index = 0; index < 15; index++) { + printf("%f ", array_f[index]); + if ((index%8) == 0) printf("\n"); + + } + printf("\n\n"); +} + +/***************************************************************** + * PRINT_INT_ARRAY: + * IN int array_i[] -- array of integers + *****************************************************************/ +void print_int_array ( array_i ) + int array_i[]; + +{ + + int index; + + printf("array_i :\n"); + printf("=========\n\n"); + for (index = 0; index < 50; index++) { + printf("%d ", array_i[index]); + if ((index%8) == 0) printf("\n"); + } + printf("\n\n"); + +} + +/***************************************************************** + * PRINT_ALL_ARRAYS: + * IN int array_i[] -- array of integers + * IN char array_c[] -- array of characters + * IN float array_f[] -- array of floats + * IN double array_d[] -- array of doubles + *****************************************************************/ +void print_all_arrays( array_i, array_c, array_f, array_d ) + int array_i[]; + char array_c[]; + float array_f[]; + double array_d[]; + +{ + print_int_array(array_i); + print_char_array(array_c); + print_float_array(array_f); + print_double_array(array_d); +} + +/***************************************************************** + * LOOP_COUNT : + * A do nothing function. Used to provide a point at which calls can be made. + *****************************************************************/ +void loop_count () { + + int index; + + for (index=0; index<4; index++); +} + +/***************************************************************** + * COMPUTE_WITH_SMALL_STRUCTS : + * A do nothing function. Used to provide a point at which calls can be made. + * IN int seed + *****************************************************************/ +void compute_with_small_structs ( seed ) + int seed; +{ + + struct small_rep_info_t array[4]; + int index; + + for (index = 0; index < 4; index++) { + array[index].value = index*seed; + array[index].head = (index+1)*seed; + } + + for (index = 1; index < 4; index++) { + array[index].value = array[index].value + array[index-1].value; + array[index].head = array[index].head + array[index-1].head; + } +} + +/***************************************************************** + * INIT_BIT_FLAGS : + * Initializes a bit_flags_t structure. Can call this function see + * the call command behavior when integer arguments do not fit into + * registers and must be placed on the stack. + * OUT struct bit_flags_t *bit_flags -- structure to be filled + * IN unsigned a -- 0 or 1 + * IN unsigned b -- 0 or 1 + * IN unsigned g -- 0 or 1 + * IN unsigned d -- 0 or 1 + * IN unsigned e -- 0 or 1 + * IN unsigned o -- 0 or 1 + *****************************************************************/ +void init_bit_flags ( bit_flags, a, b, g, d, e, o ) +struct bit_flags_t *bit_flags; +unsigned a; +unsigned b; +unsigned g; +unsigned d; +unsigned e; +unsigned o; +{ + + bit_flags->alpha = a; + bit_flags->beta = b; + bit_flags->gamma = g; + bit_flags->delta = d; + bit_flags->epsilon = e; + bit_flags->omega = o; +} + +/***************************************************************** + * INIT_BIT_FLAGS_COMBO : + * Initializes a bit_flags_combo_t structure. Can call this function + * to see the call command behavior when integer and character arguments + * do not fit into registers and must be placed on the stack. + * OUT struct bit_flags_combo_t *bit_flags_combo -- structure to fill + * IN unsigned a -- 0 or 1 + * IN unsigned b -- 0 or 1 + * IN char ch1 + * IN unsigned g -- 0 or 1 + * IN unsigned d -- 0 or 1 + * IN char ch2 + * IN unsigned e -- 0 or 1 + * IN unsigned o -- 0 or 1 + *****************************************************************/ +void init_bit_flags_combo ( bit_flags_combo, a, b, ch1, g, d, ch2, e, o ) + struct bit_flags_combo_t *bit_flags_combo; + unsigned a; + unsigned b; + char ch1; + unsigned g; + unsigned d; + char ch2; + unsigned e; + unsigned o; +{ + + bit_flags_combo->alpha = a; + bit_flags_combo->beta = b; + bit_flags_combo->ch1 = ch1; + bit_flags_combo->gamma = g; + bit_flags_combo->delta = d; + bit_flags_combo->ch2 = ch2; + bit_flags_combo->epsilon = e; + bit_flags_combo->omega = o; +} + + +/***************************************************************** + * INIT_ONE_DOUBLE : + * OUT struct one_double_t *one_double -- structure to fill + * IN double init_val + *****************************************************************/ +void init_one_double ( one_double, init_val ) + struct one_double_t *one_double; + double init_val; +{ + + one_double->double1 = init_val; +} + +/***************************************************************** + * INIT_TWO_FLOATS : + * OUT struct two_floats_t *two_floats -- structure to be filled + * IN float init_val1 + * IN float init_val2 + *****************************************************************/ +void init_two_floats ( two_floats, init_val1, init_val2 ) + struct two_floats_t *two_floats; + float init_val1; + float init_val2; +{ + two_floats->float1 = init_val1; + two_floats->float2 = init_val2; +} + +/***************************************************************** + * INIT_TWO_CHARS : + * OUT struct two_char_t *two_char -- structure to be filled + * IN char init_val1 + * IN char init_val2 + *****************************************************************/ +void init_two_chars ( two_char, init_val1, init_val2 ) + struct two_char_t *two_char; + char init_val1; + char init_val2; +{ + + two_char->ch1 = init_val1; + two_char->ch2 = init_val2; +} + +/***************************************************************** + * INIT_THREE_CHARS : + * OUT struct three_char_t *three_char -- structure to be filled + * IN char init_val1 + * IN char init_val2 + * IN char init_val3 + *****************************************************************/ +void init_three_chars ( three_char, init_val1, init_val2, init_val3 ) + struct three_char_t *three_char; + char init_val1; + char init_val2; + char init_val3; +{ + + three_char->ch1 = init_val1; + three_char->ch2 = init_val2; + three_char->ch3 = init_val3; +} + +/***************************************************************** + * INIT_FIVE_CHARS : + * OUT struct five_char_t *five_char -- structure to be filled + * IN char init_val1 + * IN char init_val2 + * IN char init_val3 + * IN char init_val4 + * IN char init_val5 + *****************************************************************/ +void init_five_chars ( five_char, init_val1, init_val2, init_val3,init_val4,init_val5 ) + struct five_char_t *five_char; + char init_val1; + char init_val2; + char init_val3; + char init_val4; + char init_val5; +{ + five_char->ch1 = init_val1; + five_char->ch2 = init_val2; + five_char->ch3 = init_val3; + five_char->ch4 = init_val4; + five_char->ch5 = init_val5; +} + +/***************************************************************** + * INIT_INT_CHAR_COMBO : + * OUT struct int_char_combo_t *combo -- structure to be filled + * IN int init_val1 + * IN char init_val2 + *****************************************************************/ +void init_int_char_combo ( combo, init_val1, init_val2 ) + struct int_char_combo_t *combo; + int init_val1; + char init_val2; +{ + + combo->int1 = init_val1; + combo->ch1 = init_val2; +} + +/***************************************************************** + * INIT_STRUCT_REP : + * OUT struct small_rep_into_t *small_struct -- structure to be filled + * IN int seed + *****************************************************************/ +void init_struct_rep( small_struct, seed ) + struct small_rep_info_t *small_struct; + int seed; + +{ + + small_struct->value = 2 + (seed*2); + small_struct->head = 0; +} + +/***************************************************************** + * INIT_SMALL_STRUCTS : + * Takes all the small structures as input and calls the appropriate + * initialization routine for each structure + *****************************************************************/ +void init_small_structs (struct1, struct2, struct3,struct4,flags,flags_combo, +three_char, five_char,int_char_combo, d1, d2,d3,f1,f2,f3) + struct small_rep_info_t *struct1; + struct small_rep_info_t *struct2; + struct small_rep_info_t *struct3; + struct small_rep_info_t *struct4; + struct bit_flags_t *flags; + struct bit_flags_combo_t *flags_combo; + struct three_char_t *three_char; + struct five_char_t *five_char; + struct int_char_combo_t *int_char_combo; + struct one_double_t *d1; + struct one_double_t *d2; + struct one_double_t *d3; + struct two_floats_t *f1; + struct two_floats_t *f2; + struct two_floats_t *f3; + +{ + + init_bit_flags(flags, (unsigned)1, (unsigned)0, (unsigned)1, + (unsigned)0, (unsigned)1, (unsigned)0 ); + init_bit_flags_combo(flags_combo, (unsigned)1, (unsigned)0, 'y', + (unsigned)1, (unsigned)0, 'n', + (unsigned)1, (unsigned)0 ); + init_three_chars(three_char, 'a', 'b', 'c'); + init_five_chars(five_char, 'l', 'm', 'n', 'o', 'p'); + init_int_char_combo(int_char_combo, 123, 'z'); + init_struct_rep(struct1, 2); + init_struct_rep(struct2, 4); + init_struct_rep(struct3, 5); + init_struct_rep(struct4, 6); + init_one_double ( d1, 10.5); + init_one_double ( d2, -3.34); + init_one_double ( d3, 675.09123); + init_two_floats ( f1, 45.234, 43.6); + init_two_floats ( f2, 78.01, 122.10); + init_two_floats ( f3, -1232.345, -199.21); +} + +/***************************************************************** + * PRINT_TEN_DOUBLES : + * ????????????????????????????? + ****************************************************************/ +void print_ten_doubles ( d1, d2, d3, d4, d5, d6, d7, d8, d9, d10 ) + double d1; + double d2; + double d3; + double d4; + double d5; + double d6; + double d7; + double d8; + double d9; + double d10; +{ + + printf("Two Doubles : %f\t%f\n", d1, d2); + printf("Two Doubles : %f\t%f\n", d3, d4); + printf("Two Doubles : %f\t%f\n", d5, d6); + printf("Two Doubles : %f\t%f\n", d7, d8); + printf("Two Doubles : %f\t%f\n", d9, d10); +} + +/***************************************************************** + * PRINT_BIT_FLAGS : + * IN struct bit_flags_t bit_flags + ****************************************************************/ +void print_bit_flags ( bit_flags ) +struct bit_flags_t bit_flags; +{ + + if (bit_flags.alpha) printf("alpha\n"); + if (bit_flags.beta) printf("beta\n"); + if (bit_flags.gamma) printf("gamma\n"); + if (bit_flags.delta) printf("delta\n"); + if (bit_flags.epsilon) printf("epsilon\n"); + if (bit_flags.omega) printf("omega\n"); +} + +/***************************************************************** + * PRINT_BIT_FLAGS_COMBO : + * IN struct bit_flags_combo_t bit_flags_combo + ****************************************************************/ +void print_bit_flags_combo ( bit_flags_combo ) +struct bit_flags_combo_t bit_flags_combo; +{ + + if (bit_flags_combo.alpha) printf("alpha\n"); + if (bit_flags_combo.beta) printf("beta\n"); + if (bit_flags_combo.gamma) printf("gamma\n"); + if (bit_flags_combo.delta) printf("delta\n"); + if (bit_flags_combo.epsilon) printf("epsilon\n"); + if (bit_flags_combo.omega) printf("omega\n"); + printf("ch1: %c\tch2: %c\n", bit_flags_combo.ch1, bit_flags_combo.ch2); +} + +/***************************************************************** + * PRINT_ONE_DOUBLE : + * IN struct one_double_t one_double + ****************************************************************/ +void print_one_double ( one_double ) +struct one_double_t one_double; +{ + + printf("Contents of one_double_t: \n\n"); + printf("%f\n", one_double.double1); +} + +/***************************************************************** + * PRINT_TWO_FLOATS : + * IN struct two_floats_t two_floats + ****************************************************************/ +void print_two_floats ( two_floats ) +struct two_floats_t two_floats; +{ + + printf("Contents of two_floats_t: \n\n"); + printf("%f\t%f\n", two_floats.float1, two_floats.float2); +} + +/***************************************************************** + * PRINT_TWO_CHARS : + * IN struct two_char_t two_char + ****************************************************************/ +void print_two_chars ( two_char ) +struct two_char_t two_char; +{ + + printf("Contents of two_char_t: \n\n"); + printf("%c\t%c\n", two_char.ch1, two_char.ch2); +} + +/***************************************************************** + * PRINT_THREE_CHARS : + * IN struct three_char_t three_char + ****************************************************************/ +void print_three_chars ( three_char ) +struct three_char_t three_char; +{ + + printf("Contents of three_char_t: \n\n"); + printf("%c\t%c\t%c\n", three_char.ch1, three_char.ch2, three_char.ch3); +} + +/***************************************************************** + * PRINT_FIVE_CHARS : + * IN struct five_char_t five_char + ****************************************************************/ +void print_five_chars ( five_char ) +struct five_char_t five_char; +{ + + printf("Contents of five_char_t: \n\n"); + printf("%c\t%c\t%c\t%c\t%c\n", five_char.ch1, five_char.ch2, + five_char.ch3, five_char.ch4, + five_char.ch5); +} + +/***************************************************************** + * PRINT_INT_CHAR_COMBO : + * IN struct int_char_combo_t int_char_combo + ****************************************************************/ +void print_int_char_combo ( int_char_combo ) +struct int_char_combo_t int_char_combo; +{ + + printf("Contents of int_char_combo_t: \n\n"); + printf("%d\t%c\n", int_char_combo.int1, int_char_combo.ch1); +} + +/***************************************************************** + * PRINT_STRUCT_REP : + * The last parameter must go onto the stack rather than into a register. + * This is a good function to call to test small structures. + * IN struct small_rep_info_t struct1 + * IN struct small_rep_info_t struct2 + * IN struct small_rep_info_t struct3 + ****************************************************************/ +void print_struct_rep( struct1, struct2, struct3) + struct small_rep_info_t struct1; + struct small_rep_info_t struct2; + struct small_rep_info_t struct3; + +{ + + + printf("Contents of struct1: \n\n"); + printf("%10d%10d\n", struct1.value, struct1.head); + printf("Contents of struct2: \n\n"); + printf("%10d%10d\n", struct2.value, struct2.head); + printf("Contents of struct3: \n\n"); + printf("%10d%10d\n", struct3.value, struct3.head); + +} + +/***************************************************************** + * SUM_STRUCT_PRINT : + * The last two parameters must go onto the stack rather than into a register. + * This is a good function to call to test small structures. + * IN struct small_rep_info_t struct1 + * IN struct small_rep_info_t struct2 + * IN struct small_rep_info_t struct3 + * IN struct small_rep_info_t struct4 + ****************************************************************/ +void sum_struct_print ( seed, struct1, struct2, struct3, struct4) + int seed; + struct small_rep_info_t struct1; + struct small_rep_info_t struct2; + struct small_rep_info_t struct3; + struct small_rep_info_t struct4; + +{ + int sum; + + printf("Sum of the 4 struct values and seed : \n\n"); + sum = seed + struct1.value + struct2.value + struct3.value + struct4.value; + printf("%10d\n", sum); +} + +/***************************************************************** + * PRINT_SMALL_STRUCTS : + * This is a good function to call to test small structures. + * All of the small structures of odd sizes (40 bits, 8bits, etc.) + * are pushed onto the stack. + ****************************************************************/ +void print_small_structs ( struct1, struct2, struct3, struct4, flags, +flags_combo, three_char, five_char, int_char_combo, d1, d2,d3,f1,f2,f3) + struct small_rep_info_t struct1; + struct small_rep_info_t struct2; + struct small_rep_info_t struct3; + struct small_rep_info_t struct4; + struct bit_flags_t flags; + struct bit_flags_combo_t flags_combo; + struct three_char_t three_char; + struct five_char_t five_char; + struct int_char_combo_t int_char_combo; + struct one_double_t d1; + struct one_double_t d2; + struct one_double_t d3; + struct two_floats_t f1; + struct two_floats_t f2; + struct two_floats_t f3; +{ + print_bit_flags(flags); + print_bit_flags_combo(flags_combo); + print_three_chars(three_char); + print_five_chars(five_char); + print_int_char_combo(int_char_combo); + sum_struct_print(10, struct1, struct2, struct3, struct4); + print_struct_rep(struct1, struct2, struct3); + print_one_double(d1); + print_one_double(d2); + print_one_double(d3); + print_two_floats(f1); + print_two_floats(f2); + print_two_floats(f3); +} + +/***************************************************************** + * PRINT_LONG_ARG_LIST : + * This is a good function to call to test small structures. + * The first two parameters ( the doubles ) go into registers. The + * remaining arguments are pushed onto the stack. Depending on where + * print_long_arg_list is called from, the size of the argument list + * may force more space to be pushed onto the stack as part of the callers + * frame. + ****************************************************************/ +void print_long_arg_list ( a, b, c, d, e, f, struct1, struct2, struct3, +struct4, flags, flags_combo, three_char, five_char, int_char_combo, d1,d2,d3, +f1, f2, f3 ) + double a; + double b; + int c; + int d; + int e; + int f; + struct small_rep_info_t struct1; + struct small_rep_info_t struct2; + struct small_rep_info_t struct3; + struct small_rep_info_t struct4; + struct bit_flags_t flags; + struct bit_flags_combo_t flags_combo; + struct three_char_t three_char; + struct five_char_t five_char; + struct int_char_combo_t int_char_combo; + struct one_double_t d1; + struct one_double_t d2; + struct one_double_t d3; + struct two_floats_t f1; + struct two_floats_t f2; + struct two_floats_t f3; + +{ + printf("double : %f\n", a); + printf("double : %f\n", b); + printf("int : %d\n", c); + printf("int : %d\n", d); + printf("int : %d\n", e); + printf("int : %d\n", f); + print_small_structs( struct1, struct2, struct3, struct4, flags, flags_combo, + three_char, five_char, int_char_combo, d1, d2, d3, + f1, f2, f3); +} + + +void print_one_large_struct( linked_list1 ) + struct array_rep_info_t linked_list1; + +{ + + /* printf("Contents of linked list1: \n\n"); + printf("Element Value | Index of Next Element\n"); + printf("-------------------------------------\n"); + printf(" | \n");*/ + /*for (index = 0; index < 10; index++) {*/ + + printf("%10d%10d\n", linked_list1.values[0], + linked_list1.next_index[0]); + /*}*/ +} + +/***************************************************************** + * PRINT_ARRAY_REP : + * The three structure parameters should fit into registers. + * IN struct array_rep_info_t linked_list1 + * IN struct array_rep_info_t linked_list2 + * IN struct array_rep_info_t linked_list3 + ****************************************************************/ +void print_array_rep( linked_list1, linked_list2, linked_list3 ) + struct array_rep_info_t linked_list1; + struct array_rep_info_t linked_list2; + struct array_rep_info_t linked_list3; + +{ + + int index; + + printf("Contents of linked list1: \n\n"); + printf("Element Value | Index of Next Element\n"); + printf("-------------------------------------\n"); + printf(" | \n"); + for (index = 0; index < 10; index++) { + + printf("%10d%10d\n", linked_list1.values[index], + linked_list1.next_index[index]); + } + + printf("Contents of linked list2: \n\n"); + printf("Element Value | Index of Next Element\n"); + printf("-------------------------------------\n"); + printf(" | \n"); + for (index = 0; index < 10; index++) { + + printf("%10d%10d\n", linked_list2.values[index], + linked_list2.next_index[index]); + } + + printf("Contents of linked list3: \n\n"); + printf("Element Value | Index of Next Element\n"); + printf("-------------------------------------\n"); + printf(" | \n"); + for (index = 0; index < 10; index++) { + + printf("%10d%10d\n", linked_list3.values[index], + linked_list3.next_index[index]); + } + +} + +/***************************************************************** + * SUM_ARRAY_PRINT : + * The last structure parameter must be pushed onto the stack + * IN int seed + * IN struct array_rep_info_t linked_list1 + * IN struct array_rep_info_t linked_list2 + * IN struct array_rep_info_t linked_list3 + * IN struct array_rep_info_t linked_list4 + ****************************************************************/ +void sum_array_print ( seed, linked_list1, linked_list2, linked_list3,linked_list4) + int seed; + struct array_rep_info_t linked_list1; + struct array_rep_info_t linked_list2; + struct array_rep_info_t linked_list3; + struct array_rep_info_t linked_list4; + +{ + int index; + int sum; + + printf("Sum of 4 arrays, by element (add in seed as well): \n\n"); + printf("Seed: %d\n", seed); + printf("Element Index | Sum \n"); + printf("-------------------------\n"); + printf(" | \n"); + + for (index = 0; index < 10; index++) { + + sum = seed + linked_list1.values[index] + linked_list2.values[index] + + linked_list3.values[index] + linked_list4.values[index]; + printf("%10d%10d\n", index, sum); + } +} + +/***************************************************************** + * INIT_ARRAY_REP : + * IN struct array_rep_info_t *linked_list + * IN int seed + ****************************************************************/ +void init_array_rep( linked_list, seed ) + struct array_rep_info_t *linked_list; + int seed; + +{ + + int index; + + for (index = 0; index < 10; index++) { + + linked_list->values[index] = (2*index) + (seed*2); + linked_list->next_index[index] = index + 1; + } + linked_list->head = 0; +} + + +int main () { + + /* variables for array and enumerated type testing + */ + char char_array[120]; + double double_array[100]; + float float_array[15]; + int integer_array[50]; + int index; + id_int student_id = 23; + colors my_shirt = YELLOW; + + /* variables for large structure testing + */ + int number = 10; + struct array_rep_info_t *list1; + struct array_rep_info_t *list2; + struct array_rep_info_t *list3; + struct array_rep_info_t *list4; + + /* variables for testing a very long argument list + */ + double a; + double b; + int c; + int d; + int e; + int f; + + /* variables for testing a small structures and a very long argument list + */ + struct small_rep_info_t *struct1; + struct small_rep_info_t *struct2; + struct small_rep_info_t *struct3; + struct small_rep_info_t *struct4; + struct bit_flags_t *flags; + struct bit_flags_combo_t *flags_combo; + struct three_char_t *three_char; + struct five_char_t *five_char; + struct int_char_combo_t *int_char_combo; + struct one_double_t *d1; + struct one_double_t *d2; + struct one_double_t *d3; + struct two_floats_t *f1; + struct two_floats_t *f2; + struct two_floats_t *f3; + + /* Initialize arrays + */ + for (index = 0; index < 120; index++) { + if ((index%2) == 0) char_array[index] = 'Z'; + else char_array[index] = 'a'; + } + + for (index = 0; index < 100; index++) { + double_array[index] = index*23.4567; + } + + for (index = 0; index < 15; index++) { + float_array[index] = index/7.02; + } + + for (index = 0; index < 50; index++) { + integer_array[index] = -index; + } + + /* Print arrays + */ + print_char_array(char_array); + print_double_array(double_array); + print_float_array(float_array); + print_student_id_shirt_color(student_id, my_shirt); + print_int_array(integer_array); + print_all_arrays(integer_array, char_array, float_array, double_array); + + /* Allocate space for large structures + */ + list1 = (struct array_rep_info_t *)malloc(sizeof(struct array_rep_info_t)); + list2 = (struct array_rep_info_t *)malloc(sizeof(struct array_rep_info_t)); + list3 = (struct array_rep_info_t *)malloc(sizeof(struct array_rep_info_t)); + list4 = (struct array_rep_info_t *)malloc(sizeof(struct array_rep_info_t)); + + /* Initialize large structures + */ + init_array_rep(list1, 2); + init_array_rep(list2, 4); + init_array_rep(list3, 5); + init_array_rep(list4, 10); + printf("HELLO WORLD\n"); + printf("BYE BYE FOR NOW\n"); + printf("VERY GREEN GRASS\n"); + + /* Print large structures + */ + sum_array_print(10, *list1, *list2, *list3, *list4); + print_array_rep(*list1, *list2, *list3); + print_one_large_struct(*list1); + + /* Allocate space for small structures + */ + struct1 = (struct small_rep_info_t *)malloc(sizeof(struct small_rep_info_t)); + struct2 = (struct small_rep_info_t *)malloc(sizeof(struct small_rep_info_t)); + struct3 = (struct small_rep_info_t *)malloc(sizeof(struct small_rep_info_t)); + struct4 = (struct small_rep_info_t *)malloc(sizeof(struct small_rep_info_t)); + flags = (struct bit_flags_t *)malloc(sizeof(struct bit_flags_t)); + flags_combo = (struct bit_flags_combo_t *)malloc(sizeof(struct bit_flags_combo_t)); + three_char = (struct three_char_t *)malloc(sizeof(struct three_char_t)); + five_char = (struct five_char_t *)malloc(sizeof(struct five_char_t)); + int_char_combo = (struct int_char_combo_t *)malloc(sizeof(struct int_char_combo_t)); + + d1 = (struct one_double_t *)malloc(sizeof(struct one_double_t)); + d2 = (struct one_double_t *)malloc(sizeof(struct one_double_t)); + d3 = (struct one_double_t *)malloc(sizeof(struct one_double_t)); + + f1 = (struct two_floats_t *)malloc(sizeof(struct two_floats_t)); + f2 = (struct two_floats_t *)malloc(sizeof(struct two_floats_t)); + f3 = (struct two_floats_t *)malloc(sizeof(struct two_floats_t)); + + /* Initialize small structures + */ + init_small_structs ( struct1, struct2, struct3, struct4, flags, + flags_combo, three_char, five_char, int_char_combo, + d1, d2, d3, f1, f2, f3); + + /* Print small structures + */ + print_small_structs ( *struct1, *struct2, *struct3, *struct4, *flags, + *flags_combo, *three_char, *five_char, *int_char_combo, + *d1, *d2, *d3, *f1, *f2, *f3); + + /* Print a very long arg list + */ + a = 22.22; + b = 33.333; + c = 0; + d = -25; + e = 100; + f = 2345; + + print_long_arg_list ( a, b, c, d, e, f, *struct1, *struct2, *struct3, *struct4, + *flags, *flags_combo, *three_char, *five_char, *int_char_combo, + *d1, *d2, *d3, *f1, *f2, *f3); + + /* Initialize small structures + */ + init_one_double ( d1, 1.11111); + init_one_double ( d2, -345.34); + init_one_double ( d3, 546464.2); + init_two_floats ( f1, 0.234, 453.1); + init_two_floats ( f2, 78.345, 23.09); + init_two_floats ( f3, -2.345, 1.0); + init_bit_flags(flags, (unsigned)1, (unsigned)0, (unsigned)1, + (unsigned)0, (unsigned)1, (unsigned)0 ); + init_bit_flags_combo(flags_combo, (unsigned)1, (unsigned)0, 'y', + (unsigned)1, (unsigned)0, 'n', + (unsigned)1, (unsigned)0 ); + init_three_chars(three_char, 'x', 'y', 'z'); + init_five_chars(five_char, 'h', 'e', 'l', 'l', 'o'); + init_int_char_combo(int_char_combo, 13, '!'); + init_struct_rep(struct1, 10); + init_struct_rep(struct2, 20); + init_struct_rep(struct3, 30); + init_struct_rep(struct4, 40); + + compute_with_small_structs(35); + loop_count(); + printf("HELLO WORLD\n"); + printf("BYE BYE FOR NOW\n"); + printf("VERY GREEN GRASS\n"); + + /* Print small structures + */ + print_one_double(*d1); + print_one_double(*d2); + print_one_double(*d3); + print_two_floats(*f1); + print_two_floats(*f2); + print_two_floats(*f3); + print_bit_flags(*flags); + print_bit_flags_combo(*flags_combo); + print_three_chars(*three_char); + print_five_chars(*five_char); + print_int_char_combo(*int_char_combo); + sum_struct_print(10, *struct1, *struct2, *struct3, *struct4); + print_struct_rep(*struct1, *struct2, *struct3); + + return 0; +} + + + + + diff --git a/gdb/testsuite/gdb.base/call-return-struct.c b/gdb/testsuite/gdb.base/call-return-struct.c new file mode 100644 index 0000000000..c89cb11f51 --- /dev/null +++ b/gdb/testsuite/gdb.base/call-return-struct.c @@ -0,0 +1,530 @@ +#include +#include +#include + +/************************************************************************** + * TESTS : + * function returning large structures, which go on the stack + * functions returning varied sized structs which go on in the registers. + ***************************************************************************/ + + +/* A large structure (> 64 bits) used to test passing large structures as + * parameters + */ + +struct array_rep_info_t { + int next_index[10]; + int values[10]; + int head; +}; + +/***************************************************************************** + * Small structures ( <= 64 bits). These are used to test passing small + * structures as parameters and test argument size promotion. + *****************************************************************************/ + + /* 64 bits + */ +struct small_rep_info_t { + int value; + int head; +}; + +/* 6 bits : really fits in 8 bits and is promoted to 32 bits + */ +struct bit_flags_t { + unsigned alpha :1; + unsigned beta :1; + unsigned gamma :1; + unsigned delta :1; + unsigned epsilon :1; + unsigned omega :1; +}; + +/* 22 bits : really fits in 40 bits and is promoted to 64 bits + */ +struct bit_flags_combo_t { + unsigned alpha :1; + unsigned beta :1; + char ch1; + unsigned gamma :1; + unsigned delta :1; + char ch2; + unsigned epsilon :1; + unsigned omega :1; +}; + +/* 64 bits + */ +struct one_double_t { + double double1; +}; + +/* 64 bits + */ +struct two_floats_t { + float float1; + float float2; +}; + + +/* 24 bits : promoted to 32 bits + */ +struct three_char_t { + char ch1; + char ch2; + char ch3; +}; + +/* 40 bits : promoted to 64 bits + */ +struct five_char_t { + char ch1; + char ch2; + char ch3; + char ch4; + char ch5; +}; + +/* 40 bits : promoted to 64 bits + */ +struct int_char_combo_t { + int int1; + char ch1; +}; + + +/***************************************************************** + * LOOP_COUNT : + * A do nothing function. Used to provide a point at which calls can be made. + *****************************************************************/ +void loop_count () { + + int index; + + for (index=0; index<4; index++); +} + +/***************************************************************** + * INIT_BIT_FLAGS : + * Initializes a bit_flags_t structure. Can call this function see + * the call command behavior when integer arguments do not fit into + * registers and must be placed on the stack. + * OUT struct bit_flags_t *bit_flags -- structure to be filled + * IN unsigned a -- 0 or 1 + * IN unsigned b -- 0 or 1 + * IN unsigned g -- 0 or 1 + * IN unsigned d -- 0 or 1 + * IN unsigned e -- 0 or 1 + * IN unsigned o -- 0 or 1 + *****************************************************************/ +void init_bit_flags (bit_flags,a,b,g,d,e,o) +struct bit_flags_t *bit_flags; +unsigned a; +unsigned b; +unsigned g; +unsigned d; +unsigned e; +unsigned o; +{ + + bit_flags->alpha = a; + bit_flags->beta = b; + bit_flags->gamma = g; + bit_flags->delta = d; + bit_flags->epsilon = e; + bit_flags->omega = o; +} + +/***************************************************************** + * INIT_BIT_FLAGS_COMBO : + * Initializes a bit_flags_combo_t structure. Can call this function + * to see the call command behavior when integer and character arguments + * do not fit into registers and must be placed on the stack. + * OUT struct bit_flags_combo_t *bit_flags_combo -- structure to fill + * IN unsigned a -- 0 or 1 + * IN unsigned b -- 0 or 1 + * IN char ch1 + * IN unsigned g -- 0 or 1 + * IN unsigned d -- 0 or 1 + * IN char ch2 + * IN unsigned e -- 0 or 1 + * IN unsigned o -- 0 or 1 + *****************************************************************/ +void init_bit_flags_combo (bit_flags_combo, a, b, ch1, g, d, ch2, e, o) +struct bit_flags_combo_t *bit_flags_combo; +unsigned a; +unsigned b; +char ch1; +unsigned g; +unsigned d; +char ch2; +unsigned e; +unsigned o; +{ + + bit_flags_combo->alpha = a; + bit_flags_combo->beta = b; + bit_flags_combo->ch1 = ch1; + bit_flags_combo->gamma = g; + bit_flags_combo->delta = d; + bit_flags_combo->ch2 = ch2; + bit_flags_combo->epsilon = e; + bit_flags_combo->omega = o; +} + + +/***************************************************************** + * INIT_ONE_DOUBLE : + * OUT struct one_double_t *one_double -- structure to fill + * IN double init_val + *****************************************************************/ +void init_one_double (one_double, init_val) +struct one_double_t *one_double; +double init_val; +{ + + one_double->double1 = init_val; +} + +/***************************************************************** + * INIT_TWO_FLOATS : + * OUT struct two_floats_t *two_floats -- structure to be filled + * IN float init_val1 + * IN float init_val2 + *****************************************************************/ +void init_two_floats (two_floats, init_val1, init_val2) +struct two_floats_t *two_floats; +float init_val1; +float init_val2; +{ + + two_floats->float1 = init_val1; + two_floats->float2 = init_val2; +} + +/***************************************************************** + * INIT_THREE_CHARS : + * OUT struct three_char_t *three_char -- structure to be filled + * IN char init_val1 + * IN char init_val2 + * IN char init_val3 + *****************************************************************/ +void init_three_chars ( three_char, init_val1, init_val2, init_val3) +struct three_char_t *three_char; +char init_val1; +char init_val2; +char init_val3; +{ + + three_char->ch1 = init_val1; + three_char->ch2 = init_val2; + three_char->ch3 = init_val3; +} + +/***************************************************************** + * INIT_FIVE_CHARS : + * OUT struct five_char_t *five_char -- structure to be filled + * IN char init_val1 + * IN char init_val2 + * IN char init_val3 + * IN char init_val4 + * IN char init_val5 + *****************************************************************/ +void init_five_chars ( five_char, init_val1, init_val2, init_val3, init_val4, init_val5) +struct five_char_t *five_char; +char init_val1; +char init_val2; +char init_val3; +char init_val4; +char init_val5; +{ + + five_char->ch1 = init_val1; + five_char->ch2 = init_val2; + five_char->ch3 = init_val3; + five_char->ch4 = init_val4; + five_char->ch5 = init_val5; +} + +/***************************************************************** + * INIT_INT_CHAR_COMBO : + * OUT struct int_char_combo_t *combo -- structure to be filled + * IN int init_val1 + * IN char init_val2 + *****************************************************************/ +void init_int_char_combo ( combo, init_val1, init_val2) +struct int_char_combo_t *combo; +int init_val1; +char init_val2; +{ + + combo->int1 = init_val1; + combo->ch1 = init_val2; +} + +/***************************************************************** + * INIT_STRUCT_REP : + * OUT struct small_rep_into_t *small_struct -- structure to be filled + * IN int seed + *****************************************************************/ +void init_struct_rep( small_struct, seed) +struct small_rep_info_t *small_struct; +int seed; + +{ + + small_struct->value = 2 + (seed*2); + small_struct->head = 0; +} + +/***************************************************************** + * PRINT_BIT_FLAGS : + * IN struct bit_flags_t bit_flags + ****************************************************************/ +struct bit_flags_t print_bit_flags ( bit_flags) +struct bit_flags_t bit_flags; +{ + + if (bit_flags.alpha) printf("alpha\n"); + if (bit_flags.beta) printf("beta\n"); + if (bit_flags.gamma) printf("gamma\n"); + if (bit_flags.delta) printf("delta\n"); + if (bit_flags.epsilon) printf("epsilon\n"); + if (bit_flags.omega) printf("omega\n"); + return bit_flags; + +} + +/***************************************************************** + * PRINT_BIT_FLAGS_COMBO : + * IN struct bit_flags_combo_t bit_flags_combo + ****************************************************************/ +struct bit_flags_combo_t print_bit_flags_combo ( bit_flags_combo ) +struct bit_flags_combo_t bit_flags_combo; +{ + + if (bit_flags_combo.alpha) printf("alpha\n"); + if (bit_flags_combo.beta) printf("beta\n"); + if (bit_flags_combo.gamma) printf("gamma\n"); + if (bit_flags_combo.delta) printf("delta\n"); + if (bit_flags_combo.epsilon) printf("epsilon\n"); + if (bit_flags_combo.omega) printf("omega\n"); + printf("ch1: %c\tch2: %c\n", bit_flags_combo.ch1, bit_flags_combo.ch2); + return bit_flags_combo; + +} + +/***************************************************************** + * PRINT_ONE_DOUBLE : + * IN struct one_double_t one_double + ****************************************************************/ +struct one_double_t print_one_double ( one_double ) +struct one_double_t one_double; +{ + + printf("Contents of one_double_t: \n\n"); + printf("%f\n", one_double.double1); + return one_double; + +} + +/***************************************************************** + * PRINT_TWO_FLOATS : + * IN struct two_floats_t two_floats + ****************************************************************/ +struct two_floats_t print_two_floats ( two_floats ) +struct two_floats_t two_floats; +{ + + printf("Contents of two_floats_t: \n\n"); + printf("%f\t%f\n", two_floats.float1, two_floats.float2); + return two_floats; + +} + +/***************************************************************** + * PRINT_THREE_CHARS : + * IN struct three_char_t three_char + ****************************************************************/ +struct three_char_t print_three_chars ( three_char ) +struct three_char_t three_char; +{ + + printf("Contents of three_char_t: \n\n"); + printf("%c\t%c\t%c\n", three_char.ch1, three_char.ch2, three_char.ch3); + return three_char; + +} + +/***************************************************************** + * PRINT_FIVE_CHARS : + * IN struct five_char_t five_char + ****************************************************************/ +struct five_char_t print_five_chars ( five_char ) +struct five_char_t five_char; +{ + + printf("Contents of five_char_t: \n\n"); + printf("%c\t%c\t%c\t%c\t%c\n", five_char.ch1, five_char.ch2, + five_char.ch3, five_char.ch4, + five_char.ch5); + return five_char; + +} + +/***************************************************************** + * PRINT_INT_CHAR_COMBO : + * IN struct int_char_combo_t int_char_combo + ****************************************************************/ +struct int_char_combo_t print_int_char_combo ( int_char_combo ) +struct int_char_combo_t int_char_combo; +{ + + printf("Contents of int_char_combo_t: \n\n"); + printf("%d\t%c\n", int_char_combo.int1, int_char_combo.ch1); + return int_char_combo; + +} + +/***************************************************************** + * PRINT_STRUCT_REP : + ****************************************************************/ +struct small_rep_info_t print_struct_rep( struct1 ) +struct small_rep_info_t struct1; + +{ + + printf("Contents of struct1: \n\n"); + printf("%10d%10d\n", struct1.value, struct1.head); + struct1.value =+5; + + return struct1; + + +} + + +struct array_rep_info_t print_one_large_struct( linked_list1 ) +struct array_rep_info_t linked_list1; +{ + + + printf("%10d%10d\n", linked_list1.values[0], + linked_list1.next_index[0]); + + return linked_list1; + +} + +/***************************************************************** + * INIT_ARRAY_REP : + * IN struct array_rep_info_t *linked_list + * IN int seed + ****************************************************************/ +void init_array_rep( linked_list, seed ) +struct array_rep_info_t *linked_list; +int seed; + +{ + + int index; + + for (index = 0; index < 10; index++) { + + linked_list->values[index] = (2*index) + (seed*2); + linked_list->next_index[index] = index + 1; + } + linked_list->head = 0; +} + + +int main () { + + /* variables for large structure testing + */ + int number = 10; + struct array_rep_info_t *list1; + + /* variables for testing a small structures and a very long argument list + */ + struct small_rep_info_t *struct1; + struct bit_flags_t *flags; + struct bit_flags_combo_t *flags_combo; + struct three_char_t *three_char; + struct five_char_t *five_char; + struct int_char_combo_t *int_char_combo; + struct one_double_t *d1; + struct two_floats_t *f3; + + + /* Allocate space for large structures + */ + list1 = (struct array_rep_info_t *)malloc(sizeof(struct array_rep_info_t)); + + /* Initialize large structures + */ + init_array_rep(list1, 2); + + /* Print large structures + */ + print_one_large_struct(*list1); + + /* Allocate space for small structures + */ + struct1 = (struct small_rep_info_t *)malloc(sizeof(struct small_rep_info_t)); + flags = (struct bit_flags_t *)malloc(sizeof(struct bit_flags_t)); + flags_combo = (struct bit_flags_combo_t *)malloc(sizeof(struct bit_flags_combo_t)); + three_char = (struct three_char_t *)malloc(sizeof(struct three_char_t)); + five_char = (struct five_char_t *)malloc(sizeof(struct five_char_t)); + int_char_combo = (struct int_char_combo_t *)malloc(sizeof(struct int_char_combo_t)); + + d1 = (struct one_double_t *)malloc(sizeof(struct one_double_t)); + f3 = (struct two_floats_t *)malloc(sizeof(struct two_floats_t)); + + /* Initialize small structures + */ + init_one_double ( d1, 1.11111); + init_two_floats ( f3, -2.345, 1.0); + init_bit_flags(flags, (unsigned)1, (unsigned)0, (unsigned)1, + (unsigned)0, (unsigned)1, (unsigned)0 ); + init_bit_flags_combo(flags_combo, (unsigned)1, (unsigned)0, 'y', + (unsigned)1, (unsigned)0, 'n', + (unsigned)1, (unsigned)0 ); + init_three_chars(three_char, 'x', 'y', 'z'); + init_five_chars(five_char, 'h', 'e', 'l', 'l', 'o'); + init_int_char_combo(int_char_combo, 13, '!'); + init_struct_rep(struct1, 10); + + + /* Print small structures + */ + print_one_double(*d1); + print_two_floats(*f3); + print_bit_flags(*flags); + print_bit_flags_combo(*flags_combo); + print_three_chars(*three_char); + print_five_chars(*five_char); + print_int_char_combo(*int_char_combo); + print_struct_rep(*struct1); + + loop_count(); + + return 0; +} + + + + + + + + + + + + + + + diff --git a/gdb/testsuite/gdb.base/call-strings.c b/gdb/testsuite/gdb.base/call-strings.c new file mode 100644 index 0000000000..9ba875b5d3 --- /dev/null +++ b/gdb/testsuite/gdb.base/call-strings.c @@ -0,0 +1,54 @@ +#include +char buf[100]; +char bigbuf[1000]; +char * s; + +char * str_func1(s1) +char *s1; +{ + printf("first string arg is: %s\n", s1); + strcpy(bigbuf, s1); + return bigbuf; +} + +char * str_func(s1, + s2, + s3, + s4, + s5, + s6, + s7) +char * s1; +char * s2; +char * s3; +char * s4; +char * s5; +char * s6; +char * s7; +{ + printf("first string arg is: %s\n", s1); + printf("second string arg is: %s\n", s2); + printf("third string arg is: %s\n", s3); + printf("fourth string arg is: %s\n", s4); + printf("fifth string arg is: %s\n", s5); + printf("sixth string arg is: %s\n", s6); + printf("seventh string arg is: %s\n", s7); + strcpy(bigbuf, s1); + strcat(bigbuf, s2); + strcat(bigbuf, s3); + strcat(bigbuf, s4); + strcat(bigbuf, s5); + strcat(bigbuf, s6); + strcat(bigbuf, s7); + return bigbuf; +} + + +main() +{ + s = &buf[0]; + strcpy(buf, "test string"); + str_func("abcd", "efgh", "ijkl", "mnop", "qrst", "uvwx", "yz12"); + str_func1("abcd"); +} + diff --git a/gdb/testsuite/gdb.base/callfuncs2.c b/gdb/testsuite/gdb.base/callfuncs2.c new file mode 100644 index 0000000000..ac14d457ae --- /dev/null +++ b/gdb/testsuite/gdb.base/callfuncs2.c @@ -0,0 +1,267 @@ +/* Support program for testing gdb's ability to call functions + in an inferior which doesn't itself call malloc, pass appropriate + arguments to those functions, and get the returned result. */ + +#ifdef NO_PROTOTYPES +#define PARAMS(paramlist) () +#else +#define PARAMS(paramlist) paramlist +#endif + +char char_val1 = 'a'; +char char_val2 = 'b'; + +short short_val1 = 10; +short short_val2 = -23; + +int int_val1 = 87; +int int_val2 = -26; + +long long_val1 = 789; +long long_val2 = -321; + +float float_val1 = 3.14159; +float float_val2 = -2.3765; + +double double_val1 = 45.654; +double double_val2 = -67.66; + +#define DELTA (0.001) + +char *string_val1 = "string 1"; +char *string_val2 = "string 2"; + +char char_array_val1[] = "carray 1"; +char char_array_val2[] = "carray 2"; + +struct struct1 { + char c; + short s; + int i; + long l; + float f; + double d; + char a[4]; +} struct_val1 = { 'x', 87, 76, 51, 2.1234, 9.876, "foo" }; + +/* Some functions that can be passed as arguments to other test + functions, or called directly. */ + +int add (a, b) +int a, b; +{ + return (a + b); +} + +int doubleit (a) +int a; +{ + return (a + a); +} + +int (*func_val1) PARAMS((int,int)) = add; +int (*func_val2) PARAMS((int)) = doubleit; + +/* An enumeration and functions that test for specific values. */ + +enum enumtype { enumval1, enumval2, enumval3 }; +enum enumtype enum_val1 = enumval1; +enum enumtype enum_val2 = enumval2; +enum enumtype enum_val3 = enumval3; + +t_enum_value1 (enum_arg) +enum enumtype enum_arg; +{ + return (enum_arg == enum_val1); +} + +t_enum_value2 (enum_arg) +enum enumtype enum_arg; +{ + return (enum_arg == enum_val2); +} + +t_enum_value3 (enum_arg) +enum enumtype enum_arg; +{ + return (enum_arg == enum_val3); +} + +/* A function that takes a vector of integers (along with an explicit + count) and returns their sum. */ + +int sum_args (argc, argv) +int argc; +int argv[]; +{ + int sumval = 0; + int idx; + + for (idx = 0; idx < argc; idx++) + { + sumval += argv[idx]; + } + return (sumval); +} + +/* Test that we can call functions that take structs and return + members from that struct */ + +char t_structs_c (tstruct) struct struct1 tstruct; { return (tstruct.c); } +short t_structs_s (tstruct) struct struct1 tstruct; { return (tstruct.s); } +int t_structs_i (tstruct) struct struct1 tstruct; { return (tstruct.i); } +long t_structs_l (tstruct) struct struct1 tstruct; { return (tstruct.l); } +float t_structs_f (tstruct) struct struct1 tstruct; { return (tstruct.f); } +double t_structs_d (tstruct) struct struct1 tstruct; { return (tstruct.d); } +char *t_structs_a (tstruct) struct struct1 tstruct; { return (tstruct.a); } + +/* Test that calling functions works if there are a lot of arguments. */ +int +sum10 (i0, i1, i2, i3, i4, i5, i6, i7, i8, i9) + int i0, i1, i2, i3, i4, i5, i6, i7, i8, i9; +{ + return i0 + i1 + i2 + i3 + i4 + i5 + i6 + i7 + i8 + i9; +} + +/* Gotta have a main to be able to generate a linked, runnable + executable, and also provide a useful place to set a breakpoint. */ + +main () +{ +#ifdef usestubs + set_debug_traps(); + breakpoint(); +#endif + t_structs_c(struct_val1); +} + +/* Functions that expect specific values to be passed and return + either 0 or 1, depending upon whether the values were + passed incorrectly or correctly, respectively. */ + +int t_char_values (char_arg1, char_arg2) +char char_arg1, char_arg2; +{ + return ((char_arg1 == char_val1) && (char_arg2 == char_val2)); +} + +int +#ifdef NO_PROTOTYPES +t_small_values (arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10) + char arg1; + short arg2; + int arg3; + char arg4; + short arg5; + char arg6; + short arg7; + int arg8; + short arg9; + short arg10; +#else +t_small_values (char arg1, short arg2, int arg3, char arg4, short arg5, + char arg6, short arg7, int arg8, short arg9, short arg10) +#endif +{ + return arg1 + arg2 + arg3 + arg4 + arg5 + arg6 + arg7 + arg8 + arg9 + arg10; +} + +int t_short_values (short_arg1, short_arg2) +short short_arg1, short_arg2; +{ + return ((short_arg1 == short_val1) && (short_arg2 == short_val2)); +} + +int t_int_values (int_arg1, int_arg2) +int int_arg1, int_arg2; +{ + return ((int_arg1 == int_val1) && (int_arg2 == int_val2)); +} + +int t_long_values (long_arg1, long_arg2) +long long_arg1, long_arg2; +{ + return ((long_arg1 == long_val1) && (long_arg2 == long_val2)); +} + +int t_float_values (float_arg1, float_arg2) +float float_arg1, float_arg2; +{ + return ((float_arg1 - float_val1) < DELTA + && (float_arg1 - float_val1) > -DELTA + && (float_arg2 - float_val2) < DELTA + && (float_arg2 - float_val2) > -DELTA); +} + +int +#ifdef NO_PROTOTYPES +/* In this case we are just duplicating t_float_values, but that is the + easiest way to deal with either ANSI or non-ANSI. */ +t_float_values2 (float_arg1, float_arg2) + float float_arg1, float_arg2; +#else +t_float_values2 (float float_arg1, float float_arg2) +#endif +{ + return ((float_arg1 - float_val1) < DELTA + && (float_arg1 - float_val1) > -DELTA + && (float_arg2 - float_val2) < DELTA + && (float_arg2 - float_val2) > -DELTA); +} + +int t_double_values (double_arg1, double_arg2) +double double_arg1, double_arg2; +{ + return ((double_arg1 - double_val1) < DELTA + && (double_arg1 - double_val1) > -DELTA + && (double_arg2 - double_val2) < DELTA + && (double_arg2 - double_val2) > -DELTA); +} + +int t_string_values (string_arg1, string_arg2) +char *string_arg1, *string_arg2; +{ + return (!strcmp (string_arg1, string_val1) && + !strcmp (string_arg2, string_val2)); +} + +int t_char_array_values (char_array_arg1, char_array_arg2) +char char_array_arg1[], char_array_arg2[]; +{ + return (!strcmp (char_array_arg1, char_array_val1) && + !strcmp (char_array_arg2, char_array_val2)); +} + + +/* This used to simply compare the function pointer arguments with + known values for func_val1 and func_val2. Doing so is valid ANSI + code, but on some machines (RS6000, HPPA, others?) it may fail when + called directly by GDB. + + In a nutshell, it's not possible for GDB to determine when the address + of a function or the address of the function's stub/trampoline should + be passed. + + So, to avoid GDB lossage in the common case, we perform calls through the + various function pointers and compare the return values. For the HPPA + at least, this allows the common case to work. + + If one wants to try something more complicated, pass the address of + a function accepting a "double" as one of its first 4 arguments. Call + that function indirectly through the function pointer. This would fail + on the HPPA. */ + +int t_func_values (func_arg1, func_arg2) +int (*func_arg1) PARAMS ((int, int)); +int (*func_arg2) PARAMS ((int)); +{ + return ((*func_arg1) (5,5) == (*func_val1) (5,5) + && (*func_arg2) (6) == (*func_val2) (6)); +} + +int t_call_add (func_arg1, a, b) +int (*func_arg1) PARAMS ((int, int)); +int a, b; +{ + return ((*func_arg1)(a, b)); +} diff --git a/gdb/testsuite/gdb.base/condbreak.c b/gdb/testsuite/gdb.base/condbreak.c new file mode 100644 index 0000000000..491d6e5dd5 --- /dev/null +++ b/gdb/testsuite/gdb.base/condbreak.c @@ -0,0 +1,81 @@ +#ifdef vxworks + +# include + +/* VxWorks does not supply atoi. */ +static int +atoi (z) + char *z; +{ + int i = 0; + + while (*z >= '0' && *z <= '9') + i = i * 10 + (*z++ - '0'); + return i; +} + +/* I don't know of any way to pass an array to VxWorks. This function + can be called directly from gdb. */ + +vxmain (arg) +char *arg; +{ + char *argv[2]; + + argv[0] = ""; + argv[1] = arg; + main (2, argv, (char **) 0); +} + +#else /* ! vxworks */ +# include +#endif /* ! vxworks */ + +/* + * The following functions do nothing useful. They are included simply + * as places to try setting breakpoints at. They are explicitly + * "one-line functions" to verify that this case works (some versions + * of gcc have or have had problems with this). + */ + +int marker1 () { return (0); } +int marker2 (a) int a; { return (1); } +void marker3 (a, b) char *a, *b; {} +void marker4 (d) long d; {} + +/* + * This simple classical example of recursion is useful for + * testing stack backtraces and such. + */ + +int +main (argc, argv, envp) +int argc; +char *argv[], **envp; +{ +#ifdef usestubs + set_debug_traps(); + breakpoint(); +#endif + if (argc == 123456) { + fprintf (stderr, "usage: factorial \n"); + return 1; + } + printf ("%d\n", factorial (atoi ("6"))); + + marker1 (); + marker2 (43); + marker3 ("stack", "trace"); + marker4 (177601976L); + return 0; +} + +int factorial (value) +int value; +{ + if (value > 1) { + value *= factorial (value - 1); + } + return (value); +} + diff --git a/gdb/testsuite/gdb.base/constvars.c b/gdb/testsuite/gdb.base/constvars.c new file mode 100644 index 0000000000..4fe9dadef2 --- /dev/null +++ b/gdb/testsuite/gdb.base/constvars.c @@ -0,0 +1,178 @@ +void marker1 (void) +{ + +} + +// misc. function params + +int qux1 (const char cc, const char & ccr, const char * ccp, char * const cpc) +{ + return 33; +} + +int qux2 (volatile unsigned char vuc, const volatile int cvi, + volatile short & vsr, volatile long * vlp, float * volatile fpv, + const volatile signed char * const volatile cvscpcv) +{ + return 400; +} + + +int main(void) +{ + char lave = 'B'; + unsigned char lavish = 10; + short lax = 20; + unsigned short lecherous = 30; + long lechery = 40; + unsigned long lectern = 50; + float leeway = 60; + double legacy = 70; + signed char lemonade = 35; + + const char laconic = 'A'; + const unsigned char laggard = 1; + const short lagoon = 2; + const unsigned short laity = 3; + const long lambent = 4; + const unsigned long laminated = 5; + const float lampoon = 6; + const double languid = 7; + + // pointers to constant variables + const char *legend = &lave; + const unsigned char *legerdemain = &lavish; + const short *leniency = &lax; + const unsigned short *leonine = &lecherous; + const long *lesion = &lechery; + const unsigned long *lethal = &lectern; + const float *lethargic = &leeway; + const double *levity = &legacy; + + // constant pointers to constant variables + const char *const lewd = &laconic; + const unsigned char *const lexicographer = &laggard; + const short *const lexicon = &lagoon; + const unsigned short *const liaison = &laity; + const long *const libation = &lambent; + const unsigned long *const libelous = &laminated; + const float *const libertine = &lampoon; + const double *const libidinous = &languid; + + // this is the same as const char * legend .... + char const *languish = &laconic; + unsigned char const *languor = &laggard; + short const *lank = &lagoon; + unsigned short const *lapidary = &laity; + long const *larceny = &lambent; + unsigned long const *largess = &laminated; + float const *lascivious = &lampoon; + double const *lassitude = &languid; + + // constant pointers to variable + char *const lamprey = &lave; + unsigned char *const lariat = &lavish; + short *const laudanum = &lax; + unsigned short *const lecithin = &lecherous; + long *const leviathan = &lechery; + unsigned long *const libretto = &lectern; + float *const lissome = &leeway; + double *const locust = &legacy; + + // volatile variables + + volatile char vox = 'X'; + volatile unsigned char victuals = 13; + volatile short vixen = 200; + volatile unsigned short vitriol = 300; + volatile long vellum = 1000; + volatile unsigned long valve = 2000; + volatile float vacuity = 3.0; + volatile double vertigo = 10.3; + + // pointers to volatile variables + + volatile char * vampire = &vox; + volatile unsigned char * viper = &victuals; + volatile short * vigour = &vixen; + volatile unsigned short * vapour = &vitriol; + volatile long * ventricle = &vellum; + volatile unsigned long * vigintillion = &valve; + volatile float * vocation = &vacuity; + volatile double * veracity = &vertigo; + + // volatile pointers to volatile variables + + volatile char * volatile vapidity = &vox; + volatile unsigned char * volatile velocity = &victuals; + volatile short * volatile veneer = &vixen; + volatile unsigned short * volatile video = &vitriol; + volatile long * volatile vacuum = &vellum; + volatile unsigned long * volatile veniality = &valve; + volatile float * volatile vitality = &vacuity; + volatile double * volatile voracity = &vertigo; + + // const volatile vars + + const volatile char victor = 'Y'; + const volatile unsigned char vicar = 11; + + // pointers to const volatiles + + const volatile char * victory = &victor; + const volatile unsigned char * vicarage = &vicar; + + // const pointers to volatile vars + + volatile char * const vein = &vox; + volatile unsigned char * const vogue = &victuals; + + // const pointers to const volatile vars + + const volatile char * const cavern = &victor; + const volatile unsigned char * const coverlet = &vicar; + + // volatile pointers to const vars + + const char * volatile caveat = &laconic; + const unsigned char * volatile covenant = &laggard; + + // volatile pointers to const volatile vars + + const volatile char * volatile vizier = &victor; + const volatile unsigned char * volatile vanadium = &vicar; + + // const volatile pointers + + char * const volatile vane = &lave; + unsigned char * const volatile veldt = &lavish; + + // const volatile pointers to const vars + + const char * const volatile cove = &laconic; + const unsigned char * const volatile cavity = &laggard; + + // const volatile pointers to volatile vars + + volatile char * const volatile vagus = &vox; + volatile unsigned char * const volatile vagrancy = &victuals; + + // const volatile pointers to const volatile + + const volatile char * const volatile vagary = &victor; + const volatile unsigned char * const volatile vendor = &vicar; + + // misc. references + + const char & radiation = laconic; + volatile signed char & remuneration = lemonade; + + #ifdef usestubs + set_debug_traps(); + breakpoint(); + #endif + marker1(); + + + return 0; +} diff --git a/gdb/testsuite/gdb.base/pointers2.c b/gdb/testsuite/gdb.base/pointers2.c new file mode 100644 index 0000000000..6c30621a4e --- /dev/null +++ b/gdb/testsuite/gdb.base/pointers2.c @@ -0,0 +1,51 @@ +void marker1 () +{ + +} + + +int main() +{ + char C, *pC, **ppC, ***pppC, ****ppppC, *****pppppC, ******ppppppC; + unsigned char UC, *pUC; + short S, *pS; + unsigned short US, *pUS; + int I, *pI; + unsigned int UI, *pUI; + long L, *pL; + unsigned long UL, *pUL; + float F, *pF; + double D, *pD; + C = 'A'; + UC = 21; + S = -14; + US = 7; + I = 102; + UI = 1002; + L = -234; + UL = 234; + F = 1.25E10; + D = -1.375E-123; + pC = &C; + ppC = &pC; + pppC = &ppC; + ppppC = &pppC; + pppppC = &ppppC; + ppppppC = &pppppC; + pUC = &UC; + pS = &S; + pUS = &US; + pI = &I; + pUI = &UI; + pL = &L; + pUL = &UL; + pF = &F; + pD = &D; + + #ifdef usestubs + set_debug_traps(); + breakpoint(); + #endif + marker1(); + return 0; +} diff --git a/gdb/testsuite/gdb.base/shmain.c b/gdb/testsuite/gdb.base/shmain.c new file mode 100644 index 0000000000..954c3db6d0 --- /dev/null +++ b/gdb/testsuite/gdb.base/shmain.c @@ -0,0 +1,47 @@ +/* A test */ + +#include "ss.h" +#include + +extern int shr1(); +extern int shr2(); +extern float sg; + +int eglob; + +struct { + int a; + int b; +} s; + +int g; + +int local_structarg(x) +struct s x; +{ + return x.b; +} + +main() +{ + struct s y; + g = 1; + g = shr1(g); + g = shr2(g); + g = mainshr1(g); + sg = 1.1; + printf("address of sg is 0x%x\n", &sg); + y.a = 3; + y.b = 4; + g = local_structarg(y); + g = structarg(y); + g = pstructarg(&y); +} + +int mainshr1(g) +int g; +{ + return 2*g; +} + + diff --git a/gdb/testsuite/gdb.hp/attach.c b/gdb/testsuite/gdb.hp/attach.c new file mode 100644 index 0000000000..1aad3c1cc0 --- /dev/null +++ b/gdb/testsuite/gdb.hp/attach.c @@ -0,0 +1,19 @@ +/* This program is intended to be started outside of gdb, and then + attached to by gdb. Thus, it simply spins in a loop. The loop + is exited when & if the variable 'should_exit' is non-zero. (It + is initialized to zero in this program, so the loop will never + exit unless/until gdb sets the variable to non-zero.) + */ +#include + +int should_exit = 0; + +main () +{ + int local_i = 0; + + while (! should_exit) + { + local_i++; + } +} diff --git a/gdb/testsuite/gdb.hp/attach2.c b/gdb/testsuite/gdb.hp/attach2.c new file mode 100644 index 0000000000..8eb7a05674 --- /dev/null +++ b/gdb/testsuite/gdb.hp/attach2.c @@ -0,0 +1,23 @@ +/* This program is intended to be started outside of gdb, and then + attached to by gdb. Thus, it simply spins in a loop. The loop + is exited when & if the variable 'should_exit' is non-zero. (It + is initialized to zero in this program, so the loop will never + exit unless/until gdb sets the variable to non-zero.) + */ +#include +#include + +int should_exit = 0; + +main () +{ + int local_i = 0; + + sleep( 10 ); /* System call causes register fetch to fail */ + /* This is a known HPUX "feature" */ + while (! should_exit) + { + local_i++; + } + return (0); +} diff --git a/gdb/testsuite/gdb.hp/average.c b/gdb/testsuite/gdb.hp/average.c new file mode 100644 index 0000000000..070eaefa27 --- /dev/null +++ b/gdb/testsuite/gdb.hp/average.c @@ -0,0 +1,39 @@ +/* This is a sample program for the HP WDB debugger. */ + +#include + +#define num 10 + +static int my_list[num] = {3,4,2,0,2,1,8,3,6,7}; + +#ifdef __STDC__ +void print_average(int list[], int low, int high) +#else +void print_average(list, low, high) +int list[], low, high; +#endif + { + int total, num_elements, average; + total = sum(list, low, high); + num_elements = high - low; /* note this is an off-by-one bug */ + + average = total / num_elements; + printf("%10.d\n", average); + } + +#ifdef __STDC__ +int main(void) +#else +main () +#endif +{ + char c; + int first = 0; + int last = num-1; + + /* Try two test cases. */ + print_average (my_list, first, last); + print_average (my_list, first, last - 3); +foo: + exit(0); +} diff --git a/gdb/testsuite/gdb.hp/compiler.c b/gdb/testsuite/gdb.hp/compiler.c new file mode 100644 index 0000000000..8eb0d47dd1 --- /dev/null +++ b/gdb/testsuite/gdb.hp/compiler.c @@ -0,0 +1,31 @@ +/* Often the behavior of any particular test depends upon what compiler was + used to compile the test. As each test is compiled, this file is + preprocessed by the same compiler used to compile that specific test + (different tests might be compiled by different compilers, particularly + if compiled at different times), and used to generate a *.ci (compiler + info) file for that test. + + I.E., when callfuncs is compiled, a callfuncs.ci file will be generated, + which can then be sourced by callfuncs.exp to give callfuncs.exp access + to information about the compilation environment. + + TODO: It might be a good idea to add expect code that tests each + definition made with 'set" to see if one already exists, and if so + warn about conflicts if it is being set to something else. */ + +/* This needs to be kept in sync with whatis.c and gdb.exp(get_compiler_info). + If this ends up being hairy, we could use a common header file. */ + +#if defined (__STDC__) || defined (_AIX) +set signed_keyword_not_used 0 +#else +set signed_keyword_not_used 1 +#endif + +#if defined (__GNUC__) +set gcc_compiled __GNUC__ +#else +set gcc_compiled 0 +#endif + +return 0 diff --git a/gdb/testsuite/gdb.hp/compiler.cc b/gdb/testsuite/gdb.hp/compiler.cc new file mode 100644 index 0000000000..aa35c7510f --- /dev/null +++ b/gdb/testsuite/gdb.hp/compiler.cc @@ -0,0 +1,34 @@ +/* Often the behavior of any particular test depends upon what compiler was + used to compile the test. As each test is compiled, this file is + preprocessed by the same compiler used to compile that specific test + (different tests might be compiled by different compilers, particularly + if compiled at different times), and used to generate a *.ci (compiler + info) file for that test. + + I.E., when callfuncs is compiled, a callfuncs.ci file will be generated, + which can then be sourced by callfuncs.exp to give callfuncs.exp access + to information about the compilation environment. + + TODO: It might be a good idea to add expect code that tests each + definition made with 'set" to see if one already exists, and if so + warn about conflicts if it is being set to something else. */ + +#if defined(__GNUC__) && __GNUC__ >= 2 && __GNUC_MINOR__ >= 6 +set supports_template_debugging 1 +#else +set supports_template_debugging 0 +#endif + +#if defined(__cplusplus) +set supports_template_debugging 1 +#else +set supports_template_debugging 0 +#endif + +#if defined (__GNUC__) +set gcc_compiled __GNUC__ +#else +set gcc_compiled 0 +#endif + +return 0 diff --git a/gdb/testsuite/gdb.hp/execd-program.c b/gdb/testsuite/gdb.hp/execd-program.c new file mode 100644 index 0000000000..0320991062 --- /dev/null +++ b/gdb/testsuite/gdb.hp/execd-program.c @@ -0,0 +1,28 @@ +#include + +/* There is a global_i in follow_exec, which exec's us. We + should not be able to see that other definition of global_i + after we are exec'd. + */ +int global_i = 0; + +main (argc, argv) + int argc; + char * argv[]; +{ + /* There is a local_j in follow_exec, which exec's us. We + should not be able to see that other definition of local_j + after we are exec'd. + */ + int local_j = argc; + char * s; + + printf ("Hello from execd_program...\n"); + if (argc != 2) + { + printf ("expected one string argument\n"); + exit (-1); + } + s = argv[1]; + printf ("argument received: %s\n", s); +} diff --git a/gdb/testsuite/gdb.hp/follow-exec.c b/gdb/testsuite/gdb.hp/follow-exec.c new file mode 100644 index 0000000000..c51fa52dcf --- /dev/null +++ b/gdb/testsuite/gdb.hp/follow-exec.c @@ -0,0 +1,35 @@ +#include + +int global_i = 100; + +main () +{ + int local_j = global_i+1; + int local_k = local_j+1; + + printf ("follow-exec is about to execlp(execd-program)...\n"); + + execlp ("gdb.hp/execd-program", + "gdb.hp/execd-program", + "execlp arg1 from follow-exec", + (char *)0); + + printf ("follow-exec is about to execl(execd-program)...\n"); + + execl ("gdb.hp/execd-program", + "gdb.hp/execd-program", + "execl arg1 from follow-exec", + "execl arg2 from follow-exec", + (char *)0); + + { + static char * argv[] = { + "gdb.hp/execd-program", + "execv arg1 from follow-exec", + 0}; + + printf ("follow-exec is about to execv(execd-program)...\n"); + + execv ("gdb.hp/execd-program", argv); + } +} diff --git a/gdb/testsuite/gdb.hp/follow-fork.c b/gdb/testsuite/gdb.hp/follow-fork.c new file mode 100644 index 0000000000..89f92ae22f --- /dev/null +++ b/gdb/testsuite/gdb.hp/follow-fork.c @@ -0,0 +1,25 @@ +#include + +void callee (i) + int i; +{ + printf("callee: %d\n", i); +} + +main () +{ + int pid; + int v = 5; + + pid = fork (); + if (pid == 0) + { + v++; + /* printf ("I'm the child!\n"); */ + } + else + { + v--; + /* printf ("I'm the proud parent of child #%d!\n", pid); */ + } +} diff --git a/gdb/testsuite/gdb.hp/follow-vfork-and-exec.c b/gdb/testsuite/gdb.hp/follow-vfork-and-exec.c new file mode 100644 index 0000000000..c7e6cd3290 --- /dev/null +++ b/gdb/testsuite/gdb.hp/follow-vfork-and-exec.c @@ -0,0 +1,15 @@ +#include + +main () +{ + int pid; + + pid = vfork (); + if (pid == 0) { + printf ("I'm the child!\n"); + execlp ("gdb.hp/vforked-program", "gdb.hp/vforked-program", (char *)0); + } + else { + printf ("I'm the proud parent of child #%d!\n", pid); + } +} diff --git a/gdb/testsuite/gdb.hp/misc-hp.cc b/gdb/testsuite/gdb.hp/misc-hp.cc new file mode 100644 index 0000000000..af46830601 --- /dev/null +++ b/gdb/testsuite/gdb.hp/misc-hp.cc @@ -0,0 +1,514 @@ +// Test various -*- C++ -*- things. + +typedef struct fleep fleep; +struct fleep { int a; } s; + +// ====================== simple class structures ======================= + +struct default_public_struct { + // defaults to public: + int a; + int b; +}; + +struct explicit_public_struct { + public: + int a; + int b; +}; + +struct protected_struct { + protected: + int a; + int b; +}; + +struct private_struct { + private: + int a; + int b; +}; + +struct mixed_protection_struct { + public: + int a; + int b; + private: + int c; + int d; + protected: + int e; + int f; + public: + int g; + private: + int h; + protected: + int i; +}; + +class public_class { + public: + int a; + int b; +}; + +class protected_class { + protected: + int a; + int b; +}; + +class default_private_class { + // defaults to private: + int a; + int b; +}; + +class explicit_private_class { + private: + int a; + int b; +}; + +class mixed_protection_class { + public: + int a; + int b; + private: + int c; + int d; + protected: + int e; + int f; + public: + int g; + private: + int h; + protected: + int i; +}; + +class const_vol_method_class { +public: + int a; + int b; + int foo (int &) const; + int bar (int &) volatile; + int baz (int &) const volatile; +}; + +int const_vol_method_class::foo (int & ir) const +{ + return ir + 3; +} +int const_vol_method_class::bar (int & ir) volatile +{ + return ir + 4; +} +int const_vol_method_class::baz (int & ir) const volatile +{ + return ir + 5; +} + +// ========================= simple inheritance ========================== + +class A { + public: + int a; + int x; +}; + +A g_A; + +class B : public A { + public: + int b; + int x; +}; + +B g_B; + +class C : public A { + public: + int c; + int x; +}; + +C g_C; + +class D : public B, public C { + public: + int d; + int x; +}; + +D g_D; + +class E : public D { + public: + int e; + int x; +}; + +E g_E; + +class class_with_anon_union +{ + public: + int one; + union + { + int a; + long b; + }; +}; + +class_with_anon_union g_anon_union; + +void inheritance2 (void) +{ +} + +void inheritance1 (void) +{ + int ival; + int *intp; + + // {A::a, A::x} + + g_A.A::a = 1; + g_A.A::x = 2; + + // {{A::a,A::x},B::b,B::x} + + g_B.A::a = 3; + g_B.A::x = 4; + g_B.B::b = 5; + g_B.B::x = 6; + + // {{A::a,A::x},C::c,C::x} + + g_C.A::a = 7; + g_C.A::x = 8; + g_C.C::c = 9; + g_C.C::x = 10; + + // {{{A::a,A::x},B::b,B::x},{{A::a,A::x},C::c,C::x},D::d,D::x} + + // The following initialization code is non-portable, but allows us + // to initialize all members of g_D until we can fill in the missing + // initialization code with legal C++ code. + + for (intp = (int *) &g_D, ival = 11; + intp < ((int *) &g_D + sizeof (g_D) / sizeof (int)); + intp++, ival++) + { + *intp = ival; + } + + // Overlay the nonportable initialization with legal initialization. + + // ????? = 11; (g_D.A::a = 11; is ambiguous) + // ????? = 12; (g_D.A::x = 12; is ambiguous) + g_D.B::b = 13; + g_D.B::x = 14; + // ????? = 15; + // ????? = 16; + g_D.C::c = 17; + g_D.C::x = 18; + g_D.D::d = 19; + g_D.D::x = 20; + + + // {{{{A::a,A::x},B::b,B::x},{{A::a,A::x},C::c,C::x},D::d,D::x}},E::e,E::x} + + // The following initialization code is non-portable, but allows us + // to initialize all members of g_D until we can fill in the missing + // initialization code with legal C++ code. + + for (intp = (int *) &g_E, ival = 21; + intp < ((int *) &g_E + sizeof (g_E) / sizeof (int)); + intp++, ival++) + { + *intp = ival; + } + + // Overlay the nonportable initialization with legal initialization. + + // ????? = 21; (g_E.A::a = 21; is ambiguous) + // ????? = 22; (g_E.A::x = 22; is ambiguous) + g_E.B::b = 23; + g_E.B::x = 24; + // ????? = 25; + // ????? = 26; + g_E.C::c = 27; + g_E.C::x = 28; + g_E.D::d = 29; + g_E.D::x = 30; + g_E.E::e = 31; + g_E.E::x = 32; + + g_anon_union.one = 1; + g_anon_union.a = 2; + + inheritance2 (); +} + +// ======================== virtual base classes========================= + +class vA { + public: + int va; + int vx; +}; + +vA g_vA; + +class vB : public virtual vA { + public: + int vb; + int vx; +}; + +vB g_vB; + +class vC : public virtual vA { + public: + int vc; + int vx; +}; + +vC g_vC; + +class vD : public virtual vB, public virtual vC { + public: + int vd; + int vx; +}; + +vD g_vD; + +class vE : public virtual vD { + public: + int ve; + int vx; +}; + +vE g_vE; + +void inheritance4 (void) +{ +} + +void inheritance3 (void) +{ + int ival; + int *intp; + + // {vA::va, vA::vx} + + g_vA.vA::va = 1; + g_vA.vA::vx = 2; + + // {{vA::va, vA::vx}, vB::vb, vB::vx} + + g_vB.vA::va = 3; + g_vB.vA::vx = 4; + g_vB.vB::vb = 5; + g_vB.vB::vx = 6; + + // {{vA::va, vA::vx}, vC::vc, vC::vx} + + g_vC.vA::va = 7; + g_vC.vA::vx = 8; + g_vC.vC::vc = 9; + g_vC.vC::vx = 10; + + // {{{{vA::va, vA::vx}, vB::vb, vB::vx}, vC::vc, vC::vx}, vD::vd,vD::vx} + + g_vD.vA::va = 11; + g_vD.vA::vx = 12; + g_vD.vB::vb = 13; + g_vD.vB::vx = 14; + g_vD.vC::vc = 15; + g_vD.vC::vx = 16; + g_vD.vD::vd = 17; + g_vD.vD::vx = 18; + + + // {{{{{vA::va,vA::vx},vB::vb,vB::vx},vC::vc,vC::vx},vD::vd,vD::vx},vE::ve,vE::vx} + + g_vD.vA::va = 19; + g_vD.vA::vx = 20; + g_vD.vB::vb = 21; + g_vD.vB::vx = 22; + g_vD.vC::vc = 23; + g_vD.vC::vx = 24; + g_vD.vD::vd = 25; + g_vD.vD::vx = 26; + g_vE.vE::ve = 27; + g_vE.vE::vx = 28; + + inheritance4 (); +} + +// ====================================================================== + +class Base1 { + public: + int x; + Base1(int i) { x = i; } +}; + +class Foo +{ + public: + int x; + int y; + static int st; + Foo (int i, int j) { x = i; y = j; } + int operator! (); + operator int (); + int times (int y); +}; + +class Bar : public Base1, public Foo { + public: + int z; + Bar (int i, int j, int k) : Base1 (10*k), Foo (i, j) { z = k; } +}; + +class ClassWithEnum { +public: + enum PrivEnum { red, green, blue, yellow = 42 }; + PrivEnum priv_enum; + int x; +}; + +int Foo::operator! () { return !x; } + +int Foo::times (int y) { return x * y; } + +int Foo::st = 100; + +Foo::operator int() { return x; } + +Foo foo(10, 11); +Bar bar(20, 21, 22); + +class Contains_static_instance +{ + public: + int x; + int y; + Contains_static_instance (int i, int j) { x = i; y = j; } + static Contains_static_instance null; +}; + +Contains_static_instance Contains_static_instance::null(0,0); +Contains_static_instance csi(10,20); + +class Contains_nested_static_instance +{ + public: + class Nested + { + public: + Nested(int i) : z(i) {} + int z; + static Contains_nested_static_instance xx; + }; + + Contains_nested_static_instance(int i, int j) : x(i), y(j) {} + + int x; + int y; + + static Contains_nested_static_instance null; + static Nested yy; +}; + +Contains_nested_static_instance Contains_nested_static_instance::null(0, 0); +Contains_nested_static_instance::Nested Contains_nested_static_instance::yy(5); +Contains_nested_static_instance + Contains_nested_static_instance::Nested::xx(1,2); +Contains_nested_static_instance cnsi(30,40); + +typedef struct { + int one; + int two; +} tagless_struct; +tagless_struct v_tagless; + +/* Try to get the compiler to allocate a class in a register. */ +class small { + public: + int x; + int method (); +}; +int small::method () +{ + return x + 5; +} +void marker_reg1 () {} + +int +register_class () +{ + /* We don't call any methods for v, so gcc version cygnus-2.3.3-930220 + might put this variable in a register. This is a lose, though, because + it means that GDB can't call any methods for that variable. */ + register small v; + + int i; + + /* Perform a computation sufficiently complicated that optimizing compilers + won't optimized out the variable. If some compiler constant-folds this + whole loop, maybe using a parameter to this function here would help. */ + v.x = 0; + for (i = 0; i < 13; ++i) + v.x += i; + --v.x; /* v.x is now 77 */ + marker_reg1 (); + return v.x + 5; +} + +int +main() +{ +#ifdef usestubs + set_debug_traps(); + breakpoint(); +#endif + inheritance1 (); + inheritance3 (); + register_class (); + + /* FIXME: pmi gets optimized out. Need to do some more computation with + it or something. (No one notices, because the test is xfail'd anyway, + but that probably won't always be true...). */ + int Foo::* pmi = &Foo::y; + + /* Make sure the AIX linker doesn't remove the variable. */ + v_tagless.one = 5; + + /* Class with enumeration inside it */ + ClassWithEnum obj_with_enum; + obj_with_enum.priv_enum = ClassWithEnum::green; + + return foo.*pmi; +} + +/* Create an instance for some classes, otherwise they get optimized away. */ + +default_public_struct default_public_s; +explicit_public_struct explicit_public_s; +protected_struct protected_s; +private_struct private_s; +mixed_protection_struct mixed_protection_s; +public_class public_c; +protected_class protected_c; +default_private_class default_private_c; +explicit_private_class explicit_private_c; +mixed_protection_class mixed_protection_c; diff --git a/gdb/testsuite/gdb.hp/more-steps.c b/gdb/testsuite/gdb.hp/more-steps.c new file mode 100644 index 0000000000..c5ba1e2686 --- /dev/null +++ b/gdb/testsuite/gdb.hp/more-steps.c @@ -0,0 +1,140 @@ +/* BeginSourceFile more_steps.c + + This file creates a lot of threads which then execute + in parallel, so that wdb can be tested on handling + simultaneous thread events. + + To compile: + + cc -Ae +DA1.0 -g -o more_steps -lpthread more_steps.c + + To run: + + more_threads +*/ + +#include +#include +#include +#include +#include + +#define TRUE 1 +#define FALSE 0 +#define N_THREADS 3 +#define PHASES 3 + +typedef enum { + ZERO, + ONE, + TWO, + THREE +} phase_t; + +/* Uncomment to turn on debugging output */ +/* #define DEBUG */ + +/* Locks. + */ +int lock_one; /* Main W, others R */ +int lock_two; /* ditto */ +int lock_end[ N_THREADS ]; /* Main R, others R[i] */ +int phase[ N_THREADS ]; + +/* Routine for each thread to run. + */ +void *spin( vp ) + void * vp; +{ + int me = (int) vp; + int i; + + lock_end[ me ] = TRUE; + + phase[ me ] = ONE; + + while( lock_one ); + + phase[ me ] = TWO; + + while( lock_two ); + + phase[ me ] = THREE; + + lock_end[ me ] = FALSE; +} + +void +do_pass() +{ + int i; + pthread_t t[ N_THREADS ]; + int err; + int done; + + /* Start N_THREADS threads, then join them so + * that they are terminated. + */ + for( i = 0; i < N_THREADS; i++ ) { + err = pthread_create( &t[i], NULL, spin, (void *)i ); + if( err != 0 ) { + printf( "== Start/stop, error in thread %d create\n", i ); + } + } + + /* Do phase 1. + */ + lock_one = FALSE; + + /* Do phase 2. + */ + lock_two = FALSE; + + /* Be done. + */ + done = 0; + while( !done ) { + + /* Be optimistic. + */ + done = 1; + for( i = 0; i < N_THREADS; i++ ) { + if( lock_end[i] ) { + /* Thread "i" is not ready yet. + */ + done = 0; + break; + } + } + } + + /* Finish up + */ + for( i = 0; i < N_THREADS; i++ ) { + err = pthread_join(t[i], NULL ); /* Line 105 */ + if( err != 0 ) { /* Line 106 */ + printf( "== Start/stop, error in thread %d join\n", i ); + } + } + + i = 10; /* Line 109. Null line for setting bpts on. */ +} + +main( argc, argv ) +int argc; +char **argv; +{ + int i; + + /* Init + */ + lock_one = TRUE; + lock_two = TRUE; + for( i = 0; i < N_THREADS; i++ ) { + lock_end[i] = TRUE; + phase[i] = ZERO; + } + + do_pass(); + return(0); +} diff --git a/gdb/testsuite/gdb.hp/optimize.c b/gdb/testsuite/gdb.hp/optimize.c new file mode 100644 index 0000000000..2a8daa8c7a --- /dev/null +++ b/gdb/testsuite/gdb.hp/optimize.c @@ -0,0 +1,76 @@ +/* Source for debugging optimimzed code test. + + cc -g -O -o optimize optimize.c +*/ +int callee(); +int test_opt; + +int main() +{ + int a,b,c,d,e,f,g,h; + + a = 10;; + + /* Value propagate + */ + b = 2 * a + 1; + c = 3 * b + 2; + + /* Re-use expressions + */ + d = (2 * a + 1) * (3 * b + 2); + e = (2 * a + 1) * (3 * b + 2); + + /* Create dead stores--do lines still exist? + */ + d = (2 * a + 1) * (3 * b + 2); + e = (2 * a + 1) * (3 * b + 2); + d = (2 * a + 1) * (3 * b + 2); + e = (2 * a + 1) * (3 * b + 2); + + /* Alpha and psi motion + */ + if( test_opt ) { + f = e - d; + f = f--; + } + else { + f = e - d; + f = f + d * e; + } + + /* Chi and Rho motion + */ + h = 0; + do { + h++; + a = b * c + d * e; /* Chi */ + f = f + d * e; + g = f + d * e; /* Rho */ + callee( g+1 ); + test_opt = (test_opt != 1); /* Cycles */ + } while( g && h < 10); + + /* Opps for tail recursion, unrolling, + * folding, evaporating + */ + for( a = 0; a < 100; a++ ) { + callee( callee ( callee( a ))); + callee( callee ( callee( a ))); + callee( callee ( callee( a ))); + } + + return callee( test_opt ); +} + +/* defined late to keep line numbers the same +*/ +int callee( x ) + int x; /* not used! */ +{ + test_opt++; /* side effect */ + + return test_opt; +} + +/* end */ \ No newline at end of file diff --git a/gdb/testsuite/gdb.hp/quicksort.c b/gdb/testsuite/gdb.hp/quicksort.c new file mode 100644 index 0000000000..b44b828a8d --- /dev/null +++ b/gdb/testsuite/gdb.hp/quicksort.c @@ -0,0 +1,284 @@ +/* BeginSourceFile quicksort.c + + This file is take from the DDE test system. It spawns six + threads to do a sort of an array of random numbers. + + The locations marked "quick N" are used in the test "quicksort.exp". + + The locations marked "att N" are used in the test "attach.exp". + + To compile: + + cc -Ae +DA1.0 -g -o quicksort -lpthread quicksort.c + + To run: + + quicksort --normal run + quicksort 1 --waits before starting to allow attach +*/ + +#include +#include +#include +#include +#include + +#define TRUE 1 +#define FALSE 0 +#define SORTSET 100000 + +/* Uncomment to turn on debugging output */ +/* #define QUICK_DEBUG */ + +/* Uncomment to turn on wait on each thread create */ +/* #define THREAD_WAIT */ + +/* Fewer than SORT_DIRECT items are sorted with an insertion sort. */ +#define SORT_DIRECT 20 + +/* Work at this depth or less generates a separate work item. */ +#define DEFER_DEPTH 6 + +/* Workpile controller */ +typedef void (*work_proc_t)(void *); + +typedef struct workpile_struct { + pthread_mutex_t lock; /* mutex for this structure */ + pthread_cond_t work_wait; /* workers waiting for work */ + pthread_cond_t finish_wait; /* to wait for workers to finish */ + int max_pile; /* length of workpile array */ + work_proc_t worker_proc; /* work procedure */ + int n_working; /* number of workers working */ + int n_waiting; /* number of workers waiting for work */ + int n_pile; /* number of pointers in the workpile */ + int inp; /* FIFO input pointer */ + int outp; /* FIFO output pointer */ + void *pile[1]; /* array of pointers - the workpile */ +} *workpile_t; + +typedef struct { + float *data; /* Array to sort */ + int n; /* Number of elements in the array */ + int depth; /* Depth of recursion */ + workpile_t wp; /* Workpile to use */ +} quick_sort_args; + +/* True if waiting for attach. + */ +int wait_here = FALSE; + +static workpile_t quick_sort_workpile = NULL; + +void *worker(void * wptr); + +/* Allocates and initializes a workpile that holds max_pile entries. + * worker_proc is called to process each work item on the queue. + */ +workpile_t +work_init(int max_pile, work_proc_t worker_proc, int n_threads) +{ + int err; + pthread_t t; + workpile_t wp = (workpile_t) + malloc(sizeof (struct workpile_struct) + + (max_pile * sizeof (void *))); + + if (wp != NULL) { + pthread_mutex_init(&wp->lock, NULL); + pthread_cond_init(&wp->work_wait, NULL); + pthread_cond_init(&wp->finish_wait, NULL); + wp->max_pile = max_pile; + wp->worker_proc = worker_proc; + wp->n_working = wp->n_waiting = wp->n_pile = 0; + wp->inp = wp->outp = 0; + while (n_threads--) { + err = pthread_create(&t, NULL, + worker, (void *)&wp); +#ifdef QUICK_DEBUG + printf( "== Quicksort: created new thread\n" ); +#ifdef THREAD_WAIT + if( n_threads > 0 ) { + int i; + printf( "== Quicksort: waiting on user input of an integer\n" ); + scanf( "%d", &i ); + printf( "== Quicksort: continuing with quicksort\n" ); + } +#endif +#endif + + assert(err == 0); /* quick 1 */ + } + /* All the threads have now been created. + */ + assert( n_threads == -1 ); /* att 1 */ + if( wait_here ) { +#ifdef QUICK_DEBUG + printf( "== Quicksort: waiting for attach\n" ); +#endif + sleep( 25 ); + } + wait_here = 99; /* att 2, otherwise useless */ + } + return (wp); /* quick 2 */ +} + +/* + * Worker thread routine. Continuously looks for work, calls the + * worker_proc associated with the workpile to do work. + */ +void * +worker(void * wptr) +{ + workpile_t wp; + void *ptr; + + wp = * (workpile_t *) wptr; + + pthread_mutex_lock(&wp->lock); + wp->n_working++; + for (;;) { + while (wp->n_pile == 0) { /* wait for new work */ + if (--wp->n_working == 0) + pthread_cond_signal(&wp->finish_wait); + wp->n_waiting++; + pthread_cond_wait(&wp->work_wait, &wp->lock); + wp->n_waiting--; /* quick 3 */ + wp->n_working++; + } + wp->n_pile--; + ptr = wp->pile[wp->outp]; + wp->outp = (wp->outp + 1) % wp->max_pile; + pthread_mutex_unlock(&wp->lock); + /* Call application worker routine. */ + (*wp->worker_proc)(ptr); + pthread_mutex_lock(&wp->lock); /* quick 4 */ + } + /* NOTREACHED */ +} + +/* Puts ptr in workpile. Called at the outset, or within a worker. */ +void +work_put(workpile_t wp, void *ptr) +{ + pthread_mutex_lock(&wp->lock); + if (wp->n_waiting) { + /* idle workers to be awakened */ + pthread_cond_signal(&wp->work_wait); + } + assert(wp->n_pile != wp->max_pile); /* check for room */ + wp->n_pile++; + wp->pile[wp->inp] = ptr; + wp->inp = (wp->inp + 1) % wp->max_pile; + pthread_mutex_unlock(&wp->lock); +} + + +/* Wait until all work is done and workers quiesce. */ +void +work_wait(workpile_t wp) +{ + pthread_mutex_lock(&wp->lock); + while(wp->n_pile !=0 || wp->n_working != 0) + pthread_cond_wait(&wp->finish_wait, &wp->lock); + pthread_mutex_unlock(&wp->lock); +} + +void +quick_sort_aux(float *data, int n, int depth, workpile_t wp, int deferrable) +{ + int i,j; + + /* If array small, use insertion sort */ + if (n <= SORT_DIRECT) { + for (j = 1; j < n; j++) { + /* data[0..j-1] in sort; find a spot for data[j] */ + float key = data[j]; + for (i = j - 1; i >= 0 && key < data[i]; i--) + data[i+1] = data[i]; + data[i+1] = key; + } + return; + } + /* Defer this work to work queue if policy says so */ + if (deferrable && depth <= DEFER_DEPTH) { + quick_sort_args *q = (quick_sort_args *) + malloc(sizeof (quick_sort_args)); + assert(q != NULL); + q->data = data; q->n = n; q->depth = depth; q->wp = wp; + work_put(wp, (void *)q); + return; + } + /* Otherwise, partition data based on a median estimate */ +#define swap(i,j) {float t = data[i]; data[i] = data[j]; data[j] = t;} + i = 0; + j = n - 1; + for (;;) { + while (data[i] < data[j]) j--; + if (i >= j) break; + swap(i, j); i++; + while (data[i] < data[j]) i++; + if (i >= j) { i = j; break; } + swap(i, j); j--; + } + /* Median value is now at data[i] */ + /* Partitioned so that data[0..i-1] <= median <= data[i+1..n-1] */ + quick_sort_aux(data, i, depth+1, wp, TRUE); + quick_sort_aux(&data[i+1], n-i-1, depth+1, wp, TRUE); +} +/* Called from workpile controller with argument pointing to work. */ +void +quick_sort_worker(void *a) +{ + quick_sort_args *q = (quick_sort_args *)a; + quick_sort_aux(q->data, q->n, q->depth, q->wp, FALSE); + free(q); +} +/* Main routine, called by client to do a sort. */ +void +quick_sort(float *data, int n) +{ + if (quick_sort_workpile == NULL) { + int n_threads = 6; + quick_sort_workpile = work_init(2 << DEFER_DEPTH, + quick_sort_worker, n_threads); + assert(quick_sort_workpile != NULL); + } + + quick_sort_aux(data, n, 0, quick_sort_workpile, FALSE); + + /* Wait for all work to finish */ + work_wait(quick_sort_workpile); + +#ifdef QUICK_DEBUG + printf( "== Quicksort: done sorting\n" ); +#endif +} + + +main( argc, argv ) +int argc; +char **argv; +{ + float data[SORTSET]; + int i; int debugging = 0; + + if((argc > 1) && (0 != argv )) { + if( 1 == atoi( argv[1] ) ) + wait_here = TRUE; + } + + for(i = 0; i < SORTSET; i++) + data[SORTSET -1 -i] = drand48(); + + for(i = 0; i < SORTSET; i++) + if (debugging) + printf("data[%d] = %f\n", i, data[i]); + + quick_sort(data, SORTSET); + for(i = 0; i < SORTSET; i++) + if (debugging) + printf("data[%d] = %f\n", i, data[i]); + + return(0); +} +/* EndSourceFile */ diff --git a/gdb/testsuite/gdb.hp/run-hp.c b/gdb/testsuite/gdb.hp/run-hp.c new file mode 100644 index 0000000000..91da1e0fc1 --- /dev/null +++ b/gdb/testsuite/gdb.hp/run-hp.c @@ -0,0 +1,70 @@ +/* + * This simple classical example of recursion is useful for + * testing stack backtraces and such. + */ + +#ifdef vxworks + +# include + +/* VxWorks does not supply atoi. */ +static int +atoi (z) + char *z; +{ + int i = 0; + + while (*z >= '0' && *z <= '9') + i = i * 10 + (*z++ - '0'); + return i; +} + +/* I don't know of any way to pass an array to VxWorks. This function + can be called directly from gdb. */ + +vxmain (arg) +char *arg; +{ + char *argv[2]; + + argv[0] = ""; + argv[1] = arg; + main (2, argv, (char **) 0); +} + +#else /* ! vxworks */ +# include +#endif /* ! vxworks */ + +main (argc, argv, envp) +int argc; +char *argv[], **envp; +{ +#ifdef usestubs + set_debug_traps(); + breakpoint(); +#endif +#ifdef FAKEARGV + printf ("%d\n", factorial (1)); +#else + if (argc != 2) { + printf ("usage: factorial \n"); + return 1; + } else { + printf ("%d\n", factorial (atoi (argv[1]))); + } +#endif + return 0; +} + +int factorial (value) +int value; +{ + int local_var; + + if (value > 1) { + value *= factorial (value - 1); + } + local_var = value; + return (value); +} diff --git a/gdb/testsuite/gdb.hp/start-stop.c b/gdb/testsuite/gdb.hp/start-stop.c new file mode 100644 index 0000000000..dcf2c7ebb1 --- /dev/null +++ b/gdb/testsuite/gdb.hp/start-stop.c @@ -0,0 +1,161 @@ +/* BeginSourceFile start_stop.c + + This file creates and deletes threads, so that wdb + can be tested on thread delete. + + To compile: + + cc -Ae +DA1.0 -g -o start_stop -lpthread start_stop.c + + To run: + + start_stop --normal run + start_stop 1 --waits in each thread to keep it alive. +*/ + +#include +#include +#include +#include +#include + +#define TRUE 1 +#define FALSE 0 +#define OUTER_LOOP_COUNT 3 +#define N_THREADS 3 +#define MAX_LOCAL_VAL 40 + +/* Uncomment to turn on debugging output */ +/* #define START_DEBUG */ + +/* True if waiting for attach. + */ +int wait_here; + +/* Thing to check for debugging purposes. +*/ +int a_global = 0; + +/* Thread-local storage. + */ +__thread int a_thread_local; + +/* Check the results of thread-local storage. + */ +int thread_local_val[ N_THREADS ]; +int val_debugger_saw[ N_THREADS ]; + +/* Routine for each thread to run, does nothing. + */ +void *spin( vp ) + void * vp; +{ + int me = (int) vp; + int i; + +#ifdef START_DEBUG + printf( "== In thread %d\n", me ); +#endif + + a_global++; + + a_thread_local = 0; + for( i = 0; i < a_global; i++ ) { + a_thread_local += i; + } + + thread_local_val[ me ] = a_thread_local; /* Line 67 */ + + printf( "== Thread %d, a_thread_local is %d\n", + (int) vp, a_thread_local ); + + if( wait_here ) { + /* Extend life of thread to extend life of thread-local var. + * This makes life easier for human debugging (though you'd + * probably want to make the delay longer). + */ + sleep( 5 ); + } +} + +void +do_pass( pass ) + int pass; +{ + int i; + pthread_t t[ N_THREADS ]; + int err; + + for( i = 0; i < N_THREADS; i++) { + thread_local_val[i] = 0; + val_debugger_saw[i] = 0; + } + + /* Start N_THREADS threads, then join them so + * that they are terminated. + */ + for( i = 0; i < N_THREADS; i++ ) { + err = pthread_create( &t[i], NULL, spin, (void *)i ); + if( err != 0 ) { + printf( "== Start/stop, error in thread %d create\n", i ); + } + } + + for( i = 0; i < N_THREADS; i++ ) { + err = pthread_join(t[i], NULL ); /* Line 105 */ + if( err != 0 ) { /* Line 106 */ + printf( "== Start/stop, error in thread %d join\n", i ); + } + } + + i = 10; /* Line 109. Null line for setting bpts on. */ + +/*#ifdef START_DEBUG*/ + for( i = 0; i < N_THREADS; i++) { + printf( " Local in thread %d was %d, debugger saw %d\n", + i, thread_local_val[i], val_debugger_saw[i] ); + } + printf( "== Pass %d done\n", pass ); +/*#endif*/ + +} + +void +do_it() +{ + /* We want to start some threads and then + * end them, and then do it again and again + */ + int i; + int dummy; + + for( i = 0; i < OUTER_LOOP_COUNT; i++ ) { + do_pass( i ); + dummy = i; /* Line 134, null line for setting bps on */ + } +} + +main( argc, argv ) +int argc; +char **argv; +{ + wait_here = FALSE; + if((argc > 1) && (0 != argv )) { + if( 1 == atoi( argv[1] ) ) + wait_here = TRUE; + } + +#ifdef START_DEBUG + printf( "== Test starting\n" ); +#endif + + do_it(); + +#ifdef START_DEBUG + printf( "== Test done\n" ); +#endif + + return(0); +} + +/* EndSourceFile */ diff --git a/gdb/testsuite/gdb.hp/sum.c b/gdb/testsuite/gdb.hp/sum.c new file mode 100644 index 0000000000..c28afa5385 --- /dev/null +++ b/gdb/testsuite/gdb.hp/sum.c @@ -0,0 +1,15 @@ +/* This is a sample program for the HP/DDE debugger. */ +#include + +#ifdef __STDC__ +int sum(int list[], int low, int high) +#else +int sum(list, low, high) +int list[], low, high; +#endif + { + int i, s = 0; + for (i = low; i <= high; i++) + s += list[i]; + return(s); + } diff --git a/gdb/testsuite/gdb.hp/templates-hp.cc b/gdb/testsuite/gdb.hp/templates-hp.cc new file mode 100644 index 0000000000..25241dc6db --- /dev/null +++ b/gdb/testsuite/gdb.hp/templates-hp.cc @@ -0,0 +1,785 @@ +/* This test code is from Wendell Baker (wbaker@comet.berkeley.edu) */ + +#include + +int a_i; +char a_c; +double a_d; + +typedef void *Pix; + +int +f(int i) +{ return 0; } + +int +f(int i, char c) +{ return 0; } + +int +f(int i, char c, double d) +{ return 0; } + +int +f(int i, char c, double d, char *cs) +{ return 0; } + +int +f(int i, char c, double d, char *cs, void (*fig)(int, char)) +{ return 0; } + +int +f(int i, char c, double d, char *cs, void (*fig)(char, int)) +{ return 0; } + +class R { +public: + int i; +}; +class S { +public: + int i; +}; +class T { +public: + int i; +}; + +char g(char, const char, volatile char) +{ return 'c'; } +char g(R, char&, const char&, volatile char&) +{ return 'c'; } +char g(char*, const char*, volatile char*) +{ return 'c'; } +char g(S, char*&, const char*&, volatile char*&) +{ return 'c'; } + +signed char g(T,signed char, const signed char, volatile signed char) +{ return 'c'; } +signed char g(T, R, signed char&, const signed char&, volatile signed char&) +{ return 'c'; } +signed char g(T, signed char*, const signed char*, volatile signed char*) +{ return 'c'; } +signed char g(T, S, signed char*&, const signed char*&, volatile signed char*&) +{ return 'c'; } + +unsigned char g(unsigned char, const unsigned char, volatile unsigned char) +{ return 'c'; } +unsigned char g(R, unsigned char&, const unsigned char&, volatile unsigned char&) +{ return 'c'; } +unsigned char g(unsigned char*, const unsigned char*, volatile unsigned char*) +{ return 'c'; } +unsigned char g(S, unsigned char*&, const unsigned char*&, volatile unsigned char*&) +{ return 'c'; } + +short g(short, const short, volatile short) +{ return 0; } +short g(R, short&, const short&, volatile short&) +{ return 0; } +short g(short*, const short*, volatile short*) +{ return 0; } +short g(S, short*&, const short*&, volatile short*&) +{ return 0; } + +signed short g(T, signed short, const signed short, volatile signed short) +{ return 0; } +signed short g(T, R, signed short&, const signed short&, volatile signed short&) +{ return 0; } +signed short g(T, signed short*, const signed short*, volatile signed short*) +{ return 0; } +signed short g(T, S, double, signed short*&, const signed short*&, volatile signed short*&) +{ return 0; } + +unsigned short g(unsigned short, const unsigned short, volatile unsigned short) +{ return 0; } +unsigned short g(R, unsigned short&, const unsigned short&, volatile unsigned short&) +{ return 0; } +unsigned short g(unsigned short*, const unsigned short*, volatile unsigned short*) +{ return 0; } +unsigned short g(S, unsigned short*&, const unsigned short*&, volatile unsigned short*&) +{ return 0; } + +int g(int, const int, volatile int) +{ return 0; } +int g(R, int&, const int&, volatile int&) +{ return 0; } +int g(int*, const int*, volatile int*) +{ return 0; } +int g(S, int*&, const int*&, volatile int*&) +{ return 0; } + +signed int g(T, signed int, const signed int, volatile signed int) +{ return 0; } +signed int g(T, R, signed int&, const signed int&, volatile signed int&) +{ return 0; } +signed int g(T, signed int*, const signed int*, volatile signed int*) +{ return 0; } +signed int g(T, S, signed int*&, const signed int*&, volatile signed int*&) +{ return 0; } + +unsigned int g(unsigned int, const unsigned int, volatile unsigned int) +{ return 0; } +unsigned int g(R, unsigned int&, const unsigned int&, volatile unsigned int&) +{ return 0; } +unsigned int g(unsigned int*, const unsigned int*, volatile unsigned int*) +{ return 0; } +unsigned int g(S, unsigned int*&, const unsigned int*&, volatile unsigned int*&) +{ return 0; } + +long g(long, const long, volatile long) +{ return 0; } +long g(R, long&, const long&, volatile long&) +{ return 0; } +long g(long*, const long*, volatile long*) +{ return 0; } +long g(S, long*&, const long*&, volatile long*&) +{ return 0; } + +signed long g(T, signed long, const signed long, volatile signed long) +{ return 0; } +signed long g(T, R, signed long&, const signed long&, volatile signed long&) +{ return 0; } +signed long g(T, signed long*, const signed long*, volatile signed long*) +{ return 0; } +signed long g(T, S, signed long*&, const signed long*&, volatile signed long*&) +{ return 0; } + +unsigned long g(unsigned long, const unsigned long, volatile unsigned long) +{ return 0; } +unsigned long g(S, unsigned long&, const unsigned long&, volatile unsigned long&) +{ return 0; } +unsigned long g(unsigned long*, const unsigned long*, volatile unsigned long*) +{ return 0; } +unsigned long g(S, unsigned long*&, const unsigned long*&, volatile unsigned long*&) +{ return 0; } + +#ifdef __GNUC__ +long long g(long long, const long long, volatile long long) +{ return 0; } +long long g(S, long long&, const long long&, volatile long long&) +{ return 0; } +long long g(long long*, const long long*, volatile long long*) +{ return 0; } +long long g(R, long long*&, const long long*&, volatile long long*&) +{ return 0; } + +signed long long g(T, signed long long, const signed long long, volatile signed long long) +{ return 0; } +signed long long g(T, R, signed long long&, const signed long long&, volatile signed long long&) +{ return 0; } +signed long long g(T, signed long long*, const signed long long*, volatile signed long long*) +{ return 0; } +signed long long g(T, S, signed long long*&, const signed long long*&, volatile signed long long*&) +{ return 0; } + +unsigned long long g(unsigned long long, const unsigned long long, volatile unsigned long long) +{ return 0; } +unsigned long long g(R, unsigned long long*, const unsigned long long*, volatile unsigned long long*) +{ return 0; } +unsigned long long g(unsigned long long&, const unsigned long long&, volatile unsigned long long&) +{ return 0; } +unsigned long long g(S, unsigned long long*&, const unsigned long long*&, volatile unsigned long long*&) +{ return 0; } +#endif + +float g(float, const float, volatile float) +{ return 0; } +float g(char, float&, const float&, volatile float&) +{ return 0; } +float g(float*, const float*, volatile float*) +{ return 0; } +float g(char, float*&, const float*&, volatile float*&) +{ return 0; } + +double g(double, const double, volatile double) +{ return 0; } +double g(char, double&, const double&, volatile double&) +{ return 0; } +double g(double*, const double*, volatile double*) +{ return 0; } +double g(char, double*&, const double*&, volatile double*&) +{ return 0; } + +#ifdef __GNUC__ +long double g(long double, const long double, volatile long double) +{ return 0; } +long double g(char, long double&, const long double&, volatile long double&) +{ return 0; } +long double g(long double*, const long double*, volatile long double*) +{ return 0; } +long double g(char, long double*&, const long double*&, volatile long double*&) +{ return 0; } +#endif + +class c { +public: + c(int) {}; + int i; +}; + +class c g(c, const c, volatile c) +{ return 0; } +c g(char, c&, const c&, volatile c&) +{ return 0; } +c g(c*, const c*, volatile c*) +{ return 0; } +c g(char, c*&, const c*&, volatile c*&) +{ return 0; } + +/* +void h(char = 'a') +{ } +void h(char, signed char = 'a') +{ } +void h(unsigned char = 'a') +{ } +*/ +/* +void h(char = (char)'a') +{ } +void h(char, signed char = (signed char)'a') +{ } +void h(unsigned char = (unsigned char)'a') +{ } + + +void h(short = (short)43) +{ } +void h(char, signed short = (signed short)43) +{ } +void h(unsigned short = (unsigned short)43) +{ } + +void h(int = (int)43) +{ } +void h(char, signed int = (signed int)43) +{ } +void h(unsigned int = (unsigned int)43) +{ } + + +void h(long = (long)43) +{ } +void h(char, signed long = (signed long)43) +{ } +void h(unsigned long = (unsigned long)43) +{ } + +#ifdef __GNUC__ +void h(long long = 43) +{ } +void h(char, signed long long = 43) +{ } +void h(unsigned long long = 43) +{ } +#endif + +void h(float = 4.3e-10) +{ } +void h(double = 4.3) +{ } +#ifdef __GNUC__ +void h(long double = 4.33e33) +{ } +#endif +*/ +void printf(const char *format, ... ) +{ + // elipsis +} + +class T1 { +public: + static void* operator new(size_t); + static void operator delete(void *pointer); + + void operator=(const T1&); + T1& operator=(int); + + int operator==(int) const; + int operator==(const T1&) const; + int operator!=(int) const; + int operator!=(const T1&) const; + + int operator<=(int) const; + int operator<=(const T1&) const; + int operator<(int) const; + int operator<(const T1&) const; + int operator>=(int) const; + int operator>=(const T1&) const; + int operator>(int) const; + int operator>(const T1&) const; + + void operator+(int) const; + T1& operator+(const T1&) const; + void operator+=(int) const; + T1& operator+=(const T1&) const; + + T1& operator++() const; + + void operator-(int) const; + T1& operator-(const T1&) const; + void operator-=(int) const; + T1& operator-=(const T1&) const; + + T1& operator--() const; + + void operator*(int) const; + T1& operator*(const T1&) const; + void operator*=(int) const; + T1& operator*=(const T1&) const; + + void operator/(int) const; + T1& operator/(const T1&) const; + void operator/=(int) const; + T1& operator/=(const T1&) const; + + void operator%(int) const; + T1& operator%(const T1&) const; + void operator%=(int) const; + T1& operator%=(const T1&) const; + + void operator&&(int) const; + T1& operator&&(const T1&) const; + + void operator||(int) const; + T1& operator||(const T1&) const; + + void operator&(int) const; + T1& operator&(const T1&) const; + void operator&=(int) const; + T1& operator&=(const T1&) const; + + void operator|(int) const; + T1& operator|(const T1&) const; + void operator|=(int) const; + T1& operator|=(const T1&) const; + + void operator^(int) const; + T1& operator^(const T1&) const; + void operator^=(int) const; + T1& operator^=(const T1&) const; + + T1& operator!() const; + T1& operator~() const; +}; + +void* +T1::operator new(size_t) +{ return 0; } + +void +T1::operator delete(void *pointer) +{ } + +class T2 { +public: + T2(int i): integer(i) + { } + int integer; +}; + +int operator==(const T2&, const T2&) +{ return 0; } +int operator==(const T2&, char) +{ return 0; } +int operator!=(const T2&, const T2&) +{ return 0; } +int operator!=(const T2&, char) +{ return 0; } + +int operator<=(const T2&, const T2&) +{ return 0; } +int operator<=(const T2&, char) +{ return 0; } +int operator<(const T2&, const T2&) +{ return 0; } +int operator<(const T2&, char) +{ return 0; } +int operator>=(const T2&, const T2&) +{ return 0; } +int operator>=(const T2&, char) +{ return 0; } +int operator>(const T2&, const T2&) +{ return 0; } +int operator>(const T2&, char) +{ return 0; } + +T2 operator+(const T2 t, int i) +{ return t.integer + i; } +T2 operator+(const T2 a, const T2& b) +{ return a.integer + b.integer; } +T2& operator+=(T2& t, int i) +{ t.integer += i; return t; } +T2& operator+=(T2& a, const T2& b) +{ a.integer += b.integer; return a; } + +T2 operator-(const T2 t, int i) +{ return t.integer - i; } +T2 operator-(const T2 a, const T2& b) +{ return a.integer - b.integer; } +T2& operator-=(T2& t, int i) +{ t.integer -= i; return t; } +T2& operator-=(T2& a, const T2& b) +{ a.integer -= b.integer; return a; } + +T2 operator*(const T2 t, int i) +{ return t.integer * i; } +T2 operator*(const T2 a, const T2& b) +{ return a.integer * b.integer; } +T2& operator*=(T2& t, int i) +{ t.integer *= i; return t; } +T2& operator*=(T2& a, const T2& b) +{ a.integer *= b.integer; return a; } + +T2 operator/(const T2 t, int i) +{ return t.integer / i; } +T2 operator/(const T2 a, const T2& b) +{ return a.integer / b.integer; } +T2& operator/=(T2& t, int i) +{ t.integer /= i; return t; } +T2& operator/=(T2& a, const T2& b) +{ a.integer /= b.integer; return a; } + +T2 operator%(const T2 t, int i) +{ return t.integer % i; } +T2 operator%(const T2 a, const T2& b) +{ return a.integer % b.integer; } +T2& operator%=(T2& t, int i) +{ t.integer %= i; return t; } +T2& operator%=(T2& a, const T2& b) +{ a.integer %= b.integer; return a; } + +template +class T5 { +public: + T5(int); + T5(const T5&); + ~T5(); + static void* operator new(size_t); + static void operator delete(void *pointer); + int value(); + + static T X; + T x; + int val; +}; + +template +T5::T5(int v) +{ val = v; } + +template +T5::T5(const T5&) +{} + +template +T5::~T5() +{} + +template +void* +T5::operator new(size_t) +{ return 0; } + +template +void +T5::operator delete(void *pointer) +{ } + +template +int +T5::value() +{ return val; } + + +#if ! defined(__GNUC__) || defined(GCC_BUG) +template +T T5::X; +#endif + + + + +T5 t5c(1); +T5 t5i(2); +T5 t5fi1(3); +T5 t5fi2(4); + + + + + + +class x { +public: + int (*manage[5])(double, + void *(*malloc)(unsigned size), + void (*free)(void *pointer)); + int (*device[5])(int open(const char *, unsigned mode, unsigned perms, int extra = 0), + int *(*read)(int fd, void *place, unsigned size), + int *(*write)(int fd, void *place, unsigned size), + void (*close)(int fd)); +}; +T5 t5x(5); + +#if !defined(__GNUC__) || (__GNUC__ >= 2 && __GNUC_MINOR__ >= 6) +template class T5; +template class T5; +template class T5; +template class T5; +template class T5; +#endif + +class T7 { +public: + static int get(); + static void put(int); +}; + +int +T7::get() +{ return 1; } + +void +T7::put(int i) +{ + // nothing +} + +// More template kinds. GDB 4.16 didn't handle these, but +// Wildebeest does. Note: Assuming HP aCC is used to compile +// this file; with g++ or HP cfront or other compilers the +// demangling may not get done correctly. + +// Ordinary template, to be instantiated with different types +template +class Foo { +public: + int x; + T t; + T foo (int, T); +}; + + +template T Foo::foo (int i, T tt) +{ + return tt; +} + +// Template with int parameter + +template +class Bar { +public: + int x; + T t; + T bar (int, T); +}; + + +template T Bar::bar (int i, T tt) +{ + if (i < sz) + return tt; + else + return 0; +} + +// function template with int parameter +template int dummy (T tt, int i) +{ + return tt; +} + +// Template with partial specializations +template +class Spec { +public: + int x; + T1 spec (T2); +}; + +template +T1 Spec::spec (T2 t2) +{ + return 0; +} + +template +class Spec { +public: + int x; + T spec (T*); +}; + +template +T Spec::spec (T * tp) +{ + return *tp; +} + +// Template with char parameter +template +class Baz { +public: + int x; + T t; + T baz (int, T); +}; + +template T Baz::baz (int i, T tt) +{ + if (i < sz) + return tt; + else + return 0; +} + +// Template with char * parameter +template +class Qux { +public: + int x; + T t; + T qux (int, T); +}; + +template T Qux::qux (int i, T tt) +{ + if (sz[0] == 'q') + return tt; + else + return 0; +} + +// Template with a function pointer parameter +template +class Qux1 { +public: + int x; + T t; + T qux (int, T); +}; + +template T Qux1::qux (int i, T tt) +{ + if (f != 0) + return tt; + else + return 0; +} + +// Some functions to provide as arguments to template +int gf1 (int a) { + return a * 2 + 13; +} +int gf2 (int a) { + return a * 2 + 26; +} + +char string[3]; + + +// Template for nested instantiations + +template +class Garply { +public: + int x; + T t; + T garply (int, T); +}; + +template T Garply::garply (int i, T tt) +{ + if (i > x) + return tt; + else + { + x += i; + return tt; + } +} + + +int main() +{ + int i; +#ifdef usestubs + set_debug_traps(); + breakpoint(); +#endif + i = i + 1; + + // New tests added here + + Foo fint; + Foo fchar; + Foo fvpchar; + + Bar bint; + Bar 3)> bint2; + + Baz bazint; + Baz bazint2; + + Qux quxint2; + Qux quxint; + + Qux1 qux11; + + int x = fint.foo(33, 47); + char c = fchar.foo(33, 'x'); + volatile char * cp = fvpchar.foo(33, 0); + + int y = dummy (400, 600); + + int z = bint.bar(55, 66); + z += bint2.bar(55, 66); + + c = bazint2.baz(4, 'y'); + c = quxint2.qux(4, 'z'); + + y = bazint.baz(4,3); + y = quxint.qux(4, 22); + y += qux11.qux(4, 22); + + y *= gf1(y) - gf2(y); + + Spec sic; + Spec siip; + + sic.spec ('c'); + siip.spec (&x); + + Garply f; + Garply fc; + f.x = 13; + + Garply > nf; + nf.x = 31; + + x = f.garply (3, 4); + + fc = nf.garply (3, fc); + + y = x + fc.x; + + + return 0; + +} + + + + + + + + + + + + + diff --git a/gdb/testsuite/gdb.hp/thread-local-in-lib.c b/gdb/testsuite/gdb.hp/thread-local-in-lib.c new file mode 100644 index 0000000000..c42dce96ff --- /dev/null +++ b/gdb/testsuite/gdb.hp/thread-local-in-lib.c @@ -0,0 +1,79 @@ +/* Thread local in a library. +*/ +#include "thread-local-in-lib.h" +/* + * #define NTHREADS 4 + * #define NUM_ELEMS 12 + */ + +extern void* adder( void * ); + +pthread_mutex_t mutex; /* mutex for protecting global data total */ + +int numbers[NUM_ELEMS] = {5, 4, 3, 2, 1, 6, 7, 8, 9, 10, 12, 11}; +int total = 0; + +int debugger_saw[NTHREADS][ELEMS_PER_THREAD]; /* [4][3] */ +int the_code_saw[NTHREADS][ELEMS_PER_THREAD]; + +int get_number(i) +int i; +{ + /* sleep to force context switch to another thread in non-MP system + * so that TLS symbols are used by multiple threads concurrently + * in some way. + */ + sleep(1); + return numbers[i]; +} + +main() +{ + pthread_t thread[NTHREADS]; + void *status; + int i, j, ret; + + printf("== Thread: Test started\n"); + + for( i = 0; i < NTHREADS; i++ ) { + for( j = 0; j < ELEMS_PER_THREAD; j++ ) { + debugger_saw[i][j] = 0; + the_code_saw[i][j] = 0; + } + } + + ret = pthread_mutex_init(&mutex, NULL); + if (ret != 0) { + printf("== Thread: pthread_mutex_init() error: %d\n", ret); + exit(1); + } + + for (i=0; i < NTHREADS; i++) { + ret = pthread_create( &thread[i], + NULL, + adder, + (void *) i); + if (ret != 0) { + printf("== Thread: pthread_create() error: %d\n", ret); + exit(1); + } + printf("== Thread: thread %d created\n", i); + } + + for (i=0; i < NTHREADS; i++) { + pthread_join( thread[i], &status); + } + + printf("== Thread: total = %d\n", total); /* Expect "78" */ + + for( i = 0; i < NTHREADS; i++ ) { + for( j = 0; j < ELEMS_PER_THREAD; j++ ) { + printf( "== Thread: the debugger saw %d, the program saw %d\n", + debugger_saw[i][j], + the_code_saw[i][j] ); + } + } + + printf("== Thread: Test ended\n"); + exit(0); +} diff --git a/gdb/testsuite/gdb.hp/thread-local-in-lib.h b/gdb/testsuite/gdb.hp/thread-local-in-lib.h new file mode 100644 index 0000000000..c9395dfd0c --- /dev/null +++ b/gdb/testsuite/gdb.hp/thread-local-in-lib.h @@ -0,0 +1,7 @@ +#include +#include + +#define NTHREADS 4 +#define NUM_ELEMS 12 + +#define ELEMS_PER_THREAD (NUM_ELEMS/NTHREADS) diff --git a/gdb/testsuite/gdb.hp/thread-local-in-lib.lib.c b/gdb/testsuite/gdb.hp/thread-local-in-lib.lib.c new file mode 100644 index 0000000000..0fe03b35e5 --- /dev/null +++ b/gdb/testsuite/gdb.hp/thread-local-in-lib.lib.c @@ -0,0 +1,92 @@ +#include + +/* Library code for thread local in lib test. +*/ +#include "thread-local-in-lib.h" + +extern pthread_mutex_t mutex; +extern int get_number(); +extern int total; +extern int the_code_saw[NTHREADS][ELEMS_PER_THREAD]; + +/* The debugger should see this without a declaration. + * + * extern int debugger_saw[NTHREADS][ELEMS_PER_THREAD]; + */ + +/* The actual thread locals. + */ +__thread int sum; +__thread int x[ ELEMS_PER_THREAD ]; /* [3] */ + +void sumup() +{ + int j; + + sum = 0; + for (j = 0; j < ELEMS_PER_THREAD; j++) { + sum += x[j]; + } + + if( sum == x[0] ) + /* It won't be "==", but this lets us set a breakpoint + * and look at the thread-local storage. + */ + sum++; + + x[0] = x[2]; /* Another no-op for debugger use */ +} + +void *adder( vid ) + void * vid; +{ + int id; + int i, j; + int ret; + + id = (int) vid; + + /* printf( "== Thread: Welcome to adder %d\n", id ); */ + + for (j = 0; j < ELEMS_PER_THREAD; j++) { + x[j] = 0; + } + + for (i = id, j = 0; i < NUM_ELEMS; i += NTHREADS, j++ ) { + + /* printf( "== Thread: id %d, i %d, j %d\n", id, i, j ); + fflush( stdout ); */ + + x[j] = get_number(i); /* {0,1,2,3} +0, +4, +8 */ + + /* Record for posterity; the debugger will gather + * the same data here, using "x[j]". + */ + the_code_saw[ id ][ j ] = x[j]; + + /* printf( "== Thread %d, sample %d, val %d, i %d\n", id, j, x[j],i ); + fflush( stdout ); */ + } + + sumup(); + /* printf("== Thread: adder %d contributes total %d\n", id, sum); */ + + /* protect global data */ + ret = pthread_mutex_lock(&mutex); + if (ret != 0) { + printf("== Thread: pthread_mutex_lock() error: %d\n", ret); + exit(1); + } + + total += sum; + + ret = pthread_mutex_unlock(&mutex); + if (ret != 0) { + printf("== Thread: pthread_mutex_unlock() error: %d\n", ret); + exit(1); + } + + if( NTHREADS != 4 || ELEMS_PER_THREAD != 3 || NUM_ELEMS != 12 ) { + printf( "** ERROR in test code **\n" ); + } +} diff --git a/gdb/testsuite/gdb.hp/vforked-program.c b/gdb/testsuite/gdb.hp/vforked-program.c new file mode 100644 index 0000000000..52c6cd2bbf --- /dev/null +++ b/gdb/testsuite/gdb.hp/vforked-program.c @@ -0,0 +1,6 @@ +#include + +main() +{ + printf("Hello from vforked_program...\n"); +} diff --git a/gdb/testsuite/gdb.hp/virtfunc-hp.cc b/gdb/testsuite/gdb.hp/virtfunc-hp.cc new file mode 100644 index 0000000000..6552a6233f --- /dev/null +++ b/gdb/testsuite/gdb.hp/virtfunc-hp.cc @@ -0,0 +1,192 @@ +// Pls try the following program on virtual functions and try to do print on +// most of the code in main(). Almost none of them works ! + +// +// The inheritance structure is: +// +// V : VA VB +// A : (V) +// B : A +// D : AD (V) +// C : (V) +// E : B (V) D C +// + +class VA +{ +public: + int va; +}; + +class VB +{ +public: + int vb; + int fvb(); + virtual vvb(); +}; + +class V : public VA, public VB +{ +public: + int f(); + virtual vv(); + int w; +}; + +class A : virtual public V +{ +public: + virtual int f(); +private: + int a; +}; + +class B : public A +{ +public: + int f(); +private: + int b; +}; + +class C : public virtual V +{ +public: + int c; +}; + +class AD +{ +public: + virtual int vg() = 0; +}; + +class D : public AD, virtual public V +{ +public: + static void s(); + virtual int vg(); + virtual int vd(); + int fd(); + int d; +}; + +class E : public B, virtual public V, public D, public C +{ +public: + int f(); + int vg(); + int vv(); + int e; +}; + +D dd; +D* ppd = ⅆ +AD* pAd = ⅆ + +A a; +B b; +C c; +D d; +E e; +V v; +VB vb; + + +A* pAa = &a; +A* pAe = &e; + +B* pBe = &e; + +D* pDd = &d; +D* pDe = &e; + +V* pVa = &a; +V* pVv = &v; +V* pVe = &e; +V* pVd = &d; + +AD* pADe = &e; + +E* pEe = &e; + +VB* pVB = &vb; + +void init() +{ + a.vb = 1; + b.vb = 2; + c.vb = 3; + d.vb = 4; + e.vb = 5; + v.vb = 6; + vb.vb = 7; + + d.d = 1; + e.d = 2; +} + +extern "C" printf(const char *, ...); + +int all_count = 0; +int failed_count = 0; + +#define TEST(EXPR, EXPECTED) \ + ret = EXPR; \ + if (ret != EXPECTED) {\ + printf("Failed %s is %d, should be %d!\n", #EXPR, ret, EXPECTED); \ + failed_count++; } \ + all_count++; + +int ret; + +void test_calls() +{ + TEST(pAe->f(), 20); + TEST(pAa->f(), 1); + + TEST(pDe->vg(), 202); + TEST(pADe->vg(), 202); + TEST(pDd->vg(), 101); + + TEST(pEe->vvb(), 411); + + TEST(pVB->vvb(), 407); + + TEST(pBe->vvb(), 411); + TEST(pDe->vvb(), 411); + + TEST(pEe->vd(), 282); + TEST(pEe->fvb(), 311); + + TEST(pEe->D::vg(), 102); + printf("Did %d tests, of which %d failed.\n", all_count, failed_count); +} + +int main() +{ + + init(); + + e.w = 7; + e.vb = 11; + + test_calls(); + return 0; + +} + +int A::f() {return 1;} +int B::f() {return 2;} +void D::s() {} +int E::f() {return 20;} +int D::vg() {return 100+d;} +int E::vg() {return 200+d;} +int V::f() {return 600+w;} +int V::vv() {return 400+w;} +int E::vv() {return 450+w;} +int D::fd() {return 250+d;} +int D::vd() {return 280+d;} +int VB::fvb() {return 300+vb;} +int VB::vvb() {return 400+vb;} diff --git a/gdb/testsuite/gdb.hp/watchpoint-hp.c b/gdb/testsuite/gdb.hp/watchpoint-hp.c new file mode 100644 index 0000000000..7336fe2bec --- /dev/null +++ b/gdb/testsuite/gdb.hp/watchpoint-hp.c @@ -0,0 +1,166 @@ +#include +/* + * Since using watchpoints can be very slow, we have to take some pains to + * ensure that we don't run too long with them enabled or we run the risk + * of having the test timeout. To help avoid this, we insert some marker + * functions in the execution stream so we can set breakpoints at known + * locations, without worrying about invalidating line numbers by changing + * this file. We use null bodied functions are markers since gdb does + * not support breakpoints at labeled text points at this time. + * + * One place we need is a marker for when we start executing our tests + * instructions rather than any process startup code, so we insert one + * right after entering main(). Another is right before we finish, before + * we start executing any process termination code. + * + * Another problem we have to guard against, at least for the test + * suite, is that we need to ensure that the line that causes the + * watchpoint to be hit is still the current line when gdb notices + * the hit. Depending upon the specific code generated by the compiler, + * the instruction after the one that triggers the hit may be part of + * the same line or part of the next line. Thus we ensure that there + * are always some instructions to execute on the same line after the + * code that should trigger the hit. + */ + +int count = -1; +int ival1 = -1; +int ival2 = -1; +int ival3 = -1; +int ival4 = -1; +int ival5 = -1; +char buf[10]; +struct foo +{ + int val; +}; +struct foo struct1, struct2, *ptr1, *ptr2; + +int doread = 0; + +void marker1 () +{ +} + +void marker2 () +{ +} + +void marker4 () +{ +} + +void marker5 () +{ +} + +void marker6 () +{ +} + +void recurser (x) + int x; +{ + int local_x; + + if (x > 0) + recurser (x-1); + local_x = x; +} + +void +func2 () +{ + int local_a; + static int static_b; + + ival5++; + local_a = ival5; + static_b = local_a; +} + +int +func1 () +{ + /* The point of this is that we will set a breakpoint at this call. + + Then, if DECR_PC_AFTER_BREAK equals the size of a function call + instruction (true on a sun3 if this is gcc-compiled--FIXME we + should use asm() to make it work for any compiler, present or + future), then we will end up branching to the location just after + the breakpoint. And we better not confuse that with hitting the + breakpoint. */ + func2 (); + return 73; +} + +int main () +{ + struct1.val = 1; + struct2.val = 2; + ptr1 = &struct1; + ptr2 = &struct2; + marker1 (); + func1 (); + for (count = 0; count < 4; count++) { + ival1 = count; + ival3 = count; ival4 = count; + } + ival1 = count; /* Outside loop */ + ival2 = count; + ival3 = count; ival4 = count; + marker2 (); + if (doread) + { + static char msg[] = "type stuff for buf now:"; + write (1, msg, sizeof (msg) - 1); + read (0, &buf[0], 5); + } + marker4 (); + + /* We have a watchpoint on ptr1->val. It should be triggered if + ptr1's value changes. */ + ptr1 = ptr2; + + /* This should not trigger the watchpoint. If it does, then we + used the wrong value chain to re-insert the watchpoints or we + are not evaluating the watchpoint expression correctly. */ + struct1.val = 5; + marker5 (); + + /* We have a watchpoint on ptr1->val. It should be triggered if + ptr1's value changes. */ + ptr1 = ptr2; + + /* This should not trigger the watchpoint. If it does, then we + used the wrong value chain to re-insert the watchpoints or we + are not evaluating the watchpoint expression correctly. */ + struct1.val = 5; + marker5 (); + + /* We're going to watch locals of func2, to see that out-of-scope + watchpoints are detected and properly deleted. + */ + marker6 (); + + /* This invocation is used for watches of a single + local variable. */ + func2 (); + + /* This invocation is used for watches of an expression + involving a local variable. */ + func2 (); + + /* This invocation is used for watches of a static + (non-stack-based) local variable. */ + func2 (); + + /* This invocation is used for watches of a local variable + when recursion happens. + */ + marker6 (); + recurser (2); + + marker6 (); + return 0; +} diff --git a/gdb/testsuite/gdb.hp/xdb.c b/gdb/testsuite/gdb.hp/xdb.c new file mode 100644 index 0000000000..e3e3fc23e9 --- /dev/null +++ b/gdb/testsuite/gdb.hp/xdb.c @@ -0,0 +1,20 @@ +#include + +int callee( x ) +int x; +{ + int y = x * x; + return (y - 2); +} + +main() +{ + int i; + for (i = 1; i < 10; i++) + { + printf( "%d ", callee( i )); + + } + printf( " Goodbye!\n" ); + +} diff --git a/gdb/testsuite/gdb.hp/xdb0.c b/gdb/testsuite/gdb.hp/xdb0.c new file mode 100644 index 0000000000..fa5c76f741 --- /dev/null +++ b/gdb/testsuite/gdb.hp/xdb0.c @@ -0,0 +1,42 @@ +#include "xdb0.h" + +main () +{ + int x; +#ifdef usestubs + set_debug_traps(); + breakpoint(); +#endif + x = 0; + foo (x++); + foo (x++); + foo (x++); + foo (x++); + foo (x++); + foo (x++); + foo (x++); + foo (x++); + foo (x++); + foo (x++); + foo (x++); + foo (x++); + foo (x++); + foo (x++); + foo (x++); + foo (x++); + foo (x++); + foo (x++); + foo (x++); + foo (x++); + foo (x++); + foo (x++); + foo (x++); + foo (x++); + foo (x++); +} + +static void +unused () +{ + /* Not used for anything */ +} diff --git a/gdb/testsuite/gdb.hp/xdb0.h b/gdb/testsuite/gdb.hp/xdb0.h new file mode 100644 index 0000000000..c4d337c677 --- /dev/null +++ b/gdb/testsuite/gdb.hp/xdb0.h @@ -0,0 +1,36 @@ +/* An include file that actually causes code to be generated in the + including file. This is known to cause problems on some systems. */ + +static void +foo (x) +int x; +{ + bar (x++); + bar (x++); + bar (x++); + bar (x++); + bar (x++); + bar (x++); + bar (x++); + bar (x++); + bar (x++); + bar (x++); + bar (x++); + bar (x++); + bar (x++); + bar (x++); + bar (x++); + bar (x++); + bar (x++); + bar (x++); + bar (x++); + bar (x++); + bar (x++); + bar (x++); + bar (x++); + bar (x++); + bar (x++); + bar (x++); + bar (x++); + bar (x++); +} diff --git a/gdb/testsuite/gdb.hp/xdb1.c b/gdb/testsuite/gdb.hp/xdb1.c new file mode 100644 index 0000000000..51632b94d0 --- /dev/null +++ b/gdb/testsuite/gdb.hp/xdb1.c @@ -0,0 +1,33 @@ +void +bar (x) +int x; +{ + printf ("%d\n", x); + + long_line (); +} + +static void +unused () +{ + /* Not used for anything */ +} + + +/* This routine has a very long line that will break searching in older + versions of GDB. */ + +long_line () +{ + oof (67); + + oof (6789); + + oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* 5 */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* 10 */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* 15 */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* 20 */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* 25 */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* 30 */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* 35 */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* 40 */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* 45 */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* 50 */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* 55 */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* 60 */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* 65 */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (1234); /* 70 */ +} + +oof (n) + int n; +{ + return n + 1; +}