Commit | Line | Data |
---|---|---|
14a1aa17 YQ |
1 | /* This testcase is part of GDB, the GNU debugger. |
2 | ||
ecd75fc8 | 3 | Copyright 2010-2014 Free Software Foundation, Inc. |
14a1aa17 YQ |
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 | ||
00bf0b85 SS |
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 | ||
27 | char spbuf[200]; | |
28 | ||
29 | char trbuf[1000]; | |
30 | char *trptr; | |
31 | char *tfsizeptr; | |
32 | ||
3f1175a9 PA |
33 | /* These globals are put in the trace buffer. */ |
34 | ||
00bf0b85 SS |
35 | int testglob = 31415; |
36 | ||
fce3c1f0 SS |
37 | int testglob2 = 271828; |
38 | ||
3f1175a9 PA |
39 | /* But these below are not. */ |
40 | ||
fce3c1f0 SS |
41 | const int constglob = 10000; |
42 | ||
3f1175a9 PA |
43 | int nonconstglob = 14124; |
44 | ||
00bf0b85 SS |
45 | int |
46 | start_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 | ||
64 | void | |
65 | finish_trace_file (int fd) | |
66 | { | |
67 | close (fd); | |
68 | } | |
69 | ||
fce3c1f0 SS |
70 | |
71 | void | |
72 | add_memory_block (char *addr, int size) | |
73 | { | |
74 | short short_x; | |
ba4a8bdd | 75 | unsigned long long ll_x; |
fce3c1f0 SS |
76 | |
77 | *((char *) trptr) = 'M'; | |
78 | trptr += 1; | |
ba4a8bdd YQ |
79 | ll_x = (unsigned long) addr; |
80 | memcpy (trptr, &ll_x, sizeof (unsigned long long)); | |
81 | trptr += sizeof (unsigned long long); | |
fce3c1f0 SS |
82 | short_x = size; |
83 | memcpy (trptr, &short_x, 2); | |
84 | trptr += 2; | |
85 | memcpy (trptr, addr, size); | |
86 | trptr += size; | |
87 | } | |
88 | ||
00bf0b85 | 89 | void |
6c28cbf2 | 90 | write_basic_trace_file (void) |
00bf0b85 | 91 | { |
6c28cbf2 SS |
92 | int fd, int_x; |
93 | short short_x; | |
00bf0b85 | 94 | |
32cfb09d | 95 | fd = start_trace_file (TFILE_DIR "tfile-basic.tf"); |
00bf0b85 SS |
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. */ | |
6c28cbf2 | 111 | /* FIXME need a portable way to print function address in hex */ |
00bf0b85 SS |
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. */ | |
6c28cbf2 SS |
122 | /* (Encapsulate better if we're going to do lots of this; note that |
123 | buffer endianness is the target program's enddianness.) */ | |
00bf0b85 | 124 | trptr = trbuf; |
6c28cbf2 SS |
125 | short_x = 1; |
126 | memcpy (trptr, &short_x, 2); | |
127 | trptr += 2; | |
00bf0b85 | 128 | tfsizeptr = trptr; |
6c28cbf2 | 129 | trptr += 4; |
fce3c1f0 SS |
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); | |
00bf0b85 | 134 | /* Go back and patch in the frame size. */ |
6c28cbf2 SS |
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 | ||
610197fd PA |
147 | /* Convert number NIB to a hex digit. */ |
148 | ||
149 | static int | |
150 | tohex (int nib) | |
151 | { | |
152 | if (nib < 10) | |
153 | return '0' + nib; | |
154 | else | |
155 | return 'a' + nib - 10; | |
156 | } | |
157 | ||
158 | int | |
159 | bin2hex (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 | ||
6c28cbf2 SS |
172 | void |
173 | write_error_trace_file (void) | |
174 | { | |
175 | int fd; | |
610197fd PA |
176 | const char made_up[] = "made-up error"; |
177 | int len = sizeof (made_up) - 1; | |
178 | char *hex = alloca (len * 2 + 1); | |
6c28cbf2 | 179 | |
32cfb09d | 180 | fd = start_trace_file (TFILE_DIR "tfile-error.tf"); |
6c28cbf2 SS |
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 | ||
610197fd PA |
190 | bin2hex (made_up, hex, len); |
191 | ||
6c28cbf2 | 192 | /* Dump trace status, in the general form of the qTstatus reply. */ |
610197fd PA |
193 | snprintf (spbuf, sizeof spbuf, |
194 | "status 0;" | |
195 | "terror:%s:1;" | |
196 | "tframes:0;tcreated:0;tfree:100;tsize:1000\n", | |
197 | hex); | |
6c28cbf2 SS |
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; | |
00bf0b85 SS |
213 | |
214 | /* Write end of tracebuffer marker. */ | |
6c28cbf2 SS |
215 | memset (trptr, 0, 6); |
216 | trptr += 6; | |
00bf0b85 SS |
217 | |
218 | write (fd, trbuf, trptr - trbuf); | |
219 | ||
220 | finish_trace_file (fd); | |
221 | } | |
222 | ||
223 | void | |
224 | done_making_trace_files (void) | |
225 | { | |
226 | } | |
227 | ||
228 | int | |
229 | main (int argc, char **argv, char **envp) | |
230 | { | |
231 | write_basic_trace_file (); | |
232 | ||
6c28cbf2 SS |
233 | write_error_trace_file (); |
234 | ||
00bf0b85 SS |
235 | done_making_trace_files (); |
236 | ||
237 | return 0; | |
238 | } | |
239 |