Extending the ddb command set
Guillaume Ballet
gballet at gmail.com
Sun Aug 17 17:17:55 UTC 2008
On Sat, Aug 16, 2008 at 5:15 PM, Sam Leffler <sam at freebsd.org> wrote:
>
> Guillaume Ballet wrote:
>>
>> Hello hackers,
>>
>> I am currently working on a small project and would like to add a few
>> commands to the set that is available in ddb.
>>
>> I found that very interesting albeit succinct presentation:
>> http://people.freebsd.org/~jhb/papers/bsdcan/2008/slides.odp<http://people.freebsd.org/%7Ejhb/papers/bsdcan/2008/slides.odp>
>>
>> where the author hints that I should use DB_COMMAND, which I did. Yet when
>> invoking ddb, the command does not appear in the help list. I have taken a
>> look at the source code and was expecting set_db_cmd_set to appear in my
>> module's section list when calling objdump -h
>>
>> Is DB_COMMAND only working within the kernel itself, and not modules?
>>
>>
>
> That is correct; you can't add ddb cmds from modules. It should be doable; just hasn't been done yet.
>
> Sam
>
It is indeed doable: Here are the diffs for a first attempt at doing
this. I am not entirely satisfied with it, though, as it does not work
with DB_SHOW_COMMAND and the likes... Also, I have to declare a lot of
ddb-related stuff into kern_linker.c and I don't like it. I am
currently working at improving the whole thing, but in the mean time
if someone wants to give it a try, comments/rants would be greatly
appreciated.
Guillaume
--- sys/linker.h.orig 2008-08-17 18:45:56.000000000 +0200
+++ sys/linker.h 2008-08-17 18:50:57.000000000 +0200
@@ -155,6 +155,9 @@
int linker_ddb_search_symbol(caddr_t _value, c_linker_sym_t *_sym,
long *_diffp);
int linker_ddb_symbol_values(c_linker_sym_t _sym, linker_symval_t *_symval);
+struct command;
+int linker_ddb_cmd_search(char *, struct command **);
+int linker_ddb_cmd_list(void);
/* HWPMC helper */
--- kern/kern_linker.c.orig 2008-08-17 08:38:51.000000000 +0200
+++ kern/kern_linker.c 2008-08-17 18:47:45.000000000 +0200
@@ -777,6 +777,9 @@
* that the files list is inconsistant instead.
*/
+#include <ddb/ddb.h>
+#include <ddb/db_output.h>
+
int
linker_ddb_lookup(const char *symstr, c_linker_sym_t *sym)
{
@@ -831,6 +834,52 @@
}
return (ENOENT);
}
+
+int linker_ddb_cmd_list()
+{
+ linker_file_t lf;
+ struct command **start, **stop, **search;
+
+ TAILQ_FOREACH(lf, &linker_files, link) {
+ if (!linker_file_lookup_set(lf,"db_cmd_set",&start,&stop,NULL)) {
+ for (search=start; search < stop; search++) {
+ db_printf("%-12s", (*search)->name);
+ db_end_line(12);
+ }
+ }
+ }
+
+ return 0;
+}
+
+int linker_ddb_cmd_search(char *name, struct command **cmdp)
+{
+ linker_file_t lf;
+ char *lp, *rp;
+ struct command **cmd, **start, **stop;
+ int c;
+
+ TAILQ_FOREACH(lf, &linker_files, link) {
+ if (!linker_file_lookup_set(lf, "db_cmd_set", &start, &stop, NULL)) {
+ for (cmd=start; cmd < stop; cmd++) {
+ lp = name;
+ rp = (*cmd)->name;
+
+ while((c = *lp) == *rp) {
+ if (c == 0) {
+ *cmdp = *cmd;
+ return 0;
+ }
+
+ lp++;
+ rp++;
+ }
+ }
+ }
+ }
+
+ return -1;
+}
#endif
/*
--- ddb/db_command.c.orig 2008-08-17 10:26:26.000000000 +0200
+++ ddb/db_command.c 2008-08-17 18:42:22.000000000 +0200
@@ -253,6 +253,9 @@
if (result == CMD_UNIQUE)
return (CMD_UNIQUE);
}
+ if (result == CMD_NONE && linker_ddb_cmd_search(name,cmdp) == 0) {
+ result = CMD_UNIQUE;
+ }
if (result == CMD_NONE) {
/* check for 'help' */
if (name[0] == 'h' && name[1] == 'e'
@@ -280,6 +283,7 @@
db_printf("%-12s", (*aux_cmdp)->name);
db_end_line(12);
}
+ linker_ddb_cmd_list();
}
static void
--- ddb/db_command.h.orig 2008-08-17 18:37:34.000000000 +0200
+++ ddb/db_command.h 2008-08-17 18:49:29.000000000 +0200
@@ -46,4 +46,7 @@
extern db_addr_t db_next; /* next address to be examined
or written */
+extern int linker_ddb_cmd_search(char*,struct command **);
+extern int linker_ddb_cmd_list(void);
+
#endif /* !_DDB_DB_COMMAND_H_ */
More information about the freebsd-hackers
mailing list