1 /*
2  * Copyright (c) 2014, STMicroelectronics International N.V.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  * 1. Redistributions of source code must retain the above copyright notice,
9  * this list of conditions and the following disclaimer.
10  *
11  * 2. Redistributions in binary form must reproduce the above copyright notice,
12  * this list of conditions and the following disclaimer in the documentation
13  * and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
19  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25  * POSSIBILITY OF SUCH DAMAGE.
26  */
27 #include <stdio.h>
28 #include <stdarg.h>
29 #include <stdint.h>
30 #include <ctype.h>
31 #include <pthread.h>
32 
33 #include <unistd.h>
34 #include <sys/syscall.h>
35 #include <sys/types.h>
36 
37 #include "teec_trace.h"
38 
39 #define MIN(x, y) (((x) < (y)) ? (x) : (y))
40 
41 /*
42  * The length of the prefix is 37, for example it looks like this:
43  * P = Prefix
44  * M = Message
45  * F = Function name
46  * L = Line number
47  * PPPP: MMMMM [FFFFFFFFFFFFFFF : LLLLL]
48  */
49 #define MAX_PRINT_SIZE 256
50 
51 #ifdef TEEC_LOG_FILE
log_to_file(const char * buffer)52 static void log_to_file(const char *buffer)
53 {
54 	FILE *log_file = fopen(TEEC_LOG_FILE, "a");
55 
56 	if (log_file != NULL) {
57 		fprintf(log_file, "%s", buffer);
58 		fclose(log_file);
59 		log_file = NULL;
60 	}
61 }
62 #else
63 #define log_to_file(buffer)
64 #endif
65 
66 static const char * const trace_level_strings[] = {
67 	"", "ERR", "INF", "DBG", "FLW"
68 };
69 
_dprintf(const char * function,int line,int level,const char * prefix,const char * fmt,...)70 void _dprintf(const char *function, int line, int level, const char *prefix,
71 	      const char *fmt, ...)
72 {
73 	char msg[MAX_PRINT_SIZE];
74 	int n = 0;
75 	va_list ap;
76 
77 	if (function) {
78 		int thread_id = syscall(SYS_gettid);
79 
80 		n = snprintf(msg, sizeof(msg), "%s [%d] %s:%s:%d: ",
81 			trace_level_strings[level], thread_id, prefix,
82 			function, line);
83 		if (n < 0)
84 			return;
85 	}
86 
87 	if ((size_t)n < sizeof(msg)) {
88 		va_start(ap, fmt);
89 		n = vsnprintf(msg + n, sizeof(msg) - n, fmt, ap);
90 		va_end(ap);
91 		if (n < 0)
92 			return;
93 	}
94 
95 	fprintf(stdout, "%s", msg);
96 	log_to_file(msg);
97 }
98 
99 #if (defined(DEBUGLEVEL_3) || defined(DEBUGLEVEL_true) || defined(DEBUGLEVEL_4))
dump_buffer(const char * bname,const uint8_t * buffer,size_t blen)100 void dump_buffer(const char *bname, const uint8_t *buffer, size_t blen)
101 {
102 	fprintf(stderr, "#### %s\n", bname);
103 
104 	while (blen > 0) {
105 		size_t n = 0;
106 
107 		for (n = 0; n < 16; n++) {
108 			if (n < blen)
109 				fprintf(stderr, "%02x ", (int)buffer[n]);
110 			else
111 				fprintf(stderr, "   ");
112 
113 			if (n == 7)
114 				fprintf(stderr, " ");
115 		}
116 
117 		fprintf(stderr, " |");
118 
119 		for (n = 0; n < 16; n++) {
120 			if (n < blen) {
121 				if (isprint(buffer[n]))
122 					fprintf(stderr, "%c", (int)buffer[n]);
123 				else
124 					fprintf(stderr, ".");
125 			}
126 		}
127 
128 		fprintf(stderr, "|\n");
129 
130 		blen -= MIN(blen, 16);
131 		buffer += 16;
132 	}
133 }
134 #else
dump_buffer(const char * bname,const uint8_t * buffer,size_t blen)135 void dump_buffer(const char *bname, const uint8_t *buffer, size_t blen)
136 {
137 	(void)bname;
138 	(void)buffer;
139 	(void)blen;
140 }
141 #endif
142