From mboxrd@z Thu Jan 1 00:00:00 1970 From: Don Slutz Subject: [PATCH v5 10/17] xenctx: Add -m (--memory) option to dump memory at maddr. Date: Thu, 20 Mar 2014 15:06:58 -0400 Message-ID: <1395342425-16260-11-git-send-email-dslutz@verizon.com> References: <1395342425-16260-1-git-send-email-dslutz@verizon.com> Mime-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Return-path: In-Reply-To: <1395342425-16260-1-git-send-email-dslutz@verizon.com> List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Sender: xen-devel-bounces@lists.xen.org Errors-To: xen-devel-bounces@lists.xen.org To: xen-devel@lists.xen.org Cc: Ian Campbell , Stefano Stabellini , George Dunlap , Don Slutz , Ian Jackson , Don Slutz , Jan Beulich List-Id: xen-devel@lists.xenproject.org Currently not supported on ARM. New routine read_mem_word() will correctly read a word that crosses a page boundary. It will not fault if the 2nd page can not be mapped. Here is an example: Memory (address ffffffff803ddf90): ffffffff80048d19 0000000000200800 ffffffff803e7801 0000000000086800 0000000000000000 ffffffff80430720 ffffffff803e722f 80008e000010019c 00000000ffffffff 0000000000000000 0000000000000000 0000000000200000 0000000000000000 0000000000000000 0000000000000000 00cf9b000000ffff 00af9b000000ffff 00cf93000000ffff 00cffb000000ffff 00cff3000000ffff Signed-off-by: Don Slutz --- v5: Remove extra #ifndef. Make common routine print_lines(). tools/xentrace/xenctx.c | 232 +++++++++++++++++++++++++++++++++--------------- 1 file changed, 162 insertions(+), 70 deletions(-) diff --git a/tools/xentrace/xenctx.c b/tools/xentrace/xenctx.c index 5732665..13f56ed 100644 --- a/tools/xentrace/xenctx.c +++ b/tools/xentrace/xenctx.c @@ -33,23 +33,6 @@ #define DEFAULT_BYTES_PER_LINE 32 #define DEFAULT_LINES 5 -static struct xenctx { - xc_interface *xc_handle; - int domid; - int frame_ptrs; - int stack_trace; - int disp_all; - int multiple_pages; - int bytes_per_line; - int lines; - int decode_as_ascii; - int tag_stack_dump; - int tag_call_trace; - int all_vcpus; - int self_paused; - xc_dominfo_t dominfo; -} xenctx; - #if defined (__i386__) || defined (__x86_64__) typedef unsigned long long guest_word_t; #define FMT_32B_WORD "%08llx" @@ -73,6 +56,27 @@ typedef uint64_t guest_word_t; #define MAX_BYTES_PER_LINE 128 +static struct xenctx { + xc_interface *xc_handle; + int domid; + int frame_ptrs; + int stack_trace; + int disp_all; + int multiple_pages; + int bytes_per_line; + int lines; + int decode_as_ascii; + int tag_stack_dump; + int tag_call_trace; + int all_vcpus; +#ifndef NO_TRANSLATION + guest_word_t mem_addr; + int do_memory; +#endif + int self_paused; + xc_dominfo_t dominfo; +} xenctx; + struct symbol { guest_word_t address; char *name; @@ -634,6 +638,36 @@ static guest_word_t read_stack_word(guest_word_t *src, int width) return word; } +static guest_word_t read_mem_word(vcpu_guest_context_any_t *ctx, int vcpu, + guest_word_t virt, int width) +{ + if ( (virt & 7) == 0 ) + { + guest_word_t *p = map_page(ctx, vcpu, virt); + + if ( p ) + return read_stack_word(p, width); + else + return -1; + } else { + guest_word_t word = -1; + char *src, *dst; + int i; + + dst = (char*)&word; + for (i = 0; i < width; i++ ) + { + src = map_page(ctx, vcpu, virt + i); + if ( src ) + *dst++ = *src; + else + return word; + } + return word; + } +} +#endif + static void print_stack_word(guest_word_t word, int width) { if (width == 4) @@ -642,6 +676,78 @@ static void print_stack_word(guest_word_t word, int width) printf(FMT_64B_WORD, word); } +#ifndef NO_TRANSLATION +static int print_lines(vcpu_guest_context_any_t *ctx, int vcpu, int width, + guest_word_t mem_addr, guest_word_t mem_limit) +{ + guest_word_t mem_start = mem_addr; + guest_word_t word; + guest_word_t ascii[MAX_BYTES_PER_LINE/4]; + int i; + + for (i = 1; i < xenctx.lines + 1 && mem_addr < mem_limit; i++) + { + int j = 0; + int k; + + if ( xenctx.tag_stack_dump ) + { + print_stack_word(mem_addr, width); + printf(":"); + } + while ( mem_addr < mem_limit && + mem_addr < mem_start + i * xenctx.bytes_per_line ) + { + void *p = map_page(ctx, vcpu, mem_addr); + if ( !p ) + return -1; + word = read_mem_word(ctx, vcpu, mem_addr, width); + if ( xenctx.decode_as_ascii ) + ascii[j++] = word; + printf(" "); + print_stack_word(word, width); + mem_addr += width; + } + if ( xenctx.decode_as_ascii ) + { + /* + * Line up ascii output if less than bytes_per_line + * were printed. + */ + for (k = j; k < xenctx.bytes_per_line / width; k++) + printf(" %*s", width * 2, ""); + printf(" "); + for (k = 0; k < j; k++) + { + int l; + unsigned char *bytep = (unsigned char*)&ascii[k]; + + for (l = 0; l < width; l++) + { + if (isprint(*bytep)) + printf("%c", *bytep); + else + printf("."); + bytep++; + } + } + } + printf("\n"); + } + printf("\n"); + return 0; +} + +static void print_mem(vcpu_guest_context_any_t *ctx, int vcpu, int width, + guest_word_t mem_addr) +{ + printf("Memory (address "); + print_stack_word(mem_addr, width); + printf("):\n"); + print_lines(ctx, vcpu, width, mem_addr, + mem_addr + xenctx.lines * xenctx.bytes_per_line); +} + static int print_code(vcpu_guest_context_any_t *ctx, int vcpu) { guest_word_t instr; @@ -672,8 +778,6 @@ static int print_stack(vcpu_guest_context_any_t *ctx, int vcpu, int width) guest_word_t frame; guest_word_t word; guest_word_t *p; - guest_word_t ascii[MAX_BYTES_PER_LINE/4]; - int i; if ( width ) xenctx.bytes_per_line = ((xenctx.bytes_per_line + width - 1) / width) * width; @@ -685,56 +789,8 @@ static int print_stack(vcpu_guest_context_any_t *ctx, int vcpu, int width) if ( xenctx.lines ) { printf("Stack:\n"); - for (i = 1; i < xenctx.lines + 1 && stack < stack_limit; i++) - { - int j = 0; - int k; - - if ( xenctx.tag_stack_dump ) - { - print_stack_word(stack, width); - printf(":"); - } - while ( stack < stack_limit && - stack < stack_pointer(ctx) + i * xenctx.bytes_per_line ) - { - p = map_page(ctx, vcpu, stack); - if ( !p ) - return -1; - word = read_stack_word(p, width); - if ( xenctx.decode_as_ascii ) - ascii[j++] = word; - printf(" "); - print_stack_word(word, width); - stack += width; - } - if ( xenctx.decode_as_ascii ) - { - /* - * Line up ascii output if less than bytes_per_line - * were printed. - */ - for (k = j; k < xenctx.bytes_per_line / width; k++) - printf(" %*s", width * 2, ""); - printf(" "); - for (k = 0; k < j; k++) - { - int l; - unsigned char *bytep = (unsigned char*)&ascii[k]; - - for (l = 0; l < width; l++) - { - if (isprint(*bytep)) - printf("%c", *bytep); - else - printf("."); - bytep++; - } - } - } - printf("\n"); - } - printf("\n"); + if ( print_lines(ctx, vcpu, width, stack, stack_limit) ) + return -1; } if(xenctx.stack_trace) @@ -882,6 +938,13 @@ static void dump_ctx(int vcpu) } #endif +#ifndef NO_TRANSLATION + if ( xenctx.do_memory ) + { + print_mem(&ctx, vcpu, guest_word_size, xenctx.mem_addr); + return; + } +#endif print_ctx(&ctx); #ifndef NO_TRANSLATION if (print_code(&ctx, vcpu)) @@ -941,13 +1004,21 @@ static void usage(void) printf(" add address on each line of Stack dump.\n"); printf(" -T, --tag-trace\n"); printf(" add address on each line of Call or Stack trace.\n"); +#ifndef NO_TRANSLATION + printf(" -m maddr, --memory=maddr\n"); + printf(" dump memory at maddr.\n"); +#endif } int main(int argc, char **argv) { int ch; int ret; +#ifndef NO_TRANSLATION + static const char *sopts = "fs:hak:SCn:b:l:DtTm:"; +#else static const char *sopts = "fs:hak:SCn:b:l:DtT"; +#endif static const struct option lopts[] = { {"stack-trace", 0, NULL, 'S'}, {"symbol-table", 1, NULL, 's'}, @@ -957,6 +1028,9 @@ int main(int argc, char **argv) {"decode-as-ascii", 0, NULL, 'D'}, {"tag-stack-dump", 0, NULL, 't'}, {"tag-trace", 0, NULL, 'T'}, +#ifndef NO_TRANSLATION + {"memory", 1, NULL, 'm'}, +#endif {"bytes-per-line", 1, NULL, 'b'}, {"lines", 1, NULL, 'l'}, {"all", 0, NULL, 'a'}, @@ -967,6 +1041,7 @@ int main(int argc, char **argv) const char *symbol_table = NULL; int vcpu = 0; + int do_default = 1; xenctx.bytes_per_line = DEFAULT_BYTES_PER_LINE; xenctx.lines = DEFAULT_LINES; @@ -1024,10 +1099,18 @@ int main(int argc, char **argv) break; case 'C': xenctx.all_vcpus = 1; + do_default = 0; break; case 'k': kernel_start = strtoull(optarg, NULL, 0); break; +#ifndef NO_TRANSLATION + case 'm': + xenctx.mem_addr = strtoull(optarg, NULL, 0); + xenctx.do_memory = 1; + do_default = 0; + break; +#endif case 'h': usage(); exit(-1); @@ -1077,9 +1160,18 @@ int main(int argc, char **argv) xenctx.self_paused = 1; } +#ifndef NO_TRANSLATION + if ( xenctx.do_memory ) + { + dump_ctx(vcpu); + if (xenctx.all_vcpus) + printf("\n"); + } + xenctx.do_memory = 0; +#endif if (xenctx.all_vcpus) dump_all_vcpus(); - else + if ( do_default ) dump_ctx(vcpu); if (xenctx.self_paused) { -- 1.8.4