xref: /aosp_15_r20/external/tpm2-tss/src/util/log.cpp (revision 758e9fba6fc9adbf15340f70c73baee7b168b1c9)
1*758e9fbaSOystein Eftevaag #ifdef HAVE_CONFIG_H
2*758e9fbaSOystein Eftevaag #include <config.h>
3*758e9fbaSOystein Eftevaag #endif
4*758e9fbaSOystein Eftevaag 
5*758e9fbaSOystein Eftevaag #include <string.h>
6*758e9fbaSOystein Eftevaag #include <stdio.h>
7*758e9fbaSOystein Eftevaag #include <stdarg.h>
8*758e9fbaSOystein Eftevaag #include <stdlib.h>
9*758e9fbaSOystein Eftevaag #include <ctype.h>
10*758e9fbaSOystein Eftevaag 
11*758e9fbaSOystein Eftevaag #define LOGMODULE log
12*758e9fbaSOystein Eftevaag #include "log.h"
13*758e9fbaSOystein Eftevaag 
14*758e9fbaSOystein Eftevaag #include <android-base/logging.h>
15*758e9fbaSOystein Eftevaag 
16*758e9fbaSOystein Eftevaag #if !defined(_MSC_VER) || defined(__INTEL_COMPILER)
17*758e9fbaSOystein Eftevaag #define likely(x)       __builtin_expect(!!(x), 1)
18*758e9fbaSOystein Eftevaag #define unlikely(x)     __builtin_expect(!!(x), 0)
19*758e9fbaSOystein Eftevaag #else
20*758e9fbaSOystein Eftevaag /* Microsoft Visual Studio gives internal error C1001 with _builtin_expect */
21*758e9fbaSOystein Eftevaag #define likely(x)       (x)
22*758e9fbaSOystein Eftevaag #define unlikely(x)     (x)
23*758e9fbaSOystein Eftevaag #endif
24*758e9fbaSOystein Eftevaag 
25*758e9fbaSOystein Eftevaag extern "C" {
26*758e9fbaSOystein Eftevaag 
27*758e9fbaSOystein Eftevaag /**
28*758e9fbaSOystein Eftevaag  * Compares two strings byte by byte and ignores the
29*758e9fbaSOystein Eftevaag  * character's case. Stops at the n-th byte of both
30*758e9fbaSOystein Eftevaag  * strings.
31*758e9fbaSOystein Eftevaag  *
32*758e9fbaSOystein Eftevaag  * This is basically a replacement of the POSIX-function
33*758e9fbaSOystein Eftevaag  * _strncasecmp_. Since tpm2-tss is supposed to be compatible
34*758e9fbaSOystein Eftevaag  * with ISO C99 and not with POSIX, _strncasecmp_ had to be
35*758e9fbaSOystein Eftevaag  * replaced. This function creates lowercase representations
36*758e9fbaSOystein Eftevaag  * of the strings and compares them bytewise.
37*758e9fbaSOystein Eftevaag  *
38*758e9fbaSOystein Eftevaag  * @param string1 The first of the two strings to compare
39*758e9fbaSOystein Eftevaag  * @param string2 The second of the two strings to compare
40*758e9fbaSOystein Eftevaag  * @param n The maximum number of bytes to compare
41*758e9fbaSOystein Eftevaag  * @return 0 if both strings are equal (case insensitive),
42*758e9fbaSOystein Eftevaag  *  an integer greater than zero if string1 is greater than
43*758e9fbaSOystein Eftevaag  *  string 2 and an integer smaller than zero if string1 is
44*758e9fbaSOystein Eftevaag  *  smaller than string2
45*758e9fbaSOystein Eftevaag  *
46*758e9fbaSOystein Eftevaag  */
47*758e9fbaSOystein Eftevaag static int
case_insensitive_strncmp(const char * string1,const char * string2,size_t n)48*758e9fbaSOystein Eftevaag case_insensitive_strncmp(const char *string1,
49*758e9fbaSOystein Eftevaag         const char *string2,
50*758e9fbaSOystein Eftevaag         size_t n)
51*758e9fbaSOystein Eftevaag {
52*758e9fbaSOystein Eftevaag     if ((string1 == NULL) && (string2 == NULL)) {
53*758e9fbaSOystein Eftevaag         return 0;
54*758e9fbaSOystein Eftevaag     }
55*758e9fbaSOystein Eftevaag     if ((string1 == NULL) && (string2 != NULL)) {
56*758e9fbaSOystein Eftevaag         return -1;
57*758e9fbaSOystein Eftevaag     }
58*758e9fbaSOystein Eftevaag     if ((string1 != NULL) && (string2 == NULL)) {
59*758e9fbaSOystein Eftevaag         return 1;
60*758e9fbaSOystein Eftevaag     }
61*758e9fbaSOystein Eftevaag     if (n == 0) { // Zero bytes are always equal
62*758e9fbaSOystein Eftevaag         return 0;
63*758e9fbaSOystein Eftevaag     }
64*758e9fbaSOystein Eftevaag     if (string1 == string2) { // return equal if they point to same location
65*758e9fbaSOystein Eftevaag         return 0;
66*758e9fbaSOystein Eftevaag     }
67*758e9fbaSOystein Eftevaag 
68*758e9fbaSOystein Eftevaag     int result;
69*758e9fbaSOystein Eftevaag     do {
70*758e9fbaSOystein Eftevaag         result = tolower((unsigned char) *string1) - tolower((unsigned char) *string2);
71*758e9fbaSOystein Eftevaag         if (result != 0) {
72*758e9fbaSOystein Eftevaag                 break;
73*758e9fbaSOystein Eftevaag         }
74*758e9fbaSOystein Eftevaag     } while (*string1++ != '\0' && *string2++ != '\0' && --n );
75*758e9fbaSOystein Eftevaag     return result;
76*758e9fbaSOystein Eftevaag }
77*758e9fbaSOystein Eftevaag 
78*758e9fbaSOystein Eftevaag static log_level
79*758e9fbaSOystein Eftevaag getLogLevel(const char *module, log_level logdefault);
80*758e9fbaSOystein Eftevaag 
81*758e9fbaSOystein Eftevaag void
doLogBlob(log_level loglevel,const char * module,log_level logdefault,log_level * status,const char * file,const char * func,int line,const uint8_t * blob,size_t size,const char * fmt,...)82*758e9fbaSOystein Eftevaag doLogBlob(log_level loglevel, const char *module, log_level logdefault,
83*758e9fbaSOystein Eftevaag            log_level *status,
84*758e9fbaSOystein Eftevaag            const char *file, const char *func, int line,
85*758e9fbaSOystein Eftevaag            const uint8_t *blob, size_t size, const char *fmt, ...)
86*758e9fbaSOystein Eftevaag {
87*758e9fbaSOystein Eftevaag     if (unlikely(*status == LOGLEVEL_UNDEFINED))
88*758e9fbaSOystein Eftevaag         *status = getLogLevel(module, logdefault);
89*758e9fbaSOystein Eftevaag     if (loglevel > *status)
90*758e9fbaSOystein Eftevaag         return;
91*758e9fbaSOystein Eftevaag 
92*758e9fbaSOystein Eftevaag     va_list vaargs;
93*758e9fbaSOystein Eftevaag     va_start(vaargs, fmt);
94*758e9fbaSOystein Eftevaag     /* TODO: Unfortunately, vsnprintf(NULL, 0, ...) do not behave the same as
95*758e9fbaSOystein Eftevaag        snprintf(NULL, 0, ...). Until there is an alternative, messages on
96*758e9fbaSOystein Eftevaag        logblob are restricted to 255 characters
97*758e9fbaSOystein Eftevaag     int msg_len = vsnprintf(NULL, 0, fmt, vaargs); */
98*758e9fbaSOystein Eftevaag     int msg_len = 255;
99*758e9fbaSOystein Eftevaag     char msg[msg_len+1];
100*758e9fbaSOystein Eftevaag     vsnprintf(msg, sizeof(msg), fmt, vaargs);
101*758e9fbaSOystein Eftevaag     va_end(vaargs);
102*758e9fbaSOystein Eftevaag 
103*758e9fbaSOystein Eftevaag     doLog(loglevel, module, logdefault, status, file, func, line,
104*758e9fbaSOystein Eftevaag           "%s (size=%zi):", msg, size);
105*758e9fbaSOystein Eftevaag 
106*758e9fbaSOystein Eftevaag     unsigned int i, y, x, off, off2;
107*758e9fbaSOystein Eftevaag     unsigned int width = 16;
108*758e9fbaSOystein Eftevaag #define LINE_LEN 64
109*758e9fbaSOystein Eftevaag     char buffer[LINE_LEN];
110*758e9fbaSOystein Eftevaag 
111*758e9fbaSOystein Eftevaag     for (i = 1, off = 0, off2 = 0; i <= size; i++) {
112*758e9fbaSOystein Eftevaag         if (i == 1) {
113*758e9fbaSOystein Eftevaag             sprintf(&buffer[off], "%04x: ", i - 1);
114*758e9fbaSOystein Eftevaag             off += 6;
115*758e9fbaSOystein Eftevaag         }
116*758e9fbaSOystein Eftevaag 
117*758e9fbaSOystein Eftevaag         /* data output */
118*758e9fbaSOystein Eftevaag         sprintf(&buffer[off], "%02x", blob[i-1]);
119*758e9fbaSOystein Eftevaag         off += 2;
120*758e9fbaSOystein Eftevaag 
121*758e9fbaSOystein Eftevaag         /* ASCII output */
122*758e9fbaSOystein Eftevaag         if ((i % width == 0 && i > 1) || i == size) {
123*758e9fbaSOystein Eftevaag             sprintf(&buffer[off], "  ");
124*758e9fbaSOystein Eftevaag             off += 2;
125*758e9fbaSOystein Eftevaag             /* Align to the right */
126*758e9fbaSOystein Eftevaag             for (x = off; x < width * 2 + 8; x++) {
127*758e9fbaSOystein Eftevaag                 sprintf(&buffer[off], " ");
128*758e9fbaSOystein Eftevaag                 off++;
129*758e9fbaSOystein Eftevaag             }
130*758e9fbaSOystein Eftevaag 
131*758e9fbaSOystein Eftevaag             /* Account for a line that is not 'full' */
132*758e9fbaSOystein Eftevaag             unsigned int less = width - (i % width);
133*758e9fbaSOystein Eftevaag             if (less == width)
134*758e9fbaSOystein Eftevaag                 less = 0;
135*758e9fbaSOystein Eftevaag 
136*758e9fbaSOystein Eftevaag             for (y = 0; y < width - less; y++) {
137*758e9fbaSOystein Eftevaag                 if (isgraph(blob[off2 + y])) {
138*758e9fbaSOystein Eftevaag                     sprintf(&buffer[y + off], "%c", blob[off2 + y]);
139*758e9fbaSOystein Eftevaag                 } else {
140*758e9fbaSOystein Eftevaag                     sprintf(&buffer[y + off], "%c", '.');
141*758e9fbaSOystein Eftevaag                 }
142*758e9fbaSOystein Eftevaag             }
143*758e9fbaSOystein Eftevaag             /* print the line and restart */
144*758e9fbaSOystein Eftevaag             fprintf (stderr, "%s\n", buffer);
145*758e9fbaSOystein Eftevaag             off2 = i;
146*758e9fbaSOystein Eftevaag             off = 0;
147*758e9fbaSOystein Eftevaag             memset(buffer, '\0', LINE_LEN);
148*758e9fbaSOystein Eftevaag             sprintf(&buffer[off], "%04x: ", i);
149*758e9fbaSOystein Eftevaag             off += 6;
150*758e9fbaSOystein Eftevaag         }
151*758e9fbaSOystein Eftevaag     }
152*758e9fbaSOystein Eftevaag }
153*758e9fbaSOystein Eftevaag 
154*758e9fbaSOystein Eftevaag void
doLog(log_level loglevel,const char * module,log_level logdefault,log_level * status,const char * file,const char * func,int line,const char * msg,...)155*758e9fbaSOystein Eftevaag doLog(log_level loglevel, const char *module, log_level logdefault,
156*758e9fbaSOystein Eftevaag            log_level *status,
157*758e9fbaSOystein Eftevaag            const char *file, const char *func, int line,
158*758e9fbaSOystein Eftevaag            const char *msg, ...)
159*758e9fbaSOystein Eftevaag {
160*758e9fbaSOystein Eftevaag     if (unlikely(*status == LOGLEVEL_UNDEFINED))
161*758e9fbaSOystein Eftevaag         *status = getLogLevel(module, logdefault);
162*758e9fbaSOystein Eftevaag 
163*758e9fbaSOystein Eftevaag     if (loglevel > *status)
164*758e9fbaSOystein Eftevaag         return;
165*758e9fbaSOystein Eftevaag 
166*758e9fbaSOystein Eftevaag     int size = snprintf(NULL, 0, "%s:%s:%s:%d:%s() %s ",
167*758e9fbaSOystein Eftevaag                 log_strings[loglevel], module, file, line, func, msg);
168*758e9fbaSOystein Eftevaag     char fmt[size+1];
169*758e9fbaSOystein Eftevaag     snprintf(fmt, sizeof(fmt), "%s:%s:%s:%d:%s() %s ",
170*758e9fbaSOystein Eftevaag                 log_strings[loglevel], module, file, line, func, msg);
171*758e9fbaSOystein Eftevaag 
172*758e9fbaSOystein Eftevaag     va_list vaargs;
173*758e9fbaSOystein Eftevaag     va_start(vaargs, msg);
174*758e9fbaSOystein Eftevaag     int complete_size = vsnprintf(NULL, 0, fmt, vaargs);
175*758e9fbaSOystein Eftevaag     va_end(vaargs);
176*758e9fbaSOystein Eftevaag 
177*758e9fbaSOystein Eftevaag     va_start(vaargs, msg);
178*758e9fbaSOystein Eftevaag     char complete[complete_size+1];
179*758e9fbaSOystein Eftevaag     vsnprintf(complete, sizeof(complete), fmt, vaargs);
180*758e9fbaSOystein Eftevaag     va_end(vaargs);
181*758e9fbaSOystein Eftevaag 
182*758e9fbaSOystein Eftevaag     fprintf(stderr, "%s\n", complete);
183*758e9fbaSOystein Eftevaag 
184*758e9fbaSOystein Eftevaag     switch (loglevel) {
185*758e9fbaSOystein Eftevaag       case LOGLEVEL_NONE:
186*758e9fbaSOystein Eftevaag         LOG(ERROR) << complete;
187*758e9fbaSOystein Eftevaag         break;
188*758e9fbaSOystein Eftevaag       case LOGLEVEL_ERROR:
189*758e9fbaSOystein Eftevaag         LOG(ERROR) << complete;
190*758e9fbaSOystein Eftevaag         break;
191*758e9fbaSOystein Eftevaag       case LOGLEVEL_WARNING:
192*758e9fbaSOystein Eftevaag         LOG(WARNING) << complete;
193*758e9fbaSOystein Eftevaag         break;
194*758e9fbaSOystein Eftevaag       case LOGLEVEL_INFO:
195*758e9fbaSOystein Eftevaag         LOG(INFO) << complete;
196*758e9fbaSOystein Eftevaag         break;
197*758e9fbaSOystein Eftevaag       case LOGLEVEL_DEBUG:
198*758e9fbaSOystein Eftevaag         LOG(DEBUG) << complete;
199*758e9fbaSOystein Eftevaag         break;
200*758e9fbaSOystein Eftevaag       case LOGLEVEL_TRACE:
201*758e9fbaSOystein Eftevaag         LOG(VERBOSE) << complete;
202*758e9fbaSOystein Eftevaag         break;
203*758e9fbaSOystein Eftevaag       case LOGLEVEL_UNDEFINED:
204*758e9fbaSOystein Eftevaag       default:
205*758e9fbaSOystein Eftevaag         LOG(WARNING) << complete;
206*758e9fbaSOystein Eftevaag         break;
207*758e9fbaSOystein Eftevaag     }
208*758e9fbaSOystein Eftevaag }
209*758e9fbaSOystein Eftevaag 
210*758e9fbaSOystein Eftevaag static log_level
log_stringlevel(const char * n)211*758e9fbaSOystein Eftevaag log_stringlevel(const char *n)
212*758e9fbaSOystein Eftevaag {
213*758e9fbaSOystein Eftevaag     log_level i;
214*758e9fbaSOystein Eftevaag     for(i = (log_level) 0; i < sizeof(log_strings)/sizeof(log_strings[0]); i = (log_level) ((int) i + 1)) {
215*758e9fbaSOystein Eftevaag         if (case_insensitive_strncmp(log_strings[i], n, strlen(log_strings[i])) == 0) {
216*758e9fbaSOystein Eftevaag             return i;
217*758e9fbaSOystein Eftevaag         }
218*758e9fbaSOystein Eftevaag     }
219*758e9fbaSOystein Eftevaag     return LOGLEVEL_UNDEFINED;
220*758e9fbaSOystein Eftevaag }
221*758e9fbaSOystein Eftevaag 
222*758e9fbaSOystein Eftevaag static log_level
getLogLevel(const char * module,log_level logdefault)223*758e9fbaSOystein Eftevaag getLogLevel(const char *module, log_level logdefault)
224*758e9fbaSOystein Eftevaag {
225*758e9fbaSOystein Eftevaag     log_level loglevel = logdefault;
226*758e9fbaSOystein Eftevaag     char *envlevel = getenv("TSS2_LOG");
227*758e9fbaSOystein Eftevaag     char *i = envlevel;
228*758e9fbaSOystein Eftevaag     if (envlevel == NULL)
229*758e9fbaSOystein Eftevaag         return loglevel;
230*758e9fbaSOystein Eftevaag     while ((i = strchr(i, '+')) != NULL) {
231*758e9fbaSOystein Eftevaag         if ((envlevel <= i - strlen("all") &&
232*758e9fbaSOystein Eftevaag 	     case_insensitive_strncmp(i - 3, "all", 3) == 0) ||
233*758e9fbaSOystein Eftevaag             (envlevel <= i - strlen(module) &&
234*758e9fbaSOystein Eftevaag              case_insensitive_strncmp(i - strlen(module), module, strlen(module)) == 0)) {
235*758e9fbaSOystein Eftevaag             log_level tmp = log_stringlevel(i+1);
236*758e9fbaSOystein Eftevaag             if (tmp != LOGLEVEL_UNDEFINED)
237*758e9fbaSOystein Eftevaag                 loglevel = tmp;
238*758e9fbaSOystein Eftevaag         }
239*758e9fbaSOystein Eftevaag         i = i + 1;
240*758e9fbaSOystein Eftevaag     }
241*758e9fbaSOystein Eftevaag     return loglevel;
242*758e9fbaSOystein Eftevaag }
243*758e9fbaSOystein Eftevaag 
244*758e9fbaSOystein Eftevaag } // extern "C"
245