From: Dmitry V. Levin Date: Sat, 18 Nov 2017 01:35:20 +0000 (+0000) Subject: ipc_shm: decode hugetlb page size in shmget flags X-Git-Tag: v4.21~303 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=f34045326262ff82fb8959d6dee22237424600ac;p=strace ipc_shm: decode hugetlb page size in shmget flags Decode alternative hugetlb page sizes introduced by kernel commit v3.8-rc1~175^2~36. * ipc_shm.c [!SHM_HUGE_SHIFT] (SHM_HUGE_SHIFT): New macro. [!SHM_HUGE_MASK] (SHM_HUGE_MASK): Likewise. (SYS_FUNC(shmget)): Print hugetlb page size. * tests/ipc_shm.c: Check it. --- diff --git a/ipc_shm.c b/ipc_shm.c index 7284b183..b358fc69 100644 --- a/ipc_shm.c +++ b/ipc_shm.c @@ -39,6 +39,14 @@ # include #endif +#ifndef SHM_HUGE_SHIFT +# define SHM_HUGE_SHIFT 26 +#endif + +#ifndef SHM_HUGE_MASK +# define SHM_HUGE_MASK 0x3f +#endif + #include "xlat/shm_resource_flags.h" #include "xlat/shm_flags.h" @@ -50,9 +58,24 @@ SYS_FUNC(shmget) else tprints("IPC_PRIVATE"); tprintf(", %" PRI_klu ", ", tcp->u_arg[1]); - if (printflags(shm_resource_flags, tcp->u_arg[2] & ~0777, NULL) != 0) + + unsigned int flags = tcp->u_arg[2] & ~0777; + const unsigned int mask = SHM_HUGE_MASK << SHM_HUGE_SHIFT; + const unsigned int hugetlb_value = flags & mask; + + flags &= ~mask; + if (flags || !hugetlb_value) + printflags(shm_resource_flags, flags, NULL); + + if (hugetlb_value) + tprintf("%s%u<> SHM_HUGE_SHIFT); + + if (flags || hugetlb_value) tprints("|"); print_numeric_umode_t(tcp->u_arg[2] & 0777); + return RVAL_DECODED; } diff --git a/tests/ipc_shm.c b/tests/ipc_shm.c index 9e9c5609..fd700f8f 100644 --- a/tests/ipc_shm.c +++ b/tests/ipc_shm.c @@ -32,6 +32,14 @@ #include #include +#ifndef SHM_HUGE_SHIFT +# define SHM_HUGE_SHIFT 26 +#endif + +#ifndef SHM_HUGE_MASK +# define SHM_HUGE_MASK 0x3f +#endif + #include "xlat.h" #include "xlat/shm_resource_flags.h" @@ -64,20 +72,54 @@ main(void) #else (size_t) 0x1e55c0de5dec0dedULL; #endif - static const int bogus_flags = 0xface1e55; - + static const unsigned int bogus_ipc_shm_flags = + IPC_CREAT | IPC_EXCL | SHM_HUGETLB | SHM_NORESERVE; + static const unsigned int huge_mask = SHM_HUGE_MASK << SHM_HUGE_SHIFT; + static const unsigned int huge_flags = 21 << SHM_HUGE_SHIFT; + int bogus_flags; int rc; struct shmid_ds ds; + rc = shmget(bogus_key, bogus_size, 0); + printf("shmget\\(%#llx, %zu, 000\\) += %s\n", + zero_extend_signed_to_ull(bogus_key), bogus_size, + sprintrc_grep(rc)); + + rc = shmget(bogus_key, bogus_size, huge_flags); + printf("shmget\\(%#llx, %zu, %s\\|%#03o\\) += %s\n", + zero_extend_signed_to_ull(bogus_key), bogus_size, + "21<