(root)/
glibc-2.38/
sysdeps/
aarch64/
sysdep.h
       1  /* Copyright (C) 1997-2023 Free Software Foundation, Inc.
       2  
       3     This file is part of the GNU C Library.
       4  
       5     The GNU C Library is free software; you can redistribute it and/or
       6     modify it under the terms of the GNU Lesser General Public License as
       7     published by the Free Software Foundation; either version 2.1 of the
       8     License, or (at your option) any later version.
       9  
      10     The GNU C Library is distributed in the hope that it will be useful,
      11     but WITHOUT ANY WARRANTY; without even the implied warranty of
      12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      13     Lesser General Public License for more details.
      14  
      15     You should have received a copy of the GNU Lesser General Public
      16     License along with the GNU C Library; if not, see
      17     <https://www.gnu.org/licenses/>.  */
      18  
      19  #ifndef _AARCH64_SYSDEP_H
      20  #define _AARCH64_SYSDEP_H
      21  
      22  #include <sysdeps/generic/sysdep.h>
      23  
      24  #ifdef __LP64__
      25  # define AARCH64_R(NAME)	R_AARCH64_ ## NAME
      26  # define PTR_REG(n)		x##n
      27  # define PTR_LOG_SIZE		3
      28  # define PTR_ARG(n)
      29  # define SIZE_ARG(n)
      30  #else
      31  # define AARCH64_R(NAME)	R_AARCH64_P32_ ## NAME
      32  # define PTR_REG(n)		w##n
      33  # define PTR_LOG_SIZE		2
      34  # define PTR_ARG(n)		mov     w##n, w##n
      35  # define SIZE_ARG(n)		mov     w##n, w##n
      36  #endif
      37  
      38  #define PTR_SIZE	(1<<PTR_LOG_SIZE)
      39  
      40  #ifndef __ASSEMBLER__
      41  /* Strip pointer authentication code from pointer p.  */
      42  static inline void *
      43  strip_pac (void *p)
      44  {
      45    register void *ra asm ("x30") = (p);
      46    asm ("hint 7 // xpaclri" : "+r"(ra));
      47    return ra;
      48  }
      49  
      50  /* This is needed when glibc is built with -mbranch-protection=pac-ret
      51     with a gcc that is affected by PR target/94891.  */
      52  # if HAVE_AARCH64_PAC_RET
      53  #  undef RETURN_ADDRESS
      54  #  define RETURN_ADDRESS(n) strip_pac (__builtin_return_address (n))
      55  # endif
      56  #endif
      57  
      58  #ifdef	__ASSEMBLER__
      59  
      60  /* Syntactic details of assembler.  */
      61  
      62  #define ASM_SIZE_DIRECTIVE(name) .size name,.-name
      63  
      64  /* Branch Target Identitication support.  */
      65  #if HAVE_AARCH64_BTI
      66  # define BTI_C		hint	34
      67  # define BTI_J		hint	36
      68  #else
      69  # define BTI_C		nop
      70  # define BTI_J		nop
      71  #endif
      72  
      73  /* Return address signing support (pac-ret).  */
      74  #define PACIASP		hint	25
      75  #define AUTIASP		hint	29
      76  
      77  /* GNU_PROPERTY_AARCH64_* macros from elf.h for use in asm code.  */
      78  #define FEATURE_1_AND 0xc0000000
      79  #define FEATURE_1_BTI 1
      80  #define FEATURE_1_PAC 2
      81  
      82  /* Add a NT_GNU_PROPERTY_TYPE_0 note.  */
      83  #define GNU_PROPERTY(type, value)	\
      84    .section .note.gnu.property, "a";	\
      85    .p2align 3;				\
      86    .word 4;				\
      87    .word 16;				\
      88    .word 5;				\
      89    .asciz "GNU";				\
      90    .word type;				\
      91    .word 4;				\
      92    .word value;				\
      93    .word 0;				\
      94    .text
      95  
      96  /* Add GNU property note with the supported features to all asm code
      97     where sysdep.h is included.  */
      98  #if HAVE_AARCH64_BTI && HAVE_AARCH64_PAC_RET
      99  GNU_PROPERTY (FEATURE_1_AND, FEATURE_1_BTI|FEATURE_1_PAC)
     100  #elif HAVE_AARCH64_BTI
     101  GNU_PROPERTY (FEATURE_1_AND, FEATURE_1_BTI)
     102  #endif
     103  
     104  /* Define an entry point visible from C.  */
     105  #define ENTRY(name)						\
     106    .globl C_SYMBOL_NAME(name);					\
     107    .type C_SYMBOL_NAME(name),%function;				\
     108    .p2align 6;							\
     109    C_LABEL(name)							\
     110    cfi_startproc;						\
     111    BTI_C;							\
     112    CALL_MCOUNT
     113  
     114  /* Define an entry point visible from C.  */
     115  #define ENTRY_ALIGN(name, align)				\
     116    .globl C_SYMBOL_NAME(name);					\
     117    .type C_SYMBOL_NAME(name),%function;				\
     118    .p2align align;						\
     119    C_LABEL(name)							\
     120    cfi_startproc;						\
     121    BTI_C;							\
     122    CALL_MCOUNT
     123  
     124  /* Define an entry point visible from C with a specified alignment and
     125     pre-padding with NOPs.  This can be used to ensure that a critical
     126     loop within a function is cache line aligned.  Note this version
     127     does not adjust the padding if CALL_MCOUNT is defined. */
     128  
     129  #define ENTRY_ALIGN_AND_PAD(name, align, padding)		\
     130    .globl C_SYMBOL_NAME(name);					\
     131    .type C_SYMBOL_NAME(name),%function;				\
     132    .p2align align;						\
     133    .rep padding - 1; /* -1 for bti c.  */			\
     134    nop;								\
     135    .endr;							\
     136    C_LABEL(name)							\
     137    cfi_startproc;						\
     138    BTI_C;							\
     139    CALL_MCOUNT
     140  
     141  #undef	END
     142  #define END(name)						\
     143    cfi_endproc;							\
     144    ASM_SIZE_DIRECTIVE(name)
     145  
     146  /* If compiled for profiling, call `mcount' at the start of each function.  */
     147  #ifdef	PROF
     148  # define CALL_MCOUNT						\
     149  	str	x30, [sp, #-80]!;				\
     150  	cfi_adjust_cfa_offset (80);				\
     151  	cfi_rel_offset (x30, 0);				\
     152  	stp	x0, x1, [sp, #16];				\
     153  	cfi_rel_offset (x0, 16);				\
     154  	cfi_rel_offset (x1, 24);				\
     155  	stp	x2, x3, [sp, #32];				\
     156  	cfi_rel_offset (x2, 32);				\
     157  	cfi_rel_offset (x3, 40);				\
     158  	stp	x4, x5, [sp, #48];				\
     159  	cfi_rel_offset (x4, 48);				\
     160  	cfi_rel_offset (x5, 56);				\
     161  	stp	x6, x7, [sp, #64];				\
     162  	cfi_rel_offset (x6, 64);				\
     163  	cfi_rel_offset (x7, 72);				\
     164  	mov	x0, x30;					\
     165  	bl	mcount;						\
     166  	ldp	x0, x1, [sp, #16];				\
     167  	cfi_restore (x0);					\
     168  	cfi_restore (x1);					\
     169  	ldp	x2, x3, [sp, #32];				\
     170  	cfi_restore (x2);					\
     171  	cfi_restore (x3);					\
     172  	ldp	x4, x5, [sp, #48];				\
     173  	cfi_restore (x4);					\
     174  	cfi_restore (x5);					\
     175  	ldp	x6, x7, [sp, #64];				\
     176  	cfi_restore (x6);					\
     177  	cfi_restore (x7);					\
     178  	ldr	x30, [sp], #80;					\
     179  	cfi_adjust_cfa_offset (-80);				\
     180  	cfi_restore (x30);
     181  #else
     182  # define CALL_MCOUNT		/* Do nothing.  */
     183  #endif
     184  
     185  /* Local label name for asm code.  */
     186  #ifndef L
     187  # define L(name)         .L##name
     188  #endif
     189  
     190  /* Load or store to/from a pc-relative EXPR into/from R, using T.
     191     Note R and T are register numbers and not register names.  */
     192  #define LDST_PCREL(OP, R, T, EXPR)			\
     193  	adrp	x##T, EXPR;				\
     194  	OP	PTR_REG (R), [x##T, #:lo12:EXPR];	\
     195  
     196  /* Load or store to/from a got-relative EXPR into/from R, using T.
     197     Note R and T are register numbers and not register names.  */
     198  #define LDST_GLOBAL(OP, R, T,  EXPR)			\
     199  	adrp	x##T, :got:EXPR;			\
     200  	ldr	PTR_REG (T), [x##T, #:got_lo12:EXPR];	\
     201  	OP	PTR_REG (R), [x##T];
     202  
     203  /* Load an immediate into R.
     204     Note R is a register number and not a register name.  */
     205  #ifdef __LP64__
     206  # define MOVL(R, NAME)					\
     207  	movz	PTR_REG (R), #:abs_g3:NAME;		\
     208  	movk	PTR_REG (R), #:abs_g2_nc:NAME;		\
     209  	movk	PTR_REG (R), #:abs_g1_nc:NAME;		\
     210  	movk	PTR_REG (R), #:abs_g0_nc:NAME;
     211  #else
     212  # define MOVL(R, NAME)					\
     213  	movz	PTR_REG (R), #:abs_g1:NAME;		\
     214  	movk	PTR_REG (R), #:abs_g0_nc:NAME;
     215  #endif
     216  
     217  /* Since C identifiers are not normally prefixed with an underscore
     218     on this system, the asm identifier `syscall_error' intrudes on the
     219     C name space.  Make sure we use an innocuous name.  */
     220  #define syscall_error	__syscall_error
     221  #define mcount		_mcount
     222  
     223  #endif	/* __ASSEMBLER__ */
     224  
     225  #endif  /* _AARCH64_SYSDEP_H */