1 1.1 christos #ifndef JEMALLOC_INTERNAL_JEMALLOC_PROBE_CUSTOM_H 2 1.1 christos #define JEMALLOC_INTERNAL_JEMALLOC_PROBE_CUSTOM_H 3 1.1 christos 4 1.1 christos /* clang-format off */ 5 1.1 christos 6 1.1 christos /* 7 1.1 christos * This section is based on sys/sdt.h and 8 1.1 christos * https://sourceware.org/systemtap/wiki/UserSpaceProbeImplementation 9 1.1 christos */ 10 1.1 christos 11 1.1 christos /* Emit NOP for the probe. */ 12 1.1 christos #if (defined(__x86_64__) || defined(__i386__) || defined(__aarch64__) || \ 13 1.1 christos defined(__arm__)) && defined(__linux__) 14 1.1 christos #define JE_SDT_NOP nop 15 1.1 christos #else 16 1.1 christos #error "Architecture not supported" 17 1.1 christos #endif 18 1.1 christos 19 1.1 christos /* Assembly macros */ 20 1.1 christos #define JE_SDT_S(x) #x 21 1.1 christos 22 1.1 christos #define JE_SDT_ASM_1(x) JE_SDT_S(x) "\n" 23 1.1 christos 24 1.1 christos #define JE_SDT_ASM_2(x, y) \ 25 1.1 christos JE_SDT_S(x) "," JE_SDT_S(y) "\n" 26 1.1 christos 27 1.1 christos #define JE_SDT_ASM_3(x, y, z) \ 28 1.1 christos JE_SDT_S(x) "," JE_SDT_S(y) "," JE_SDT_S(z) "\n" 29 1.1 christos 30 1.1 christos #define JE_SDT_ASM_3(x, y, z) \ 31 1.1 christos JE_SDT_S(x) "," JE_SDT_S(y) "," JE_SDT_S(z) "\n" 32 1.1 christos 33 1.1 christos #define JE_SDT_ASM_4(x, y, z, p) \ 34 1.1 christos JE_SDT_S(x) "," JE_SDT_S(y) "," JE_SDT_S(z) "," JE_SDT_S(p) "\n" 35 1.1 christos 36 1.1 christos #define JE_SDT_ASM_5(x, y, z, p, q) \ 37 1.1 christos JE_SDT_S(x) "," JE_SDT_S(y) "," JE_SDT_S(z) "," JE_SDT_S(p) "," \ 38 1.1 christos JE_SDT_S(q) "\n" 39 1.1 christos 40 1.1 christos /* Arg size */ 41 1.1 christos #ifdef __LP64__ 42 1.1 christos #define JE_SDT_ASM_ADDR .8byte 43 1.1 christos #else 44 1.1 christos #define JE_SDT_ASM_ADDR .4byte 45 1.1 christos #endif 46 1.1 christos 47 1.1 christos #define JE_SDT_NOTE_NAME "stapsdt" 48 1.1 christos #define JE_SDT_NOTE_TYPE 3 49 1.1 christos 50 1.1 christos #define JE_SDT_SEMAPHORE_NONE(provider, name) \ 51 1.1 christos JE_SDT_ASM_1(JE_SDT_ASM_ADDR 0) /* No Semaphore support */ 52 1.1 christos #define JE_SDT_SEMAPHORE_OPERAND(provider, name) \ 53 1.1 christos [__sdt_semaphore] "ip" (0) /* No Semaphore */ 54 1.1 christos 55 1.1 christos #define JE_SDT_ASM_STRING(x) JE_SDT_ASM_1(.asciz JE_SDT_S(x)) 56 1.1 christos 57 1.1 christos #define JE_SDT_NOTE(provider, name, arg_template) \ 58 1.1 christos JE_SDT_ASM_1(990: JE_SDT_NOP) \ 59 1.1 christos JE_SDT_ASM_3( .pushsection .note.stapsdt,"?","note") \ 60 1.1 christos JE_SDT_ASM_1( .balign 4) \ 61 1.1 christos JE_SDT_ASM_3( .4byte 992f-991f, 994f-993f, JE_SDT_NOTE_TYPE) \ 62 1.1 christos JE_SDT_ASM_1(991: .asciz JE_SDT_NOTE_NAME) \ 63 1.1 christos JE_SDT_ASM_1(992: .balign 4) \ 64 1.1 christos JE_SDT_ASM_1(993: JE_SDT_ASM_ADDR 990b) \ 65 1.1 christos JE_SDT_ASM_1( JE_SDT_ASM_ADDR _.stapsdt.base) \ 66 1.1 christos JE_SDT_SEMAPHORE_NONE(provider, name) \ 67 1.1 christos JE_SDT_ASM_STRING(provider) \ 68 1.1 christos JE_SDT_ASM_STRING(name) \ 69 1.1 christos JE_SDT_ASM_STRING(arg_template) \ 70 1.1 christos JE_SDT_ASM_1(994: .balign 4) \ 71 1.1 christos JE_SDT_ASM_1( .popsection) 72 1.1 christos 73 1.1 christos #define JE_SDT_BASE \ 74 1.1 christos JE_SDT_ASM_1( .ifndef _.stapsdt.base) \ 75 1.1 christos JE_SDT_ASM_5( .pushsection .stapsdt.base, "aG", "progbits", \ 76 1.1 christos .stapsdt.base,comdat) \ 77 1.1 christos JE_SDT_ASM_1( .weak _.stapsdt.base) \ 78 1.1 christos JE_SDT_ASM_1( .hidden _.stapsdt.base) \ 79 1.1 christos JE_SDT_ASM_1( _.stapsdt.base: .space 1) \ 80 1.1 christos JE_SDT_ASM_2( .size _.stapsdt.base, 1) \ 81 1.1 christos JE_SDT_ASM_1( .popsection) \ 82 1.1 christos JE_SDT_ASM_1( .endif) 83 1.1 christos 84 1.1 christos 85 1.1 christos /* 86 1.1 christos * Default constraint for probes arguments. 87 1.1 christos * See https://gcc.gnu.org/onlinedocs/gcc/Constraints.html 88 1.1 christos */ 89 1.1 christos #ifndef JE_SDT_ARG_CONSTRAINT 90 1.1 christos #define JE_SDT_ARG_CONSTRAINT "nor" 91 1.1 christos #endif 92 1.1 christos 93 1.1 christos #define JE_SDT_ARGARRAY(x) ((__builtin_classify_type(x) == 14) || \ 94 1.1 christos (__builtin_classify_type(x) == 5)) 95 1.1 christos #define JE_SDT_ARGSIZE(x) (JE_SDT_ARGARRAY(x) ? sizeof(void*) : sizeof(x)) 96 1.1 christos 97 1.1 christos /* 98 1.1 christos * Format of each probe argument as operand. Size tagged with JE_SDT_Sn, 99 1.1 christos * with "n" constraint. Value is tagged with JE_SDT_An with configured 100 1.1 christos * constraint. 101 1.1 christos */ 102 1.1 christos #define JE_SDT_ARG(n, x) \ 103 1.1 christos [JE_SDT_S##n] "n" ((size_t)JE_SDT_ARGSIZE(x)), \ 104 1.1 christos [JE_SDT_A##n] JE_SDT_ARG_CONSTRAINT(x) 105 1.1 christos 106 1.1 christos /* Templates to append arguments as operands. */ 107 1.1 christos #define JE_SDT_OPERANDS_0() [__sdt_dummy] "g" (0) 108 1.1 christos #define JE_SDT_OPERANDS_1(_1) JE_SDT_ARG(1, _1) 109 1.1 christos #define JE_SDT_OPERANDS_2(_1, _2) JE_SDT_OPERANDS_1(_1), JE_SDT_ARG(2, _2) 110 1.1 christos #define JE_SDT_OPERANDS_3(_1, _2, _3) JE_SDT_OPERANDS_2(_1, _2), JE_SDT_ARG(3, _3) 111 1.1 christos #define JE_SDT_OPERANDS_4(_1, _2, _3, _4) \ 112 1.1 christos JE_SDT_OPERANDS_3(_1, _2, _3), JE_SDT_ARG(4, _4) 113 1.1 christos #define JE_SDT_OPERANDS_5(_1, _2, _3, _4, _5) \ 114 1.1 christos JE_SDT_OPERANDS_4(_1, _2, _3, _4), JE_SDT_ARG(5, _5) 115 1.1 christos #define JE_SDT_OPERANDS_6(_1, _2, _3, _4, _5, _6) \ 116 1.1 christos JE_SDT_OPERANDS_5(_1, _2, _3, _4, _5), JE_SDT_ARG(6, _6) 117 1.1 christos #define JE_SDT_OPERANDS_7(_1, _2, _3, _4, _5, _6, _7) \ 118 1.1 christos JE_SDT_OPERANDS_6(_1, _2, _3, _4, _5, _6), JE_SDT_ARG(7, _7) 119 1.1 christos 120 1.1 christos /* Templates to reference the arguments from operands. */ 121 1.1 christos #define JE_SDT_ARGFMT(num) %n[JE_SDT_S##num]@%[JE_SDT_A##num] 122 1.1 christos #define JE_SDT_ARG_TEMPLATE_0 /* No args */ 123 1.1 christos #define JE_SDT_ARG_TEMPLATE_1 JE_SDT_ARGFMT(1) 124 1.1 christos #define JE_SDT_ARG_TEMPLATE_2 JE_SDT_ARG_TEMPLATE_1 JE_SDT_ARGFMT(2) 125 1.1 christos #define JE_SDT_ARG_TEMPLATE_3 JE_SDT_ARG_TEMPLATE_2 JE_SDT_ARGFMT(3) 126 1.1 christos #define JE_SDT_ARG_TEMPLATE_4 JE_SDT_ARG_TEMPLATE_3 JE_SDT_ARGFMT(4) 127 1.1 christos #define JE_SDT_ARG_TEMPLATE_5 JE_SDT_ARG_TEMPLATE_4 JE_SDT_ARGFMT(5) 128 1.1 christos #define JE_SDT_ARG_TEMPLATE_6 JE_SDT_ARG_TEMPLATE_5 JE_SDT_ARGFMT(6) 129 1.1 christos #define JE_SDT_ARG_TEMPLATE_7 JE_SDT_ARG_TEMPLATE_6 JE_SDT_ARGFMT(7) 130 1.1 christos 131 1.1 christos #define JE_SDT_PROBE( \ 132 1.1 christos provider, name, n, arglist) \ 133 1.1 christos do { \ 134 1.1 christos __asm__ __volatile__( \ 135 1.1 christos JE_SDT_NOTE(provider, name, \ 136 1.1 christos JE_SDT_ARG_TEMPLATE_##n) \ 137 1.1 christos :: JE_SDT_SEMAPHORE_OPERAND(provider, name), \ 138 1.1 christos JE_SDT_OPERANDS_##n arglist); \ 139 1.1 christos __asm__ __volatile__(JE_SDT_BASE); \ 140 1.1 christos } while (0) 141 1.1 christos 142 1.1 christos #define JE_USDT(name, N, ...) \ 143 1.1 christos JE_SDT_PROBE(jemalloc, name, N, (__VA_ARGS__)) 144 1.1 christos 145 1.1 christos 146 1.1 christos #endif /* JEMALLOC_INTERNAL_JEMALLOC_PROBE_CUSTOM_H */ 147 1.1 christos 148 1.1 christos /* clang-format on */ 149