comparison rvinterf/ctracedec/decode.c @ 858:4c6e7ada647b

compressed trace decoder almost fully implemented
author Space Falcon <falcon@ivan.Harhan.ORG>
date Sat, 02 May 2015 08:08:26 +0000
parents
children
comparison
equal deleted inserted replaced
857:2768b4339275 858:4c6e7ada647b
1 /*
2 * This module implements the actual decoding of compressed traces.
3 */
4
5 #include <sys/types.h>
6 #include <stdio.h>
7 #include <ctype.h>
8 #include <string.h>
9 #include <strings.h>
10 #include <stdlib.h>
11
12 extern char *str2ind_tab_filename;
13 extern int str2ind_array_size;
14 extern char **str2ind_orig_strings;
15 extern char **str2ind_param_strings;
16
17 #define MAX_PRINTF_PARAMS 16
18
19 static int cindex, cindex_nchars;
20 static u_char param_bytes_array[256];
21 static int param_bytes_count;
22 static char *format_string, *param_type_string;
23 static int num_printf_params;
24 static u_long printf_params[MAX_PRINTF_PARAMS];
25 static char output_buf[2048];
26
27 decode_hex_digit(c)
28 {
29 if (isdigit(c))
30 return(c - '0');
31 else if (isupper(c))
32 return(c - 'A' + 10);
33 else
34 return(c - 'a' + 10);
35 }
36
37 static int
38 decode_idx_and_params(line)
39 char *line;
40 {
41 char *cp;
42 u_char *dp;
43
44 for (cp = line; isdigit(*cp); cp++)
45 ;
46 if (*cp && *cp != ' ')
47 return(-1);
48 cindex = atoi(line);
49 cindex_nchars = cp - line;
50 for (dp = param_bytes_array; *cp; ) {
51 if (*cp++ != ' ')
52 return(-1);
53 if (!isxdigit(cp[0]) || !isxdigit(cp[1]))
54 return(-1);
55 *dp++ = decode_hex_digit(cp[0]) << 4 | decode_hex_digit(cp[1]);
56 cp += 2;
57 }
58 param_bytes_count = dp - param_bytes_array;
59 return(0);
60 }
61
62 static void
63 decode_parameters(filename_for_errs, lineno_for_errs)
64 char *filename_for_errs;
65 {
66 int pi, type;
67 u_char *bp, *endp;
68
69 bp = param_bytes_array;
70 endp = bp + param_bytes_count;
71 for (pi = 0; pi < num_printf_params; pi++) {
72 type = param_type_string[pi];
73 switch (type) {
74 case 'c':
75 if (bp >= endp) {
76 wrong_param_byte_count: fprintf(stderr,
77 "%s line %d: wrong number of parameter bytes for %s entry #%d\n",
78 filename_for_errs, lineno_for_errs,
79 str2ind_tab_filename, cindex);
80 exit(1);
81 }
82 printf_params[pi] = *bp++;
83 continue;
84 case 'i':
85 case 'p':
86 case '*':
87 if (bp > endp - 4)
88 goto wrong_param_byte_count;
89 printf_params[pi] = (u_long) bp[0] |
90 (u_long) bp[1] << 8 |
91 (u_long) bp[2] << 16 |
92 (u_long) bp[3] << 24;
93 bp += 4;
94 continue;
95 case 's':
96 printf_params[pi] = (u_long) bp;
97 for (;;) {
98 if (bp >= endp) {
99 fprintf(stderr,
100 "%s line %d: unterminated string parameter in compressed trace\n",
101 filename_for_errs,
102 lineno_for_errs);
103 exit(1);
104 }
105 if (!*bp++)
106 break;
107 }
108 continue;
109 default:
110 fprintf(stderr,
111 "%s entry #%d: parameter type \'%c\' not supported\n",
112 str2ind_tab_filename, cindex, type);
113 exit(1);
114 }
115 }
116 if (bp != endp)
117 goto wrong_param_byte_count;
118 }
119
120 process_ctrace_line(line, cindex_offset, filename_for_errs, lineno_for_errs)
121 char *line, *filename_for_errs;
122 {
123 if (decode_idx_and_params(line + cindex_offset) < 0) {
124 fprintf(stderr,
125 "%s line %d: unable to decode compressed trace line\n",
126 filename_for_errs, lineno_for_errs);
127 exit(1);
128 }
129 if (cindex >= str2ind_array_size) {
130 fprintf(stderr,
131 "%s line %d: index %d exceeds the range of %s\n",
132 filename_for_errs, lineno_for_errs, cindex,
133 str2ind_tab_filename);
134 exit(1);
135 }
136 format_string = str2ind_orig_strings[cindex];
137 param_type_string = str2ind_param_strings[cindex];
138 num_printf_params = strlen(param_type_string);
139 if (num_printf_params > MAX_PRINTF_PARAMS) {
140 fprintf(stderr,
141 "error: entry #%d in %s has too many parameters\n",
142 cindex, str2ind_tab_filename);
143 exit(1);
144 }
145 decode_parameters(filename_for_errs, lineno_for_errs);
146 ind2str_doprnt(format_string, printf_params, output_buf);
147 printf("%.*s \"%s\"\n", cindex_offset + cindex_nchars, line,
148 output_buf);
149 return(0);
150 }