sysdep.h 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. /* Assembler macros for x86-64.
  2. Copyright (C) 2001-2026 Free Software Foundation, Inc.
  3. This file is part of the GNU C Library.
  4. The GNU C Library is free software; you can redistribute it and/or
  5. modify it under the terms of the GNU Lesser General Public
  6. License as published by the Free Software Foundation; either
  7. version 2.1 of the License, or (at your option) any later version.
  8. The GNU C Library is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. Lesser General Public License for more details.
  12. You should have received a copy of the GNU Lesser General Public
  13. License along with the GNU C Library; if not, see
  14. <https://www.gnu.org/licenses/>. */
  15. #ifndef _X86_64_SYSDEP_H
  16. #define _X86_64_SYSDEP_H 1
  17. #include <sysdeps/x86/sysdep.h>
  18. #include <x86-lp_size.h>
  19. /* __CET__ is defined by GCC with Control-Flow Protection values:
  20. enum cf_protection_level
  21. {
  22. CF_NONE = 0,
  23. CF_BRANCH = 1 << 0,
  24. CF_RETURN = 1 << 1,
  25. CF_FULL = CF_BRANCH | CF_RETURN,
  26. CF_SET = 1 << 2
  27. };
  28. */
  29. /* Set if CF_BRANCH (IBT) is enabled. */
  30. #define X86_FEATURE_1_IBT (1U << 0)
  31. /* Set if CF_RETURN (SHSTK) is enabled. */
  32. #define X86_FEATURE_1_SHSTK (1U << 1)
  33. #ifdef __CET__
  34. # define CET_ENABLED 1
  35. # define SHSTK_ENABLED (__CET__ & X86_FEATURE_1_SHSTK)
  36. #else
  37. # define CET_ENABLED 0
  38. # define SHSTK_ENABLED 0
  39. #endif
  40. #ifdef __ASSEMBLER__
  41. /* Syntactic details of assembler. */
  42. #ifdef _CET_ENDBR
  43. # define _CET_NOTRACK notrack
  44. #else
  45. # define _CET_ENDBR
  46. # define _CET_NOTRACK
  47. #endif
  48. /* Define an entry point visible from C. */
  49. #define ENTRY_P2ALIGN(name, alignment) \
  50. .globl C_SYMBOL_NAME(name); \
  51. .type C_SYMBOL_NAME(name),@function; \
  52. .align ALIGNARG(alignment); \
  53. C_LABEL(name) \
  54. cfi_startproc; \
  55. _CET_ENDBR; \
  56. CALL_MCOUNT
  57. /* This macro is for setting proper CFI with DW_CFA_expression describing
  58. the register as saved relative to %rsp instead of relative to the CFA.
  59. Expression is DW_OP_drop, DW_OP_breg7 (%rsp is register 7), sleb128 offset
  60. from %rsp. */
  61. #define cfi_offset_rel_rsp(regn, off) .cfi_escape 0x10, regn, 0x4, 0x13, \
  62. 0x77, off & 0x7F | 0x80, off >> 7
  63. /* If compiled for profiling, call `mcount' at the start of each function. */
  64. #ifdef PROF
  65. /* The mcount code relies on a normal frame pointer being on the stack
  66. to locate our caller, so push one just for its benefit. */
  67. #define CALL_MCOUNT \
  68. pushq %rbp; \
  69. cfi_adjust_cfa_offset(8); \
  70. movq %rsp, %rbp; \
  71. cfi_def_cfa_register(%rbp); \
  72. call JUMPTARGET(mcount); \
  73. popq %rbp; \
  74. cfi_def_cfa(rsp,8);
  75. #else
  76. #define CALL_MCOUNT /* Do nothing. */
  77. #endif
  78. #define PSEUDO(name, syscall_name, args) \
  79. lose: \
  80. jmp JUMPTARGET(syscall_error) \
  81. .globl syscall_error; \
  82. ENTRY (name) \
  83. DO_CALL (syscall_name, args); \
  84. jb lose
  85. #undef JUMPTARGET
  86. #ifdef SHARED
  87. # ifdef BIND_NOW
  88. # define JUMPTARGET(name) *name##@GOTPCREL(%rip)
  89. # else
  90. # define JUMPTARGET(name) name##@PLT
  91. # endif
  92. #else
  93. /* For static archives, branch to target directly. */
  94. # define JUMPTARGET(name) name
  95. #endif
  96. /* Instruction to operate on long and pointer. */
  97. #define LP_OP(insn) insn##q
  98. /* Assembler address directive. */
  99. #define ASM_ADDR .quad
  100. /* Registers to hold long and pointer. */
  101. #define RAX_LP rax
  102. #define RBP_LP rbp
  103. #define RBX_LP rbx
  104. #define RCX_LP rcx
  105. #define RDI_LP rdi
  106. #define RDX_LP rdx
  107. #define RSI_LP rsi
  108. #define RSP_LP rsp
  109. #define R8_LP r8
  110. #define R9_LP r9
  111. #define R10_LP r10
  112. #define R11_LP r11
  113. #define R12_LP r12
  114. #define R13_LP r13
  115. #define R14_LP r14
  116. #define R15_LP r15
  117. /* Zero upper vector registers and return with xtest. NB: Use VZEROALL
  118. to avoid RTM abort triggered by VZEROUPPER inside transactionally. */
  119. #define ZERO_UPPER_VEC_REGISTERS_RETURN_XTEST \
  120. xtest; \
  121. jnz 1f; \
  122. vzeroupper; \
  123. ret; \
  124. 1: \
  125. vzeroall; \
  126. ret
  127. /* Can be used to replace vzeroupper that is not directly before a
  128. return. This is useful when hoisting a vzeroupper from multiple
  129. return paths to decrease the total number of vzerouppers and code
  130. size. */
  131. #define COND_VZEROUPPER_XTEST \
  132. xtest; \
  133. jz 1f; \
  134. vzeroall; \
  135. jmp 2f; \
  136. 1: \
  137. vzeroupper; \
  138. 2:
  139. /* In RTM define this as COND_VZEROUPPER_XTEST. */
  140. #ifndef COND_VZEROUPPER
  141. # define COND_VZEROUPPER vzeroupper
  142. #endif
  143. /* Zero upper vector registers and return. */
  144. #ifndef ZERO_UPPER_VEC_REGISTERS_RETURN
  145. # define ZERO_UPPER_VEC_REGISTERS_RETURN \
  146. VZEROUPPER; \
  147. ret
  148. #endif
  149. #ifndef VZEROUPPER_RETURN
  150. # define VZEROUPPER_RETURN VZEROUPPER; ret
  151. #endif
  152. #else /* __ASSEMBLER__ */
  153. /* Instruction to operate on long and pointer. */
  154. #define LP_OP(insn) #insn "q"
  155. /* Assembler address directive. */
  156. #define ASM_ADDR ".quad"
  157. /* Registers to hold long and pointer. */
  158. #define RAX_LP "rax"
  159. #define RBP_LP "rbp"
  160. #define RBX_LP "rbx"
  161. #define RCX_LP "rcx"
  162. #define RDI_LP "rdi"
  163. #define RDX_LP "rdx"
  164. #define RSI_LP "rsi"
  165. #define RSP_LP "rsp"
  166. #define R8_LP "r8"
  167. #define R9_LP "r9"
  168. #define R10_LP "r10"
  169. #define R11_LP "r11"
  170. #define R12_LP "r12"
  171. #define R13_LP "r13"
  172. #define R14_LP "r14"
  173. #define R15_LP "r15"
  174. #endif /* __ASSEMBLER__ */
  175. #endif /* _X86_64_SYSDEP_H */