From 3cf55950d0f6aa43eb5ad119bad1dbda69f75a54 Mon Sep 17 00:00:00 2001 From: Francis Deslauriers Date: Fri, 5 Jun 2020 11:38:14 -0400 Subject: [PATCH] syscalls: Make mmap()'s fields `prot` and `flags` enums The `prot` flags is a simple CTF enumeration. The `flags` field is a CTF struct of 2 CTF enumerations (`type` and `options`). This is needed to express the two parts of this integer flag. The 4 least significant bits of the integer are reserved to express the type of the mapping (MAP_SHARED=0x1, MAP_PRIVATE=0x2, and MAP_SHARED_VALIDATE=0x3). The remaining 28 bits are used to specify optional configurations on the mapping. As opposed to the type part, the options part is bit flag field where all values are power of 2. This part can be expressed as ORed bit flag values. Signed-off-by: Francis Deslauriers Signed-off-by: Mathieu Desnoyers Change-Id: I5ae78754b5863b31d9a3ba1b1173502e1ae284d3 --- .../headers/syscalls_integers_override.h | 135 +++++++++++++++++- src/lttng-syscalls.c | 1 + 2 files changed, 134 insertions(+), 2 deletions(-) diff --git a/include/instrumentation/syscalls/headers/syscalls_integers_override.h b/include/instrumentation/syscalls/headers/syscalls_integers_override.h index e5578640..3ad03526 100644 --- a/include/instrumentation/syscalls/headers/syscalls_integers_override.h +++ b/include/instrumentation/syscalls/headers/syscalls_integers_override.h @@ -2,6 +2,119 @@ #ifndef CREATE_SYSCALL_TABLE +/* + * The `flags` argument of the mmap syscall is split in two parts: + * - The type of mapping is described by the four least significant bits of the 4 + * bytes integer, + * - The options on the mapping are described by the remaining 28 most + * significant bits. + */ +#define MAPPING_TYPE_RESERVED_BITS 4 +#define LTTNG_MMAP_FLAGS_TO_CTF(x) ((x) >> MAPPING_TYPE_RESERVED_BITS) + +/* + * Enumeration of the mmap flags, as described in the 'mmap' + * system call man page. + */ +SC_LTTNG_TRACEPOINT_ENUM(lttng_mmap_protection, + TP_ENUM_VALUES( + ctf_enum_value("PROT_EXEC", PROT_EXEC) + ctf_enum_value("PROT_READ", PROT_READ) + ctf_enum_value("PROT_WRITE", PROT_WRITE) + ctf_enum_value("PROT_NONE", PROT_NONE) + ) +) + +SC_LTTNG_TRACEPOINT_ENUM(lttng_mmap_flags_mapping_type, + TP_ENUM_VALUES( + ctf_enum_value("MAP_SHARED", MAP_SHARED) + ctf_enum_value("MAP_PRIVATE", MAP_PRIVATE) +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,15,0)) + ctf_enum_value("MAP_SHARED_VALIDATE", MAP_SHARED_VALIDATE) +#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(4,15,0)) */ + ) +) + +/* + * Shift the values of the options so we can read them from the `flags` integer + * directly. + */ +SC_LTTNG_TRACEPOINT_ENUM(lttng_mmap_flags_options, + TP_ENUM_VALUES( + ctf_enum_value("", 0) + ctf_enum_value("MAP_32BIT", LTTNG_MMAP_FLAGS_TO_CTF(MAP_32BIT)) + ctf_enum_value("MAP_ANONYMOUS", LTTNG_MMAP_FLAGS_TO_CTF(MAP_ANONYMOUS)) + ctf_enum_value("MAP_DENYWRITE", LTTNG_MMAP_FLAGS_TO_CTF(MAP_DENYWRITE)) + ctf_enum_value("MAP_EXECUTABLE", LTTNG_MMAP_FLAGS_TO_CTF(MAP_EXECUTABLE)) + ctf_enum_value("MAP_FIXED", LTTNG_MMAP_FLAGS_TO_CTF(MAP_FIXED)) +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,17,0)) + ctf_enum_value("MAP_FIXED_NOREPLACE", LTTNG_MMAP_FLAGS_TO_CTF(MAP_FIXED_NOREPLACE)) +#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(4,17,0)) */ + ctf_enum_value("MAP_GROWSDOWN", LTTNG_MMAP_FLAGS_TO_CTF(MAP_GROWSDOWN)) + ctf_enum_value("MAP_HUGETLB", LTTNG_MMAP_FLAGS_TO_CTF(MAP_HUGETLB)) +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)) + ctf_enum_value("MAP_HUGETLB_2MB", LTTNG_MMAP_FLAGS_TO_CTF(MAP_HUGE_2MB)) + ctf_enum_value("MAP_HUGETLB_1GB", LTTNG_MMAP_FLAGS_TO_CTF(MAP_HUGE_1GB)) +#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)) */ + ctf_enum_value("MAP_LOCKED", LTTNG_MMAP_FLAGS_TO_CTF(MAP_LOCKED)) + ctf_enum_value("MAP_NONBLOCK", LTTNG_MMAP_FLAGS_TO_CTF(MAP_NONBLOCK)) + ctf_enum_value("MAP_NORESERVE", LTTNG_MMAP_FLAGS_TO_CTF(MAP_NORESERVE)) + ctf_enum_value("MAP_POPULATE", LTTNG_MMAP_FLAGS_TO_CTF(MAP_POPULATE)) + ctf_enum_value("MAP_STACK", LTTNG_MMAP_FLAGS_TO_CTF(MAP_STACK)) +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,15,0)) + ctf_enum_value("MAP_SYNC", LTTNG_MMAP_FLAGS_TO_CTF(MAP_SYNC)) +#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(4,15,0)) */ + ctf_enum_value("MAP_UNINITIALIZED", LTTNG_MMAP_FLAGS_TO_CTF(MAP_UNINITIALIZED)) + ) +) + +#define LTTNG_MMAP_FLAGS_TYPE \ +{ \ + .name = "type", \ + .type = { \ + .atype = atype_enum_nestable, \ + .u = { \ + .enum_nestable = { \ + .desc = &__enum_lttng_mmap_flags_mapping_type, \ + .container_type = __LTTNG_COMPOUND_LITERAL( \ + struct lttng_type, __type_integer(uint32_t, \ + 4, 1, -1, __BYTE_ORDER, 16, none)), \ + }, \ + }, \ + }, \ +} + +#define LTTNG_MMAP_FLAGS_OPTIONS \ +{ \ + .name = "options", \ + .type = { \ + .atype = atype_enum_nestable, \ + .u = { \ + .enum_nestable = { \ + .desc = &__enum_lttng_mmap_flags_options, \ + .container_type = __LTTNG_COMPOUND_LITERAL( \ + struct lttng_type, __type_integer(uint32_t, \ + 28, 1, -1, __BYTE_ORDER, 16, none)),\ + }, \ + }, \ + }, \ +} + +#if (__BYTE_ORDER == __LITTLE_ENDIAN) +#define LTTNG_MMAP_FLAGS \ + [0] = LTTNG_MMAP_FLAGS_TYPE, \ + [1] = LTTNG_MMAP_FLAGS_OPTIONS, + +#else +#define LTTNG_MMAP_FLAGS \ + [0] = LTTNG_MMAP_FLAGS_OPTIONS, \ + [1] = LTTNG_MMAP_FLAGS_TYPE, +#endif + +/* + * Use a custom field here so that tracer writes a single integer and the + * work of splitting it up in two fields is left to the trace reader. + */ #define OVERRIDE_32_mmap #define OVERRIDE_64_mmap SC_LTTNG_TRACEPOINT_EVENT(mmap, @@ -13,8 +126,26 @@ SC_LTTNG_TRACEPOINT_EVENT(mmap, TP_FIELDS(sc_exit(ctf_integer_hex(unsigned long, ret, ret)) sc_in(ctf_integer_hex(unsigned long, addr, addr)) sc_in(ctf_integer(size_t, len, len)) - sc_in(ctf_integer(int, prot, prot)) - sc_in(ctf_integer(int, flags, flags)) + sc_in(ctf_enum(lttng_mmap_protection, int, prot, prot)) + sc_in( + ctf_custom_field( + ctf_custom_type( + { + .atype = atype_struct_nestable, + .u.struct_nestable.nr_fields = 2, + .u.struct_nestable.fields = + __LTTNG_COMPOUND_LITERAL(struct lttng_event_field, + LTTNG_MMAP_FLAGS + ), + .u.struct_nestable.alignment = lttng_alignof(uint32_t) * CHAR_BIT, + } + ), + flags, + ctf_custom_code( + ctf_integer_type(uint32_t, flags) + ) + ) + ) sc_in(ctf_integer(int, fd, fd)) sc_in(ctf_integer(off_t, offset, off)) ) diff --git a/src/lttng-syscalls.c b/src/lttng-syscalls.c index a5b5f403..0c28a467 100644 --- a/src/lttng-syscalls.c +++ b/src/lttng-syscalls.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include -- 2.34.1