StaticTracepoint-ELFx86.h 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. /*
  2. * Copyright 2016-present Facebook, Inc.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #pragma once
  17. // clang-format off
  18. #include <cstddef>
  19. // Default constraint for the probe arguments as operands.
  20. #ifndef FOLLY_SDT_ARG_CONSTRAINT
  21. #define FOLLY_SDT_ARG_CONSTRAINT "nor"
  22. #endif
  23. // Instruction to emit for the probe.
  24. #define FOLLY_SDT_NOP nop
  25. // Note section properties.
  26. #define FOLLY_SDT_NOTE_NAME "stapsdt"
  27. #define FOLLY_SDT_NOTE_TYPE 3
  28. // Semaphore variables are put in this section
  29. #define FOLLY_SDT_SEMAPHORE_SECTION ".probes"
  30. // Size of address depending on platform.
  31. #ifdef __LP64__
  32. #define FOLLY_SDT_ASM_ADDR .8byte
  33. #else
  34. #define FOLLY_SDT_ASM_ADDR .4byte
  35. #endif
  36. // Assembler helper Macros.
  37. #define FOLLY_SDT_S(x) #x
  38. #define FOLLY_SDT_ASM_1(x) FOLLY_SDT_S(x) "\n"
  39. #define FOLLY_SDT_ASM_2(a, b) FOLLY_SDT_S(a) "," FOLLY_SDT_S(b) "\n"
  40. #define FOLLY_SDT_ASM_3(a, b, c) FOLLY_SDT_S(a) "," FOLLY_SDT_S(b) "," \
  41. FOLLY_SDT_S(c) "\n"
  42. #define FOLLY_SDT_ASM_STRING(x) FOLLY_SDT_ASM_1(.asciz FOLLY_SDT_S(x))
  43. // Helper to determine the size of an argument.
  44. #define FOLLY_SDT_IS_ARRAY_POINTER(x) ((__builtin_classify_type(x) == 14) || \
  45. (__builtin_classify_type(x) == 5))
  46. #define FOLLY_SDT_ARGSIZE(x) (FOLLY_SDT_IS_ARRAY_POINTER(x) \
  47. ? sizeof(void*) \
  48. : sizeof(x))
  49. // Format of each probe arguments as operand.
  50. // Size of the arugment tagged with FOLLY_SDT_Sn, with "n" constraint.
  51. // Value of the argument tagged with FOLLY_SDT_An, with configured constraint.
  52. #define FOLLY_SDT_ARG(n, x) \
  53. [FOLLY_SDT_S##n] "n" ((size_t)FOLLY_SDT_ARGSIZE(x)), \
  54. [FOLLY_SDT_A##n] FOLLY_SDT_ARG_CONSTRAINT (x)
  55. // Templates to append arguments as operands.
  56. #define FOLLY_SDT_OPERANDS_0() [__sdt_dummy] "g" (0)
  57. #define FOLLY_SDT_OPERANDS_1(_1) FOLLY_SDT_ARG(1, _1)
  58. #define FOLLY_SDT_OPERANDS_2(_1, _2) \
  59. FOLLY_SDT_OPERANDS_1(_1), FOLLY_SDT_ARG(2, _2)
  60. #define FOLLY_SDT_OPERANDS_3(_1, _2, _3) \
  61. FOLLY_SDT_OPERANDS_2(_1, _2), FOLLY_SDT_ARG(3, _3)
  62. #define FOLLY_SDT_OPERANDS_4(_1, _2, _3, _4) \
  63. FOLLY_SDT_OPERANDS_3(_1, _2, _3), FOLLY_SDT_ARG(4, _4)
  64. #define FOLLY_SDT_OPERANDS_5(_1, _2, _3, _4, _5) \
  65. FOLLY_SDT_OPERANDS_4(_1, _2, _3, _4), FOLLY_SDT_ARG(5, _5)
  66. #define FOLLY_SDT_OPERANDS_6(_1, _2, _3, _4, _5, _6) \
  67. FOLLY_SDT_OPERANDS_5(_1, _2, _3, _4, _5), FOLLY_SDT_ARG(6, _6)
  68. #define FOLLY_SDT_OPERANDS_7(_1, _2, _3, _4, _5, _6, _7) \
  69. FOLLY_SDT_OPERANDS_6(_1, _2, _3, _4, _5, _6), FOLLY_SDT_ARG(7, _7)
  70. #define FOLLY_SDT_OPERANDS_8(_1, _2, _3, _4, _5, _6, _7, _8) \
  71. FOLLY_SDT_OPERANDS_7(_1, _2, _3, _4, _5, _6, _7), FOLLY_SDT_ARG(8, _8)
  72. #define FOLLY_SDT_OPERANDS_9(_1, _2, _3, _4, _5, _6, _7, _8, _9) \
  73. FOLLY_SDT_OPERANDS_8(_1, _2, _3, _4, _5, _6, _7, _8), FOLLY_SDT_ARG(9, _9)
  74. // Templates to reference the arguments from operands in note section.
  75. #define FOLLY_SDT_ARGFMT(no) %n[FOLLY_SDT_S##no]@%[FOLLY_SDT_A##no]
  76. #define FOLLY_SDT_ARG_TEMPLATE_0 /*No arguments*/
  77. #define FOLLY_SDT_ARG_TEMPLATE_1 FOLLY_SDT_ARGFMT(1)
  78. #define FOLLY_SDT_ARG_TEMPLATE_2 FOLLY_SDT_ARG_TEMPLATE_1 FOLLY_SDT_ARGFMT(2)
  79. #define FOLLY_SDT_ARG_TEMPLATE_3 FOLLY_SDT_ARG_TEMPLATE_2 FOLLY_SDT_ARGFMT(3)
  80. #define FOLLY_SDT_ARG_TEMPLATE_4 FOLLY_SDT_ARG_TEMPLATE_3 FOLLY_SDT_ARGFMT(4)
  81. #define FOLLY_SDT_ARG_TEMPLATE_5 FOLLY_SDT_ARG_TEMPLATE_4 FOLLY_SDT_ARGFMT(5)
  82. #define FOLLY_SDT_ARG_TEMPLATE_6 FOLLY_SDT_ARG_TEMPLATE_5 FOLLY_SDT_ARGFMT(6)
  83. #define FOLLY_SDT_ARG_TEMPLATE_7 FOLLY_SDT_ARG_TEMPLATE_6 FOLLY_SDT_ARGFMT(7)
  84. #define FOLLY_SDT_ARG_TEMPLATE_8 FOLLY_SDT_ARG_TEMPLATE_7 FOLLY_SDT_ARGFMT(8)
  85. #define FOLLY_SDT_ARG_TEMPLATE_9 FOLLY_SDT_ARG_TEMPLATE_8 FOLLY_SDT_ARGFMT(9)
  86. // Semaphore define, declare and probe note format
  87. #define FOLLY_SDT_SEMAPHORE(provider, name) \
  88. folly_sdt_semaphore_##provider##_##name
  89. #define FOLLY_SDT_DEFINE_SEMAPHORE(provider, name) \
  90. extern "C" { \
  91. volatile unsigned short FOLLY_SDT_SEMAPHORE(provider, name) \
  92. __attribute__((section(FOLLY_SDT_SEMAPHORE_SECTION), used)) = 0; \
  93. }
  94. #define FOLLY_SDT_DECLARE_SEMAPHORE(provider, name) \
  95. extern "C" volatile unsigned short FOLLY_SDT_SEMAPHORE(provider, name)
  96. #define FOLLY_SDT_SEMAPHORE_NOTE_0(provider, name) \
  97. FOLLY_SDT_ASM_1( FOLLY_SDT_ASM_ADDR 0) /*No Semaphore*/ \
  98. #define FOLLY_SDT_SEMAPHORE_NOTE_1(provider, name) \
  99. FOLLY_SDT_ASM_1(FOLLY_SDT_ASM_ADDR FOLLY_SDT_SEMAPHORE(provider, name))
  100. // Structure of note section for the probe.
  101. #define FOLLY_SDT_NOTE_CONTENT(provider, name, has_semaphore, arg_template) \
  102. FOLLY_SDT_ASM_1(990: FOLLY_SDT_NOP) \
  103. FOLLY_SDT_ASM_3( .pushsection .note.stapsdt,"","note") \
  104. FOLLY_SDT_ASM_1( .balign 4) \
  105. FOLLY_SDT_ASM_3( .4byte 992f-991f, 994f-993f, FOLLY_SDT_NOTE_TYPE) \
  106. FOLLY_SDT_ASM_1(991: .asciz FOLLY_SDT_NOTE_NAME) \
  107. FOLLY_SDT_ASM_1(992: .balign 4) \
  108. FOLLY_SDT_ASM_1(993: FOLLY_SDT_ASM_ADDR 990b) \
  109. FOLLY_SDT_ASM_1( FOLLY_SDT_ASM_ADDR 0) /*Reserved for Base Address*/ \
  110. FOLLY_SDT_SEMAPHORE_NOTE_##has_semaphore(provider, name) \
  111. FOLLY_SDT_ASM_STRING(provider) \
  112. FOLLY_SDT_ASM_STRING(name) \
  113. FOLLY_SDT_ASM_STRING(arg_template) \
  114. FOLLY_SDT_ASM_1(994: .balign 4) \
  115. FOLLY_SDT_ASM_1( .popsection)
  116. // Main probe Macro.
  117. #define FOLLY_SDT_PROBE(provider, name, has_semaphore, n, arglist) \
  118. __asm__ __volatile__ ( \
  119. FOLLY_SDT_NOTE_CONTENT( \
  120. provider, name, has_semaphore, FOLLY_SDT_ARG_TEMPLATE_##n) \
  121. :: FOLLY_SDT_OPERANDS_##n arglist \
  122. ) \
  123. // Helper Macros to handle variadic arguments.
  124. #define FOLLY_SDT_NARG_(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, N, ...) N
  125. #define FOLLY_SDT_NARG(...) \
  126. FOLLY_SDT_NARG_(__VA_ARGS__, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
  127. #define FOLLY_SDT_PROBE_N(provider, name, has_semaphore, N, ...) \
  128. FOLLY_SDT_PROBE(provider, name, has_semaphore, N, (__VA_ARGS__))