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