1/* i386-specific implementation of profiling support.
2   Copyright (C) 1997-2022 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/* We need a special version of the `mcount' function since for ix86 it
22   must not clobber any register.  This has several reasons:
23     - there is a bug in gcc as of version 2.7.2.2 which prohibits the
24       use of profiling together with nested functions
25     - the ELF `fixup' function uses GCC's regparm feature
26     - some (future) systems might want to pass parameters in registers.  */
27
28	.globl C_SYMBOL_NAME(_mcount)
29	.type C_SYMBOL_NAME(_mcount), @function
30	.align ALIGNARG(4)
31C_LABEL(_mcount)
32	_CET_ENDBR
33	/* Save the caller-clobbered registers.  */
34	pushl %eax
35	pushl %ecx
36	pushl %edx
37
38	movl 12(%esp), %edx
39	movl 4(%ebp), %eax
40
41	/* No need to access the PLT or GOT, __mcount_internal is an
42	   internal function and we can make a relative call.  */
43	call C_SYMBOL_NAME(__mcount_internal)
44
45	/* Pop the saved registers.  Please note that `mcount' has no
46	   return value.  */
47	popl %edx
48	popl %ecx
49	popl %eax
50	ret
51	ASM_SIZE_DIRECTIVE(C_SYMBOL_NAME(_mcount))
52
53#undef mcount
54weak_alias (_mcount, mcount)
55
56	/* Same as above, but doesn't require a frame pointer */
57	.globl C_SYMBOL_NAME(__fentry__)
58	.type C_SYMBOL_NAME(__fentry__), @function
59	.align ALIGNARG(4)
60C_LABEL(__fentry__)
61	_CET_ENDBR
62	/* Save the caller-clobbered registers.  */
63	pushl %eax
64	pushl %ecx
65	pushl %edx
66
67	movl 12(%esp), %edx
68	movl 16(%esp), %eax
69
70	/* No need to access the PLT or GOT, __mcount_internal is an
71	   internal function and we can make a relative call.  */
72	call C_SYMBOL_NAME(__mcount_internal)
73
74	/* Pop the saved registers.  Please note that `__fentry__' has no
75	   return value.  */
76	popl %edx
77	popl %ecx
78	popl %eax
79	ret
80	ASM_SIZE_DIRECTIVE(C_SYMBOL_NAME(__fentry__))
81