>From 0cde596e587b2344948118c04ed7416d68ae5fe2 Mon Sep 17 00:00:00 2001 From: zhangyanfei Date: Thu, 9 Feb 2012 15:32:11 +0800 Subject: [PATCH] Add option -C for sub-command search. Signed-off-by: zhangyanfei --- help.c | 5 +- memory.c | 271 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 261 insertions(+), 15 deletions(-) diff --git a/help.c b/help.c index f752283..d3317f4 100755 --- a/help.c +++ b/help.c @@ -2343,7 +2343,7 @@ char *help_search[] = { "seach", "search memory", "[-s start] [ -[kKV] | -u | -p ] [-e end | -l length] [-m mask]\n" -" -[cwh] value ...", +" [-C num] -[cwh] value ...", " This command searches for a given value within a range of user virtual, kernel", " virtual, or physical memory space. If no end nor length value is entered, ", " then the search stops at the end of user virtual, kernel virtual, or physical", @@ -2374,6 +2374,9 @@ char *help_search[] = { " appropriate for the memory type specified.", " -l length Length in bytes of address range to search.", " -m mask Ignore the bits that are set in the hexadecimal mask value.", +" -C num Also display memory contents just before and after value. The size", +" of the memory displayed before(after) value is num * sizeof(value).", +" Note, this option is ignored when -c is specified.", " -c Search for character string values instead of unsigned longs. If", " the string contains any space(s), it must be encompassed by double", " quotes.", diff --git a/memory.c b/memory.c index 55a184b..6672770 100755 --- a/memory.c +++ b/memory.c @@ -87,6 +87,8 @@ struct meminfo { /* general purpose memory information structure */ struct searchinfo { int mode; int vcnt; + int c_num; + ulong memtype; union { /* default ulong search */ struct { @@ -176,6 +178,8 @@ static int dump_page_lists(struct meminfo *); static void dump_kmeminfo(void); static int page_to_phys(ulong, physaddr_t *); static void display_memory(ulonglong, long, ulong, int, void *); +static int get_search_page(ulonglong, char *, struct searchinfo *); +static void display_with_pre_and_post(void *, ulonglong, ulonglong, struct searchinfo *); static ulong search_ulong(ulong *, ulong, int, struct searchinfo *); static ulong search_uint(ulong *, ulong, int, struct searchinfo *); static ulong search_ushort(ulong *, ulong, int, struct searchinfo *); @@ -11617,7 +11621,7 @@ generic_get_kvaddr_ranges(struct vaddr_range *rp) void cmd_search(void) { - int i, c, ranges; + int i, c, ranges, c_num; ulonglong start, end; ulong mask, memtype, len; ulong uvaddr_start, uvaddr_end; @@ -11631,6 +11635,7 @@ cmd_search(void) #define vaddr_overflow(ADDR) (BITS32() && ((ADDR) > 0xffffffffULL)) + c_num = 0; start = end = mask = sflag = pflag = Kflag = Vflag = memtype = len = 0; kvaddr_start = kvaddr_end = 0; uvaddr_start = UNINITIALIZED; @@ -11668,7 +11673,7 @@ cmd_search(void) searchinfo.mode = SEARCH_ULONG; /* default search */ - while ((c = getopt(argcnt, args, "l:ukKVps:e:v:m:hwc")) != EOF) { + while ((c = getopt(argcnt, args, "l:ukKVps:e:v:m:hwcC:")) != EOF) { switch(c) { case 'u': @@ -11769,6 +11774,10 @@ cmd_search(void) searchinfo.mode = SEARCH_CHARS; break; + case 'C': + c_num = dtoi(optarg, FAULT_ON_ERROR, NULL); + break; + default: argerrs++; break; @@ -11790,6 +11799,8 @@ cmd_search(void) if (argerrs || !sflag || !args[optind] || (len && end) || !memtype) cmd_usage(pc->curcmd, SYNOPSIS); + searchinfo.memtype = memtype; + /* * Verify starting address. */ @@ -11916,6 +11927,37 @@ cmd_search(void) } } + if (c_num) { + switch (searchinfo.mode) + { + case SEARCH_ULONG: + if (c_num > PAGESIZE()/sizeof(long)) { + error(INFO, "WARNING: too many numbers and" + " -C option is ignored\n"); + c_num = 0; + } + break; + case SEARCH_UINT: + if (c_num > PAGESIZE()/sizeof(int)) { + error(INFO, "WARNING: too many numbers and" + " -C option is ignored\n"); + c_num = 0; + } + break; + case SEARCH_USHORT: + if (c_num > PAGESIZE()/sizeof(short)) { + error(INFO, "WARNING: too many numbers and" + " -C option is ignored\n"); + c_num = 0; + } + break; + case SEARCH_CHARS: + error(INFO, "-C option ignored on string search\n"); + c_num = 0; + break; + } + } + searchinfo.c_num = c_num; searchinfo.vcnt = 0; while (args[optind]) { @@ -12013,15 +12055,191 @@ cmd_search(void) #define SEARCHMASK(X) ((X) | mask) +static int +get_search_page(ulonglong ppp, char *pagebuf, struct searchinfo *si) +{ + ulong page; + physaddr_t paddr; + ulong pp; + ulong memtype; + + pp = (ulong)ppp; + memtype = si->memtype; + + if (memtype == PHYSADDR) { + if (!phys_to_page(ppp, &page) || + !readmem(ppp, PHYSADDR, pagebuf, PAGESIZE(), + "search page", RETURN_ON_ERROR|QUIET)) { + return 0; + } + return 1; + } + + /* + * Keep it virtual for Xen hypervisor. + */ + if (XEN_HYPER_MODE()) { + if (!readmem(pp, KVADDR, pagebuf, PAGESIZE(), + "search page", RETURN_ON_ERROR|QUIET)) { + return 0; + } + return 1; + } + + switch (memtype) + { + case UVADDR: + if (!uvtop(CURRENT_CONTEXT(), pp, &paddr, 0) || + !phys_to_page(paddr, &page)) { + return 0; + } + break; + + case KVADDR: + if (!kvtop(CURRENT_CONTEXT(), pp, &paddr, 0) || + !phys_to_page(paddr, &page)) { + return 0; + } + break; + } + + if (!readmem(paddr, PHYSADDR, pagebuf, PAGESIZE(), + "search page", RETURN_ON_ERROR|QUIET)) { + return 0; + } + + return 1; +} + +#define print_addr(addr, si) \ +do { \ + if (si->memtype == PHYSADDR) \ + fprintf(fp, "%llx: ", addr); \ + else \ + fprintf(fp, "%lx: ", (ulong)addr); \ +} while (0); + +#define print_value(bufptr, offset, si) \ +do { \ + switch(si->mode) \ + { \ + case SEARCH_ULONG: \ + fprintf(fp, "%lx ", *((ulong *)bufptr + offset)); \ + break; \ + case SEARCH_UINT: \ + fprintf(fp, "%x ", *((uint *)bufptr + offset)); \ + break; \ + case SEARCH_USHORT: \ + fprintf(fp, "%x ", *((ushort *)bufptr + offset)); \ + break; \ + } \ +} while (0); + +static void +display_with_pre_and_post(void *bufptr, ulonglong addr_base, ulonglong addr, struct searchinfo *si) +{ + int cnt, cnt1, cnt2, wordcnt, exist; + int i, c_num, t, offset; + char *buf; + ulonglong pre_addr_base, post_addr_base, tmpaddr; + + switch (si->mode) + { + case SEARCH_USHORT: + t = sizeof(ushort); + break; + case SEARCH_UINT: + t = sizeof(uint); + break; + case SEARCH_ULONG: + default: + t = sizeof(ulong); + break; + } + + cnt = offset = 0; + cnt1 = (addr - addr_base) / t; + cnt2 = (PAGESIZE() - (addr - addr_base)) / t - 1; + wordcnt = PAGESIZE() / t; + exist = 0; + c_num = si->c_num; + pre_addr_base = post_addr_base = addr_base; + + buf = GETBUF(PAGESIZE()); + + if (cnt1 < c_num && addr_base >= PAGESIZE()) { /* read pre-page */ + pre_addr_base -= PAGESIZE(); + exist = get_search_page(pre_addr_base, buf, si); + } + + if (exist) { + cnt = cnt1 - c_num + wordcnt; + tmpaddr = pre_addr_base + cnt * t; + print_addr(tmpaddr, si); + for (i = cnt; i < wordcnt; i++) + print_value(buf, i, si); + } else { + if (cnt1 >= c_num) { + tmpaddr = addr - c_num * t; + print_addr(tmpaddr, si); + } else if (cnt1 != 0) + print_addr(addr_base, si); + } + + cnt = cnt1 < c_num ? 0 : cnt1 - c_num; + for (i = cnt; i < cnt1; i++) { + offset = i - cnt1; + print_value(bufptr, offset, si); + } + if (exist || cnt1 != 0) + fprintf(fp, "\n"); + + print_addr(addr, si); + print_value(bufptr, 0, si); + + exist = 0; + if (cnt2 < c_num) { /* read post-page */ + post_addr_base += PAGESIZE(); + exist = get_search_page(post_addr_base, buf, si); + } + + cnt = cnt2 < c_num ? cnt2 : c_num - 1; + for (i = 1; i <= cnt; i++) + print_value(bufptr, i, si); + + if (cnt2 >= c_num) { + fprintf(fp, "\n"); + tmpaddr = addr + c_num * t; + print_addr(tmpaddr, si); + print_value(bufptr, c_num, si); + } else { + if (exist) { + cnt = c_num - cnt2 - 1; + for (i = 0; i < cnt; i++) + print_value(buf, i, si); + fprintf(fp, "\n"); + tmpaddr = post_addr_base + cnt * t; + print_addr(tmpaddr, si); + print_value(buf, cnt, si); + } + } + fprintf(fp, "\n--\n"); +} + static ulong search_ulong(ulong *bufptr, ulong addr, int longcnt, struct searchinfo *si) { int i, j; + ulong addr_base = VIRTPAGEBASE(addr); ulong mask = si->s_parms.s_ulong.mask; for (i = 0; i < longcnt; i++, bufptr++, addr += sizeof(long)) { for (j = 0; j < si->vcnt; j++) { - if (SEARCHMASK(*bufptr) == SEARCHMASK(si->s_parms.s_ulong.value[j])) - fprintf(fp, "%lx: %lx\n", addr, *bufptr); + if (SEARCHMASK(*bufptr) == SEARCHMASK(si->s_parms.s_ulong.value[j])) { + if (si->c_num) + display_with_pre_and_post(bufptr, addr_base, addr, si); + else + fprintf(fp, "%lx: %lx\n", addr, *bufptr); + } } } return addr; @@ -12032,11 +12250,16 @@ static ulonglong search_ulong_p(ulong *bufptr, ulonglong addr, int longcnt, struct searchinfo *si) { int i, j; + ulonglong addr_base = PHYSPAGEBASE(addr); ulong mask = si->s_parms.s_ulong.mask; for (i = 0; i < longcnt; i++, bufptr++, addr += sizeof(long)) { for (j = 0; j < si->vcnt; j++) { - if (SEARCHMASK(*bufptr) == SEARCHMASK(si->s_parms.s_ulong.value[j])) - fprintf(fp, "%llx: %lx\n", addr, *bufptr); + if (SEARCHMASK(*bufptr) == SEARCHMASK(si->s_parms.s_ulong.value[j])) { + if (si->c_num) + display_with_pre_and_post(bufptr, addr_base, addr, si); + else + fprintf(fp, "%llx: %lx\n", addr, *bufptr); + } } } return addr; @@ -12048,12 +12271,17 @@ search_uint(ulong *bufptr, ulong addr, int longcnt, struct searchinfo *si) int i, j; int cnt = longcnt * (sizeof(long)/sizeof(int)); uint *ptr = (uint *)bufptr; + ulong addr_base = VIRTPAGEBASE(addr); uint mask = si->s_parms.s_uint.mask; for (i = 0; i < cnt; i++, ptr++, addr += sizeof(int)) { for (j = 0; j < si->vcnt; j++) { - if (SEARCHMASK(*ptr) == SEARCHMASK(si->s_parms.s_uint.value[j])) - fprintf(fp, "%lx: %x\n", addr, *ptr); + if (SEARCHMASK(*ptr) == SEARCHMASK(si->s_parms.s_uint.value[j])) { + if (si->c_num) + display_with_pre_and_post(ptr, addr_base, addr, si); + else + fprintf(fp, "%lx: %x\n", addr, *ptr); + } } } return addr; @@ -12066,12 +12294,17 @@ search_uint_p(ulong *bufptr, ulonglong addr, int longcnt, struct searchinfo *si) int i, j; int cnt = longcnt * (sizeof(long)/sizeof(int)); uint *ptr = (uint *)bufptr; + ulonglong addr_base = PHYSPAGEBASE(addr); uint mask = si->s_parms.s_uint.mask; for (i = 0; i < cnt; i++, ptr++, addr += sizeof(int)) { for (j = 0; j < si->vcnt; j++) { - if (SEARCHMASK(*ptr) == SEARCHMASK(si->s_parms.s_uint.value[j])) - fprintf(fp, "%llx: %x\n", addr, *ptr); + if (SEARCHMASK(*ptr) == SEARCHMASK(si->s_parms.s_uint.value[j])) { + if (si->c_num) + display_with_pre_and_post(ptr, addr_base, addr, si); + else + fprintf(fp, "%llx: %x\n", addr, *ptr); + } } } return addr; @@ -12083,12 +12316,17 @@ search_ushort(ulong *bufptr, ulong addr, int longcnt, struct searchinfo *si) int i, j; int cnt = longcnt * (sizeof(long)/sizeof(short)); ushort *ptr = (ushort *)bufptr; + ulong addr_base = VIRTPAGEBASE(addr); ushort mask = si->s_parms.s_ushort.mask; for (i = 0; i < cnt; i++, ptr++, addr += sizeof(short)) { for (j = 0; j < si->vcnt; j++) { - if (SEARCHMASK(*ptr) == SEARCHMASK(si->s_parms.s_ushort.value[j])) - fprintf(fp, "%lx: %x\n", addr, *ptr); + if (SEARCHMASK(*ptr) == SEARCHMASK(si->s_parms.s_ushort.value[j])) { + if (si->c_num) + display_with_pre_and_post(ptr, addr_base, addr, si); + else + fprintf(fp, "%lx: %x\n", addr, *ptr); + } } } return addr; @@ -12101,12 +12339,17 @@ search_ushort_p(ulong *bufptr, ulonglong addr, int longcnt, struct searchinfo *s int i, j; int cnt = longcnt * (sizeof(long)/sizeof(short)); ushort *ptr = (ushort *)bufptr; + ulonglong addr_base = PHYSPAGEBASE(addr); ushort mask = si->s_parms.s_ushort.mask; for (i = 0; i < cnt; i++, ptr++, addr += sizeof(short)) { for (j = 0; j < si->vcnt; j++) { - if (SEARCHMASK(*ptr) == SEARCHMASK(si->s_parms.s_ushort.value[j])) - fprintf(fp, "%llx: %x\n", addr, *ptr); + if (SEARCHMASK(*ptr) == SEARCHMASK(si->s_parms.s_ushort.value[j])) { + if (si->c_num) + display_with_pre_and_post(ptr, addr_base, addr, si); + else + fprintf(fp, "%llx: %x\n", addr, *ptr); + } } } return addr; -- 1.7.1