[PATCH] Add -C option for search

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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@xxxxxxxxxxxxxx>
Date: Fri, 3 Feb 2012 10:42:59 +0800
Subject: [PATCH] Add option -C for sub-command search.

Signed-off-by: zhangyanfei <zhangyanfei@xxxxxxxxxxxxxx>
---
 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]\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",
@@ -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\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]) {
@@ -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, "\n"); \
+	} \
+} 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, "\n"); \
+			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, "\n"); \
+						fprintf(fp, addr_mark, \
+							(addr2_base + k * sizeof(type))); \
+					} \
+					fprintf(fp, value_mark, \
+						*(((type *)buf_to_handle.ubp)-cnt3+k)); \
+				} \
+			} \
+		} \
+		fprintf(fp, "\n--\n"); \
+	} else { \
+		fprintf(fp, "\n"); \
+	} \
+} 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\n", 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\n", 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\n", 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\n", 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\n", 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\n", 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\n", *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\n", 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\n", 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@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/crash-utility

[Index of Archives]     [Fedora Development]     [Fedora Desktop]     [Fedora SELinux]     [Yosemite News]     [KDE Users]     [Fedora Tools]

 

Powered by Linux