From aad76968cd5934ee17f36cd8e817e86ae952b533 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Sun, 30 Dec 2018 20:24:59 +0100 Subject: pmap: make 32-bit version work better on 64-bit kernels Signed-off-by: Denys Vlasenko --- include/libbb.h | 7 ++++++- libbb/procps.c | 8 ++++---- procps/pmap.c | 8 +++++++- 3 files changed, 17 insertions(+), 6 deletions(-) diff --git a/include/libbb.h b/include/libbb.h index daa96728b..d2563999a 100644 --- a/include/libbb.h +++ b/include/libbb.h @@ -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; }; diff --git a/libbb/procps.c b/libbb/procps.c index 9d8a921df..af3ad86ff 100644 --- a/libbb/procps.c +++ b/libbb/procps.c @@ -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); diff --git a/procps/pmap.c b/procps/pmap.c index c8fa0d280..9e541c707 100644 --- a/procps/pmap.c +++ b/procps/pmap.c @@ -37,6 +37,12 @@ # 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 ", -- cgit v1.2.3