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