Home | History | Annotate | Line # | Download | only in internal
      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