9 #include "jdb_symbol.h"
10 #include "jdb_tbuf_output.h"
12 #include "static_init.h"
16 static __attribute__((format(printf, 3, 4)))
18 my_snprintf(char *&buf, int &maxlen, const char *format, ...)
26 va_start(list, format);
27 len = vsnprintf(buf, maxlen, format, list);
30 if (len<0 || len>=maxlen)
41 format_timeout(Mword us, char *&buf, int &maxlen)
43 if (us >= 1000000000) // =>100s
44 my_snprintf(buf, maxlen, ">99s");
45 else if (us >= 10000000) // >=10s
46 my_snprintf(buf, maxlen, "%lds", us/1000000);
47 else if (us >= 1000000) // >=1s
48 my_snprintf(buf, maxlen, "%ld.%lds", us/1000000, (us%1000000)/100000);
49 else if (us >= 10000) // 10ms
50 my_snprintf(buf, maxlen, "%ldm", us/1000);
51 else if (us >= 1000) // 1ms
52 my_snprintf(buf, maxlen, "%ld.%ldm", us/1000, (us%1000)/100);
54 my_snprintf(buf, maxlen, "%ld%c", us, Config::char_micro);
57 template< typename T >
62 switch (e->ipc_type())
64 case L4_obj_ref::Ipc_call: return "call";
65 case L4_obj_ref::Ipc_call_ipc: return "call ipc";
66 case L4_obj_ref::Ipc_send: return "send";
67 case L4_obj_ref::Ipc_recv: return "recv";
68 case L4_obj_ref::Ipc_send_and_wait: return "snd wait";
69 case L4_obj_ref::Ipc_reply_and_wait: return "repl";
70 case L4_obj_ref::Ipc_wait: return "wait";
71 default: return "unk ipc";
75 static char const * const __tag_interpreter_strings_l4re[] = {
84 static char const * const __tag_interpreter_strings_fiasco[] = {
110 tag_to_string(L4_msg_tag const &tag)
112 if (0x4000 <= tag.proto() && tag.proto() <= 0x4006)
113 return __tag_interpreter_strings_l4re[tag.proto() - 0x4000];
114 if (-21L <= tag.proto() && tag.proto() <= -1)
115 return __tag_interpreter_strings_fiasco[-tag.proto() - 1];
121 tag_interpreter_snprintf(char *&buf, int &maxlen, L4_msg_tag const &tag)
129 s = tag_to_string(tag);
131 len = snprintf(buf, maxlen, "%s%04lx", s, tag.raw() & 0xffff);
133 len = snprintf(buf, maxlen, L4_PTR_FMT, tag.raw());
135 if (len<0 || len>=maxlen)
142 // ipc / irq / shortcut success
145 formatter_ipc(Tb_entry *tb, const char *tidstr, unsigned tidlen,
146 char *buf, int maxlen)
148 Tb_entry_ipc *e = static_cast<Tb_entry_ipc*>(tb);
149 unsigned char type = e->ipc_type();
151 type = L4_obj_ref::Ipc_call_ipc;
153 // ipc operation / shortcut succeeded/failed
154 const char *m = get_ipc_type(e);
156 my_snprintf(buf, maxlen, "%s: ", (e->type()==Tbuf_ipc) ? "ipc" : "sc ");
157 my_snprintf(buf, maxlen, "%s%-*s %s->",
158 /*e->dst().next_period() ? "[NP] " :*/ "", tidlen, tidstr, m);
160 // print destination id
161 if (e->dst().special())
162 my_snprintf(buf, maxlen, "[C:INV] DID=%lx", e->dbg_id());
164 my_snprintf(buf, maxlen, "[C:%lx] DID=%lx", e->dst().raw(), e->dbg_id());
166 my_snprintf(buf, maxlen, " L=%lx", e->label());
168 // print mwords if have send part
169 if (type & L4_obj_ref::Ipc_send)
171 my_snprintf(buf, maxlen, " [");
173 tag_interpreter_snprintf(buf, maxlen, e->tag());
175 my_snprintf(buf, maxlen, "] (" L4_PTR_FMT "," L4_PTR_FMT ")",
176 e->dword(0), e->dword(1));
179 my_snprintf(buf, maxlen, " TO=");
180 L4_timeout_pair to = e->timeout();
181 if (type & L4_obj_ref::Ipc_send)
183 if (to.snd.is_absolute())
185 // absolute send timeout
186 Unsigned64 end = 0; // FIXME: to.snd.microsecs_abs (e->kclock());
187 format_timeout((Mword)(end > e->kclock() ? end-e->kclock() : 0),
192 // relative send timeout
193 if (to.snd.is_never())
194 my_snprintf(buf, maxlen, "INF");
195 else if (to.snd.is_zero())
196 my_snprintf(buf, maxlen, "0");
198 format_timeout((Mword)to.snd.microsecs_rel(0), buf, maxlen);
201 if (type & L4_obj_ref::Ipc_send
202 && type & L4_obj_ref::Ipc_recv)
203 my_snprintf(buf, maxlen, "/");
204 if (type & L4_obj_ref::Ipc_recv)
206 if (to.rcv.is_absolute())
208 // absolute receive timeout
209 Unsigned64 end = 0; // FIXME: to.rcv.microsecs_abs (e->kclock());
210 format_timeout((Mword)(end > e->kclock() ? end-e->kclock() : 0),
215 // relative receive timeout
216 if (to.rcv.is_never())
217 my_snprintf(buf, maxlen, "INF");
218 else if (to.rcv.is_zero())
219 my_snprintf(buf, maxlen, "0");
221 format_timeout((Mword)to.rcv.microsecs_rel(0), buf, maxlen);
231 formatter_ipc_res(Tb_entry *tb, const char *tidstr, unsigned tidlen,
232 char *buf, int maxlen)
234 Tb_entry_ipc_res *e = static_cast<Tb_entry_ipc_res*>(tb);
236 if (e->tag().has_error())
239 error = L4_error::None;
240 const char *m = "answ"; //get_ipc_type(e);
242 my_snprintf(buf, maxlen, " %s%-*s %s [%08lx] L=%lx err=%lx (%s) (%lx,%lx) ",
243 e->is_np() ? "[np] " : "",
244 tidlen, tidstr, m, e->tag().raw(), e->from(),
245 error.raw(), error.str_error(), e->dword(0),
253 #include "kobject_dbg.h"
258 formatter_pf(Tb_entry *tb, const char *tidstr, unsigned tidlen,
259 char *buf, int maxlen)
261 Tb_entry_pf *e = static_cast<Tb_entry_pf*>(tb);
264 snprintf(ip_buf, sizeof(ip_buf), L4_PTR_FMT, e->ip());
265 my_snprintf(buf, maxlen, "pf: %-*s pfa=" L4_PTR_FMT " ip=%s (%c%c) spc=%p",
266 tidlen, tidstr, e->pfa(), e->ip() ? ip_buf : "unknown",
267 !PF::is_read_error(e->error()) ? (e->error() & 4 ? 'w' : 'W')
268 : (e->error() & 4 ? 'r' : 'R'),
269 !PF::is_translation_error(e->error()) ? 'p' : '-',
278 formatter_pf_res(Tb_entry *tb, const char *tidstr, unsigned tidlen,
279 char *buf, int maxlen)
281 Tb_entry_pf_res *e = static_cast<Tb_entry_pf_res*>(tb);
283 // e->ret contains only an error code
284 // e->err contains only up to 3 dwords
285 my_snprintf(buf, maxlen, " %-*s pfa=" L4_PTR_FMT " dope=%02lx (%s%s) "
287 tidlen, tidstr, e->pfa(),
288 e->ret().raw(), e->ret().error() ? "L4_IPC_" : "",
289 e->ret().str_error(),
290 e->err().raw(), e->err().error() ? "L4_IPC_" : "",
291 e->err().str_error());
296 // kernel event (enter_kdebug("*..."))
299 formatter_ke(Tb_entry *tb, const char *tidstr, unsigned tidlen,
300 char *buf, int maxlen)
302 Tb_entry_ke *e = static_cast<Tb_entry_ke*>(tb);
305 snprintf(ip_buf, sizeof(ip_buf), " @ " L4_PTR_FMT, e->ip());
306 my_snprintf(buf, maxlen, "ke: %-*s \"%s\"%s",
307 tidlen, tidstr, e->msg(), e->ip() ? ip_buf : "");
312 // kernel event (enter_kdebug_verb("*+...", val1, val2, val3))
315 formatter_ke_reg(Tb_entry *tb, const char *tidstr, unsigned tidlen,
316 char *buf, int maxlen)
318 Tb_entry_ke_reg *e = static_cast<Tb_entry_ke_reg*>(tb);
321 snprintf(ip_buf, sizeof(ip_buf), " @ " L4_PTR_FMT, e->ip());
322 my_snprintf(buf, maxlen, "ke: %-*s \"%s\" "
323 L4_PTR_FMT " " L4_PTR_FMT " " L4_PTR_FMT "%s",
324 tidlen, tidstr, e->msg(), e->val1(), e->val2(), e->val3(),
325 e->ip() ? ip_buf : "");
334 formatter_bp(Tb_entry *tb, const char *tidstr, unsigned tidlen,
335 char *buf, int maxlen)
337 Tb_entry_bp *e = static_cast<Tb_entry_bp*>(tb);
339 my_snprintf(buf, maxlen, "b%c: %-*s @ " L4_PTR_FMT " ",
340 "iwpa"[e->mode() & 3], tidlen, tidstr, e->ip());
341 switch (e->mode() & 3)
348 my_snprintf(buf, maxlen, "[" L4_PTR_FMT "]=%02lx",
349 e->addr(), e->value());
352 my_snprintf(buf, maxlen, "[" L4_PTR_FMT "]=%04lx",
353 e->addr(), e->value());
356 my_snprintf(buf, maxlen, "[" L4_PTR_FMT "]=" L4_PTR_FMT,
357 e->addr(), e->value());
362 my_snprintf(buf, maxlen, "[" L4_PTR_FMT "]", e->addr());
372 formatter_ctx_switch(Tb_entry *tb, const char *tidstr, unsigned tidlen,
373 char *buf, int maxlen)
375 char symstr[24], spcstr[16] = "";
376 Tb_entry_ctx_sw *e = static_cast<Tb_entry_ctx_sw*>(tb);
383 sctx = e->from_sched()->context();
384 sctxid = static_cast<Thread*>(sctx)->dbg_id();
386 dst = static_cast<Thread const *>(e->dst())->dbg_id();
387 dst_orig = static_cast<Thread const *>(e->dst_orig())->dbg_id();
389 Address addr = e->kernel_ip();
391 if (!Jdb_symbol::match_addr_to_symbol_fuzzy(&addr, 0 /*kernel*/,
392 symstr, sizeof(symstr)))
393 snprintf(symstr, sizeof(symstr), L4_PTR_FMT, e->kernel_ip());
395 my_snprintf(buf, maxlen, " %-*s%s '%02lx",
396 tidlen, tidstr, spcstr, e->from_prio());
397 if (sctx != e->ctx())
398 my_snprintf(buf, maxlen, "(%lx)", sctxid);
400 my_snprintf(buf, maxlen, " ==> %lx ", dst);
402 if (dst != dst_orig || e->lock_cnt())
403 my_snprintf(buf, maxlen, "(");
406 my_snprintf(buf, maxlen, "want %lx",
409 if (dst != dst_orig && e->lock_cnt())
410 my_snprintf(buf, maxlen, " ");
413 my_snprintf(buf, maxlen, "lck %ld", e->lock_cnt());
415 if (dst != dst_orig || e->lock_cnt())
416 my_snprintf(buf, maxlen, ") ");
418 my_snprintf(buf, maxlen, " krnl %s", symstr);
427 formatter_trap(Tb_entry *tb, const char *tidstr, unsigned tidlen,
428 char *buf, int maxlen)
430 Tb_entry_trap *e = static_cast<Tb_entry_trap*>(tb);
433 my_snprintf(buf, maxlen, "#%02x: %-*s err=%08x @ " L4_PTR_FMT,
434 e->trapno(), tidlen, tidstr, e->error(), e->ip());
436 my_snprintf(buf, maxlen,
438 ? "#%02x: %-*s err=%04x @ " L4_PTR_FMT
439 " cs=%04x sp=" L4_PTR_FMT " cr2=" L4_PTR_FMT
440 : "#%02x: %-*s err=%04x @ " L4_PTR_FMT
441 " cs=%04x sp=" L4_PTR_FMT " eax=" L4_PTR_FMT,
443 tidlen, tidstr, e->error(), e->ip(), e->cs(), e->sp(),
444 e->trapno() == 14 ? e->cr2() : e->eax());
452 formatter_sched(Tb_entry *tb, const char *tidstr, unsigned tidlen,
453 char *buf, int maxlen)
455 Tb_entry_sched *e = static_cast<Tb_entry_sched*>(tb);
456 Thread const *_t = static_cast<Thread const *>(e->owner());
458 if (Jdb_util::is_mapped(_t))
462 my_snprintf(buf, maxlen,
463 "%-*s (ts %s) owner:%lx id:%2x, prio:%2x, left:%6ld/%-6lu",
465 e->mode() == 0 ? "save" :
466 e->mode() == 1 ? "load" :
467 e->mode() == 2 ? "invl" : "????",
469 e->id(), e->prio(), e->left(), e->quantum());
477 formatter_preemption(Tb_entry *tb, const char *tidstr, unsigned tidlen,
478 char *buf, int maxlen)
480 Tb_entry_preemption *e = static_cast<Tb_entry_preemption*>(tb);
481 Mword t = e->preempter();
483 my_snprintf(buf, maxlen,
484 "pre: %-*s sent to %lx",
490 // kernel event log binary data
493 formatter_ke_bin(Tb_entry *tb, const char *tidstr, unsigned tidlen,
494 char *buf, int maxlen)
496 Tb_entry_ke_bin *e = static_cast<Tb_entry_ke_bin*>(tb);
499 snprintf(ip_buf, sizeof(ip_buf), " @ " L4_PTR_FMT, e->ip());
500 my_snprintf(buf, maxlen, "ke: %-*s BINDATA %s",
501 tidlen, tidstr, e->ip() ? ip_buf : "");
506 STATIC_INITIALIZER(init_formatters);
508 // register all available format functions
513 Jdb_tbuf_output::register_ff(Tbuf_pf, formatter_pf);
514 Jdb_tbuf_output::register_ff(Tbuf_pf_res, formatter_pf_res);
515 Jdb_tbuf_output::register_ff(Tbuf_ipc, formatter_ipc);
516 Jdb_tbuf_output::register_ff(Tbuf_ipc_res, formatter_ipc_res);
517 Jdb_tbuf_output::register_ff(Tbuf_ke, formatter_ke);
518 Jdb_tbuf_output::register_ff(Tbuf_ke_reg, formatter_ke_reg);
519 Jdb_tbuf_output::register_ff(Tbuf_shortcut_succeeded, formatter_ipc);
520 Jdb_tbuf_output::register_ff(Tbuf_context_switch, formatter_ctx_switch);
521 Jdb_tbuf_output::register_ff(Tbuf_breakpoint, formatter_bp);
522 Jdb_tbuf_output::register_ff(Tbuf_trap, formatter_trap);
523 Jdb_tbuf_output::register_ff(Tbuf_sched, formatter_sched);
524 Jdb_tbuf_output::register_ff(Tbuf_preemption, formatter_preemption);
525 Jdb_tbuf_output::register_ff(Tbuf_ke_bin, formatter_ke_bin);