]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/valgrind/src/valgrind-3.6.0-svn/callgrind/debug.c
b89b753613e06113de2ce680c06998edd68440dc
[l4.git] / l4 / pkg / valgrind / src / valgrind-3.6.0-svn / callgrind / debug.c
1 /*
2    This file is part of Callgrind, a Valgrind tool for call graph
3    profiling programs.
4
5    Copyright (C) 2002-2010, Josef Weidendorfer (Josef.Weidendorfer@gmx.de)
6
7    This tool is derived from and contains lot of code from Cachegrind
8    Copyright (C) 2002 Nicholas Nethercote (njn@valgrind.org)
9
10    This program is free software; you can redistribute it and/or
11    modify it under the terms of the GNU General Public License as
12    published by the Free Software Foundation; either version 2 of the
13    License, or (at your option) any later version.
14
15    This program is distributed in the hope that it will be useful, but
16    WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18    General Public License for more details.
19
20    You should have received a copy of the GNU General Public License
21    along with this program; if not, write to the Free Software
22    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
23    02111-1307, USA.
24
25    The GNU General Public License is contained in the file COPYING.
26 */
27
28 #include "global.h"
29 #include "events.h"
30
31 /* If debugging mode of, dummy functions are provided (see below)
32  */
33 #if CLG_ENABLE_DEBUG
34
35 /*------------------------------------------------------------*/
36 /*--- Debug output helpers                                 ---*/
37 /*------------------------------------------------------------*/
38
39 static void print_indent(int s)
40 {
41     /* max of 40 spaces */
42     char sp[] = "                                        ";
43     if (s>40) s=40;
44     VG_(printf)("%s", sp+40-s);
45 }
46
47 void CLG_(print_bb)(int s, BB* bb)
48 {
49     if (s<0) {
50         s = -s;
51         print_indent(s);
52     }
53
54     VG_(printf)("BB %#lx (Obj '%s')", bb_addr(bb), bb->obj->name);
55 }
56
57 static
58 void print_mangled_cxt(Context* cxt, int rec_index)
59 {
60     int i;
61
62     if (!cxt)
63       VG_(printf)("(none)");
64     else {
65       VG_(printf)("%s", cxt->fn[0]->name);
66       if (rec_index >0)
67         VG_(printf)("'%d", rec_index +1);
68       for(i=1;i<cxt->size;i++)
69         VG_(printf)("'%s", cxt->fn[i]->name);
70     }
71 }
72
73
74
75 void CLG_(print_cxt)(int s, Context* cxt, int rec_index)
76 {
77   if (s<0) {
78     s = -s;
79     print_indent(s);
80   }
81   
82   if (cxt) {
83     UInt *pactive = CLG_(get_fn_entry)(cxt->fn[0]->number);
84     CLG_ASSERT(rec_index < cxt->fn[0]->separate_recursions);
85     
86     VG_(printf)("Cxt %d" ,cxt->base_number + rec_index);
87     if (*pactive>0)
88       VG_(printf)(" [active=%d]", *pactive);
89     VG_(printf)(": ");  
90     print_mangled_cxt(cxt, rec_index);
91     VG_(printf)("\n");
92   }
93   else
94     VG_(printf)("(no context)\n");
95 }
96
97 void CLG_(print_execstate)(int s, exec_state* es)
98 {
99   if (s<0) {
100     s = -s;
101     print_indent(s);
102   }
103   
104   if (!es) {
105     VG_(printf)("ExecState 0x0\n");
106     return;
107   }
108
109   VG_(printf)("ExecState [Sig %d, collect %s, nonskipped %p]: jmps_passed %d\n",
110               es->sig, es->collect?"yes":"no",
111               es->nonskipped, es->jmps_passed);
112 }
113
114
115 void CLG_(print_bbcc)(int s, BBCC* bbcc)
116 {
117   BB* bb;
118
119   if (s<0) {
120     s = -s;
121     print_indent(s);
122   }
123   
124   if (!bbcc) {
125     VG_(printf)("BBCC 0x0\n");
126     return;
127   }
128  
129   bb = bbcc->bb;
130   CLG_ASSERT(bb!=0);
131
132   VG_(printf)("%s +%#lx=%#lx, ",
133               bb->obj->name + bb->obj->last_slash_pos,
134               bb->offset, bb_addr(bb));
135   CLG_(print_cxt)(s+8, bbcc->cxt, bbcc->rec_index);
136 }
137
138 void CLG_(print_eventset)(int s, EventSet* es)
139 {
140   int i;
141
142   if (s<0) {
143     s = -s;
144     print_indent(s);
145   }
146
147   if (!es) {
148     VG_(printf)("(EventSet not set)\n");
149     return;
150   }
151
152   VG_(printf)("%5s (Size/Cap %d/%d): ",
153               es->name, es->size, es->capacity);
154
155   if (es->size == 0)
156     VG_(printf)("-");
157   else {
158     for(i=0; i< es->size; i++) {
159       if (i>0) {
160         VG_(printf)(" ");
161         if (es->e[i-1].nextTop == i)
162           VG_(printf)("| ");
163       }
164       VG_(printf)("%s", es->e[i].type->name);
165     }
166   }
167   VG_(printf)("\n");
168 }
169
170
171 void CLG_(print_cost)(int s, EventSet* es, ULong* c)
172 {
173   Int i, pos;
174
175     if (s<0) {
176         s = -s;
177         print_indent(s);
178     }
179
180     if (!es) {
181       VG_(printf)("Cost (Nothing, EventSet not set)\n");
182       return;
183     }
184     if (!c) {
185       VG_(printf)("Cost (Null, EventSet %s)\n", es->name);
186       return;
187     }
188
189     if (es->size == 0) {
190       VG_(printf)("Cost (Nothing, EventSet %s with len 0)\n", es->name);
191       return;
192     } 
193
194     pos = s;
195     pos += VG_(printf)("Cost %s [%p]: %s %llu", es->name, c, es->e[0].type->name, c[0]);
196
197     i = 1;
198     while(i<es->size) {
199       if (pos > 70) {
200         VG_(printf)(",\n");
201         print_indent(s+5);
202         pos = s+5;
203       }
204       else
205         pos += VG_(printf)(", ");
206       pos += VG_(printf)("%s %llu", es->e[i].type->name, c[i]);
207       i++;
208     }
209     VG_(printf)("\n");
210 }
211
212
213 void CLG_(print_short_jcc)(jCC* jcc)
214 {
215     if (jcc)
216         VG_(printf)("%#lx => %#lx [%llu/%llu,%llu,%llu]",
217                     bb_jmpaddr(jcc->from->bb),
218                     bb_addr(jcc->to->bb),
219                     jcc->call_counter,
220                     jcc->cost ? jcc->cost[CLG_(sets).off_full_Ir]:0,
221                     jcc->cost ? jcc->cost[CLG_(sets).off_full_Dr]:0,
222                     jcc->cost ? jcc->cost[CLG_(sets).off_full_Dw]:0);
223     else
224         VG_(printf)("[Skipped JCC]");
225 }
226
227 void CLG_(print_jcc)(int s, jCC* jcc)
228 {
229     if (s<0) {
230         s = -s;
231         print_indent(s);
232     }
233
234     if (!jcc) {
235         VG_(printf)("JCC to skipped function\n");
236         return;
237     }
238     VG_(printf)("JCC %p from ", jcc);
239     CLG_(print_bbcc)(s+9, jcc->from);
240     print_indent(s+4);    
241     VG_(printf)("to   ");
242     CLG_(print_bbcc)(s+9, jcc->to);
243     print_indent(s+4);
244     VG_(printf)("Calls %llu\n", jcc->call_counter);
245     print_indent(s+4);
246     CLG_(print_cost)(s+9, CLG_(sets).full, jcc->cost);
247 }
248
249 /* dump out the current call stack */
250 void CLG_(print_stackentry)(int s, int sp)
251 {
252     call_entry* ce;
253
254     if (s<0) {
255         s = -s;
256         print_indent(s);
257     }
258
259     ce = CLG_(get_call_entry)(sp);
260     VG_(printf)("[%-2d] SP %#lx, RA %#lx", sp, ce->sp, ce->ret_addr);
261     if (ce->nonskipped)
262         VG_(printf)(" NonSkipped BB %#lx / %s",
263                     bb_addr(ce->nonskipped->bb),
264                     ce->nonskipped->cxt->fn[0]->name);
265     VG_(printf)("\n");
266     print_indent(s+5);
267     CLG_(print_jcc)(5,ce->jcc);
268 }
269
270 /* debug output */
271 #if 0
272 static void print_call_stack()
273 {
274     int c;
275
276     VG_(printf)("Call Stack:\n");
277     for(c=0;c<CLG_(current_call_stack).sp;c++)
278       CLG_(print_stackentry)(-2, c);
279 }
280 #endif
281
282 void CLG_(print_bbcc_fn)(BBCC* bbcc)
283 {
284     obj_node* obj;
285
286     if (!bbcc) {
287         VG_(printf)("%08x", 0);
288         return;
289     }
290
291     VG_(printf)("%08lx/%c  %d:", bb_addr(bbcc->bb), 
292                 (bbcc->bb->sect_kind == Vg_SectText) ? 'T' :
293                 (bbcc->bb->sect_kind == Vg_SectData) ? 'D' :
294                 (bbcc->bb->sect_kind == Vg_SectBSS) ? 'B' :
295                 (bbcc->bb->sect_kind == Vg_SectGOT) ? 'G' :
296                 (bbcc->bb->sect_kind == Vg_SectPLT) ? 'P' : 'U',
297                 bbcc->cxt->base_number+bbcc->rec_index);
298     print_mangled_cxt(bbcc->cxt, bbcc->rec_index);
299
300     obj = bbcc->cxt->fn[0]->file->obj;
301     if (obj->name[0])
302         VG_(printf)(" %s", obj->name+obj->last_slash_pos);
303
304     if (VG_(strcmp)(bbcc->cxt->fn[0]->file->name, "???") !=0) {
305         VG_(printf)(" %s", bbcc->cxt->fn[0]->file->name);
306         if ((bbcc->cxt->fn[0] == bbcc->bb->fn) && (bbcc->bb->line>0))
307             VG_(printf)(":%d", bbcc->bb->line);
308     }
309 }       
310
311 void CLG_(print_bbcc_cost)(int s, BBCC* bbcc)
312 {
313   BB* bb;
314   Int i, cjmpNo;
315   ULong ecounter;
316
317   if (s<0) {
318     s = -s;
319     print_indent(s);
320   }
321   
322   if (!bbcc) {
323     VG_(printf)("BBCC 0x0\n");
324     return;
325   }
326  
327   bb = bbcc->bb;
328   CLG_ASSERT(bb!=0);
329     
330   CLG_(print_bbcc)(s, bbcc);
331
332   ecounter = bbcc->ecounter_sum;
333
334   print_indent(s+2);
335   VG_(printf)("ECounter: sum %llu ", ecounter);
336   for(i=0; i<bb->cjmp_count; i++) {
337       VG_(printf)("[%d]=%llu ",
338                   bb->jmp[i].instr, bbcc->jmp[i].ecounter);
339   }
340   VG_(printf)("\n");
341
342   cjmpNo = 0; 
343   for(i=0; i<bb->instr_count; i++) {
344       InstrInfo* ii = &(bb->instr[i]);
345       print_indent(s+2);
346       VG_(printf)("[%2d] IOff %2d ecnt %3llu ",
347                   i, ii->instr_offset, ecounter);
348       CLG_(print_cost)(s+5, ii->eventset, bbcc->cost + ii->cost_offset);
349
350       /* update execution counter */
351       if (cjmpNo < bb->cjmp_count)
352           if (bb->jmp[cjmpNo].instr == i) {
353               ecounter -= bbcc->jmp[cjmpNo].ecounter;
354               cjmpNo++;
355           }
356   }
357 }
358
359
360 /* dump out an address with source info if available */
361 void CLG_(print_addr)(Addr addr)
362 {
363     Char fl_buf[FILENAME_LEN];
364     Char fn_buf[FN_NAME_LEN];
365     const UChar* obj_name;
366     DebugInfo* di;
367     int ln, i=0, opos=0;
368         
369     if (addr == 0) {
370         VG_(printf)("%08lx", addr);
371         return;
372     }
373
374     CLG_(get_debug_info)(addr, fl_buf, fn_buf, &ln, &di);
375
376     if (VG_(strcmp)(fn_buf,"???")==0)
377         VG_(printf)("%#lx", addr);
378     else
379         VG_(printf)("%#lx %s", addr, fn_buf);
380
381     if (di) {
382       obj_name = VG_(DebugInfo_get_filename)(di);
383       if (obj_name) {
384         while(obj_name[i]) {
385           if (obj_name[i]=='/') opos = i+1;
386           i++;
387         }
388         if (obj_name[0])
389           VG_(printf)(" %s", obj_name+opos);
390       }
391     }
392
393     if (ln>0)
394         VG_(printf)(" (%s:%u)", fl_buf,ln);
395 }
396
397 void CLG_(print_addr_ln)(Addr addr)
398 {
399   CLG_(print_addr)(addr);
400   VG_(printf)("\n");
401 }
402
403 static ULong bb_written = 0;
404
405 void CLG_(print_bbno)(void)
406 {
407   if (bb_written != CLG_(stat).bb_executions) {
408     bb_written = CLG_(stat).bb_executions;
409     VG_(printf)("BB# %llu\n",CLG_(stat).bb_executions);
410   }
411 }
412
413 void CLG_(print_context)(void)
414 {
415   BBCC* bbcc;
416
417   CLG_DEBUG(0,"In tid %d [%d] ",
418            CLG_(current_tid),  CLG_(current_call_stack).sp);
419   bbcc =  CLG_(current_state).bbcc;
420   print_mangled_cxt(CLG_(current_state).cxt,
421                     bbcc ? bbcc->rec_index : 0);
422   VG_(printf)("\n");
423 }
424
425 void* CLG_(malloc)(HChar* cc, UWord s, char* f)
426 {
427     CLG_DEBUG(3, "Malloc(%lu) in %s.\n", s, f);
428     return VG_(malloc)(cc,s);
429 }
430
431 #else /* CLG_ENABLE_DEBUG */
432
433 void CLG_(print_bbno)(void) {}
434 void CLG_(print_context)(void) {}
435 void CLG_(print_jcc)(int s, jCC* jcc) {}
436 void CLG_(print_bbcc)(int s, BBCC* bbcc) {}
437 void CLG_(print_bbcc_fn)(BBCC* bbcc) {}
438 void CLG_(print_cost)(int s, EventSet* es, ULong* cost) {}
439 void CLG_(print_bb)(int s, BB* bb) {}
440 void CLG_(print_cxt)(int s, Context* cxt, int rec_index) {}
441 void CLG_(print_short_jcc)(jCC* jcc) {}
442 void CLG_(print_stackentry)(int s, int sp) {}
443 void CLG_(print_addr)(Addr addr) {}
444 void CLG_(print_addr_ln)(Addr addr) {}
445
446 #endif