FreeCalypso > hg > freecalypso-sw
diff 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 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rvinterf/ctracedec/decode.c Sat May 02 08:08:26 2015 +0000 @@ -0,0 +1,150 @@ +/* + * This module implements the actual decoding of compressed traces. + */ + +#include <sys/types.h> +#include <stdio.h> +#include <ctype.h> +#include <string.h> +#include <strings.h> +#include <stdlib.h> + +extern char *str2ind_tab_filename; +extern int str2ind_array_size; +extern char **str2ind_orig_strings; +extern char **str2ind_param_strings; + +#define MAX_PRINTF_PARAMS 16 + +static int cindex, cindex_nchars; +static u_char param_bytes_array[256]; +static int param_bytes_count; +static char *format_string, *param_type_string; +static int num_printf_params; +static u_long printf_params[MAX_PRINTF_PARAMS]; +static char output_buf[2048]; + +decode_hex_digit(c) +{ + if (isdigit(c)) + return(c - '0'); + else if (isupper(c)) + return(c - 'A' + 10); + else + return(c - 'a' + 10); +} + +static int +decode_idx_and_params(line) + char *line; +{ + char *cp; + u_char *dp; + + for (cp = line; isdigit(*cp); cp++) + ; + if (*cp && *cp != ' ') + return(-1); + cindex = atoi(line); + cindex_nchars = cp - line; + for (dp = param_bytes_array; *cp; ) { + if (*cp++ != ' ') + return(-1); + if (!isxdigit(cp[0]) || !isxdigit(cp[1])) + return(-1); + *dp++ = decode_hex_digit(cp[0]) << 4 | decode_hex_digit(cp[1]); + cp += 2; + } + param_bytes_count = dp - param_bytes_array; + return(0); +} + +static void +decode_parameters(filename_for_errs, lineno_for_errs) + char *filename_for_errs; +{ + int pi, type; + u_char *bp, *endp; + + bp = param_bytes_array; + endp = bp + param_bytes_count; + for (pi = 0; pi < num_printf_params; pi++) { + type = param_type_string[pi]; + switch (type) { + case 'c': + if (bp >= endp) { +wrong_param_byte_count: fprintf(stderr, + "%s line %d: wrong number of parameter bytes for %s entry #%d\n", + filename_for_errs, lineno_for_errs, + str2ind_tab_filename, cindex); + exit(1); + } + printf_params[pi] = *bp++; + continue; + case 'i': + case 'p': + case '*': + if (bp > endp - 4) + goto wrong_param_byte_count; + printf_params[pi] = (u_long) bp[0] | + (u_long) bp[1] << 8 | + (u_long) bp[2] << 16 | + (u_long) bp[3] << 24; + bp += 4; + continue; + case 's': + printf_params[pi] = (u_long) bp; + for (;;) { + if (bp >= endp) { + fprintf(stderr, + "%s line %d: unterminated string parameter in compressed trace\n", + filename_for_errs, + lineno_for_errs); + exit(1); + } + if (!*bp++) + break; + } + continue; + default: + fprintf(stderr, + "%s entry #%d: parameter type \'%c\' not supported\n", + str2ind_tab_filename, cindex, type); + exit(1); + } + } + if (bp != endp) + goto wrong_param_byte_count; +} + +process_ctrace_line(line, cindex_offset, filename_for_errs, lineno_for_errs) + char *line, *filename_for_errs; +{ + if (decode_idx_and_params(line + cindex_offset) < 0) { + fprintf(stderr, + "%s line %d: unable to decode compressed trace line\n", + filename_for_errs, lineno_for_errs); + exit(1); + } + if (cindex >= str2ind_array_size) { + fprintf(stderr, + "%s line %d: index %d exceeds the range of %s\n", + filename_for_errs, lineno_for_errs, cindex, + str2ind_tab_filename); + exit(1); + } + format_string = str2ind_orig_strings[cindex]; + param_type_string = str2ind_param_strings[cindex]; + num_printf_params = strlen(param_type_string); + if (num_printf_params > MAX_PRINTF_PARAMS) { + fprintf(stderr, + "error: entry #%d in %s has too many parameters\n", + cindex, str2ind_tab_filename); + exit(1); + } + decode_parameters(filename_for_errs, lineno_for_errs); + ind2str_doprnt(format_string, printf_params, output_buf); + printf("%.*s \"%s\"\n", cindex_offset + cindex_nchars, line, + output_buf); + return(0); +}