1/* This testcase is part of GDB, the GNU debugger.
2
3   Copyright 2002-2020 Free Software Foundation, Inc.
4
5   This program is free software; you can redistribute it and/or modify
6   it under the terms of the GNU General Public License as published by
7   the Free Software Foundation; either version 3 of the License, or
8   (at your option) any later version.
9
10   This program is distributed in the hope that it will be useful,
11   but WITHOUT ANY WARRANTY; without even the implied warranty of
12   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13   GNU General Public License for more details.
14
15   You should have received a copy of the GNU General Public License
16   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
17
18#include <stdlib.h>
19#include <string.h>
20
21/* Test program partial trace data visualization.  */
22
23/* Typedefs.  */
24
25typedef struct TEST_STRUCT {
26  char   memberc;
27  int    memberi;
28  float  memberf;
29  double memberd;
30} test_struct;
31
32struct small_struct
33{
34  int member;
35};
36
37struct small_struct_b : public small_struct
38{
39};
40
41typedef int test_array [4];
42
43/* Global variables to be collected.  */
44
45char         globalc;
46int          globali;
47float        globalf;
48double       globald;
49test_struct  globalstruct;
50test_struct *globalp;
51int          globalarr[16];
52small_struct g_smallstruct;
53small_struct_b g_smallstruct_b;
54
55/* Strings.  */
56
57const char g_const_string[] = "hello world";
58char g_string_unavail[sizeof (g_const_string)];
59char g_string_partial[sizeof (g_const_string)];
60const char *g_string_p;
61
62/* Used to check that <unavailable> is not the same as 0 in array
63   element repetitions.  */
64
65struct tuple
66{
67  int a;
68  int b;
69};
70
71struct tuple tarray[8];
72
73/* Test for overcollection.  GDB used to merge memory ranges to
74   collect if they were close enough --- say, collect `a' and 'c'
75   below, and you'd get 'b' as well.  This had been presumably done to
76   cater for some target's inefficient trace buffer layout, but it is
77   really not GDB's business to assume how the target manages its
78   buffer.  If the target wants to overcollect, that's okay, since it
79   knows what is and what isn't safe to touch (think memory mapped
80   registers), and knows it's buffer layout.
81
82   The test assumes these three variables are laid out consecutively
83   in memory.  Unfortunately, we can't use an array instead, since the
84   agent expression generator does not even do constant folding,
85   meaning that anything that's more complicated than collecting a
86   global will generate an agent expression action to evaluate on the
87   target, instead of a simple "collect memory" action.  */
88int a;
89int b;
90int c;
91
92/* Random tests.  */
93
94struct StructA
95{
96  int a, b;
97  int array[10000];
98  void *ptr;
99  int bitfield:1;
100};
101
102struct StructB
103{
104  int d, ef;
105  StructA struct_a;
106  int s:1;
107  static StructA static_struct_a;
108  const char *string;
109};
110
111/* References.  */
112
113int g_int;
114int &g_ref = g_int;
115
116struct StructRef
117{
118  StructRef (unsigned int val) : ref(d) {}
119
120  void clear ()
121  {
122    d = 0;
123  }
124
125  unsigned int d;
126  unsigned int &ref;
127};
128
129struct StructB struct_b;
130struct StructA StructB::static_struct_a;
131
132StructRef g_structref(0x12345678);
133StructRef *g_structref_p = &g_structref;
134
135class Base
136{
137protected:
138  int x;
139
140public:
141  Base(void) { x = 2; };
142};
143
144class Middle: public virtual Base
145{
146protected:
147  int y;
148
149public:
150  Middle(void): Base() { y = 3; };
151};
152
153class Derived: public virtual Middle {
154protected:
155  int z;
156
157public:
158  Derived(void): Middle() { z = 4; };
159};
160
161Derived derived_unavail;
162Derived derived_partial;
163Derived derived_whole;
164
165struct Virtual {
166  int z;
167
168  virtual ~Virtual() {}
169};
170
171Virtual virtual_partial;
172Virtual *virtualp = &virtual_partial;
173
174/* Test functions.  */
175
176static void
177begin ()	/* called before anything else */
178{
179}
180
181static void
182end ()		/* called after everything else */
183{
184}
185
186/* Test (not) collecting args.  */
187
188int
189args_test_func (char   argc,
190		int    argi,
191		float  argf,
192		double argd,
193		test_struct argstruct,
194		int argarray[4])
195{
196  int i;
197
198  i =  (int) argc + argi + argf + argd + argstruct.memberi + argarray[1];
199
200  return i;
201}
202
203/* Test (not) collecting array args.  */
204
205/* Test (not) collecting locals.  */
206
207int
208local_test_func ()
209{
210  char        locc  = 11;
211  int         loci  = 12;
212  float       locf  = 13.3;
213  double      locd  = 14.4;
214  test_struct locst;
215  int         locar[4];
216  int         i;
217  struct localstruct {} locdefst;
218
219  locst.memberc  = 15;
220  locst.memberi  = 16;
221  locst.memberf  = 17.7;
222  locst.memberd  = 18.8;
223  locar[0] = 121;
224  locar[1] = 122;
225  locar[2] = 123;
226  locar[3] = 124;
227
228  i = /* set local_test_func tracepoint here */
229    (int) locc + loci + locf + locd + locst.memberi + locar[1];
230
231  return i;
232}
233
234/* Test collecting register locals.  */
235
236int
237reglocal_test_func ()
238{
239  register char        locc = 11;
240  register int         loci = 12;
241  register float       locf = 13.3;
242  register double      locd = 14.4;
243  register test_struct locst;
244  register int         locar[4];
245  int                  i;
246
247  locst.memberc  = 15;
248  locst.memberi  = 16;
249  locst.memberf  = 17.7;
250  locst.memberd  = 18.8;
251  locar[0] = 121;
252  locar[1] = 122;
253  locar[2] = 123;
254  locar[3] = 124;
255
256  i = /* set reglocal_test_func tracepoint here */
257    (int) locc + loci + locf + locd + locst.memberi + locar[1];
258
259  return i;
260}
261
262/* Test collecting static locals.  */
263
264int
265statlocal_test_func ()
266{
267  static   char        locc;
268  static   int         loci;
269  static   float       locf;
270  static   double      locd;
271  static   test_struct locst;
272  static   int         locar[4];
273  int                  i;
274
275  locc = 11;
276  loci = 12;
277  locf = 13.3;
278  locd = 14.4;
279  locst.memberc = 15;
280  locst.memberi = 16;
281  locst.memberf = 17.7;
282  locst.memberd = 18.8;
283  locar[0] = 121;
284  locar[1] = 122;
285  locar[2] = 123;
286  locar[3] = 124;
287
288  i = /* set statlocal_test_func tracepoint here */
289    (int) locc + loci + locf + locd + locst.memberi + locar[1];
290
291  /* Set static locals back to zero so collected values are clearly special. */
292  locc = 0;
293  loci = 0;
294  locf = 0;
295  locd = 0;
296  locst.memberc = 0;
297  locst.memberi = 0;
298  locst.memberf = 0;
299  locst.memberd = 0;
300  locar[0] = 0;
301  locar[1] = 0;
302  locar[2] = 0;
303  locar[3] = 0;
304
305  return i;
306}
307
308int
309globals_test_func ()
310{
311  int i = 0;
312
313  i += globalc + globali + globalf + globald;
314  i += globalstruct.memberc + globalstruct.memberi;
315  i += globalstruct.memberf + globalstruct.memberd;
316  i += globalarr[1];
317
318  return i;	/* set globals_test_func tracepoint here */
319}
320
321int
322main (int argc, char **argv, char **envp)
323{
324  int         i = 0;
325  test_struct mystruct;
326  int         myarray[4];
327
328  begin ();
329  /* Assign collectable values to global variables.  */
330  globalc = 71;
331  globali = 72;
332  globalf = 73.3;
333  globald = 74.4;
334  globalstruct.memberc = 81;
335  globalstruct.memberi = 82;
336  globalstruct.memberf = 83.3;
337  globalstruct.memberd = 84.4;
338  globalp = &globalstruct;
339
340  for (i = 0; i < 15; i++)
341    globalarr[i] = i;
342
343  mystruct.memberc = 101;
344  mystruct.memberi = 102;
345  mystruct.memberf = 103.3;
346  mystruct.memberd = 104.4;
347  myarray[0] = 111;
348  myarray[1] = 112;
349  myarray[2] = 113;
350  myarray[3] = 114;
351
352  g_int = 123;
353  memset (&struct_b, 0xaa, sizeof struct_b);
354  memset (&struct_b.static_struct_a, 0xaa, sizeof struct_b.static_struct_a);
355  struct_b.string = g_const_string;
356  memcpy (g_string_unavail, g_const_string, sizeof (g_const_string));
357  memcpy (g_string_partial, g_const_string, sizeof (g_const_string));
358  g_string_p = g_const_string;
359  a = 1; b = 2; c = 3;
360
361  /* Call test functions, so they can be traced and data collected.  */
362  i = 0;
363  i += args_test_func (1, 2, 3.3, 4.4, mystruct, myarray);
364  i += local_test_func ();
365  i += reglocal_test_func ();
366  i += statlocal_test_func ();
367  i += globals_test_func ();
368
369  /* Set 'em back to zero, so that the collected values will be
370     distinctly different from the "realtime" (end of test) values.  */
371
372  globalc = 0;
373  globali = 0;
374  globalf = 0;
375  globald = 0;
376  globalstruct.memberc = 0;
377  globalstruct.memberi = 0;
378  globalstruct.memberf = 0;
379  globalstruct.memberd = 0;
380  globalp = 0;
381  for (i = 0; i < 15; i++)
382    globalarr[i] = 0;
383
384  memset (&struct_b, 0, sizeof struct_b);
385  memset (&struct_b.static_struct_a, 0, sizeof struct_b.static_struct_a);
386  struct_b.string = NULL;
387  memset (g_string_unavail, 0, sizeof (g_string_unavail));
388  memset (g_string_partial, 0, sizeof (g_string_partial));
389  g_string_p = NULL;
390
391  a = b = c = 0;
392
393  g_int = 0;
394
395  g_structref.clear ();
396  g_structref_p = NULL;
397
398  end ();
399  return 0;
400}
401