]> granicus.if.org Git - strace/commitdiff
ipc_shm: decode hugetlb page size in shmget flags
authorDmitry V. Levin <ldv@altlinux.org>
Sat, 18 Nov 2017 01:35:20 +0000 (01:35 +0000)
committerDmitry V. Levin <ldv@altlinux.org>
Sat, 18 Nov 2017 01:35:20 +0000 (01:35 +0000)
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.

ipc_shm.c
tests/ipc_shm.c

index 7284b183e2162d9dc725e3d29c9b7f919d563f6f..b358fc6986fb485b1c07772f98e286bd181d7f5c 100644 (file)
--- a/ipc_shm.c
+++ b/ipc_shm.c
 # include <linux/shm.h>
 #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",
+                       flags ? "|" : "",
+                       hugetlb_value >> SHM_HUGE_SHIFT);
+
+       if (flags || hugetlb_value)
                tprints("|");
        print_numeric_umode_t(tcp->u_arg[2] & 0777);
+
        return RVAL_DECODED;
 }
 
index 9e9c5609ee932e36538a04163fd77c2dea6a7494..fd700f8f410e8c2737720205e62b731a209beea9 100644 (file)
 #include <stdlib.h>
 #include <sys/shm.h>
 
+#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<<SHM_HUGE_SHIFT", 0, sprintrc_grep(rc));
+
+       bogus_flags = 0xface1e55 & ~(bogus_ipc_shm_flags | huge_mask);
+       rc = shmget(bogus_key, bogus_size, bogus_flags);
+       printf("shmget\\(%#llx, %zu, %#x\\|%#03o\\) += %s\n",
+              zero_extend_signed_to_ull(bogus_key), bogus_size,
+              bogus_flags & ~0777,
+              bogus_flags & 0777, sprintrc_grep(rc));
+
+       bogus_flags |= bogus_ipc_shm_flags;
+       rc = shmget(bogus_key, bogus_size, bogus_flags);
+       printf("shmget\\(%#llx, %zu, %s\\|%#x\\|%#03o\\) += %s\n",
+              zero_extend_signed_to_ull(bogus_key), bogus_size,
+              "IPC_CREAT\\|IPC_EXCL\\|SHM_HUGETLB\\|SHM_NORESERVE",
+              bogus_flags & ~(0777 | bogus_ipc_shm_flags),
+              bogus_flags & 0777, sprintrc_grep(rc));
+
+       bogus_flags |= huge_flags;
+       rc = shmget(bogus_key, bogus_size, bogus_flags);
+       printf("shmget\\(%#llx, %zu, %s\\|%#x\\|%s\\|%#03o\\) += %s\n",
+              zero_extend_signed_to_ull(bogus_key), bogus_size,
+              "IPC_CREAT\\|IPC_EXCL\\|SHM_HUGETLB\\|SHM_NORESERVE",
+              bogus_flags & ~(0777 | bogus_ipc_shm_flags | huge_mask),
+              "21<<SHM_HUGE_SHIFT",
+              bogus_flags & 0777, sprintrc_grep(rc));
+
+       bogus_flags &= ~bogus_ipc_shm_flags;
        rc = shmget(bogus_key, bogus_size, bogus_flags);
-       printf("shmget\\(%#llx, %zu, %s%s%s%s%#x\\|%#04o\\) += %s\n",
+       printf("shmget\\(%#llx, %zu, %#x\\|%s\\|%#03o\\) += %s\n",
               zero_extend_signed_to_ull(bogus_key), bogus_size,
-              IPC_CREAT & bogus_flags ? "IPC_CREAT\\|" : "",
-              IPC_EXCL & bogus_flags ? "IPC_EXCL\\|" : "",
-              SHM_HUGETLB & bogus_flags ? "SHM_HUGETLB\\|" : "",
-              SHM_NORESERVE & bogus_flags ? "SHM_NORESERVE\\|" : "",
-              bogus_flags & ~(0777 | IPC_CREAT | IPC_EXCL
-                                   | SHM_HUGETLB | SHM_NORESERVE),
+              bogus_flags & ~(0777 | huge_mask),
+              "21<<SHM_HUGE_SHIFT",
               bogus_flags & 0777, sprintrc_grep(rc));
 
        id = shmget(private_key, 1, 0600);