1 /* This testcase is part of GDB, the GNU debugger.
2 
3    Copyright 2002-2021 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 
25 typedef struct TEST_STRUCT {
26   char   memberc;
27   int    memberi;
28   float  memberf;
29   double memberd;
30 } test_struct;
31 
32 struct small_struct
33 {
34   int member;
35 };
36 
37 struct small_struct_b : public small_struct
38 {
39 };
40 
41 typedef int test_array [4];
42 
43 /* Global variables to be collected.  */
44 
45 char         globalc;
46 int          globali;
47 float        globalf;
48 double       globald;
49 test_struct  globalstruct;
50 test_struct *globalp;
51 int          globalarr[16];
52 small_struct g_smallstruct;
53 small_struct_b g_smallstruct_b;
54 
55 /* Strings.  */
56 
57 const char g_const_string[] = "hello world";
58 char g_string_unavail[sizeof (g_const_string)];
59 char g_string_partial[sizeof (g_const_string)];
60 const char *g_string_p;
61 
62 /* Used to check that <unavailable> is not the same as 0 in array
63    element repetitions.  */
64 
65 struct tuple
66 {
67   int a;
68   int b;
69 };
70 
71 struct 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.  */
88 int a;
89 int b;
90 int c;
91 
92 /* Random tests.  */
93 
94 struct StructA
95 {
96   int a, b;
97   int array[10000];
98   void *ptr;
99   int bitfield:1;
100 };
101 
102 struct 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 
113 int g_int;
114 int &g_ref = g_int;
115 
116 struct StructRef
117 {
StructRefStructRef118   StructRef (unsigned int val) : ref(d) {}
119 
clearStructRef120   void clear ()
121   {
122     d = 0;
123   }
124 
125   unsigned int d;
126   unsigned int &ref;
127 };
128 
129 struct StructB struct_b;
130 struct StructA StructB::static_struct_a;
131 
132 StructRef g_structref(0x12345678);
133 StructRef *g_structref_p = &g_structref;
134 
135 class Base
136 {
137 protected:
138   int x;
139 
140 public:
Base(void)141   Base(void) { x = 2; };
142 };
143 
144 class Middle: public virtual Base
145 {
146 protected:
147   int y;
148 
149 public:
Middle(void)150   Middle(void): Base() { y = 3; };
151 };
152 
153 class Derived: public virtual Middle {
154 protected:
155   int z;
156 
157 public:
Derived(void)158   Derived(void): Middle() { z = 4; };
159 };
160 
161 Derived derived_unavail;
162 Derived derived_partial;
163 Derived derived_whole;
164 
165 struct Virtual {
166   int z;
167 
~VirtualVirtual168   virtual ~Virtual() {}
169 };
170 
171 Virtual virtual_partial;
172 Virtual *virtualp = &virtual_partial;
173 
174 /* Test functions.  */
175 
176 static void
begin()177 begin ()	/* called before anything else */
178 {
179 }
180 
181 static void
end()182 end ()		/* called after everything else */
183 {
184 }
185 
186 /* Test (not) collecting args.  */
187 
188 int
args_test_func(char argc,int argi,float argf,double argd,test_struct argstruct,int argarray[4])189 args_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 
207 int
local_test_func()208 local_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 
236 int
reglocal_test_func()237 reglocal_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 
264 int
statlocal_test_func()265 statlocal_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 
308 int
globals_test_func()309 globals_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 
321 int
main(int argc,char ** argv,char ** envp)322 main (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