|
|
| [Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] |
Hello Dave, I made a new patch to implement the -C option for search. This time the patch is accomplished in a simple manner according to your advice. Thanks. Zhang Yanfei
>From 0cde596e587b2344948118c04ed7416d68ae5fe2 Mon Sep 17 00:00:00 2001
From: zhangyanfei <zhangyanfei@xxxxxxxxxxxxxx>
Date: Thu, 9 Feb 2012 15:32:11 +0800
Subject: [PATCH] Add option -C for sub-command search.
Signed-off-by: zhangyanfei <zhangyanfei@xxxxxxxxxxxxxx>
---
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
-- Crash-utility mailing list Crash-utility@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/crash-utility
[Home] [Fedora Legacy List] [Fedora Maintainers] [Fedora Desktop] [Red Hat 9 Bible] [Fedora Bible] [Fedora SELinux] [Big List of Linux Books] [Yosemite News] [Yosemite Photos] [KDE Users] [Fedora Tools]
![]() |