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/help.c b/help.c index f752283..562d42b 100755 --- a/help.c +++ b/help.c @@ -3108,7 +3108,7 @@ NULL char *help_vm[] = { "vm", "virtual memory", -"[-p | -v | -m | [-R reference] | [-f vm_flags]] [pid | taskp] ... ", +"[-p | -P vmaddr | -v | -m | [-R reference] | [-f vm_flags]] [pid | taskp] ... ", " This command displays basic virtual memory information of a context,", " consisting of a pointer to its mm_struct and page dirctory, its RSS and ", " total virtual memory size; and a list of pointers to each vm_area_struct,", @@ -3124,6 +3124,8 @@ char *help_vm[] = { " -p translate each virtual page to its physical address, or if", " the page is not mapped, its swap device and offset, or", " filename and offset.", +" -P vmaddr translate each virtual page of the specified VM area to its", +" physical address, the output is like -p option.", " -R reference search for references to this number or filename.", " -m dump the mm_struct assocated with the task.", " -v dump all of the vm_area_structs associated with the task.", @@ -3302,6 +3304,18 @@ char *help_vm[] = { " Translate a FLAGS value:\n", " %s> vm -f 3875", " 3875: (READ|EXEC|MAYREAD|MAYWRITE|MAYEXEC|DENYWRITE|EXECUTABLE|LOCKED)", +" ", +" Display the page translations of VM area ffff8802953b22d8:\n", +" %s> vm -P ffff8802953b22d8", +" VMA START END FLAGS FILE", +" ffff8802953b22d8 300b000000 300b015000 8000075 /lib64/libz.so.1.2.3", +" VIRTUAL PHYSICAL ", +" 300b000000 28778c000", +" 300b001000 28778d000", +" 300b002000 FILE: /lib64/libz.so.1.2.3 OFFSET: 2000", +" 300b003000 FILE: /lib64/libz.so.1.2.3 OFFSET: 3000", +" 300b004000 FILE: /lib64/libz.so.1.2.3 OFFSET: 4000", +" ...", NULL }; diff --git a/memory.c b/memory.c index 55a184b..27c2f4e 100755 --- a/memory.c +++ b/memory.c @@ -3036,16 +3036,18 @@ cmd_vm(void) int c; ulong flag; ulong value; + ulong single_vma; ulonglong llvalue; struct task_context *tc; struct reference reference, *ref; int subsequent; flag = 0; + single_vma = 0; ref = NULL; BZERO(&reference, sizeof(struct reference)); - while ((c = getopt(argcnt, args, "f:pmvR:")) != EOF) { + while ((c = getopt(argcnt, args, "f:pmvR:P:")) != EOF) { switch(c) { case 'f': @@ -3090,6 +3092,15 @@ cmd_vm(void) } break; + case 'P': + if (flag) { + argerrs++; + } else { + flag |= PRINT_SINGLE_VMA; + single_vma = htol(optarg, FAULT_ON_ERROR, NULL); + } + break; + default: argerrs++; break; @@ -3100,9 +3111,9 @@ cmd_vm(void) cmd_usage(pc->curcmd, SYNOPSIS); if (!args[optind]) { - if (!ref) + if (!(ref || (flag & PRINT_SINGLE_VMA))) print_task_header(fp, CURRENT_CONTEXT(), 0); - vm_area_dump(CURRENT_TASK(), flag, 0, ref); + vm_area_dump(CURRENT_TASK(), flag, single_vma, ref); return; } @@ -3113,16 +3124,16 @@ cmd_vm(void) { case STR_PID: for (tc = pid_to_context(value); tc; tc = tc->tc_next) { - if (!ref) + if (!(ref || (flag & PRINT_SINGLE_VMA))) print_task_header(fp, tc, subsequent++); - vm_area_dump(tc->task, flag, 0, ref); + vm_area_dump(tc->task, flag, single_vma, ref); } break; case STR_TASK: - if (!ref) + if (!(ref || (flag & PRINT_SINGLE_VMA))) print_task_header(fp, tc, subsequent++); - vm_area_dump(tc->task, flag, 0, ref); + vm_area_dump(tc->task, flag, single_vma, ref); break; case STR_INVALID: @@ -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,13 @@ 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) { + flag |= PHYSADDR; + single_vma = vaddr; + vaddr = 0; + } + if (ref) { ref->cmdflags = VM_REF_SEARCH; if (IS_A_NUMBER(ref->str)) { @@ -3420,7 +3440,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 +3469,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 +3482,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);