(root)/
glibc-2.38/
sysdeps/
s390/
s390-64/
s390x-mcount.h
       1  /* 64 bit S/390-specific implementation of profiling support.
       2     Copyright (C) 2001-2023 Free Software Foundation, Inc.
       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
       7     License as published by the Free Software Foundation; either
       8     version 2.1 of the 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  #include <sysdep.h>
      20  
      21  /* How profiling works on 64 bit S/390:
      22     On the start of each function _mcount is called with the address of a
      23     data word in %r1 (initialized to 0, used for counting). The compiler
      24     with the option -p generates code of the form:
      25  
      26             STM    6,15,24(15)
      27             BRAS   13,.LTN0_0
      28     .LT0_0:
      29     .LC13:  .long  .LP0
      30             .data
      31             .align 4
      32     .LP0:   .long  0
      33             .text
      34     # function profiler
      35             stg    14,8(15)
      36             lg     1,.LC13-.LT0_0(13)
      37             brasl  14,_mcount
      38             lg     14,8(15)
      39  
      40     The _mcount implementation now has to call __mcount_internal with the
      41     address of .LP0 as first parameter and the return address as second
      42     parameter. &.LP0 was loaded to %r1 and the return address is in %r14.
      43     _mcount may not modify any register.
      44  
      45     Alternatively, at the start of each function __fentry__ is called using a
      46     single
      47  
      48     # function profiler
      49             brasl  0,__fentry__
      50  
      51     instruction.  In this case %r0 points to the callee, and %r14 points to the
      52     caller.  These values need to be passed to __mcount_internal using the same
      53     sequence as for _mcount, so the code below is shared between both functions.
      54     The only major difference is that __fentry__ cannot return through %r0, in
      55     which the return address is located, because br instruction is a no-op with
      56     this register.  Therefore %r1, which is clobbered by the PLT anyway, is
      57     used.  */
      58  
      59  #define xglue(x, y) x ## y
      60  #define glue(x, y) xglue(x, y)
      61  
      62  	.globl C_SYMBOL_NAME(MCOUNT_SYMBOL)
      63  	.type C_SYMBOL_NAME(MCOUNT_SYMBOL), @function
      64  	cfi_startproc
      65  	.align ALIGNARG(4)
      66  C_LABEL(MCOUNT_SYMBOL)
      67  	cfi_return_column (glue(r, MCOUNT_CALLEE_REG))
      68  	/* Save the caller-clobbered registers.  */
      69  	aghi  %r15,-224
      70  	cfi_adjust_cfa_offset (224)
      71  	/* binutils 2.28+: .cfi_val_offset r15, -160 */
      72  	.cfi_escape \
      73  		/* DW_CFA_val_offset */ 0x14, \
      74  		/* r15 */               0x0f, \
      75  		/* scaled offset */     0x14
      76  	stmg  %r14,%r5,160(%r15)
      77  	cfi_offset (r14, -224)
      78  	cfi_offset (r0, -224+16)
      79  	lg    %r2,MCOUNT_CALLER_OFF(%r15)	# callers address  = 1st param
      80  	lgr   %r3,glue(%r, MCOUNT_CALLEE_REG)	# callees address  = 2nd param
      81  
      82  #ifdef PIC
      83  	brasl %r14,__mcount_internal@PLT
      84  #else
      85  	brasl %r14,__mcount_internal
      86  #endif
      87  
      88  	/* Pop the saved registers.  Please note that `mcount' has no
      89  	   return value.  */
      90  	lmg   %r14,%r5,160(%r15)
      91  	aghi  %r15,224
      92  	cfi_adjust_cfa_offset (-224)
      93  #if MCOUNT_RETURN_REG != MCOUNT_CALLEE_REG
      94  	lgr   glue(%r, MCOUNT_RETURN_REG),glue(%r, MCOUNT_CALLEE_REG)
      95  #endif
      96  	br    glue(%r, MCOUNT_RETURN_REG)
      97  	cfi_endproc
      98  	ASM_SIZE_DIRECTIVE(C_SYMBOL_NAME(MCOUNT_SYMBOL))