diff --git a/defs.h b/defs.h index a942dbb..f3ca47b 100755 --- a/defs.h +++ b/defs.h @@ -2241,6 +2241,7 @@ struct load_module { #define PRINT_INODES (0x10) /* KVADDR, UVADDR, and PHYSADDR */ #define PRINT_MM_STRUCT (0x20) #define PRINT_VMA_STRUCTS (0x40) +#define PRINT_SINGLE_VMA (0x80) #define MIN_PAGE_SIZE (4096) diff --git a/memory.c b/memory.c index 55a184b..d3ac2dc 100755 --- a/memory.c +++ b/memory.c @@ -3045,7 +3045,7 @@ cmd_vm(void) ref = NULL; BZERO(&reference, sizeof(struct reference)); - while ((c = getopt(argcnt, args, "f:pmvR:")) != EOF) { + while ((c = getopt(argcnt, args, "f:pmvR:s:")) != EOF) { switch(c) { case 'f': @@ -3059,13 +3059,13 @@ cmd_vm(void) break; case 'p': - if (flag) + if (flag & ~PRINT_SINGLE_VMA) argerrs++; else flag |= PHYSADDR; break; case 'm': - if (flag) + if (flag & ~PRINT_SINGLE_VMA) argerrs++; else flag |= PRINT_MM_STRUCT; @@ -3090,6 +3090,17 @@ cmd_vm(void) } break; + case 's': + if ((flag & PRINT_MM_STRUCT) || ref) { + error(INFO, "-s option is only valid with -p/-v"); + argerrs++; + } else { + flag |= PRINT_SINGLE_VMA; + ref = &reference; + ref->hexval = htol(optarg, FAULT_ON_ERROR, NULL); + } + break; + default: argerrs++; break; @@ -3388,6 +3399,8 @@ vm_area_dump(ulong task, ulong flag, ulong vaddr, struct reference *ref) ulonglong vm_flags; ulong vm_file, inode; ulong dentry, vfsmnt; + ulong single_vma; + int single_vma_header; int found; struct task_mem_usage task_mem_usage, *tm; char buf1[BUFSIZE]; @@ -3401,6 +3414,12 @@ vm_area_dump(ulong task, ulong flag, ulong vaddr, struct reference *ref) tm = &task_mem_usage; get_task_mem_usage(task, tm); + single_vma_header = 0; + if (flag & PRINT_SINGLE_VMA) { + single_vma = ref->hexval; + ref = NULL; + } + if (ref) { ref->cmdflags = VM_REF_SEARCH; if (IS_A_NUMBER(ref->str)) { @@ -3420,7 +3439,7 @@ vm_area_dump(ulong task, ulong flag, ulong vaddr, struct reference *ref) return (ulong)NULL; } - if (!(flag & (UVADDR|PRINT_MM_STRUCT|PRINT_VMA_STRUCTS)) && + if (!(flag & (UVADDR|PRINT_MM_STRUCT|PRINT_VMA_STRUCTS|PRINT_SINGLE_VMA)) && !DO_REF_SEARCH(ref)) PRINT_VM_DATA(); @@ -3449,7 +3468,7 @@ vm_area_dump(ulong task, ulong flag, ulong vaddr, struct reference *ref) for (found = FALSE; vma; vma = vm_next) { - if ((flag & PHYSADDR) && !DO_REF_SEARCH(ref)) + if ((flag & PHYSADDR) && !DO_REF_SEARCH(ref) && !single_vma_header) fprintf(fp, "%s", vma_header); inode = 0; @@ -3462,6 +3481,12 @@ vm_area_dump(ulong task, ulong flag, ulong vaddr, struct reference *ref) vm_start = ULONG(vma_buf + OFFSET(vm_area_struct_vm_start)); vm_flags = get_vm_flags(vma_buf); vm_file = ULONG(vma_buf + OFFSET(vm_area_struct_vm_file)); + + if (flag & PRINT_SINGLE_VMA) { + single_vma_header++; + if (vma != single_vma) + continue; + } if (flag & PRINT_VMA_STRUCTS) { dump_struct("vm_area_struct", vma, 0);