diff -up procps-3.2.8/pmap.c.pmap procps-3.2.8/pmap.c
--- procps-3.2.8/pmap.c.pmap	2008-10-19 21:34:34.000000000 +0200
+++ procps-3.2.8/pmap.c	2010-02-08 15:40:19.000000000 +0100
@@ -126,24 +126,38 @@ static int one_proc(proc_t *p){
   char buf[32];
   char mapbuf[9600];
   char cmdbuf[512];
+  FILE *fp;
   unsigned long total_shared = 0ul;
   unsigned long total_private_readonly = 0ul;
   unsigned long total_private_writeable = 0ul;
 
+  char *cp2=NULL;
+  unsigned long long rss = 0ull;
+  unsigned long long private_dirty = 0ull;
+  unsigned long long shared_dirty = 0ull;
+  unsigned long long total_rss = 0ull;
+  unsigned long long total_private_dirty = 0ull;
+  unsigned long long total_shared_dirty = 0ull;
+  unsigned KLONG diff = 0;
+
   // Overkill, but who knows what is proper? The "w" prog
   // uses the tty width to determine this.
   int maxcmd = 0xfffff;
 
   sprintf(buf,"/proc/%u/maps",p->tgid);
-  if(!freopen(buf, "r", stdin)) return 1;
+  if ( (fp = fopen(buf, "r")) == NULL) return 1;
+  if (x_option) {
+    sprintf(buf,"/proc/%u/smaps",p->tgid);
+    if ( (fp = freopen(buf, "r", fp)) == NULL) return 1;
+  }
 
   escape_command(cmdbuf, p, sizeof cmdbuf, &maxcmd, ESC_ARGS|ESC_BRACKETS);
   printf("%u:   %s\n", p->tgid, cmdbuf);
 
   if(!q_option && (x_option|d_option)){
     if(x_option){
-      if(sizeof(KLONG)==4) printf("Address   Kbytes     RSS    Anon  Locked Mode   Mapping\n");
-      else         printf("Address           Kbytes     RSS    Anon  Locked Mode   Mapping\n");
+      if(sizeof(KLONG)==4) printf("Address   Kbytes     RSS   Dirty Mode   Mapping\n");
+      else         printf("Address           Kbytes     RSS   Dirty Mode   Mapping\n");
     }
     if(d_option){
       if(sizeof(KLONG)==4) printf("Address   Kbytes Mode  Offset           Device    Mapping\n");
@@ -151,12 +165,54 @@ static int one_proc(proc_t *p){
     }
   }
 
-  while(fgets(mapbuf,sizeof mapbuf,stdin)){
+  while(fgets(mapbuf,sizeof mapbuf,fp)){
     char flags[32];
     char *tmp; // to clean up unprintables
-    unsigned KLONG start, end, diff;
+    unsigned KLONG start, end;
     unsigned long long file_offset, inode;
     unsigned dev_major, dev_minor;
+    unsigned long long smap_value;
+    char smap_key[20];
+
+    /* hex values are lower case or numeric, keys are upper */
+    if (mapbuf[0] >= 'A' && mapbuf[0] <= 'Z') {
+      /* Its a key */
+      if (sscanf(mapbuf,"%20[^:]: %llu", smap_key, &smap_value) == 2) {
+        if (strncmp("Rss", smap_key, 3) == 0) {
+          rss = smap_value;
+          total_rss += smap_value;
+          continue;
+        }
+        if (strncmp("Shared_Dirty", smap_key, 12) == 0) {
+          shared_dirty = smap_value;
+          total_shared_dirty += smap_value;
+          continue;
+        }
+        if (strncmp("Private_Dirty", smap_key, 13) == 0) {
+          private_dirty = smap_value;
+          total_private_dirty += smap_value;
+          continue;
+        }
+        if (strncmp("Swap", smap_key, 4) == 0) { /*doesnt matter as long as last*/
+          printf(
+            (sizeof(KLONG)==8)
+              ? "%016"KLF"x %7lu %7llu %7llu %s  %s\n"
+              :      "%08lx %7lu %7llu %7llu %s  %s\n",
+            start,
+            (unsigned long)(diff>>10),
+            rss,
+            (private_dirty + shared_dirty),
+            flags,
+            cp2
+          );
+          /* reset some counters */
+          rss = shared_dirty = private_dirty = 0ull;
+          continue;
+        }
+        /* Other keys */
+        continue;
+      }
+    }
     sscanf(mapbuf,"%"KLF"x-%"KLF"x %31s %Lx %x:%x %Lu", &start, &end, flags, &file_offset, &dev_major, &dev_minor, &inode);
 
     if(start > range_high)
@@ -186,16 +242,9 @@ static int one_proc(proc_t *p){
     flags[5] = '\0';
 
     if(x_option){
-      const char *cp = mapping_name(p, start, diff, mapbuf, 0, dev_major, dev_minor, inode);
-      printf(
-        (sizeof(KLONG)==8)
-          ? "%016"KLF"x %7lu       -       -       - %s  %s\n"
-          :      "%08lx %7lu       -       -       - %s  %s\n",
-        start,
-        (unsigned long)(diff>>10),
-        flags,
-        cp
-      );
+          cp2 = mapping_name(p, start, diff, mapbuf, 0, dev_major, dev_minor, inode);
+      /* printed with the keys */
+      continue;
     }
     if(d_option){
       const char *cp = mapping_name(p, start, diff, mapbuf, 0, dev_major, dev_minor, inode);
@@ -232,10 +281,12 @@ static int one_proc(proc_t *p){
   if(!q_option){
     if(x_option){
       if(sizeof(KLONG)==8){
-        printf("----------------  ------  ------  ------  ------\n");
+        printf("----------------  ------  ------  ------\n");
         printf(
-          "total kB %15ld       -       -       -\n",
-          (total_shared + total_private_writeable + total_private_readonly) >> 10
+          "total kB %15ld %7llu %7llu\n",
+          (total_shared + total_private_writeable + total_private_readonly) >> 10,
+          total_rss, (total_shared_dirty+total_private_dirty)
+
         );
       }else{
         printf("-------- ------- ------- ------- -------\n");
