/********************************************************************* * * Copyright (C) 2002, 2003, 2008, Karlsruhe University * * File path: kdb/generic/memdump.cc * Description: Memory dumping code * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * $Id: memdump.cc,v 1.15 2006/10/02 16:05:00 reichelt Exp $ * ********************************************************************/ #include #include #include #include #include #include INC_API(tcb.h) char getc (void); void memdump_loop (space_t * space, addr_t addr); void memdump (space_t * space, addr_t addr); /** * Current wordsize for memory dumps */ static word_t memdump_wordsize = sizeof (word_t); /** * Change memory dump word size. */ DECLARE_CMD (cmd_wordsize, config, 'w', "wordsize", "change memdump word size"); CMD(cmd_wordsize, cg) { memdump_wordsize *= 2; if (memdump_wordsize > sizeof (word_t)) memdump_wordsize = 1; printf ("Memdump wordsize = %d\n", memdump_wordsize); return CMD_NOQUIT; } /** * Dump memory contents of current space. */ DECLARE_CMD (cmd_memdump, root, 'd', "memdump", "dump memory"); CMD (cmd_memdump, cg) { word_t addr = get_hex ("Dump address", kdb.last_dump); if (addr == ABORT_MAGIC) return CMD_NOQUIT; kdb.last_dump = addr; memdump_loop (kdb.kdb_current->get_space (), (addr_t) addr); return CMD_NOQUIT; } /** * Dump memory contents of other space. */ DECLARE_CMD (cmd_memdump_remote, root, 'D', "memdump", "dump memory in other space"); CMD(cmd_memdump_remote, cg) { word_t addr = get_hex ("Dump address", kdb.last_dump); if (addr == ABORT_MAGIC) return CMD_NOQUIT; kdb.last_dump = addr; memdump_loop (get_space ("Space"), (addr_t) addr); return CMD_NOQUIT; } void memdump_loop (space_t * space, addr_t addr) { if (!space) space = get_kernel_space(); do { memdump (space, addr); addr = addr_offset (addr, 16*16); } while (get_choice ("Continue?", "Continue/Quit", 'c') != 'q'); } void memdump (space_t * space, addr_t addr) { for (int j = 0; j < 16; j++) { printf ("%p ", addr); switch (memdump_wordsize) { case 1: { u8_t v, *x = (u8_t *) addr; for (int i = 0; i < 16; i++, x++) { if (i == 8) printf (" "); if (! readmem (space, x, &v)) printf ("## "); else printf ("%02x ", v); } break; } case 2: { u16_t v, *x = (u16_t *) addr; for (int i = 0; i < 8; i++, x++) { if (i == 4) printf (" "); if (! readmem (space, x, &v)) printf ("#### "); else printf ("%04x ", v); } break; } case 4: { u32_t v, *x = (u32_t *) addr; for (int i = 0; i < 4; i++, x++) { if (! readmem (space, x, &v)) printf ("######## "); else printf ("%08x ", v); } break; } #if !defined(CONFIG_IS_32BIT) case 8: { u64_t v, *x = (u64_t *) addr; for (int i = 0; i < 2; i++, x++) { if (! readmem (space, x, &v)) printf ("################ "); else printf ("%016x ", v); } break; } #endif } u8_t * c = (u8_t *) addr; printf (" "); for (int i = 0; i < 16; i++, c++) { u8_t v, *x = (u8_t *) c; if (i == 8) printf (" "); if (! readmem (space, x, &v)) printf ("#"); else printf ("%c", ((v >= 32 && v < 127) || (v >= 161 && v <= 191) || (v >= 224)) ? v : '.'); } printf ("\n"); addr = addr_offset (addr, 16); } }