pmap: make 32-bit version work better on 64-bit kernels
authorDenys Vlasenko <vda.linux@googlemail.com>
Sun, 30 Dec 2018 19:24:59 +0000 (20:24 +0100)
committerDenys Vlasenko <vda.linux@googlemail.com>
Mon, 31 Dec 2018 14:18:45 +0000 (15:18 +0100)
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
include/libbb.h
libbb/procps.c
procps/pmap.c

index daa96728b2524744a6d59caf1d504ee6948947b8..d2563999a1bc8fbb9295250b96cf0dfc58756ab4 100644 (file)
@@ -1828,7 +1828,12 @@ struct smaprec {
        unsigned long stack;
        unsigned long smap_pss, smap_swap;
        unsigned long smap_size;
-       unsigned long smap_start;
+       // For mixed 32/64 userspace, 32-bit pmap still needs
+       // 64-bit field here to correctly show 64-bit processes:
+       unsigned long long smap_start;
+       // (strictly speaking, other fields need to be wider too,
+       // but they are in kbytes, not bytes, and they hold sizes,
+       // not start addresses, sizes tend to be less than 4 terabytes)
        char smap_mode[5];
        char *smap_name;
 };
index 9d8a921dfb72caa3b857be832fc8b3b7ddd8a2e0..af3ad86ff8dd00edcbd87547420235e055d7f113 100644 (file)
@@ -120,11 +120,11 @@ void FAST_FUNC free_procps_scan(procps_status_t* sp)
 }
 
 #if ENABLE_FEATURE_TOPMEM || ENABLE_PMAP
-static unsigned long fast_strtoul_16(char **endptr)
+static unsigned long long fast_strtoull_16(char **endptr)
 {
        unsigned char c;
        char *str = *endptr;
-       unsigned long n = 0;
+       unsigned long long n = 0;
 
        /* Need to stop on both ' ' and '\n' */
        while ((c = *str++) > ' ') {
@@ -238,8 +238,8 @@ int FAST_FUNC procps_read_smaps(pid_t pid, struct smaprec *total,
 
                        *tp = ' ';
                        tp = buf;
-                       currec.smap_start = fast_strtoul_16(&tp);
-                       currec.smap_size = (fast_strtoul_16(&tp) - currec.smap_start) >> 10;
+                       currec.smap_start = fast_strtoull_16(&tp);
+                       currec.smap_size = (fast_strtoull_16(&tp) - currec.smap_start) >> 10;
 
                        strncpy(currec.smap_mode, tp, sizeof(currec.smap_mode)-1);
 
index c8fa0d28064bc614acc7f8e048cfc795a4a4b644..9e541c707a1bfde1f6b988cf3d2a6b7acba70539 100644 (file)
 # define DASHES "--------"
 #endif
 
+#if ULLONG_MAX == 0xffffffff
+# define AFMTLL "8"
+#else
+# define AFMTLL "16"
+#endif
+
 enum {
        OPT_x = 1 << 0,
        OPT_q = 1 << 1,
@@ -46,7 +52,7 @@ static void print_smaprec(struct smaprec *currec, void *data)
 {
        unsigned opt = (uintptr_t)data;
 
-       printf("%0" AFMT "lx ", currec->smap_start);
+       printf("%0" AFMTLL "llx ", currec->smap_start);
 
        if (opt & OPT_x)
                printf("%7lu %7lu %7lu %7lu ",