Tools/nativelib - Updated to handle recent(ish) kernel changes
[tpg/acess2.git] / Tools / nativelib / logging.c
1 /*
2  * Acess2 libnative (Kernel Simulation Library)
3  * - By John Hodge (thePowersGang)
4  *
5  * logging.c
6  * - Logging functions
7  */
8 #include <stdio.h>
9 #include <stdarg.h>
10 #include <stdlib.h>
11 #include <stdint.h>
12 #include <acess_logging.h>
13 #include <ctype.h>
14 #include <inttypes.h>
15 #include <shortlock.h>
16
17 extern int      Threads_GetTID();
18
19 #define LOGHDR(col,type)        fprintf(stderr, "\e["col"m[%-8.8s]"type"%2i ", Ident, Threads_GetTID())
20 #define LOGTAIL()       fprintf(stderr, "\e[0m\n")
21
22 #define PUTERR(col,type)        {\
23         if(!gbThreadInLog)      SHORTLOCK(&glDebugLock); \
24         gbThreadInLog ++; \
25         LOGHDR(col,type);\
26         va_list args; va_start(args, Message);\
27         vfprintf(stderr, Message, args);\
28         va_end(args);\
29         LOGTAIL();\
30         gbThreadInLog --; \
31         if(!gbThreadInLog)      SHORTREL(&glDebugLock); \
32 }
33
34 // === GLOBALS ===
35 int __thread    gbThreadInLog;
36 tShortSpinlock  glDebugLock;
37
38 // === CODE ===
39 void Log_KernelPanic(const char *Ident, const char *Message, ...) {
40         PUTERR("35", "k")
41         exit(-1);
42 }
43 void Log_Panic(const char *Ident, const char *Message, ...)
44         PUTERR("34", "p")
45 void Log_Error(const char *Ident, const char *Message, ...)
46         PUTERR("31", "e")
47 void Log_Warning(const char *Ident, const char *Message, ...)
48         PUTERR("33", "w")
49 void Log_Notice(const char *Ident, const char *Message, ...)
50         PUTERR("32", "n")
51 void Log_Log(const char *Ident, const char *Message, ...)
52         PUTERR("37", "l")
53 void Log_Debug(const char *Ident, const char *Message, ...)
54         PUTERR("37", "d")
55
56 void Panic(const char *Message, ...) {
57         const char *Ident = "";
58         PUTERR("35", "k")
59         exit(-1);
60 }
61 void Warning(const char *Message, ...) {
62         const char *Ident = "";
63         PUTERR("33", "W")
64 }
65 void Log(const char *Message, ...) {
66         const char *Ident = "";
67         PUTERR("37", "L")
68 }
69
70 void Debug_HexDump(const char *Prefix, const void *Data, size_t Length)
71 {
72         const uint8_t *data = Data;
73         size_t  ofs;
74         fprintf(stderr, "[HexDump ]d %s: %i bytes\n", Prefix, (int)Length);
75         for( ofs = 0; ofs + 16 <= Length; ofs += 16 )
76         {
77                 fprintf(stderr, "[HexDump ]d %s:", Prefix);
78                 fprintf(stderr, "  %02x %02x %02x %02x %02x %02x %02x %02x",
79                         data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7]);
80                 data += 8;
81                 fprintf(stderr, "  %02x %02x %02x %02x %02x %02x %02x %02x",
82                         data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7]);
83                 data += 8;
84                 fprintf(stderr, "\n");
85         }
86         
87         fprintf(stderr, "[HexDump ]d %s:", Prefix);
88         for( ; ofs < Length; ofs ++ )
89         {
90                 if( ofs % 8 == 0 )      fprintf(stderr, " ");
91                 fprintf(stderr, " %02x", data[ofs%16]);
92         }
93         fprintf(stderr, "\n");
94 }
95
96  int    giDebug_TraceLevel = 0;
97
98 void Debug_TraceEnter(const char *Function, const char *Format, ...)
99 {
100         const char *Ident = "Trace";
101         LOGHDR("37","T");
102         for( int i = 0; i < giDebug_TraceLevel; i ++ )
103                 fprintf(stderr, " ");
104         fprintf(stderr, "%s: (", Function);
105
106         va_list args;
107         va_start(args, Format);
108         
109         int hasBeenPrev = 0;
110         while(*Format)
111         {
112                 while( *Format && isblank(*Format) )
113                         Format ++;
114                 if( !*Format )  break;
115                 
116                 char type = *Format++;
117                 const char *start = Format;
118                 while( *Format && !isblank(*Format) )
119                         Format ++;
120                 
121                 if(hasBeenPrev)
122                         fprintf(stderr, ",");
123                 hasBeenPrev = 1;
124                 
125                 fprintf(stderr, "%.*s=", (int)(Format-start), start);
126                 switch(type)
127                 {
128                 case 'p':
129                         fprintf(stderr, "%p", va_arg(args,const void *));
130                         break;
131                 case 's':
132                         fprintf(stderr, "\"%s\"", va_arg(args,const char *));
133                         break;
134                 case 'i':
135                         fprintf(stderr, "%i", va_arg(args,int));
136                         break;
137                 case 'x':
138                         fprintf(stderr, "0x%x", va_arg(args,unsigned int));
139                         break;
140                 case 'X':
141                         fprintf(stderr, "0x%"PRIx64, va_arg(args,uint64_t));
142                         break;
143                 default:
144                         va_arg(args,uintptr_t);
145                         fprintf(stderr, "?");
146                         break;
147                 }
148         }
149
150         va_end(args);
151
152         fprintf(stderr, ")");
153         LOGTAIL();
154         giDebug_TraceLevel ++;
155 }
156
157 void Debug_TraceLog(const char *Function, const char *Format, ...)
158 {
159         const char *Ident = "Trace";
160         LOGHDR("37","T");
161         
162         for( int i = 0; i < giDebug_TraceLevel; i ++ )
163                 fprintf(stderr, " ");
164         fprintf(stderr, "%s: ", Function);
165         
166         va_list args;
167         va_start(args, Format);
168
169         vfprintf(stderr, Format, args);
170         
171         va_end(args);
172         LOGTAIL();
173 }
174
175 void Debug_TraceLeave(const char *Function, char Type, ...)
176 {
177         if( giDebug_TraceLevel == 0 ) {
178                 Log_Error("Debug", "Function %s called LEAVE without ENTER", Function);
179         }
180         
181         const char *Ident = "Trace";
182         LOGHDR("37","T");
183         
184         va_list args;
185         va_start(args, Type);
186
187         if( giDebug_TraceLevel > 0 )
188         {       
189                 giDebug_TraceLevel --;
190                 for( int i = 0; i < giDebug_TraceLevel; i ++ )
191                         fprintf(stderr, " ");
192         }
193         fprintf(stderr, "%s: RETURN", Function);
194         switch(Type)
195         {
196         case '-':
197                 break;
198         case 'i':
199                 fprintf(stderr, " %i", va_arg(args, int));
200                 break;
201         case 'x':
202                 fprintf(stderr, " 0x%x", va_arg(args, unsigned int));
203                 break;
204         case 'X':
205                 fprintf(stderr, " 0x%"PRIx64, va_arg(args,uint64_t));
206                 break;
207         case 's':
208                 fprintf(stderr, " \"%s\"", va_arg(args, const char *));
209                 break;
210         case 'p':
211                 fprintf(stderr, " %p", va_arg(args, const void *));
212                 break;
213         case 'n':
214                 fprintf(stderr, " NULL");
215                 break;
216         default:
217                 fprintf(stderr, " ?");
218                 break;
219         }
220         
221         va_end(args);
222         LOGTAIL();
223 }
224

UCC git Repository :: git.ucc.asn.au