tfile.exp: Test printing a non-const global that is not covered by the trace frame...
[binutils-gdb.git] / gdb / testsuite / gdb.trace / tfile.c
1 /* This program does two things; it generates valid trace files, and
2 it can also be traced so as to test trace file creation from
3 GDB. */
4
5 #include <stdio.h>
6 #include <string.h>
7 #include <fcntl.h>
8 #include <sys/stat.h>
9
10 char spbuf[200];
11
12 char trbuf[1000];
13 char *trptr;
14 char *tfsizeptr;
15
16 /* These globals are put in the trace buffer. */
17
18 int testglob = 31415;
19
20 int testglob2 = 271828;
21
22 /* But these below are not. */
23
24 const int constglob = 10000;
25
26 int nonconstglob = 14124;
27
28 int
29 start_trace_file (char *filename)
30 {
31 int fd;
32
33 fd = open (filename, O_WRONLY|O_CREAT|O_APPEND,
34 S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
35
36 if (fd < 0)
37 return fd;
38
39 /* Write a file header, with a high-bit-set char to indicate a
40 binary file, plus a hint as what this file is, and a version
41 number in case of future needs. */
42 write (fd, "\x7fTRACE0\n", 8);
43
44 return fd;
45 }
46
47 void
48 finish_trace_file (int fd)
49 {
50 close (fd);
51 }
52
53
54 void
55 add_memory_block (char *addr, int size)
56 {
57 short short_x;
58 unsigned long long ll_x;
59
60 *((char *) trptr) = 'M';
61 trptr += 1;
62 ll_x = (unsigned long) addr;
63 memcpy (trptr, &ll_x, sizeof (unsigned long long));
64 trptr += sizeof (unsigned long long);
65 short_x = size;
66 memcpy (trptr, &short_x, 2);
67 trptr += 2;
68 memcpy (trptr, addr, size);
69 trptr += size;
70 }
71
72 void
73 write_basic_trace_file (void)
74 {
75 int fd, int_x;
76 short short_x;
77
78 fd = start_trace_file ("basic.tf");
79
80 /* The next part of the file consists of newline-separated lines
81 defining status, tracepoints, etc. The section is terminated by
82 an empty line. */
83
84 /* Dump the size of the R (register) blocks in traceframes. */
85 snprintf (spbuf, sizeof spbuf, "R %x\n", 500 /* FIXME get from arch */);
86 write (fd, spbuf, strlen (spbuf));
87
88 /* Dump trace status, in the general form of the qTstatus reply. */
89 snprintf (spbuf, sizeof spbuf, "status 0;tstop:0;tframes:1;tcreated:1;tfree:100;tsize:1000\n");
90 write (fd, spbuf, strlen (spbuf));
91
92 /* Dump tracepoint definitions, in syntax similar to that used
93 for reconnection uploads. */
94 /* FIXME need a portable way to print function address in hex */
95 snprintf (spbuf, sizeof spbuf, "tp T1:%lx:E:0:0\n",
96 (long) &write_basic_trace_file);
97 write (fd, spbuf, strlen (spbuf));
98 /* (Note that we would only need actions defined if we wanted to
99 test tdump.) */
100
101 /* Empty line marks the end of the definition section. */
102 write (fd, "\n", 1);
103
104 /* Make up a simulated trace buffer. */
105 /* (Encapsulate better if we're going to do lots of this; note that
106 buffer endianness is the target program's enddianness.) */
107 trptr = trbuf;
108 short_x = 1;
109 memcpy (trptr, &short_x, 2);
110 trptr += 2;
111 tfsizeptr = trptr;
112 trptr += 4;
113 add_memory_block (&testglob, sizeof (testglob));
114 /* Divide a variable between two separate memory blocks. */
115 add_memory_block (&testglob2, 1);
116 add_memory_block (((char*) &testglob2) + 1, sizeof (testglob2) - 1);
117 /* Go back and patch in the frame size. */
118 int_x = trptr - tfsizeptr - sizeof (int);
119 memcpy (tfsizeptr, &int_x, 4);
120
121 /* Write end of tracebuffer marker. */
122 memset (trptr, 0, 6);
123 trptr += 6;
124
125 write (fd, trbuf, trptr - trbuf);
126
127 finish_trace_file (fd);
128 }
129
130 /* Convert number NIB to a hex digit. */
131
132 static int
133 tohex (int nib)
134 {
135 if (nib < 10)
136 return '0' + nib;
137 else
138 return 'a' + nib - 10;
139 }
140
141 int
142 bin2hex (const char *bin, char *hex, int count)
143 {
144 int i;
145
146 for (i = 0; i < count; i++)
147 {
148 *hex++ = tohex ((*bin >> 4) & 0xf);
149 *hex++ = tohex (*bin++ & 0xf);
150 }
151 *hex = 0;
152 return i;
153 }
154
155 void
156 write_error_trace_file (void)
157 {
158 int fd;
159 const char made_up[] = "made-up error";
160 int len = sizeof (made_up) - 1;
161 char *hex = alloca (len * 2 + 1);
162
163 fd = start_trace_file ("error.tf");
164
165 /* The next part of the file consists of newline-separated lines
166 defining status, tracepoints, etc. The section is terminated by
167 an empty line. */
168
169 /* Dump the size of the R (register) blocks in traceframes. */
170 snprintf (spbuf, sizeof spbuf, "R %x\n", 500 /* FIXME get from arch */);
171 write (fd, spbuf, strlen (spbuf));
172
173 bin2hex (made_up, hex, len);
174
175 /* Dump trace status, in the general form of the qTstatus reply. */
176 snprintf (spbuf, sizeof spbuf,
177 "status 0;"
178 "terror:%s:1;"
179 "tframes:0;tcreated:0;tfree:100;tsize:1000\n",
180 hex);
181 write (fd, spbuf, strlen (spbuf));
182
183 /* Dump tracepoint definitions, in syntax similar to that used
184 for reconnection uploads. */
185 /* FIXME need a portable way to print function address in hex */
186 snprintf (spbuf, sizeof spbuf, "tp T1:%lx:E:0:0\n",
187 (long) &write_basic_trace_file);
188 write (fd, spbuf, strlen (spbuf));
189 /* (Note that we would only need actions defined if we wanted to
190 test tdump.) */
191
192 /* Empty line marks the end of the definition section. */
193 write (fd, "\n", 1);
194
195 trptr = trbuf;
196
197 /* Write end of tracebuffer marker. */
198 memset (trptr, 0, 6);
199 trptr += 6;
200
201 write (fd, trbuf, trptr - trbuf);
202
203 finish_trace_file (fd);
204 }
205
206 void
207 done_making_trace_files (void)
208 {
209 }
210
211 int
212 main (int argc, char **argv, char **envp)
213 {
214 write_basic_trace_file ();
215
216 write_error_trace_file ();
217
218 done_making_trace_files ();
219
220 return 0;
221 }
222