FreeCalypso > hg > freecalypso-tools
view rvinterf/ctracedec/decode.c @ 461:10e168596dfd
doc/SIM-hardware-debugging: article written
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Sun, 10 Feb 2019 20:40:56 +0000 |
parents | e7502631a0f9 |
children |
line wrap: on
line source
/* * 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); }