The dump_mem_map() function displays basic data about each entry in the
mem_map[] array, or if an address is specified, just the mem_map[] entry
for that address. This patch introduces the -m option to be used with
'kmem -p' exclusively. When used with -p, a comma-separated list of one or
more struct page members may be specified to generate a custom, formatted
display. For example:

  crash> kmem -p -m mapping,index,_mapcount.counter,_count.counter
  ffffea0000000000      0x0     0       0       0
  ffffea0000000040      0x0     0       -1      1
  ffffea0000000080      0x0     0       -1      1
  ffffea00000000c0      0x0     0       -1      1
  ffffea0000000100      0x0     0       -1      1
  ffffea0000000140      0x0     0       -1      1
  ffffea0000000180      0x0     0       -1      1
  ffffea00000001c0      0x0     0       -1      1
  ffffea0000000200      0x0     0       -1      1
  ffffea0000000240      0x0     0       -1      1
  ...

Signed-off-by: Aaron Tomlin <[email protected]>
---
 help.c   |   19 +-
 memory.c | 1074 ++++++++++++++++++++++++++++++++++++--------------------------
 2 files changed, 649 insertions(+), 444 deletions(-)

diff --git a/help.c b/help.c
index b2f4d21..76b640a 100644
--- a/help.c
+++ b/help.c
@@ -5530,7 +5530,7 @@ char *help_kmem[] = {
 "kmem",
 "kernel memory",
 "[-f|-F|-p|-c|-C|-i|-s|-S|-v|-V|-n|-z|-o|-h] [slab] [[-P] address]\n"
-"       [-g [flags]] [-I slab[,slab]]",
+"       [-g [flags]] [-I slab[,slab]] [-m member[,member]]",
 "  This command displays information about the use of kernel memory.\n",
 "        -f  displays the contents of the system free memory headers.",
 "            also verifies that the page count equals nr_free_pages.",
@@ -5565,6 +5565,9 @@ char *help_kmem[] = {
 "            all slab cache names and addresses are listed.",
 "   -I slab  when used with -s or -S, one or more slab cache names in a",
 "            comma-separated list may be specified as slab caches to ignore.",
+" -m member  when used with -p, a comma-separated list of one or more",
+"            struct page members may be specified to generate a custom",
+"            formatted display.",
 "        -P  declares that the following address argument is a physical 
address.",
 "   address  when used without any flag, the address can be a kernel virtual,",
 "            or physical address; a search is made through the symbol table,",
@@ -5717,6 +5720,20 @@ char *help_kmem[] = {
 "    f5c51440     22000         0         0  1 80 slab",
 "    ...",
 "    ",
+"  Dump the mem_map[] array but select desired fields:\n",
+"    %s> kmem -p -m mapping,index,_mapcount.counter",
+"    ffffea0000000000  0x0     0       0",
+"    ffffea0000000040  0x0     0       -1",
+"    ffffea0000000080  0x0     0       -1",
+"    ffffea00000000c0  0x0     0       -1",
+"    ffffea0000000100  0x0     0       -1",
+"    ffffea0000000140  0x0     0       -1",
+"    ffffea0000000180  0x0     0       -1",
+"    ffffea00000001c0  0x0     0       -1",
+"    ffffea0000000200  0x0     0       -1",
+"    ffffea0000000240  0x0     0       -1",
+"    ...",
+"    ",
 "  Use the commands above with a page pointer or a physical address 
argument:\n",
 "    %s> kmem -f c40425b0",
 "    NODE ",
diff --git a/memory.c b/memory.c
index aacf929..d4114c2 100644
--- a/memory.c
+++ b/memory.c
@@ -55,6 +55,7 @@ struct meminfo {           /* general purpose memory 
information structure */
        ulong found;
        ulong retval;
        char *ignore;
+       char *include;
        int errors;
        int calls;
        int cpu;
@@ -4425,7 +4426,7 @@ cmd_kmem(void)
        BZERO(&meminfo, sizeof(struct meminfo));
        BZERO(&value[0], sizeof(ulonglong)*MAXARGS);
 
-        while ((c = getopt(argcnt, args, "gI:sSFfpvczCinl:L:PVoh")) != EOF) {
+        while ((c = getopt(argcnt, args, "gI:sSFfm:pvczCinl:L:PVoh")) != EOF) {
                 switch(c)
                {
                case 'V':
@@ -4480,6 +4481,10 @@ cmd_kmem(void)
                        pflag = 1;
                        break;
 
+               case 'm':
+                       meminfo.include = optarg;
+                       break;
+
                case 'I':
                        meminfo.ignore = optarg;
                        break;  
@@ -4948,7 +4953,7 @@ PG_slab_flag_init(void)
 static void
 dump_mem_map_SPARSEMEM(struct meminfo *mi)
 {
-       ulong i;
+       ulong i, j;
        long total_pages;
        int others, page_not_mapped, phys_not_mapped, page_mapping;
        ulong pp, ppend;
@@ -4967,7 +4972,11 @@ dump_mem_map_SPARSEMEM(struct meminfo *mi)
        char buf4[BUFSIZE];
        char *page_cache;
        char *pcache;
-       ulong section, section_nr, nr_mem_sections, section_size;
+       char *members = NULL;
+       char *memberlist[MAXARGS];
+       struct struct_member_data *member_data[MAXARGS];
+       int nr_members, populated;
+       ulong tmpvalue, section, section_nr, nr_mem_sections, section_size;
        long buffersize;
        char *outputbuffer;
        int bufferindex;
@@ -4980,66 +4989,81 @@ dump_mem_map_SPARSEMEM(struct meminfo *mi)
        char style3[100];
        char style4[100];
 
-       sprintf((char *)&style1, "%%lx%s%%%dllx%s%%%dlx%s%%8lx %%2d%s",
-                       space(MINSPACE),
-                       (int)MAX(PADDR_PRLEN, strlen("PHYSICAL")),
-                       space(MINSPACE),
-                       VADDR_PRLEN,
-                       space(MINSPACE),
-                       space(MINSPACE));
-       sprintf((char *)&style2, "%%-%dlx%s%%%dllx%s%s%s%s %2s ",
-                       VADDR_PRLEN,
-                       space(MINSPACE),
-                       (int)MAX(PADDR_PRLEN, strlen("PHYSICAL")),
-                       space(MINSPACE),
-                       mkstring(buf3, VADDR_PRLEN, CENTER|RJUST, " "),
-                       space(MINSPACE),
-                       mkstring(buf4, 8, CENTER|RJUST, " "),
-                       " ");
-       sprintf((char *)&style3, "%%-%dlx%s%%%dllx%s%s%s%s %%2d ",
-                       VADDR_PRLEN,
-                       space(MINSPACE),
-                       (int)MAX(PADDR_PRLEN, strlen("PHYSICAL")),
-                       space(MINSPACE),
-                       mkstring(buf3, VADDR_PRLEN, CENTER|RJUST, "-------"),
-                       space(MINSPACE),
-                       mkstring(buf4, 8, CENTER|RJUST, "-----"));
-       sprintf((char *)&style4, "%%-%dlx%s%%%dllx%s%%%dlx%s%%8lx %%2d ",
-                       VADDR_PRLEN,
-                       space(MINSPACE),
-                       (int)MAX(PADDR_PRLEN, strlen("PHYSICAL")),
-                       space(MINSPACE),
-                       VADDR_PRLEN,
-                       space(MINSPACE));
+       nr_members = mapping = index = 0;
+       reserved = shared = slabs = buffers = inode = offset = 0;
+       pg_spec = phys_spec = print_hdr = FALSE;
 
        v22 = VALID_MEMBER(page_inode);  /* page.inode vs. page.mapping */
 
-        if (v22) {
-               sprintf(hdr, "%s%s%s%s%s%s%s%sCNT FLAGS\n",
-                   mkstring(buf1, VADDR_PRLEN, CENTER, "PAGE"), 
-                   space(MINSPACE),               
-                    mkstring(buf2, MAX(PADDR_PRLEN, strlen("PHYSICAL")),
-                       RJUST, "PHYSICAL"),                 
-                   space(MINSPACE),               
-                   mkstring(buf3, VADDR_PRLEN, CENTER|RJUST, "INODE"), 
-                   space(MINSPACE),               
-                   mkstring(buf4, 8, CENTER|LJUST, "OFFSET"),
-                   space(MINSPACE-1));
-        } else {
-               sprintf(hdr, "%s%s%s%s%s%s%sCNT FLAGS\n",
-                   mkstring(buf1, VADDR_PRLEN, CENTER, "PAGE"), 
-                   space(MINSPACE),             
-                    mkstring(buf2, MAX(PADDR_PRLEN, strlen("PHYSICAL")),
-                        RJUST, "PHYSICAL"),
-                   space(MINSPACE),             
-                   mkstring(buf3, VADDR_PRLEN, CENTER|RJUST, "MAPPING"),
-                   space(MINSPACE),               
-                   mkstring(buf4, 8, CENTER|RJUST, "INDEX"));
-        }
+       if (!mi->include) {
+               sprintf((char *)&style1, "%%lx%s%%%dllx%s%%%dlx%s%%8lx %%2d%s",
+                               space(MINSPACE),
+                               (int)MAX(PADDR_PRLEN, strlen("PHYSICAL")),
+                               space(MINSPACE),
+                               VADDR_PRLEN,
+                               space(MINSPACE),
+                               space(MINSPACE));
+               sprintf((char *)&style2, "%%-%dlx%s%%%dllx%s%s%s%s %2s ",
+                               VADDR_PRLEN,
+                               space(MINSPACE),
+                               (int)MAX(PADDR_PRLEN, strlen("PHYSICAL")),
+                               space(MINSPACE),
+                               mkstring(buf3, VADDR_PRLEN, CENTER|RJUST, " "),
+                               space(MINSPACE),
+                               mkstring(buf4, 8, CENTER|RJUST, " "),
+                               " ");
+               sprintf((char *)&style3, "%%-%dlx%s%%%dllx%s%s%s%s %%2d ",
+                               VADDR_PRLEN,
+                               space(MINSPACE),
+                               (int)MAX(PADDR_PRLEN, strlen("PHYSICAL")),
+                               space(MINSPACE),
+                               mkstring(buf3, VADDR_PRLEN, CENTER|RJUST, 
"-------"),
+                               space(MINSPACE),
+                               mkstring(buf4, 8, CENTER|RJUST, "-----"));
+               sprintf((char *)&style4, "%%-%dlx%s%%%dllx%s%%%dlx%s%%8lx %%2d 
",
+                               VADDR_PRLEN,
+                               space(MINSPACE),
+                               (int)MAX(PADDR_PRLEN, strlen("PHYSICAL")),
+                               space(MINSPACE),
+                               VADDR_PRLEN,
+                               space(MINSPACE));
+
+               if (v22) {
+                       sprintf(hdr, "%s%s%s%s%s%s%s%sCNT FLAGS\n",
+                           mkstring(buf1, VADDR_PRLEN, CENTER, "PAGE"), 
+                           space(MINSPACE),               
+                           mkstring(buf2, MAX(PADDR_PRLEN, strlen("PHYSICAL")),
+                               RJUST, "PHYSICAL"),                 
+                           space(MINSPACE),               
+                           mkstring(buf3, VADDR_PRLEN, CENTER|RJUST, "INODE"), 
+                           space(MINSPACE),               
+                           mkstring(buf4, 8, CENTER|LJUST, "OFFSET"),
+                           space(MINSPACE-1));
+               } else {
+                       sprintf(hdr, "%s%s%s%s%s%s%sCNT FLAGS\n",
+                           mkstring(buf1, VADDR_PRLEN, CENTER, "PAGE"), 
+                           space(MINSPACE),             
+                           mkstring(buf2, MAX(PADDR_PRLEN, strlen("PHYSICAL")),
+                               RJUST, "PHYSICAL"),
+                           space(MINSPACE),             
+                           mkstring(buf3, VADDR_PRLEN, CENTER|RJUST, 
"MAPPING"),
+                           space(MINSPACE),               
+                           mkstring(buf4, 8, CENTER|RJUST, "INDEX"));
+               }
+       } else {
+               if (count_chars(mi->include, ',') > MAXARGS)
+                       error(FATAL, "too many members in comma-separated 
list!\n");
 
-       mapping = index = 0;
-       reserved = shared = slabs = buffers = inode = offset = 0;
-       pg_spec = phys_spec = print_hdr = FALSE;
+               if ((LASTCHAR(mi->include) == ',') || (LASTCHAR(mi->include) == 
'.'))
+                       error(FATAL, "invalid format: %s\n", mi->include);
+
+               members = GETBUF(strlen(mi->include)+1);
+               strcpy(members, mi->include);
+               replace_string(members, ",", ' ');
+               nr_members = parse_line(members, memberlist);
+               populated = FALSE;
+
+       }
 
        switch (mi->flags)
        {
@@ -5065,7 +5089,8 @@ dump_mem_map_SPARSEMEM(struct meminfo *mi)
                        error(FATAL, "dump_mem_map: no memtype specified\n");
                        break;
                }
-               print_hdr = TRUE;
+               if (!mi->include)
+                       print_hdr = TRUE;
                break;
 
        case GET_ALL:
@@ -5092,7 +5117,8 @@ dump_mem_map_SPARSEMEM(struct meminfo *mi)
                break;
 
        default:
-               print_hdr = TRUE;
+               if (!mi->include)
+                       print_hdr = TRUE;
                break;
        }
 
@@ -5188,187 +5214,251 @@ dump_mem_map_SPARSEMEM(struct meminfo *mi)
 
                        if (!done && (pg_spec || phys_spec))
                                continue;
-                       
-                       flags = ULONG(pcache + OFFSET(page_flags));
-                       if (SIZE(page_flags) == 4)
-                               flags &= 0xffffffff;
-                       count = UINT(pcache + OFFSET(page_count));
 
-                       switch (mi->flags)
-                       {
-                       case GET_ALL:
-                       case GET_BUFFERS_PAGES:
-                               if (VALID_MEMBER(page_buffers)) {
-                                       tmp = ULONG(pcache + 
-                                               OFFSET(page_buffers));
-                                       if (tmp)
-                                               buffers++;
-                               } else if (THIS_KERNEL_VERSION >= LINUX(2,6,0)) 
{
-                                       if ((flags >> v26_PG_private) & 1) 
-                                               buffers++;
-                               } else
-                                       error(FATAL, 
-                              "cannot determine whether pages have buffers\n");
+                       if (mi->include) {
+                               if (!populated) {
 
-                               if (mi->flags != GET_ALL)
-                                       continue;
+                                       j = 0;
+                                       do {
+                                               if (!(member_data[j] = 
malloc(sizeof(struct struct_member_data)))) {
+                                                       error(WARNING, "cannot 
malloc member_data space.\n");
+                                                       nr_members = j += 1;
+                                                       goto failed_member_data;
+                                               }
 
-                               /* FALLTHROUGH */
+                                               member_data[j]->structure = 
"page";
+                                               member_data[j]->member = 
memberlist[j];
+                                               if 
(!(fill_struct_member_data(member_data[j]))) {
+                                                       error(WARNING, "Failed 
to populate member_data: "
+                                                               "%s.%s does not 
exist.\n",
+                                                               
member_data[j]->structure, member_data[j]->member);
+                                                       nr_members = j += 1;
+                                                       goto failed_member_data;
+                                               }
 
-                       case GET_SLAB_PAGES:
-                               if (v22) {
-                                       if ((flags >> v22_PG_Slab) & 1) 
-                                               slabs++;
-                               } else if (vt->PG_slab) {
-                                       if ((flags >> vt->PG_slab) & 1) 
-                                               slabs++;
-                               } else {
-                                       if ((flags >> v24_PG_slab) & 1) 
-                                               slabs++;
+                                       } while (++j < nr_members);
+                                       populated = TRUE;
                                }
-                               if (mi->flags != GET_ALL)
-                                       continue;
 
-                               /* FALLTHROUGH */
 
-                       case GET_SHARED_PAGES:
-                       case GET_TOTALRAM_PAGES:
-                                if (vt->PG_reserved)
-                                       PG_reserved_flag = vt->PG_reserved;
-                               else
-                                        PG_reserved_flag = v22 ?
-                                                1 << v22_PG_reserved :
-                                                1 << v24_PG_reserved;
+                               bufferindex += sprintf(outputbuffer + 
bufferindex,
+                                       "%lx\t", pp);
 
-                               if (flags & PG_reserved_flag) {
-                                       reserved++;
-                               } else {
-                                       if ((int)count > 
-                                           (vt->flags & PGCNT_ADJ ? 0 : 1))
-                                               shared++;
-                               }
-                               continue;
-                       }
-                       page_mapping = VALID_MEMBER(page_mapping);
-       
-                       if (v22) {
-                               inode = ULONG(pcache + OFFSET(page_inode));
-                               offset = ULONG(pcache + OFFSET(page_offset));
-                       } else if (page_mapping) { 
-                               mapping = ULONG(pcache + 
-                                       OFFSET(page_mapping));
-                               index = ULONG(pcache + OFFSET(page_index));
-                       }
-       
-                       page_not_mapped = phys_not_mapped = FALSE;
+                               j = 0;
+                               do {
+                                       switch (member_data[j]->type)
+                                       {
+                                       case TYPE_CODE_PTR:
+                                               readmem(pp + 
member_data[j]->offset, KVADDR, &tmpvalue,
+                                                       member_data[j]->length, 
"tmpvalue", FAULT_ON_ERROR);
+                                               bufferindex += 
sprintf(outputbuffer + bufferindex, "0x%lx\t",
+                                                       tmpvalue);
+                                               break;
+                                       case TYPE_CODE_INT:
+                                               readmem(pp + 
member_data[j]->offset, KVADDR, &tmpvalue,
+                                                       member_data[j]->length, 
"tmpvalue", FAULT_ON_ERROR);
+                                               if 
(member_data[j]->unsigned_type ||
+                                                       member_data[j]->length 
== sizeof(ulonglong))
+                                                       bufferindex += 
sprintf(outputbuffer + bufferindex,
+                                                               "%lu\t", 
tmpvalue);
+                                               else
+                                                       bufferindex += 
sprintf(outputbuffer + bufferindex,
+                                                               "%d\t", 
(int)tmpvalue);
+                                               break;
+                                       default:
+                                               error(WARNING, "invalid data 
structure reference %s.%s\n",
+                                                       
member_data[j]->structure, member_data[j]->member);
+                                               nr_members = j += 1;
+                                               goto failed_member_data;
+                                               break;
+                                       }
+                               } while (++j < nr_members);
+
+                               bufferindex += 
sprintf(outputbuffer+bufferindex, "\n");
 
-                       if (v22) {
-                               bufferindex += sprintf(outputbuffer+bufferindex,
-                                               (char *)&style1, pp, phys, 
inode,
-                                               offset, count);
                        } else {
-                               if ((vt->flags & V_MEM_MAP)) {
-                                       if (!machdep->verify_paddr(phys)) 
-                                               phys_not_mapped = TRUE;
-                                       if (!kvtop(NULL, pp, NULL, 0))
-                                               page_not_mapped = TRUE;
+
+                               flags = ULONG(pcache + OFFSET(page_flags));
+                               if (SIZE(page_flags) == 4)
+                                       flags &= 0xffffffff;
+                               count = UINT(pcache + OFFSET(page_count));
+
+                               switch (mi->flags)
+                               {
+                               case GET_ALL:
+                               case GET_BUFFERS_PAGES:
+                                       if (VALID_MEMBER(page_buffers)) {
+                                               tmp = ULONG(pcache + 
+                                                       OFFSET(page_buffers));
+                                               if (tmp)
+                                                       buffers++;
+                                       } else if (THIS_KERNEL_VERSION >= 
LINUX(2,6,0)) {
+                                               if ((flags >> v26_PG_private) & 
1) 
+                                                       buffers++;
+                                       } else
+                                               error(FATAL, 
+                                      "cannot determine whether pages have 
buffers\n");
+
+                                       if (mi->flags != GET_ALL)
+                                               continue;
+
+                                       /* FALLTHROUGH */
+
+                               case GET_SLAB_PAGES:
+                                       if (v22) {
+                                               if ((flags >> v22_PG_Slab) & 1) 
+                                                       slabs++;
+                                       } else if (vt->PG_slab) {
+                                               if ((flags >> vt->PG_slab) & 1) 
+                                                       slabs++;
+                                       } else {
+                                               if ((flags >> v24_PG_slab) & 1) 
+                                                       slabs++;
+                                       }
+                                       if (mi->flags != GET_ALL)
+                                               continue;
+
+                                       /* FALLTHROUGH */
+
+                               case GET_SHARED_PAGES:
+                               case GET_TOTALRAM_PAGES:
+                                       if (vt->PG_reserved)
+                                               PG_reserved_flag = 
vt->PG_reserved;
+                                       else
+                                               PG_reserved_flag = v22 ?
+                                                       1 << v22_PG_reserved :
+                                                       1 << v24_PG_reserved;
+
+                                       if (flags & PG_reserved_flag) {
+                                               reserved++;
+                                       } else {
+                                               if ((int)count > 
+                                                   (vt->flags & PGCNT_ADJ ? 0 
: 1))
+                                                       shared++;
+                                       }
+                                       continue;
                                }
-                               if (page_not_mapped)
-                                       bufferindex += 
sprintf(outputbuffer+bufferindex,
-                                                       (char *)&style2, pp, 
phys);
-                               else if (!page_mapping)
-                                       bufferindex += 
sprintf(outputbuffer+bufferindex,
-                                                       (char *)&style3, pp, 
phys, count);
-                               else
+                               page_mapping = VALID_MEMBER(page_mapping);
+               
+                               if (v22) {
+                                       inode = ULONG(pcache + 
OFFSET(page_inode));
+                                       offset = ULONG(pcache + 
OFFSET(page_offset));
+                               } else if (page_mapping) { 
+                                       mapping = ULONG(pcache + 
+                                               OFFSET(page_mapping));
+                                       index = ULONG(pcache + 
OFFSET(page_index));
+                               }
+               
+                               page_not_mapped = phys_not_mapped = FALSE;
+
+                               if (v22) {
                                        bufferindex += 
sprintf(outputbuffer+bufferindex,
-                                                       (char *)&style4, pp, 
phys,
-                                                       mapping, index, count);
-                       }
-       
-                       others = 0;
-       
+                                                       (char *)&style1, pp, 
phys, inode,
+                                                       offset, count);
+                               } else {
+                                       if ((vt->flags & V_MEM_MAP)) {
+                                               if 
(!machdep->verify_paddr(phys)) 
+                                                       phys_not_mapped = TRUE;
+                                               if (!kvtop(NULL, pp, NULL, 0))
+                                                       page_not_mapped = TRUE;
+                                       }
+                                       if (page_not_mapped)
+                                               bufferindex += 
sprintf(outputbuffer+bufferindex,
+                                                               (char 
*)&style2, pp, phys);
+                                       else if (!page_mapping)
+                                               bufferindex += 
sprintf(outputbuffer+bufferindex,
+                                                               (char 
*)&style3, pp, phys, count);
+                                       else
+                                               bufferindex += 
sprintf(outputbuffer+bufferindex,
+                                                               (char 
*)&style4, pp, phys,
+                                                               mapping, index, 
count);
+                               }
+               
+                               others = 0;
+               
 #define sprintflag(X) sprintf(outputbuffer + bufferindex, X, others++ ? "," : 
"")
 
-                       if (v22) {
-                               if ((flags >> v22_PG_DMA) & 1)
-                                       bufferindex += sprintflag("%sDMA");
-                               if ((flags >> v22_PG_locked) & 1)
-                                       bufferindex += sprintflag("%slocked");
-                               if ((flags >> v22_PG_error) & 1)
-                                       bufferindex += sprintflag("%serror");
-                               if ((flags >> v22_PG_referenced) & 1)
-                                       bufferindex += 
sprintflag("%sreferenced");
-                               if ((flags >> v22_PG_dirty) & 1)
-                                       bufferindex += sprintflag("%sdirty");
-                               if ((flags >> v22_PG_uptodate) & 1)
-                                       bufferindex += sprintflag("%suptodate");
-                               if ((flags >> v22_PG_free_after) & 1)
-                                       bufferindex += 
sprintflag("%sfree_after");
-                               if ((flags >> v22_PG_decr_after) & 1)
-                                       bufferindex += 
sprintflag("%sdecr_after");
-                               if ((flags >> v22_PG_swap_unlock_after) & 1)
-                                       bufferindex += 
sprintflag("%sswap_unlock_after");
-                               if ((flags >> v22_PG_Slab) & 1)
-                                       bufferindex += sprintflag("%sslab");
-                               if ((flags >> v22_PG_swap_cache) & 1)
-                                       bufferindex += 
sprintflag("%sswap_cache");
-                               if ((flags >> v22_PG_skip) & 1)
-                                       bufferindex += sprintflag("%sskip");
-                               if ((flags >> v22_PG_reserved) & 1)
-                                       bufferindex += sprintflag("%sreserved");
-                               bufferindex += 
sprintf(outputbuffer+bufferindex, "\n");
-                       } else if (THIS_KERNEL_VERSION > LINUX(2,4,9)) {
-                               if (vt->flags & PAGEFLAGS)
-                                       bufferindex += 
translate_page_flags(outputbuffer+bufferindex, flags);
-                               else
-                                       bufferindex += 
sprintf(outputbuffer+bufferindex, "%lx\n", flags);
-                       } else {
-       
-                               if ((flags >> v24_PG_locked) & 1)
-                                       bufferindex += sprintflag("%slocked");
-                               if ((flags >> v24_PG_error) & 1)
-                                       bufferindex += sprintflag("%serror");
-                               if ((flags >> v24_PG_referenced) & 1)
-                                       bufferindex += 
sprintflag("%sreferenced");
-                               if ((flags >> v24_PG_uptodate) & 1)
-                                       bufferindex += sprintflag("%suptodate");
-                                if ((flags >> v24_PG_dirty) & 1)
-                                       bufferindex += sprintflag("%sdirty");
-                               if ((flags >> v24_PG_decr_after) & 1)
-                                       bufferindex += 
sprintflag("%sdecr_after");
-                                if ((flags >> v24_PG_active) & 1)
-                                       bufferindex += sprintflag("%sactive");
-                                if ((flags >> v24_PG_inactive_dirty) & 1)
-                                       bufferindex += 
sprintflag("%sinactive_dirty");
-                               if ((flags >> v24_PG_slab) & 1)
-                                       bufferindex += sprintflag("%sslab");
-                               if ((flags >> v24_PG_swap_cache) & 1)
-                                       bufferindex += 
sprintflag("%sswap_cache");
-                               if ((flags >> v24_PG_skip) & 1)
-                                       bufferindex += sprintflag("%sskip");
-                               if ((flags >> v24_PG_inactive_clean) & 1)
-                                       bufferindex += 
sprintflag("%sinactive_clean");
-                               if ((flags >> v24_PG_highmem) & 1)
-                                       bufferindex += sprintflag("%shighmem");
-                               if ((flags >> v24_PG_checked) & 1)
-                                       bufferindex += sprintflag("%schecked");
-                               if ((flags >> v24_PG_bigpage) & 1)
-                                       bufferindex += sprintflag("%sbigpage");
-                                if ((flags >> v24_PG_arch_1) & 1)
-                                       bufferindex += sprintflag("%sarch_1");
-                               if ((flags >> v24_PG_reserved) & 1)
-                                       bufferindex += sprintflag("%sreserved");
-                               if (phys_not_mapped)
-                                       bufferindex += sprintflag("%s[NOT 
MAPPED]");
-
-                               bufferindex += 
sprintf(outputbuffer+bufferindex, "\n");
+                               if (v22) {
+                                       if ((flags >> v22_PG_DMA) & 1)
+                                               bufferindex += 
sprintflag("%sDMA");
+                                       if ((flags >> v22_PG_locked) & 1)
+                                               bufferindex += 
sprintflag("%slocked");
+                                       if ((flags >> v22_PG_error) & 1)
+                                               bufferindex += 
sprintflag("%serror");
+                                       if ((flags >> v22_PG_referenced) & 1)
+                                               bufferindex += 
sprintflag("%sreferenced");
+                                       if ((flags >> v22_PG_dirty) & 1)
+                                               bufferindex += 
sprintflag("%sdirty");
+                                       if ((flags >> v22_PG_uptodate) & 1)
+                                               bufferindex += 
sprintflag("%suptodate");
+                                       if ((flags >> v22_PG_free_after) & 1)
+                                               bufferindex += 
sprintflag("%sfree_after");
+                                       if ((flags >> v22_PG_decr_after) & 1)
+                                               bufferindex += 
sprintflag("%sdecr_after");
+                                       if ((flags >> v22_PG_swap_unlock_after) 
& 1)
+                                               bufferindex += 
sprintflag("%sswap_unlock_after");
+                                       if ((flags >> v22_PG_Slab) & 1)
+                                               bufferindex += 
sprintflag("%sslab");
+                                       if ((flags >> v22_PG_swap_cache) & 1)
+                                               bufferindex += 
sprintflag("%sswap_cache");
+                                       if ((flags >> v22_PG_skip) & 1)
+                                               bufferindex += 
sprintflag("%sskip");
+                                       if ((flags >> v22_PG_reserved) & 1)
+                                               bufferindex += 
sprintflag("%sreserved");
+                                       bufferindex += 
sprintf(outputbuffer+bufferindex, "\n");
+                               } else if (THIS_KERNEL_VERSION > LINUX(2,4,9)) {
+                                       if (vt->flags & PAGEFLAGS)
+                                               bufferindex += 
translate_page_flags(outputbuffer+bufferindex, flags);
+                                       else
+                                               bufferindex += 
sprintf(outputbuffer+bufferindex, "%lx\n", flags);
+                               } else {
+               
+                                       if ((flags >> v24_PG_locked) & 1)
+                                               bufferindex += 
sprintflag("%slocked");
+                                       if ((flags >> v24_PG_error) & 1)
+                                               bufferindex += 
sprintflag("%serror");
+                                       if ((flags >> v24_PG_referenced) & 1)
+                                               bufferindex += 
sprintflag("%sreferenced");
+                                       if ((flags >> v24_PG_uptodate) & 1)
+                                               bufferindex += 
sprintflag("%suptodate");
+                                       if ((flags >> v24_PG_dirty) & 1)
+                                               bufferindex += 
sprintflag("%sdirty");
+                                       if ((flags >> v24_PG_decr_after) & 1)
+                                               bufferindex += 
sprintflag("%sdecr_after");
+                                       if ((flags >> v24_PG_active) & 1)
+                                               bufferindex += 
sprintflag("%sactive");
+                                       if ((flags >> v24_PG_inactive_dirty) & 
1)
+                                               bufferindex += 
sprintflag("%sinactive_dirty");
+                                       if ((flags >> v24_PG_slab) & 1)
+                                               bufferindex += 
sprintflag("%sslab");
+                                       if ((flags >> v24_PG_swap_cache) & 1)
+                                               bufferindex += 
sprintflag("%sswap_cache");
+                                       if ((flags >> v24_PG_skip) & 1)
+                                               bufferindex += 
sprintflag("%sskip");
+                                       if ((flags >> v24_PG_inactive_clean) & 
1)
+                                               bufferindex += 
sprintflag("%sinactive_clean");
+                                       if ((flags >> v24_PG_highmem) & 1)
+                                               bufferindex += 
sprintflag("%shighmem");
+                                       if ((flags >> v24_PG_checked) & 1)
+                                               bufferindex += 
sprintflag("%schecked");
+                                       if ((flags >> v24_PG_bigpage) & 1)
+                                               bufferindex += 
sprintflag("%sbigpage");
+                                       if ((flags >> v24_PG_arch_1) & 1)
+                                               bufferindex += 
sprintflag("%sarch_1");
+                                       if ((flags >> v24_PG_reserved) & 1)
+                                               bufferindex += 
sprintflag("%sreserved");
+                                       if (phys_not_mapped)
+                                               bufferindex += 
sprintflag("%s[NOT MAPPED]");
+
+                                       bufferindex += 
sprintf(outputbuffer+bufferindex, "\n");
+                               }
                        }
 
                        if (bufferindex > buffersize) {
                                fprintf(fp, "%s", outputbuffer);
                                bufferindex = 0;
                        }
-       
+
                        if (done)
                                break;
                }
@@ -5413,12 +5503,18 @@ dump_mem_map_SPARSEMEM(struct meminfo *mi)
 
        FREEBUF(outputbuffer);
        FREEBUF(page_cache);
+failed_member_data:
+       if (mi->include) {
+               FREEBUF(members);
+               for (i = 0; i < nr_members; i++)
+                       free(member_data[i]);
+       }
 }
 
 static void
 dump_mem_map(struct meminfo *mi)
 {
-       long i, n;
+       ulong i, n, j;
        long total_pages;
        int others, page_not_mapped, phys_not_mapped, page_mapping;
        ulong pp, ppend;
@@ -5439,6 +5535,11 @@ dump_mem_map(struct meminfo *mi)
        char buf4[BUFSIZE];
        char *page_cache;
        char *pcache;
+       char *members = NULL;
+       char *memberlist[MAXARGS];
+       struct struct_member_data *member_data[MAXARGS];
+       int nr_members, populated;
+       ulong tmpvalue;
        long buffersize;
        char *outputbuffer;
        int bufferindex;
@@ -5456,67 +5557,82 @@ dump_mem_map(struct meminfo *mi)
                return;
        }
 
-       sprintf((char *)&style1, "%%lx%s%%%dllx%s%%%dlx%s%%8lx %%2d%s",
-                       space(MINSPACE),
-                       (int)MAX(PADDR_PRLEN, strlen("PHYSICAL")),
-                       space(MINSPACE),
-                       VADDR_PRLEN,
-                       space(MINSPACE),
-                       space(MINSPACE));
-       sprintf((char *)&style2, "%%-%dlx%s%%%dllx%s%s%s%s %2s ",
-                       VADDR_PRLEN,
-                       space(MINSPACE),
-                       (int)MAX(PADDR_PRLEN, strlen("PHYSICAL")),
-                       space(MINSPACE),
-                       mkstring(buf3, VADDR_PRLEN, CENTER|RJUST, " "),
-                       space(MINSPACE),
-                       mkstring(buf4, 8, CENTER|RJUST, " "),
-                       " ");
-       sprintf((char *)&style3, "%%-%dlx%s%%%dllx%s%s%s%s %%2d ",
-                       VADDR_PRLEN,
-                       space(MINSPACE),
-                       (int)MAX(PADDR_PRLEN, strlen("PHYSICAL")),
-                       space(MINSPACE),
-                       mkstring(buf3, VADDR_PRLEN, CENTER|RJUST, "-------"),
-                       space(MINSPACE),
-                       mkstring(buf4, 8, CENTER|RJUST, "-----"));
-       sprintf((char *)&style4, "%%-%dlx%s%%%dllx%s%%%dlx%s%%8lx %%2d ",
-                       VADDR_PRLEN,
-                       space(MINSPACE),
-                       (int)MAX(PADDR_PRLEN, strlen("PHYSICAL")),
-                       space(MINSPACE),
-                       VADDR_PRLEN,
-                       space(MINSPACE));
+       nr_members = mapping = index = 0;
+       reserved = shared = slabs = buffers = inode = offset = 0;
+       pg_spec = phys_spec = print_hdr = FALSE;
 
        v22 = VALID_MEMBER(page_inode);  /* page.inode vs. page.mapping */
 
-        if (v22) {
-               sprintf(hdr, "%s%s%s%s%s%s%s%sCNT FLAGS\n",
-                   mkstring(buf1, VADDR_PRLEN, CENTER, "PAGE"), 
-                   space(MINSPACE),               
-                    mkstring(buf2, MAX(PADDR_PRLEN, strlen("PHYSICAL")),
-                       RJUST, "PHYSICAL"),                 
-                   space(MINSPACE),               
-                   mkstring(buf3, VADDR_PRLEN, CENTER|RJUST, "INODE"), 
-                   space(MINSPACE),               
-                   mkstring(buf4, 8, CENTER|LJUST, "OFFSET"),
-                   space(MINSPACE-1));
-        } else {
-               sprintf(hdr, "%s%s%s%s%s%s%sCNT FLAGS\n",
-                   mkstring(buf1, VADDR_PRLEN, CENTER, "PAGE"), 
-                   space(MINSPACE),             
-                    mkstring(buf2, MAX(PADDR_PRLEN, strlen("PHYSICAL")),
-                        RJUST, "PHYSICAL"),
-                   space(MINSPACE),             
-                   mkstring(buf3, VADDR_PRLEN, CENTER|RJUST, "MAPPING"),
-                   space(MINSPACE),               
-                   mkstring(buf4, 8, CENTER|RJUST, "INDEX"));
-        }
+       if (!mi->include) {
+               sprintf((char *)&style1, "%%lx%s%%%dllx%s%%%dlx%s%%8lx %%2d%s",
+                               space(MINSPACE),
+                               (int)MAX(PADDR_PRLEN, strlen("PHYSICAL")),
+                               space(MINSPACE),
+                               VADDR_PRLEN,
+                               space(MINSPACE),
+                               space(MINSPACE));
+               sprintf((char *)&style2, "%%-%dlx%s%%%dllx%s%s%s%s %2s ",
+                               VADDR_PRLEN,
+                               space(MINSPACE),
+                               (int)MAX(PADDR_PRLEN, strlen("PHYSICAL")),
+                               space(MINSPACE),
+                               mkstring(buf3, VADDR_PRLEN, CENTER|RJUST, " "),
+                               space(MINSPACE),
+                               mkstring(buf4, 8, CENTER|RJUST, " "),
+                               " ");
+               sprintf((char *)&style3, "%%-%dlx%s%%%dllx%s%s%s%s %%2d ",
+                               VADDR_PRLEN,
+                               space(MINSPACE),
+                               (int)MAX(PADDR_PRLEN, strlen("PHYSICAL")),
+                               space(MINSPACE),
+                               mkstring(buf3, VADDR_PRLEN, CENTER|RJUST, 
"-------"),
+                               space(MINSPACE),
+                               mkstring(buf4, 8, CENTER|RJUST, "-----"));
+               sprintf((char *)&style4, "%%-%dlx%s%%%dllx%s%%%dlx%s%%8lx %%2d 
",
+                               VADDR_PRLEN,
+                               space(MINSPACE),
+                               (int)MAX(PADDR_PRLEN, strlen("PHYSICAL")),
+                               space(MINSPACE),
+                               VADDR_PRLEN,
+                               space(MINSPACE));
+
+               if (v22) {
+                       sprintf(hdr, "%s%s%s%s%s%s%s%sCNT FLAGS\n",
+                           mkstring(buf1, VADDR_PRLEN, CENTER, "PAGE"), 
+                           space(MINSPACE),               
+                           mkstring(buf2, MAX(PADDR_PRLEN, strlen("PHYSICAL")),
+                               RJUST, "PHYSICAL"),                 
+                           space(MINSPACE),               
+                           mkstring(buf3, VADDR_PRLEN, CENTER|RJUST, "INODE"), 
+                           space(MINSPACE),               
+                           mkstring(buf4, 8, CENTER|LJUST, "OFFSET"),
+                           space(MINSPACE-1));
+               } else {
+                       sprintf(hdr, "%s%s%s%s%s%s%sCNT FLAGS\n",
+                           mkstring(buf1, VADDR_PRLEN, CENTER, "PAGE"), 
+                           space(MINSPACE),             
+                           mkstring(buf2, MAX(PADDR_PRLEN, strlen("PHYSICAL")),
+                               RJUST, "PHYSICAL"),
+                           space(MINSPACE),             
+                           mkstring(buf3, VADDR_PRLEN, CENTER|RJUST, 
"MAPPING"),
+                           space(MINSPACE),               
+                           mkstring(buf4, 8, CENTER|RJUST, "INDEX"));
+               }
+       } else {
+               if (count_chars(mi->include, ',') > MAXARGS)
+                       error(FATAL, "too many members in comma-separated 
list!\n");
+
+               if ((LASTCHAR(mi->include) == ',') || (LASTCHAR(mi->include) == 
'.'))
+                       error(FATAL, "invalid format: %s\n", mi->include);
+
+               members = GETBUF(strlen(mi->include)+1);
+               strcpy(members, mi->include);
+               replace_string(members, ",", ' ');
+               nr_members = parse_line(members, memberlist);
+               populated = FALSE;
+
+       }
 
-       mapping = index = 0;
-       reserved = shared = slabs = buffers = inode = offset = 0;
-       pg_spec = phys_spec = print_hdr = FALSE;
-       
        switch (mi->flags)
        {
        case ADDRESS_SPECIFIED: 
@@ -5541,7 +5657,8 @@ dump_mem_map(struct meminfo *mi)
                        error(FATAL, "dump_mem_map: no memtype specified\n");
                        break;
                }
-               print_hdr = TRUE;
+               if (!mi->include)
+                       print_hdr = TRUE;
                break;
 
        case GET_ALL:
@@ -5568,7 +5685,8 @@ dump_mem_map(struct meminfo *mi)
                break;
 
        default:
-               print_hdr = TRUE;
+               if (!mi->include)
+                       print_hdr = TRUE;
                break;
        }
 
@@ -5625,181 +5743,245 @@ dump_mem_map(struct meminfo *mi)
 
                        if (!done && (pg_spec || phys_spec))
                                continue;
-                       
-                       flags = ULONG(pcache + OFFSET(page_flags));
-                       if (SIZE(page_flags) == 4)
-                               flags &= 0xffffffff;
-                       count = UINT(pcache + OFFSET(page_count));
 
-                       switch (mi->flags)
-                       {
-                       case GET_ALL:
-                       case GET_BUFFERS_PAGES:
-                               if (VALID_MEMBER(page_buffers)) {
-                                       tmp = ULONG(pcache + 
-                                               OFFSET(page_buffers));
-                                       if (tmp)
-                                               buffers++;
-                               } else if (THIS_KERNEL_VERSION >= LINUX(2,6,0)) 
{
-                                       if ((flags >> v26_PG_private) & 1) 
-                                               buffers++;
-                               } else
-                                       error(FATAL, 
-                              "cannot determine whether pages have buffers\n");
+                       if (mi->include) {
+                               if (!populated) {
 
-                               if (mi->flags != GET_ALL)
-                                       continue;
+                                       j = 0;
+                                       do {
+                                               if (!(member_data[j] = 
malloc(sizeof(struct struct_member_data)))) {
+                                                       error(WARNING, "cannot 
malloc member_data space.\n");
+                                                       nr_members = j += 1;
+                                                       goto failed_member_data;
+                                               }
 
-                               /* FALLTHROUGH */
+                                               member_data[j]->structure = 
"page";
+                                               member_data[j]->member = 
memberlist[j];
+                                               if 
(!(fill_struct_member_data(member_data[j]))) {
+                                                       error(WARNING, "Failed 
to populate member_data: "
+                                                               "%s.%s does not 
exist.\n",
+                                                               
member_data[j]->structure, member_data[j]->member);
+                                                       nr_members = j += 1;
+                                                       goto failed_member_data;
+                                               }
 
-                       case GET_SLAB_PAGES:
-                               if (v22) {
-                                       if ((flags >> v22_PG_Slab) & 1) 
-                                               slabs++;
-                               } else if (vt->PG_slab) {
-                                       if ((flags >> vt->PG_slab) & 1) 
-                                               slabs++;
-                               } else {
-                                       if ((flags >> v24_PG_slab) & 1) 
-                                               slabs++;
+                                       } while (++j < nr_members);
+                                       populated = TRUE;
                                }
-                               if (mi->flags != GET_ALL)
-                                       continue;
 
-                               /* FALLTHROUGH */
 
-                       case GET_SHARED_PAGES:
-                       case GET_TOTALRAM_PAGES:
-                                if (vt->PG_reserved)
-                                       PG_reserved_flag = vt->PG_reserved;
-                               else
-                                        PG_reserved_flag = v22 ?
-                                                1 << v22_PG_reserved :
-                                                1 << v24_PG_reserved;
+                               bufferindex += sprintf(outputbuffer + 
bufferindex,
+                                       "%lx\t", pp);
 
-                               if (flags & PG_reserved_flag) {
-                                       reserved++;
-                               } else {
-                                       if ((int)count >
-                                           (vt->flags & PGCNT_ADJ ? 0 : 1))
-                                               shared++;
-                               }
-                               continue;
-                       }
-       
-                       page_mapping = VALID_MEMBER(page_mapping);
-
-                       if (v22) {
-                               inode = ULONG(pcache + OFFSET(page_inode));
-                               offset = ULONG(pcache + OFFSET(page_offset));
-                       } else if (page_mapping) {
-                               mapping = ULONG(pcache + 
-                                       OFFSET(page_mapping));
-                               index = ULONG(pcache + OFFSET(page_index));
-                       }
-       
-                       page_not_mapped = phys_not_mapped = FALSE;
+                               j = 0;
+                               do {
+                                       switch (member_data[j]->type)
+                                       {
+                                       case TYPE_CODE_PTR:
+                                               readmem(pp + 
member_data[j]->offset, KVADDR, &tmpvalue,
+                                                       member_data[j]->length, 
"tmpvalue", FAULT_ON_ERROR);
+                                               bufferindex += 
sprintf(outputbuffer + bufferindex, "0x%lx\t",
+                                                       tmpvalue);
+                                               break;
+                                       case TYPE_CODE_INT:
+                                               readmem(pp + 
member_data[j]->offset, KVADDR, &tmpvalue,
+                                                       member_data[j]->length, 
"tmpvalue", FAULT_ON_ERROR);
+                                               if 
(member_data[j]->unsigned_type ||
+                                                       member_data[j]->length 
== sizeof(ulonglong))
+                                                       bufferindex += 
sprintf(outputbuffer + bufferindex,
+                                                               "%lu\t", 
tmpvalue);
+                                               else
+                                                       bufferindex += 
sprintf(outputbuffer + bufferindex,
+                                                               "%d\t", 
(int)tmpvalue);
+                                               break;
+                                       default:
+                                               error(WARNING, "invalid data 
structure reference %s.%s\n",
+                                                       
member_data[j]->structure, member_data[j]->member);
+                                               nr_members = j += 1;
+                                               goto failed_member_data;
+                                               break;
+                                       }
+                               } while (++j < nr_members);
+
+                               bufferindex += 
sprintf(outputbuffer+bufferindex, "\n");
 
-                       if (v22) {
-                               bufferindex += sprintf(outputbuffer+bufferindex,
-                                               (char *)&style1, pp, phys, 
inode,
-                                               offset, count);
                        } else {
-                               if ((vt->flags & V_MEM_MAP)) {
-                                       if (!machdep->verify_paddr(phys)) 
-                                               phys_not_mapped = TRUE;
-                                       if (!kvtop(NULL, pp, NULL, 0))
-                                               page_not_mapped = TRUE;
+
+                               flags = ULONG(pcache + OFFSET(page_flags));
+                               if (SIZE(page_flags) == 4)
+                                       flags &= 0xffffffff;
+                               count = UINT(pcache + OFFSET(page_count));
+
+                               switch (mi->flags)
+                               {
+                               case GET_ALL:
+                               case GET_BUFFERS_PAGES:
+                                       if (VALID_MEMBER(page_buffers)) {
+                                               tmp = ULONG(pcache + 
+                                                       OFFSET(page_buffers));
+                                               if (tmp)
+                                                       buffers++;
+                                       } else if (THIS_KERNEL_VERSION >= 
LINUX(2,6,0)) {
+                                               if ((flags >> v26_PG_private) & 
1) 
+                                                       buffers++;
+                                       } else
+                                               error(FATAL, 
+                                      "cannot determine whether pages have 
buffers\n");
+
+                                       if (mi->flags != GET_ALL)
+                                               continue;
+
+                                       /* FALLTHROUGH */
+
+                               case GET_SLAB_PAGES:
+                                       if (v22) {
+                                               if ((flags >> v22_PG_Slab) & 1) 
+                                                       slabs++;
+                                       } else if (vt->PG_slab) {
+                                               if ((flags >> vt->PG_slab) & 1) 
+                                                       slabs++;
+                                       } else {
+                                               if ((flags >> v24_PG_slab) & 1) 
+                                                       slabs++;
+                                       }
+                                       if (mi->flags != GET_ALL)
+                                               continue;
+
+                                       /* FALLTHROUGH */
+
+                               case GET_SHARED_PAGES:
+                               case GET_TOTALRAM_PAGES:
+                                       if (vt->PG_reserved)
+                                               PG_reserved_flag = 
vt->PG_reserved;
+                                       else
+                                               PG_reserved_flag = v22 ?
+                                                       1 << v22_PG_reserved :
+                                                       1 << v24_PG_reserved;
+
+                                       if (flags & PG_reserved_flag) {
+                                               reserved++;
+                                       } else {
+                                               if ((int)count >
+                                                   (vt->flags & PGCNT_ADJ ? 0 
: 1))
+                                                       shared++;
+                                       }
+                                       continue;
                                }
-                               if (page_not_mapped)
-                                       bufferindex += 
sprintf(outputbuffer+bufferindex,
-                                                       (char *)&style2, pp, 
phys);
-                               else if (!page_mapping)
-                                       bufferindex += 
sprintf(outputbuffer+bufferindex,
-                                                       (char *)&style3, pp, 
phys, count);
-                               else
+               
+                               page_mapping = VALID_MEMBER(page_mapping);
+
+                               if (v22) {
+                                       inode = ULONG(pcache + 
OFFSET(page_inode));
+                                       offset = ULONG(pcache + 
OFFSET(page_offset));
+                               } else if (page_mapping) {
+                                       mapping = ULONG(pcache + 
+                                               OFFSET(page_mapping));
+                                       index = ULONG(pcache + 
OFFSET(page_index));
+                               }
+               
+                               page_not_mapped = phys_not_mapped = FALSE;
+
+                               if (v22) {
                                        bufferindex += 
sprintf(outputbuffer+bufferindex,
-                                                       (char *)&style4, pp, 
phys,
-                                                       mapping, index, count);
-                       }
-       
-                       others = 0;
-       
+                                                       (char *)&style1, pp, 
phys, inode,
+                                                       offset, count);
+                               } else {
+                                       if ((vt->flags & V_MEM_MAP)) {
+                                               if 
(!machdep->verify_paddr(phys)) 
+                                                       phys_not_mapped = TRUE;
+                                               if (!kvtop(NULL, pp, NULL, 0))
+                                                       page_not_mapped = TRUE;
+                                       }
+                                       if (page_not_mapped)
+                                               bufferindex += 
sprintf(outputbuffer+bufferindex,
+                                                               (char 
*)&style2, pp, phys);
+                                       else if (!page_mapping)
+                                               bufferindex += 
sprintf(outputbuffer+bufferindex,
+                                                               (char 
*)&style3, pp, phys, count);
+                                       else
+                                               bufferindex += 
sprintf(outputbuffer+bufferindex,
+                                                               (char 
*)&style4, pp, phys,
+                                                               mapping, index, 
count);
+                               }
+               
+                               others = 0;
+               
 #define sprintflag(X) sprintf(outputbuffer + bufferindex, X, others++ ? "," : 
"")
 
-                       if (v22) {
-                               if ((flags >> v22_PG_DMA) & 1)
-                                       bufferindex += sprintflag("%sDMA");
-                               if ((flags >> v22_PG_locked) & 1)
-                                       bufferindex += sprintflag("%slocked");
-                               if ((flags >> v22_PG_error) & 1)
-                                       bufferindex += sprintflag("%serror");
-                               if ((flags >> v22_PG_referenced) & 1)
-                                       bufferindex += 
sprintflag("%sreferenced");
-                               if ((flags >> v22_PG_dirty) & 1)
-                                       bufferindex += sprintflag("%sdirty");
-                               if ((flags >> v22_PG_uptodate) & 1)
-                                       bufferindex += sprintflag("%suptodate");
-                               if ((flags >> v22_PG_free_after) & 1)
-                                       bufferindex += 
sprintflag("%sfree_after");
-                               if ((flags >> v22_PG_decr_after) & 1)
-                                       bufferindex += 
sprintflag("%sdecr_after");
-                               if ((flags >> v22_PG_swap_unlock_after) & 1)
-                                       bufferindex += 
sprintflag("%sswap_unlock_after");
-                               if ((flags >> v22_PG_Slab) & 1)
-                                       bufferindex += sprintflag("%sslab");
-                               if ((flags >> v22_PG_swap_cache) & 1)
-                                       bufferindex += 
sprintflag("%sswap_cache");
-                               if ((flags >> v22_PG_skip) & 1)
-                                       bufferindex += sprintflag("%sskip");
-                               if ((flags >> v22_PG_reserved) & 1)
-                                       bufferindex += sprintflag("%sreserved");
-                               bufferindex += 
sprintf(outputbuffer+bufferindex, "\n");
-                       } else if (THIS_KERNEL_VERSION > LINUX(2,4,9)) {
-                               if (vt->flags & PAGEFLAGS)
-                                       bufferindex += 
translate_page_flags(outputbuffer+bufferindex, flags);
-                               else
-                                       bufferindex += 
sprintf(outputbuffer+bufferindex, "%lx\n", flags);
-                       } else {
-       
-                               if ((flags >> v24_PG_locked) & 1)
-                                       bufferindex += sprintflag("%slocked");
-                               if ((flags >> v24_PG_error) & 1)
-                                       bufferindex += sprintflag("%serror");
-                               if ((flags >> v24_PG_referenced) & 1)
-                                       bufferindex += 
sprintflag("%sreferenced");
-                               if ((flags >> v24_PG_uptodate) & 1)
-                                       bufferindex += sprintflag("%suptodate");
-                                if ((flags >> v24_PG_dirty) & 1)
-                                       bufferindex += sprintflag("%sdirty");
-                               if ((flags >> v24_PG_decr_after) & 1)
-                                       bufferindex += 
sprintflag("%sdecr_after");
-                                if ((flags >> v24_PG_active) & 1)
-                                       bufferindex += sprintflag("%sactive");
-                                if ((flags >> v24_PG_inactive_dirty) & 1)
-                                       bufferindex += 
sprintflag("%sinactive_dirty");
-                               if ((flags >> v24_PG_slab) & 1)
-                                       bufferindex += sprintflag("%sslab");
-                               if ((flags >> v24_PG_swap_cache) & 1)
-                                       bufferindex += 
sprintflag("%sswap_cache");
-                               if ((flags >> v24_PG_skip) & 1)
-                                       bufferindex += sprintflag("%sskip");
-                               if ((flags >> v24_PG_inactive_clean) & 1)
-                                       bufferindex += 
sprintflag("%sinactive_clean");
-                               if ((flags >> v24_PG_highmem) & 1)
-                                       bufferindex += sprintflag("%shighmem");
-                               if ((flags >> v24_PG_checked) & 1)
-                                       bufferindex += sprintflag("%schecked");
-                               if ((flags >> v24_PG_bigpage) & 1)
-                                       bufferindex += sprintflag("%sbigpage");
-                                if ((flags >> v24_PG_arch_1) & 1)
-                                       bufferindex += sprintflag("%sarch_1");
-                               if ((flags >> v24_PG_reserved) & 1)
-                                       bufferindex += sprintflag("%sreserved");
-                               if (phys_not_mapped)
-                                       bufferindex += sprintflag("%s[NOT 
MAPPED]");
-
-                               bufferindex += 
sprintf(outputbuffer+bufferindex, "\n");
+                               if (v22) {
+                                       if ((flags >> v22_PG_DMA) & 1)
+                                               bufferindex += 
sprintflag("%sDMA");
+                                       if ((flags >> v22_PG_locked) & 1)
+                                               bufferindex += 
sprintflag("%slocked");
+                                       if ((flags >> v22_PG_error) & 1)
+                                               bufferindex += 
sprintflag("%serror");
+                                       if ((flags >> v22_PG_referenced) & 1)
+                                               bufferindex += 
sprintflag("%sreferenced");
+                                       if ((flags >> v22_PG_dirty) & 1)
+                                               bufferindex += 
sprintflag("%sdirty");
+                                       if ((flags >> v22_PG_uptodate) & 1)
+                                               bufferindex += 
sprintflag("%suptodate");
+                                       if ((flags >> v22_PG_free_after) & 1)
+                                               bufferindex += 
sprintflag("%sfree_after");
+                                       if ((flags >> v22_PG_decr_after) & 1)
+                                               bufferindex += 
sprintflag("%sdecr_after");
+                                       if ((flags >> v22_PG_swap_unlock_after) 
& 1)
+                                               bufferindex += 
sprintflag("%sswap_unlock_after");
+                                       if ((flags >> v22_PG_Slab) & 1)
+                                               bufferindex += 
sprintflag("%sslab");
+                                       if ((flags >> v22_PG_swap_cache) & 1)
+                                               bufferindex += 
sprintflag("%sswap_cache");
+                                       if ((flags >> v22_PG_skip) & 1)
+                                               bufferindex += 
sprintflag("%sskip");
+                                       if ((flags >> v22_PG_reserved) & 1)
+                                               bufferindex += 
sprintflag("%sreserved");
+                                       bufferindex += 
sprintf(outputbuffer+bufferindex, "\n");
+                               } else if (THIS_KERNEL_VERSION > LINUX(2,4,9)) {
+                                       if (vt->flags & PAGEFLAGS)
+                                               bufferindex += 
translate_page_flags(outputbuffer+bufferindex, flags);
+                                       else
+                                               bufferindex += 
sprintf(outputbuffer+bufferindex, "%lx\n", flags);
+                               } else {
+               
+                                       if ((flags >> v24_PG_locked) & 1)
+                                               bufferindex += 
sprintflag("%slocked");
+                                       if ((flags >> v24_PG_error) & 1)
+                                               bufferindex += 
sprintflag("%serror");
+                                       if ((flags >> v24_PG_referenced) & 1)
+                                               bufferindex += 
sprintflag("%sreferenced");
+                                       if ((flags >> v24_PG_uptodate) & 1)
+                                               bufferindex += 
sprintflag("%suptodate");
+                                       if ((flags >> v24_PG_dirty) & 1)
+                                               bufferindex += 
sprintflag("%sdirty");
+                                       if ((flags >> v24_PG_decr_after) & 1)
+                                               bufferindex += 
sprintflag("%sdecr_after");
+                                       if ((flags >> v24_PG_active) & 1)
+                                               bufferindex += 
sprintflag("%sactive");
+                                       if ((flags >> v24_PG_inactive_dirty) & 
1)
+                                               bufferindex += 
sprintflag("%sinactive_dirty");
+                                       if ((flags >> v24_PG_slab) & 1)
+                                               bufferindex += 
sprintflag("%sslab");
+                                       if ((flags >> v24_PG_swap_cache) & 1)
+                                               bufferindex += 
sprintflag("%sswap_cache");
+                                       if ((flags >> v24_PG_skip) & 1)
+                                               bufferindex += 
sprintflag("%sskip");
+                                       if ((flags >> v24_PG_inactive_clean) & 
1)
+                                               bufferindex += 
sprintflag("%sinactive_clean");
+                                       if ((flags >> v24_PG_highmem) & 1)
+                                               bufferindex += 
sprintflag("%shighmem");
+                                       if ((flags >> v24_PG_checked) & 1)
+                                               bufferindex += 
sprintflag("%schecked");
+                                       if ((flags >> v24_PG_bigpage) & 1)
+                                               bufferindex += 
sprintflag("%sbigpage");
+                                       if ((flags >> v24_PG_arch_1) & 1)
+                                               bufferindex += 
sprintflag("%sarch_1");
+                                       if ((flags >> v24_PG_reserved) & 1)
+                                               bufferindex += 
sprintflag("%sreserved");
+                                       if (phys_not_mapped)
+                                               bufferindex += 
sprintflag("%s[NOT MAPPED]");
+
+                                       bufferindex += 
sprintf(outputbuffer+bufferindex, "\n");
+                               }
                        }
        
                        if (bufferindex > buffersize) {
@@ -5851,6 +6033,12 @@ dump_mem_map(struct meminfo *mi)
 
        FREEBUF(outputbuffer);
        FREEBUF(page_cache);
+failed_member_data:
+       if (mi->include) {
+               FREEBUF(members);
+               for (i = 0; i < nr_members; i++)
+                       free(member_data[i]);
+       }
 }
 
 /*
-- 
1.9.3

--
Crash-utility mailing list
[email protected]
https://www.redhat.com/mailman/listinfo/crash-utility

Reply via email to