FAQ Search Today's Posts Mark Forums Read
» Video Reviews

» Linux Archive

Linux-archive is a website aiming to archive linux email lists and to make them easily accessible for linux users/developers.


» Sponsor

» Partners

» Sponsor

Go Back   Linux Archive > Redhat > Crash Utility

 
 
LinkBack Thread Tools
 
Old 02-07-2012, 06:46 AM
zhangyanfei
 
Default Add -C option for search

Hello Dave,

I add a new option -C for sub-command search to display memory contents
just before and after the search target. The number of the memory unit
displayed is specified by -C.

for example,
crash> search -p -C 3 dddd
17b5100: dddddddddddddddd dddddddddddddddd dddddddddddddddd
17b5118: dddd cdcdcdcdcdcdcdcd cdcdcdcdcdcdcdcd
17b5130: cdcdcdcdcdcdcdcd
--
85d04f818: 29 ffff88085d04f818 ffffea001d3f7e30
85d04f830: dddd 1000 ffff88085b48a000
85d04f848: ffff880876383b80
--
8752cfec8: ddd9 dddb dddb
8752cfee0: dddd dddd dddf
8752cfef8: dddf
--
8752cfed0: dddb dddb dddd
8752cfee8: dddd dddf dddf
8752cff00: dde1
--
crash>


Thanks.
Zhang Yanfei
>From 42998b52ae9e09eea373feb1614f56f1e62d1e84 Mon Sep 17 00:00:00 2001
From: zhangyanfei <zhangyanfei@cn.fujitsu.com>
Date: Fri, 3 Feb 2012 10:42:59 +0800
Subject: [PATCH] Add option -C for sub-command search.

Signed-off-by: zhangyanfei <zhangyanfei@cn.fujitsu.com>
---
help.c | 5 +-
memory.c | 657 ++++++++++++++++++++++++++++++++++++++++++++++++++------------
2 files changed, 534 insertions(+), 128 deletions(-)

