Subject: Re: DDB changes
To: None <jchacon@genuity.net>
From: John Hawkinson <jhawk@MIT.EDU>
List: tech-kern
Date: 12/28/2000 08:42:34
| I've just committed changes to ddb which make x/m work.

Cool.

| I've never done much with ddb on mach (or anywhere else really) so this was 
| built using my assumptions from other hexdump routines from rom monitor's
| I've used in the distant past.
...
| I'll include the above in the man page shortly, but I wanted to get the code
| in first to get a feel from anyone if they beleive this should behave 
| differently in some drastic way. 

So, it turns out that I screwed up. You asked if x/m had ever worked,
and I said "No". This this might perhaps be true, it's sort of misleading.
I'm afraid the confusion came because I thought it never worked in Mach
either and I was too tired to go and look it up. More fool I.

Code from Mach follows.

I don't care whether we use their implementation or not (though it might
be best), but we should try to maintain UI compatibility unless there's
a good reason not to.

--jhawk

                    case 'm':
                        db_next = db_xcdump(addr, size, count+1, task);
                        return;


#define DB_XCDUMP_NC    16
 
db_addr_t
db_xcdump(
        db_addr_t       addr,
        int             size,
        int             count,
        task_t          task)  
{
        register        i, n;
        db_expr_t       value;
        int             bcount;
        db_addr_t       off; 
        char            *name;
        char            data[DB_XCDUMP_NC];
  
        db_find_task_sym_and_offset(addr, &name, &off, task);
        for (n = count*size; n > 0; n -= bcount) {
            db_prev = addr;
            if (off == 0) {
                db_printf("%s:\n", name);
                off = -1;
            }               
            db_printf("%0*X:%s", 2*sizeof(db_addr_t), addr,
                        (size != 1)? " ": "");
            bcount = ((n > DB_XCDUMP_NC)? DB_XCDUMP_NC: n);
            if (trunc_page(addr) != trunc_page(addr+bcount-1)) {
                db_addr_t next_page_addr = trunc_page(addr+bcount-1);
                if (!DB_CHECK_ACCESS(next_page_addr, sizeof(int), task))
                    bcount = next_page_addr - addr;
            }
            db_read_bytes(addr, bcount, data, task);
            for (i = 0; i < bcount && off != 0; i += size) {
                if (i % 4 == 0)
                        db_printf(" ");
                value = db_get_task_value(addr, size, FALSE, task);
                db_printf("%0*x ", size*2, value);
                addr += size;
                db_find_task_sym_and_offset(addr, &name, &off, task);
            }
            db_printf("%*s",
                        ((DB_XCDUMP_NC-i)/size)*(size*2+1)+(DB_XCDUMP_NC-i)/4,
                         "");
            bcount = i;
            db_printf("%s*", (size != 1)? " ": "");
            for (i = 0; i < bcount; i++) {
                value = data[i];
i            for (i = 0; i < bcount; i++) {
                value = data[i];
                db_printf("%c", (value >= ' ' && value <= '~')? value: '.');
            }
            db_printf("*\n");
        }
        return addr;    
}