3 #include "jdb_module.h"
8 class Jdb_kobject_handler;
10 class Jdb_kobject : public Jdb_module
16 Jdb_kobject_handler *_first;
17 Jdb_kobject_handler **_tail;
22 class Jdb_kobject_handler
24 friend class Jdb_kobject;
27 Jdb_kobject_handler(char const *type) : kobj_type(type) {}
28 char const *kobj_type;
29 virtual bool show_kobject(Kobject_common *o, int level) = 0;
30 virtual int show_kobject_short(char *, int, Kobject_common *) { return 0; }
31 virtual Kobject_common *follow_link(Kobject_common *o) { return o; }
32 virtual ~Jdb_kobject_handler() {}
33 virtual bool invoke(Kobject_common *o, Syscall_frame *f, Utcb *utcb);
34 virtual bool handle_key(Kobject_common *, int /*keycode*/) { return false; }
35 virtual Kobject *parent(Kobject_common *) { return 0; }
36 virtual char const *kobject_type() const { return kobj_type; }
43 Op_query_log_typeid = 3,
46 Op_query_log_name = 6,
49 Jdb_kobject_handler *_next;
52 class Jdb_kobject_extension : public Kobject_dbg::Dbg_extension
55 virtual ~Jdb_kobject_extension() {}
56 virtual char const *type() const = 0;
59 class Jdb_kobject_list : public Jdb_list
62 typedef bool Filter_func(Kobject_common const *);
71 Mode(char const *name, Filter_func *filter)
72 : name(name), filter(filter)
74 // make sure that non-filtered mode is first in the list so that we
75 // get this one displayed initially
76 if (!filter || !first)
89 void *get_head() const
90 { return Kobject::from_dbg(Kobject_dbg::_jdb_head.get_unused()); }
93 Mode const *_current_mode;
98 //--------------------------------------------------------------------------
106 #include "entry_frame.h"
108 #include "jdb_core.h"
109 #include "jdb_module.h"
110 #include "jdb_screen.h"
111 #include "kernel_console.h"
113 #include "keycodes.h"
114 #include "ram_quota.h"
115 #include "simpleio.h"
117 #include "static_init.h"
119 Jdb_kobject_list::Mode *Jdb_kobject_list::Mode::first;
121 class Jdb_kobject_id_hdl : public Jdb_kobject_handler
124 Jdb_kobject_id_hdl() : Jdb_kobject_handler(0) {}
125 virtual bool show_kobject(Kobject_common *, int) { return false; }
126 virtual ~Jdb_kobject_id_hdl() {}
131 Jdb_kobject_id_hdl::invoke(Kobject_common *o, Syscall_frame *f, Utcb *utcb)
133 if ( utcb->values[0] != Op_global_id
134 && utcb->values[0] != Op_kobj_to_id)
137 if (utcb->values[0] == Op_global_id)
138 utcb->values[0] = o->dbg_info()->dbg_id();
140 utcb->values[0] = Kobject_dbg::pointer_to_id((void *)utcb->values[1]);
141 f->tag(Kobject_iface::commit_result(0, 1));
148 Jdb_kobject_list::get_first()
150 Kobject *f = static_cast<Kobject*>(get_head());
151 while (f && _filter && !_filter(f))
152 f = Kobject::from_dbg(f->dbg_info()->_next);
158 Jdb_kobject_list::Jdb_kobject_list(Filter_func *filt)
159 : Jdb_list(), _current_mode(0), _filter(filt)
160 { set_start(get_first()); }
163 Jdb_kobject_list::Jdb_kobject_list()
164 : Jdb_list(), _current_mode(Mode::first), _filter(0)
167 _filter = _current_mode->filter;
169 set_start(get_first());
174 Jdb_kobject_list::show_item(char *buffer, int max, void *item) const
176 return Jdb_kobject::obj_description(buffer, max, false, static_cast<Kobject*>(item));
181 Jdb_kobject_list::enter_item(void *item) const
183 Kobject *o = static_cast<Kobject*>(item);
184 return Jdb_kobject::module()->handle_obj(o, 1);
189 Jdb_kobject_list::follow_link(void *item)
191 Kobject *o = static_cast<Kobject*>(item);
192 Jdb_kobject_handler *h = Jdb_kobject::module()->find_handler(o);
194 return h->follow_link(o);
201 Jdb_kobject_list::handle_key(void *item, int keycode)
203 Kobject *o = static_cast<Kobject*>(item);
204 Jdb_kobject_handler *h = Jdb_kobject::module()->first_global_handler();
205 bool handled = false;
208 handled |= h->handle_key(o, keycode);
209 h = h->next_global();
212 h = Jdb_kobject::module()->find_handler(o);
214 handled |= h->handle_key(o, keycode);
219 PRIVATE inline NOEXPORT
221 Jdb_kobject_list::next(Kobject *o)
228 o = Kobject::from_dbg(o->dbg_info()->_next);
230 while (o && _filter && !_filter(o));
234 PRIVATE inline NOEXPORT
236 Jdb_kobject_list::prev(Kobject *o)
243 o = Kobject::from_dbg(o->dbg_info()->_pref);
245 while (o && _filter && !_filter(o));
251 Jdb_kobject_list::seek(int cnt, void **item)
253 Kobject *c = static_cast<Kobject*>(*item);
257 for (i = 0; i < cnt; ++i)
259 Kobject *n = next(c);
267 for (i = 0; i < -cnt; ++i)
269 Kobject *n = prev(c);
289 Jdb_kobject_list::show_head() const
297 Jdb_kobject_list::get_mode_str() const
301 return _current_mode->name;
308 Jdb_kobject_list::next_mode()
313 _current_mode = _current_mode->next;
315 _current_mode = Mode::first;
317 _filter = _current_mode->filter;
320 /* When the mode changes the current object may get invisible,
321 * get a new visible one */
324 Jdb_kobject_list::get_valid(void *o)
329 if (_filter && _filter(static_cast<Kobject*>(o)))
336 Jdb_kobject_handler::invoke(Kobject_common *, Syscall_frame *, Utcb *)
340 Jdb_kobject_handler *
341 Jdb_kobject_handler::next_global()
343 Jdb_kobject_handler *h = this->_next;
353 void *Jdb_kobject::kobjp;
356 Jdb_kobject::Jdb_kobject()
357 : Jdb_module("INFO"),
366 Jdb_kobject::register_handler(Jdb_kobject_handler *h)
374 Jdb_kobject_handler *
375 Jdb_kobject::first_global_handler() const
377 if (!_first || !_first->kobj_type)
379 return _first->next_global();
383 Jdb_kobject_handler *
384 Jdb_kobject::find_handler(Kobject_common *o)
386 Jdb_kobject_handler *h = _first;
389 if (o->kobj_type() == h->kobj_type)
398 Jdb_kobject::handle_obj(Kobject *o, int lvl)
400 Jdb_kobject_handler *h = find_handler(o);
402 return h->show_kobject(o, lvl);
409 Jdb_kobject::kobject_type(Kobject_common *o)
411 Jdb_kobject_handler *h = module()->find_handler(o);
413 return h->kobject_type();
414 return o->kobj_type();
420 Jdb_kobject::obj_description(char *buffer, int max, bool dense, Kobject_common *o)
422 int pos = snprintf(buffer, max,
423 dense ? "%lx %lx [%-*s]" : "%8lx %08lx [%-*s]",
424 o->dbg_info()->dbg_id(), (Mword)o, 7, kobject_type(o));
426 Jdb_kobject_handler *h = Jdb_kobject::module()->first_global_handler();
429 pos += h->show_kobject_short(buffer + pos, max-pos, o);
430 h = h->next_global();
433 Jdb_kobject_handler *oh = Jdb_kobject::module()->find_handler(o);
435 pos += oh->show_kobject_short(buffer + pos, max-pos, o);
442 Jdb_kobject::print_kobj(Kobject *o)
444 printf("%p [type=%s]", o, o->kobj_type());
448 Jdb_module::Action_code
449 Jdb_kobject::action(int cmd, void *&, char const *&, int &)
454 Kobject *k = Kobject::pointer_to_obj(kobjp);
456 printf("Not a kobj.\n");
459 if (!handle_obj(k, 0))
460 printf("Kobj w/o handler: ");
468 Jdb_kobject_list list;
475 Jdb_module::Cmd const *
476 Jdb_kobject::cmds() const
480 { 0, "K", "kobj", "%p", "K<kobj_ptr>\tshow information for kernel object",
482 { 1, "Q", "listkobj", "", "Q\tshow information for kernel objects", 0 },
489 Jdb_kobject::num_cmds() const
492 STATIC_INITIALIZE_P(Jdb_kobject, JDB_MODULE_INIT_PRIO);
496 Jdb_kobject::fmt_handler(char /*fmt*/, int *size, char const *cmd_str, void *arg)
504 *size = sizeof(void*);
506 while((c = Jdb_core::cmd_getchar(cmd_str)) != ' ' && c!=KEY_RETURN)
511 if(c==KEY_BACKSPACE && pos>0)
517 if (pos < (int)sizeof(buffer) - 1)
525 void **a = (void**)arg;
533 char const *num = buffer;
534 if (buffer[0] == 'P')
537 n = strtoul(num, 0, 16);
541 if (buffer[0] != 'P')
542 ko = Kobject::id_to_obj(n);
544 ko = Kobject::pointer_to_obj((void*)n);
557 Jdb_core::add_fmt_handler('q', fmt_handler);
559 // static Jdb_handler enter(at_jdb_enter);
561 static Jdb_kobject_id_hdl id_hdl;
562 module()->register_handler(&id_hdl);
567 Jdb_kobject::module()
569 static Jdb_kobject jdb_kobj_module;
570 return &jdb_kobj_module;
573 // Be robust if this object is invalid
576 Jdb_kobject::print_uid(Kobject_common *o, int task_format = 0)
580 printf("%*.s", task_format, "---");
584 if (Kobject_dbg::is_kobj(o))
586 printf("%*.lx", task_format, o->dbg_info()->dbg_id());
590 printf("\033[31;1m%*s%p\033[m", task_format, "???", o);
596 sys_invoke_debug(Kobject_iface *o, Syscall_frame *f)
600 f->tag(Kobject_iface::commit_result(-L4_err::EInval));
604 Utcb *utcb = current_thread()->utcb().access();
605 //printf("sys_invoke_debug: [%p] -> %p\n", o, f);
606 Jdb_kobject_handler *h = Jdb_kobject::module()->find_handler(o);
607 if (h && h->invoke(o, f, utcb))
610 h = Jdb_kobject::module()->first_global_handler();
613 if (h->invoke(o, f, utcb))
615 h = h->next_global();
618 f->tag(Kobject_iface::commit_result(-L4_err::ENosys));
622 template< typename T >
625 Jdb_kobject_extension::find_extension(Kobject_common const *o)
627 Kobject_dbg::Dbg_extension *ex = o->dbg_info()->_jdb_data;
630 Jdb_kobject_extension *je = static_cast<Jdb_kobject_extension*>(ex);
631 if (je->type() == T::static_type)
632 return static_cast<T*>(je);
640 static Jdb_kobject_list::Mode INIT_PRIORITY(JDB_MODULE_INIT_PRIO) all("[ALL]", 0);