diff --git a/help.c b/help.c
index bb552d9..addd88d 100755
--- a/help.c
+++ b/help.c
@@ -2327,7 +2327,7 @@ char *help_search[] = {
"seach",
"search memory",
"[-s start] [ -[kKV] | -u | -p ] [-e end | -l length] [-m mask]
"
-" -[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",
@@ -2358,6 +2358,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 ea4c6a0..7571dfa 100755
--- a/memory.c
+++ b/memory.c
@@ -87,6 +87,7 @@ struct meminfo { /* general purpose memory information structure */
struct searchinfo {
int mode;
int vcnt;
+ int c_num;
union {
/* default ulong search */
struct {
@@ -115,6 +116,22 @@ struct searchinfo {
} s_parms;
};

+/*
+ * buf_handled - contains the page that has been searched
+ * buf_handling - contains the page that is been searching
+ * buf_to_handle - contains the page that is to be searched
+ */
+struct pagebuf_t {
+ int exist; /* equals 0 if buf == NULL */
+ int wordcnt; /* num of search unit in one page */
+ char *buf; /* buffer of the page for searching */
+ ulong *ubp; /* the starting searching address in buf */
+ union {
+ ulonglong paddr; /* physical address of the searching page */
+ ulong vaddr; /* virtual address of the searching page */
+ } next;
+} buf_handled, buf_handling, buf_to_handle;
+
static char *memtype_string(int, int);
static char *error_handle_string(ulong);
static void dump_mem_map(struct meminfo *);
@@ -176,15 +193,19 @@ 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 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 *);
-static ulong search_chars(ulong *, ulong, int, struct searchinfo *);
-static ulonglong search_ulong_p(ulong *, ulonglong, int, struct searchinfo *);
-static ulonglong search_uint_p(ulong *, ulonglong, int, struct searchinfo *);
-static ulonglong search_ushort_p(ulong *, ulonglong, int, struct searchinfo *);
-static ulonglong search_chars_p(ulong *, ulonglong, int, struct searchinfo *);
+static ulong search_ulong(struct searchinfo *);
+static ulong search_uint(struct searchinfo *);
+static ulong search_ushort(struct searchinfo *);
+static ulong search_chars(struct searchinfo *);
+static ulonglong search_ulong_p(struct searchinfo *);
+static ulonglong search_uint_p(struct searchinfo *);
+static ulonglong search_ushort_p(struct searchinfo *);
+static ulonglong search_chars_p(struct searchinfo *);
+static void make_pagebuf(struct pagebuf_t *, int, int, char *, ulong *, ulong);
+static int get_search_page(ulong *, ulong, ulong, int);
static void search_virtual(ulong, ulong, int, struct searchinfo *);
+static void make_pagebuf_p(struct pagebuf_t *, int, int, char *, ulong *, ulonglong);
+static int get_search_page_p(ulonglong *, ulonglong, ulonglong);
static void search_physical(ulonglong, ulonglong, struct searchinfo *);
static int next_upage(struct task_context *, ulong, ulong *);
static int next_kpage(ulong, ulong *);
@@ -11585,7 +11606,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;
@@ -11599,6 +11620,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;
@@ -11636,7 +11658,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':
@@ -11737,6 +11759,10 @@ cmd_search(void)
searchinfo.mode = SEARCH_CHARS;
break;

+ case 'C':
+ c_num = dtoi(optarg, FAULT_ON_ERROR, NULL);
+ break;
+
default:
argerrs++;
break;
@@ -11884,6 +11910,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
");
+ c_num = 0;
+ }
+ break;
+ case SEARCH_UINT:
+ if (c_num > PAGESIZE()/sizeof(int)) {
+ error(INFO, "WARNING: too many numbers and"
+ " -C option is ignored
");
+ c_num = 0;
+ }
+ break;
+ case SEARCH_USHORT:
+ if (c_num > PAGESIZE()/sizeof(short)) {
+ error(INFO, "WARNING: too many numbers and"
+ " -C option is ignored
");
+ c_num = 0;
+ }
+ break;
+ case SEARCH_CHARS:
+ error(INFO, "-C option ignored on string search
");
+ c_num = 0;
+ break;
+ }
+ }
+ searchinfo.c_num = c_num;

searchinfo.vcnt = 0;
while (args[optind]) {
@@ -11981,15 +12038,96 @@ cmd_search(void)

#define SEARCHMASK(X) ((X) | mask)

+#define report_hex_match_pre(type, addr_mark, value_mark,
+ c_num, addr_base, addr, addr1_base, addr1, bufptr)
+do {
+ int cnt1 = PAGESIZE() / sizeof(type);
+ int cnt2 = (addr - addr_base) / sizeof(type);
+ int cnt3 = (addr1 - addr1_base) / sizeof(type);
+ int dis = cnt2 - c_num;
+ int t, k;
+ if (c_num) {
+ if (dis < 0 && buf_handled.exist &&
+ (addr1_base+cnt1*sizeof(type) == addr_base)) {
+ t = (cnt1 + dis) > 0 ? (cnt1 + dis) : 0;
+ fprintf(fp, addr_mark, addr1_base + t * sizeof(type));
+ for (k = t; k < cnt1; k++)
+ fprintf(fp, value_mark,
+ *(((type *)buf_handled.ubp)-cnt3+k));
+ } else {
+ t = dis < 0 ? cnt2 : c_num;
+ if (t > 0)
+ fprintf(fp, addr_mark, addr-t*sizeof(type));
+ }
+ t = dis < 0 ? 0 : dis;
+ for (k = t; k < cnt2; k++)
+ fprintf(fp, value_mark, *(bufptr - cnt2 + k));
+ fprintf(fp, "
");
+ }
+} while (0);
+
+#define report_hex_match_post(type, addr_mark, value_mark,
+ c_num, addr_base, addr, addr2_base, addr2, bufptr)
+do {
+ int cnt1 = (PAGESIZE() - (addr - addr_base)) / sizeof(type) - 1;
+ int cnt2 = PAGESIZE() / sizeof(type);
+ int cnt3 = (addr2 - addr2_base) / sizeof(type);
+ int dis = cnt1 - c_num;
+ int t, k;
+ if (c_num) {
+ t = dis < 0 ? cnt1 : c_num - 1;
+ fprintf(fp, " ");
+ for (k = 1; k <= t; k++)
+ fprintf(fp, value_mark, *(bufptr + k));
+ if (dis >= 0) {
+ fprintf(fp, "
");
+ fprintf(fp, addr_mark, addr + c_num * sizeof(type));
+ fprintf(fp, value_mark, *(bufptr + c_num));
+ } else {
+ if (buf_to_handle.exist && addr2_base ==
+ ((addr+(cnt1+1)*sizeof(type)))) {
+ t = (cnt2 + dis) > 0 ? -dis : cnt2;
+ for (k = 0; k < t; k++) {
+ if (k == t - 1) {
+ fprintf(fp, "
");
+ fprintf(fp, addr_mark,
+ (addr2_base + k * sizeof(type)));
+ }
+ fprintf(fp, value_mark,
+ *(((type *)buf_to_handle.ubp)-cnt3+k));
+ }
+ }
+ }
+ fprintf(fp, "
--
");
+ } else {
+ fprintf(fp, "
");
+ }
+} while (0);
+
static ulong
-search_ulong(ulong *bufptr, ulong addr, int longcnt, struct searchinfo *si)
+search_ulong(struct searchinfo *si)
{
int i, j;
+ int cnt = buf_handling.wordcnt;
+ ulong *bufptr = buf_handling.ubp;
+ ulong addr = buf_handling.next.vaddr;
+ ulong addr_base = VIRTPAGEBASE(addr);
+ ulong addr1 = buf_handled.next.vaddr;
+ ulong addr1_base = VIRTPAGEBASE(addr1);
+ ulong addr2 = buf_to_handle.next.vaddr;
+ ulong addr2_base = VIRTPAGEBASE(addr2);
ulong mask = si->s_parms.s_ulong.mask;
- for (i = 0; i < longcnt; i++, bufptr++, addr += sizeof(long)) {
+ int c_num = si->c_num;
+
+ for (i = 0; i < cnt; 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
", addr, *bufptr);
+ if (SEARCHMASK(*bufptr) == SEARCHMASK(si->s_parms.s_ulong.value[j])) {
+ report_hex_match_pre(ulong, "%lx: ", "%lx ", c_num,
+ addr_base, addr, addr1_base, addr1, bufptr);
+ fprintf(fp, "%lx: %lx", addr, *bufptr);
+ report_hex_match_post(ulong, "%lx: ", "%lx ", c_num,
+ addr_base, addr, addr2_base, addr2, bufptr);
+ }
}
}
return addr;
@@ -11997,31 +12135,58 @@ search_ulong(ulong *bufptr, ulong addr, int longcnt, struct searchinfo *si)

/* phys search uses ulonglong address representation */
static ulonglong
-search_ulong_p(ulong *bufptr, ulonglong addr, int longcnt, struct searchinfo *si)
+search_ulong_p(struct searchinfo *si)
{
int i, j;
+ int cnt = buf_handling.wordcnt;
+ ulong *bufptr = buf_handling.ubp;
+ ulonglong addr = buf_handling.next.paddr;
+ ulonglong addr_base = PHYSPAGEBASE(addr);
+ ulonglong addr1 = buf_handled.next.paddr;
+ ulonglong addr1_base = PHYSPAGEBASE(addr1);
+ ulonglong addr2 = buf_to_handle.next.paddr;
+ ulonglong addr2_base = PHYSPAGEBASE(addr2);
ulong mask = si->s_parms.s_ulong.mask;
- for (i = 0; i < longcnt; i++, bufptr++, addr += sizeof(long)) {
+ int c_num = si->c_num;
+
+ for (i = 0; i < cnt; 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
", addr, *bufptr);
+ if (SEARCHMASK(*bufptr) == SEARCHMASK(si->s_parms.s_ulong.value[j])) {
+ report_hex_match_pre(ulong, "%llx: ", "%lx ", c_num,
+ addr_base, addr, addr1_base, addr1, bufptr);
+ fprintf(fp, "%llx: %lx", addr, *bufptr);
+ report_hex_match_post(ulong, "%llx: ", "%lx ", c_num,
+ addr_base, addr, addr2_base, addr2, bufptr);
+ }
}
}
return addr;
}

static ulong
-search_uint(ulong *bufptr, ulong addr, int longcnt, struct searchinfo *si)
+search_uint(struct searchinfo *si)
{
int i, j;
- int cnt = longcnt * (sizeof(long)/sizeof(int));
- uint *ptr = (uint *)bufptr;
+ int cnt = buf_handling.wordcnt * (sizeof(long)/sizeof(int));
+ uint *bufptr = (uint *)(buf_handling.ubp);
+ ulong addr = buf_handling.next.vaddr;
+ ulong addr_base = VIRTPAGEBASE(addr);
+ ulong addr1 = buf_handled.next.vaddr;
+ ulong addr1_base = VIRTPAGEBASE(addr1);
+ ulong addr2 = buf_to_handle.next.vaddr;
+ ulong addr2_base = VIRTPAGEBASE(addr2);
uint mask = si->s_parms.s_uint.mask;
+ int c_num = si->c_num;

- for (i = 0; i < cnt; i++, ptr++, addr += sizeof(int)) {
+ for (i = 0; i < cnt; i++, bufptr++, 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
", addr, *ptr);
+ if (SEARCHMASK(*bufptr) == SEARCHMASK(si->s_parms.s_uint.value[j])) {
+ report_hex_match_pre(uint, "%lx: ", "%x ", c_num,
+ addr_base, addr, addr1_base, addr1, bufptr);
+ fprintf(fp, "%lx: %x", addr, *bufptr);
+ report_hex_match_post(uint, "%lx: ", "%x ", c_num,
+ addr_base, addr, addr2_base, addr2, bufptr);
+ }
}
}
return addr;
@@ -12029,34 +12194,58 @@ search_uint(ulong *bufptr, ulong addr, int longcnt, struct searchinfo *si)

/* phys search uses ulonglong address representation */
static ulonglong
-search_uint_p(ulong *bufptr, ulonglong addr, int longcnt, struct searchinfo *si)
+search_uint_p(struct searchinfo *si)
{
int i, j;
- int cnt = longcnt * (sizeof(long)/sizeof(int));
- uint *ptr = (uint *)bufptr;
+ int cnt = buf_handling.wordcnt * (sizeof(long)/sizeof(int));
+ uint *bufptr = (uint *)(buf_handling.ubp);
+ ulonglong addr = buf_handling.next.paddr;
+ ulonglong addr_base = PHYSPAGEBASE(addr);
+ ulonglong addr1 = buf_handled.next.paddr;
+ ulonglong addr1_base = PHYSPAGEBASE(addr1);
+ ulonglong addr2 = buf_to_handle.next.paddr;
+ ulonglong addr2_base = PHYSPAGEBASE(addr2);
uint mask = si->s_parms.s_uint.mask;
+ int c_num = si->c_num;

- for (i = 0; i < cnt; i++, ptr++, addr += sizeof(int)) {
+ for (i = 0; i < cnt; i++, bufptr++, 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
", addr, *ptr);
+ if (SEARCHMASK(*bufptr) == SEARCHMASK(si->s_parms.s_uint.value[j])) {
+ report_hex_match_pre(uint, "%llx: ", "%x ", c_num,
+ addr_base, addr, addr1_base, addr1, bufptr);
+ fprintf(fp, "%llx: %x", addr, *bufptr);
+ report_hex_match_post(uint, "%llx: ", "%x ", c_num,
+ addr_base, addr, addr2_base, addr2, bufptr);
+ }
}
}
return addr;
}

static ulong
-search_ushort(ulong *bufptr, ulong addr, int longcnt, struct searchinfo *si)
+search_ushort(struct searchinfo *si)
{
int i, j;
- int cnt = longcnt * (sizeof(long)/sizeof(short));
- ushort *ptr = (ushort *)bufptr;
+ int cnt = buf_handling.wordcnt * (sizeof(long)/sizeof(short));
+ ushort *bufptr = (ushort *)(buf_handling.ubp);
+ ulong addr = buf_handling.next.vaddr;
+ ulong addr_base = VIRTPAGEBASE(addr);
+ ulong addr1 = buf_handled.next.vaddr;
+ ulong addr1_base = VIRTPAGEBASE(addr1);
+ ulong addr2 = buf_to_handle.next.vaddr;
+ ulong addr2_base = VIRTPAGEBASE(addr2);
ushort mask = si->s_parms.s_ushort.mask;
+ int c_num = si->c_num;

- for (i = 0; i < cnt; i++, ptr++, addr += sizeof(short)) {
+ for (i = 0; i < cnt; i++, bufptr++, 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
", addr, *ptr);
+ if (SEARCHMASK(*bufptr) == SEARCHMASK(si->s_parms.s_ushort.value[j])) {
+ report_hex_match_pre(ushort, "%lx: ", "%x ", c_num,
+ addr_base, addr, addr1_base, addr1, bufptr);
+ fprintf(fp, "%lx: %x", addr, *bufptr);
+ report_hex_match_post(ushort, "%lx: ", "%x ", c_num,
+ addr_base, addr, addr2_base, addr2, bufptr);
+ }
}
}
return addr;
@@ -12064,17 +12253,29 @@ search_ushort(ulong *bufptr, ulong addr, int longcnt, struct searchinfo *si)

/* phys search uses ulonglong address representation */
static ulonglong
-search_ushort_p(ulong *bufptr, ulonglong addr, int longcnt, struct searchinfo *si)
+search_ushort_p(struct searchinfo *si)
{
int i, j;
- int cnt = longcnt * (sizeof(long)/sizeof(short));
- ushort *ptr = (ushort *)bufptr;
+ int cnt = buf_handling.wordcnt * (sizeof(long)/sizeof(short));
+ ushort *bufptr = (ushort *)(buf_handling.ubp);
+ ulonglong addr = buf_handling.next.paddr;
+ ulonglong addr_base = PHYSPAGEBASE(addr);
+ ulonglong addr1 = buf_handled.next.paddr;
+ ulonglong addr1_base = PHYSPAGEBASE(addr1);
+ ulonglong addr2 = buf_to_handle.next.paddr;
+ ulonglong addr2_base = PHYSPAGEBASE(addr2);
ushort mask = si->s_parms.s_ushort.mask;
+ int c_num = si->c_num;

- for (i = 0; i < cnt; i++, ptr++, addr += sizeof(short)) {
+ for (i = 0; i < cnt; i++, bufptr++, 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
", addr, *ptr);
+ if (SEARCHMASK(*bufptr) == SEARCHMASK(si->s_parms.s_ushort.value[j])) {
+ report_hex_match_pre(ushort, "%llx: ", "%x ", c_num,
+ addr_base, addr, addr1_base, addr1, bufptr);
+ fprintf(fp, "%llx: %x", addr, *bufptr);
+ report_hex_match_post(ushort, "%llx: ", "%x ", c_num,
+ addr_base, addr, addr2_base, addr2, bufptr);
+ }
}
}
return addr;
@@ -12122,13 +12323,15 @@ report_match(ulong addr, char *ptr1, int len1, char *ptr2, int len2)
}

static ulong
-search_chars(ulong *bufptr, ulong addr, int longcnt, struct searchinfo *si)
+search_chars(struct searchinfo *si)
{
int i, j;
int len;
char *target;
+ int longcnt = buf_handling.wordcnt;
int charcnt = longcnt * sizeof(long);
- char *ptr = (char *)bufptr;
+ char *ptr = (char *)(buf_handling.ubp);
+ ulong addr = buf_handling.next.vaddr;

/* is this the first page of this search? */
if (si->s_parms.s_chars.started_flag == 0) {
@@ -12211,13 +12414,15 @@ report_match_p(ulonglong addr, char *ptr1, int len1, char *ptr2, int len2)
}

static ulonglong
-search_chars_p(ulong *bufptr, ulonglong addr_p, int longcnt, struct searchinfo *si)
+search_chars_p(struct searchinfo *si)
{
int i, j;
int len;
char *target;
+ int longcnt = buf_handling.wordcnt;
int charcnt = longcnt * sizeof(long);
- char *ptr = (char *)bufptr;
+ char *ptr = (char *)(buf_handling.ubp);
+ ulonglong addr_p = buf_handling.next.paddr;

/* is this the first page of this search? */
if (si->s_parms.s_chars.started_flag == 0) {
@@ -12279,20 +12484,121 @@ search_chars_p(ulong *bufptr, ulonglong addr_p, int longcnt, struct searchinfo *
}

static void
-search_virtual(ulong start, ulong end, int memtype, struct searchinfo *si)
+make_pagebuf(struct pagebuf_t *pb, int exist, int wordcnt, char *buf, ulong *ubp, ulong vaddr)
{
- ulong pp, next, *ubp;
+ pb->exist = exist;
+ pb->wordcnt = wordcnt;
+ pb->buf = buf;
+ pb->ubp = ubp;
+ pb->next.vaddr = vaddr;
+}
+
+#define OK 0
+#define DONE 1
+#define DO_SEARCH 2
+#define IGNORE 3
+
+static int
+get_search_page(ulong *pp, ulong next, ulong end, int memtype)
+{
+ char *pagebuf;
+ ulong *ubp;
int wordcnt, lastpage;
ulong page;
- physaddr_t paddr;
- char *pagebuf;
+ physaddr_t paddr;
+
+ pagebuf = buf_to_handle.buf;
+ lastpage = (VIRTPAGEBASE(next) == VIRTPAGEBASE(end));
+
+ /*
+ * Keep it virtual for Xen hypervisor.
+ */
+ if (XEN_HYPER_MODE()) {
+ if (!readmem(*pp, KVADDR, pagebuf, PAGESIZE(),
+ "search page", RETURN_ON_ERROR|QUIET)) {
+ if (CRASHDEBUG(1))
+ fprintf(fp,
+ "search suspended at: %lx
", *pp);
+ return DONE;
+ }
+ goto make_pagebuf;
+ }
+
+ switch (memtype)
+ {
+ case UVADDR:
+ if (!uvtop(CURRENT_CONTEXT(), *pp, &paddr, 0) ||
+ !phys_to_page(paddr, &page)) {
+ if (!next_upage(CURRENT_CONTEXT(), *pp, pp)) {
+ return DONE;
+ }
+ return IGNORE;
+ }
+ break;
+
+ case KVADDR:
+ if (!kvtop(CURRENT_CONTEXT(), *pp, &paddr, 0) ||
+ !phys_to_page(paddr, &page)) {
+ if (!next_kpage(*pp, pp)) {
+ return DONE;
+ }
+ return IGNORE;
+ }
+ break;
+ }
+
+ if (!readmem(paddr, PHYSADDR, pagebuf, PAGESIZE(),
+ "search page", RETURN_ON_ERROR|QUIET)) {
+ return DO_SEARCH;
+ }
+
+make_pagebuf:
+ ubp = (ulong *)&(pagebuf[next - *pp]);
+ if (lastpage) {
+ if (end == (ulong)(-1))
+ wordcnt = PAGESIZE()/sizeof(long);
+ else
+ wordcnt = (end - next)/sizeof(long);
+ } else
+ wordcnt = (PAGESIZE() - (next - *pp))/sizeof(long);
+
+ make_pagebuf(&buf_to_handle, 1, wordcnt, pagebuf, ubp, next);
+
+ return OK;
+}
+
+static void
+search_virtual(ulong start, ulong end, int memtype, struct searchinfo *si)
+{
+ ulong pp, next, tmppp;
+ int tmp, over;
+ char *tmpbuf;
ulong pct, pages_read, pages_checked;
time_t begin, finish;

+ over = 0;
pages_read = pages_checked = 0;
begin = finish = 0;

- pagebuf = GETBUF(PAGESIZE());
+ buf_handled.buf = GETBUF(PAGESIZE());
+ buf_handled.exist = 0;
+ buf_handling.buf = GETBUF(PAGESIZE());
+ buf_handling.exist = 0;
+ buf_to_handle.buf = GETBUF(PAGESIZE());
+ buf_to_handle.exist = 0;
+
+ tmppp = VIRTPAGEBASE(start);
+ if (tmppp >= PAGESIZE()) {
+ tmppp -= PAGESIZE();
+ tmp = get_search_page(&tmppp, tmppp, -1, memtype);
+ if (tmp == OK) {
+ tmpbuf = buf_handled.buf;
+ memcpy(&buf_handled, &buf_to_handle,
+ sizeof(struct pagebuf_t));
+ buf_to_handle.exist = 0;
+ buf_to_handle.buf = tmpbuf;
+ }
+ }

if (start & (sizeof(long)-1)) {
start &= ~(sizeof(long)-1);
@@ -12309,79 +12615,66 @@ search_virtual(ulong start, ulong end, int memtype, struct searchinfo *si)

for (pp = VIRTPAGEBASE(start); next < end; next = pp) {
pages_checked++;
- lastpage = (VIRTPAGEBASE(next) == VIRTPAGEBASE(end));
if (LKCD_DUMPFILE())
set_lkcd_nohash();

- /*
- * Keep it virtual for Xen hypervisor.
- */
- if (XEN_HYPER_MODE()) {
- if (!readmem(pp, KVADDR, pagebuf, PAGESIZE(),
- "search page", RETURN_ON_ERROR|QUIET)) {
- if (CRASHDEBUG(1))
- fprintf(fp,
- "search suspended at: %lx
", pp);
- goto done;
- }
- goto virtual;
+ tmp = get_search_page(&pp, next, end, memtype);
+ switch (tmp)
+ {
+ case OK:
+ pages_read++;
+ break;
+ case DONE:
+ goto done;
+ break;
+ case DO_SEARCH:
+ goto do_search;
+ break;
+ case IGNORE:
+ continue;
+ break;
}

- switch (memtype)
- {
- case UVADDR:
- if (!uvtop(CURRENT_CONTEXT(), pp, &paddr, 0) ||
- !phys_to_page(paddr, &page)) {
- if (!next_upage(CURRENT_CONTEXT(), pp, &pp))
- goto done;
- continue;
- }
- break;
-
- case KVADDR:
- if (!kvtop(CURRENT_CONTEXT(), pp, &paddr, 0) ||
- !phys_to_page(paddr, &page)) {
- if (!next_kpage(pp, &pp))
- goto done;
- continue;
+ if (!buf_handling.exist) {
+ tmpbuf = buf_handling.buf;
+ memcpy(&buf_handling, &buf_to_handle, sizeof(struct pagebuf_t));
+ buf_to_handle.buf = tmpbuf;
+ buf_to_handle.exist = 0;
+ if (pp + PAGESIZE() < end) {
+ pp += PAGESIZE();
+ continue;
+ } else {
+ over = 1;
+ tmppp = pp + PAGESIZE();
+ if (tmppp > pp)
+ get_search_page(&tmppp, tmppp,
+ (ulong)(-1), memtype);
}
- break;
- }
+ }

- if (!readmem(paddr, PHYSADDR, pagebuf, PAGESIZE(),
- "search page", RETURN_ON_ERROR|QUIET)) {
+do_search:
+ if (!buf_handling.exist) {
pp += PAGESIZE();
continue;
}
-virtual:
- pages_read++;
-
- ubp = (ulong *)&pagebuf[next - pp];
- if (lastpage) {
- if (end == (ulong)(-1))
- wordcnt = PAGESIZE()/sizeof(long);
- else
- wordcnt = (end - next)/sizeof(long);
- } else
- wordcnt = (PAGESIZE() - (next - pp))/sizeof(long);

switch (si->mode)
{
case SEARCH_ULONG:
- next = search_ulong(ubp, next, wordcnt, si);
+ next = search_ulong(si);
break;
case SEARCH_UINT:
- next = search_uint(ubp, next, wordcnt, si);
+ next = search_uint(si);
break;
case SEARCH_USHORT:
- next = search_ushort(ubp, next, wordcnt, si);
+ next = search_ushort(si);
break;
case SEARCH_CHARS:
- next = search_chars(ubp, next, wordcnt, si);
+ next = search_chars(si);
break;
default:
/* unimplemented search type */
- next += wordcnt * (sizeof(long));
+ next += buf_handling.wordcnt * (sizeof(long));
break;
}

@@ -12389,6 +12682,24 @@ virtual:
if ((pp % (1024*1024)) == 0)
console("%lx
", pp);

+ buf_handling.exist = 0;
+ if (!over && buf_to_handle.exist) {
+ tmpbuf = buf_handled.buf;
+ buf_handling.exist = 1;
+ memcpy(&buf_handled, &buf_handling, sizeof(struct pagebuf_t));
+ memcpy(&buf_handling, &buf_to_handle, sizeof(struct pagebuf_t));
+
+ buf_to_handle.exist = 0;
+ buf_to_handle.buf = tmpbuf;
+ if (pp + PAGESIZE() >= end) {
+ over = 1;
+ tmppp = pp + PAGESIZE();
+ if (tmppp > pp)
+ get_search_page(&tmppp, tmppp,
+ (ulong)(-1), memtype);
+ goto do_search;
+ }
+ }
pp += PAGESIZE();
}

@@ -12402,22 +12713,81 @@ done:
}
}

-
static void
-search_physical(ulonglong start_in, ulonglong end_in, struct searchinfo *si)
+make_pagebuf_p(struct pagebuf_t *pb, int exist, int wordcnt, char *buf, ulong *ubp, ulonglong paddr)
{
+ pb->exist = exist;
+ pb->wordcnt = wordcnt;
+ pb->buf = buf;
+ pb->ubp = ubp;
+ pb->next.paddr = paddr;
+}
+
+static int
+get_search_page_p(ulonglong *ppp, ulonglong pnext, ulonglong end_in)
+{
+ char *pagebuf;
ulong *ubp;
int wordcnt, lastpage;
- ulonglong pnext, ppp;
- char *pagebuf;
+ ulong page;
+
+ pagebuf = buf_to_handle.buf;
+ lastpage = (PHYSPAGEBASE(pnext) == PHYSPAGEBASE(end_in));
+
+ if (!phys_to_page(*ppp, &page) ||
+ !readmem(*ppp, PHYSADDR, pagebuf, PAGESIZE(),
+ "search page", RETURN_ON_ERROR|QUIET)) {
+ if (!next_physpage(*ppp, ppp))
+ return DO_SEARCH;
+ return IGNORE;
+ }
+
+ ubp = (ulong *)&(pagebuf[pnext - *ppp]);
+ if (lastpage) {
+ if (end_in == (ulonglong)(-1))
+ wordcnt = PAGESIZE()/sizeof(long);
+ else
+ wordcnt = (end_in - pnext)/sizeof(long);
+ } else
+ wordcnt = (PAGESIZE() - (pnext - *ppp))/sizeof(long);
+
+ make_pagebuf_p(&buf_to_handle, 1, wordcnt, pagebuf, ubp, pnext);
+
+ return OK;
+}
+
+static void
+search_physical(ulonglong start_in, ulonglong end_in, struct searchinfo *si)
+{
+ ulonglong pnext, ppp, tmpppp;
ulong pct, pages_read, pages_checked;
time_t begin, finish;
- ulong page;
+ char *tmpbuf;
+ int tmp, over;

pages_read = pages_checked = 0;
begin = finish = 0;
-
- pagebuf = GETBUF(PAGESIZE());
+ over = 0;
+
+ buf_handled.buf = GETBUF(PAGESIZE());
+ buf_handled.exist = 0;
+ buf_handling.buf = GETBUF(PAGESIZE());
+ buf_handling.exist = 0;
+ buf_to_handle.buf = GETBUF(PAGESIZE());
+ buf_to_handle.exist = 0;
+
+ tmpppp = PHYSPAGEBASE(start_in);
+ if (tmpppp >= PAGESIZE()) {
+ tmpppp -= PAGESIZE();
+ tmp = get_search_page_p(&tmpppp, tmpppp, (ulonglong)(-1));
+ if (tmp == OK) {
+ tmpbuf = buf_handled.buf;
+ memcpy(&buf_handled, &buf_to_handle,
+ sizeof(struct pagebuf_t));
+ buf_to_handle.exist = 0;
+ buf_to_handle.buf = tmpbuf;
+ }
+ }

if (start_in & (sizeof(ulonglong)-1)) {
start_in &= ~(sizeof(ulonglong)-1);
@@ -12434,48 +12804,81 @@ search_physical(ulonglong start_in, ulonglong end_in, struct searchinfo *si)
pnext = start_in;
for (ppp = PHYSPAGEBASE(start_in); pnext < end_in; pnext = ppp) {
pages_checked++;
- lastpage = (PHYSPAGEBASE(pnext) == PHYSPAGEBASE(end_in));
if (LKCD_DUMPFILE())
set_lkcd_nohash();

- if (!phys_to_page(ppp, &page) ||
- !readmem(ppp, PHYSADDR, pagebuf, PAGESIZE(),
- "search page", RETURN_ON_ERROR|QUIET)) {
- if (!next_physpage(ppp, &ppp))
- break;
+ tmp = get_search_page_p(&ppp, pnext, end_in);
+ switch (tmp)
+ {
+ case OK:
+ pages_read++;
+ break;
+ case DO_SEARCH:
+ goto do_search;
+ break;
+ case IGNORE:
continue;
+ break;
}

- pages_read++;
- ubp = (ulong *)&pagebuf[pnext - ppp];
- if (lastpage) {
- if (end_in == (ulonglong)(-1))
- wordcnt = PAGESIZE()/sizeof(long);
- else
- wordcnt = (end_in - pnext)/sizeof(long);
- } else
- wordcnt = (PAGESIZE() - (pnext - ppp))/sizeof(long);
+ if (!buf_handling.exist) {
+ tmpbuf = buf_handling.buf;
+ memcpy(&buf_handling, &buf_to_handle, sizeof(struct pagebuf_t));
+ buf_to_handle.buf = tmpbuf;
+ buf_to_handle.exist = 0;
+ if (ppp + PAGESIZE() < end_in) {
+ ppp += PAGESIZE();
+ continue;
+ } else {
+ over = 1;
+ tmpppp = ppp + PAGESIZE();
+ if (tmpppp > ppp)
+ get_search_page_p(&tmpppp, tmpppp,
+ (ulonglong)(-1));
+ }
+ }
+
+do_search:
+ if (!buf_handling.exist)
+ break;

switch (si->mode)
{
case SEARCH_ULONG:
- pnext = search_ulong_p(ubp, pnext, wordcnt, si);
+ pnext = search_ulong_p(si);
break;
case SEARCH_UINT:
- pnext = search_uint_p(ubp, pnext, wordcnt, si);
+ pnext = search_uint_p(si);
break;
case SEARCH_USHORT:
- pnext = search_ushort_p(ubp, pnext, wordcnt, si);
+ pnext = search_ushort_p(si);
break;
case SEARCH_CHARS:
- pnext = search_chars_p(ubp, pnext, wordcnt, si);
+ pnext = search_chars_p(si);
break;
default:
/* unimplemented search type */
- pnext += wordcnt * (sizeof(long));
+ pnext += buf_handling.wordcnt * (sizeof(long));
break;
}

+ buf_handling.exist = 0;
+ if (!over && buf_to_handle.exist) {
+ tmpbuf = buf_handled.buf;
+ buf_handling.exist = 1;
+ memcpy(&buf_handled, &buf_handling, sizeof(struct pagebuf_t));
+ memcpy(&buf_handling, &buf_to_handle, sizeof(struct pagebuf_t));
+
+ buf_to_handle.buf = tmpbuf;
+ buf_to_handle.exist = 0;
+ if (ppp + PAGESIZE() >= end_in) {
+ over = 1;
+ tmpppp = ppp + PAGESIZE();
+ if (tmpppp > ppp)
+ get_search_page_p(&tmpppp, tmpppp, -1);
+ goto do_search;
+ }
+ }
ppp += PAGESIZE();
}

--
1.7.1

--
Crash-utility mailing list
Crash-utility@redhat.com
https://www.redhat.com/mailman/listinfo/crash-utility
 

Thread Tools




All times are GMT. The time now is 08:59 PM.

VBulletin, Copyright ©2000 - 2014, Jelsoft Enterprises Ltd.
Content Relevant URLs by vBSEO ©2007, Crawlability, Inc.
Copyright 2007 - 2008, www.linux-archive.org