1412042e2SAndrew Turner /*- 2796df753SPedro F. Giffuni * SPDX-License-Identifier: MIT-CMU 3796df753SPedro F. Giffuni * 4412042e2SAndrew Turner * Copyright (c) 1994, 1995, 1996 Carnegie-Mellon University. 5412042e2SAndrew Turner * All rights reserved. 6412042e2SAndrew Turner * 7412042e2SAndrew Turner * Author: Chris G. Demetriou 8412042e2SAndrew Turner * 9412042e2SAndrew Turner * Permission to use, copy, modify and distribute this software and 10412042e2SAndrew Turner * its documentation is hereby granted, provided that both the copyright 11412042e2SAndrew Turner * notice and this permission notice appear in all copies of the 12412042e2SAndrew Turner * software, derivative works or modified versions, and any portions 13412042e2SAndrew Turner * thereof, and that both notices appear in supporting documentation. 14412042e2SAndrew Turner * 15412042e2SAndrew Turner * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" 16412042e2SAndrew Turner * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND 17412042e2SAndrew Turner * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 18412042e2SAndrew Turner * 19412042e2SAndrew Turner * Carnegie Mellon requests users of this software to return to 20412042e2SAndrew Turner * 21412042e2SAndrew Turner * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU 22412042e2SAndrew Turner * School of Computer Science 23412042e2SAndrew Turner * Carnegie Mellon University 24412042e2SAndrew Turner * Pittsburgh PA 15213-3890 25412042e2SAndrew Turner * 26412042e2SAndrew Turner * any improvements or extensions that they make and grant Carnegie the 27412042e2SAndrew Turner * rights to redistribute these changes. 28412042e2SAndrew Turner * 29412042e2SAndrew Turner * from: NetBSD: profile.h,v 1.9 1997/04/06 08:47:37 cgd Exp 30412042e2SAndrew Turner * from: FreeBSD: src/sys/alpha/include/profile.h,v 1.4 1999/12/29 31412042e2SAndrew Turner */ 32412042e2SAndrew Turner 33d5d97bedSMike Karels #ifdef __arm__ 34d5d97bedSMike Karels #include <arm/profile.h> 35d5d97bedSMike Karels #else /* !__arm__ */ 36d5d97bedSMike Karels 37412042e2SAndrew Turner #ifndef _MACHINE_PROFILE_H_ 38412042e2SAndrew Turner #define _MACHINE_PROFILE_H_ 39412042e2SAndrew Turner 40412042e2SAndrew Turner #define FUNCTION_ALIGNMENT 32 41412042e2SAndrew Turner 42412042e2SAndrew Turner typedef u_long fptrdiff_t; 43412042e2SAndrew Turner 4483961b7eSAndrew Turner #ifndef _KERNEL 45412042e2SAndrew Turner 4683961b7eSAndrew Turner #include <sys/cdefs.h> 47412042e2SAndrew Turner 480ef3c625SMateusz Guzik typedef __uintfptr_t uintfptr_t; 49412042e2SAndrew Turner 5016d5f9a1SAndrew Turner #define _MCOUNT_DECL \ 5116d5f9a1SAndrew Turner static void _mcount(uintfptr_t frompc, uintfptr_t selfpc) __used; \ 5216d5f9a1SAndrew Turner static void _mcount 5316d5f9a1SAndrew Turner 5416d5f9a1SAndrew Turner /* 5516d5f9a1SAndrew Turner * Call into _mcount. On arm64 the .mcount is a function so callers will 5616d5f9a1SAndrew Turner * handle caller saved registers. As we don't directly touch any callee 5716d5f9a1SAndrew Turner * saved registers we can just load the two arguments and use a tail call 5816d5f9a1SAndrew Turner * into the MI _mcount function. 5916d5f9a1SAndrew Turner * 6016d5f9a1SAndrew Turner * When building with gcc frompc will be in x0, however this is not the 6116d5f9a1SAndrew Turner * case on clang. As such we need to load it from the stack. As long as 6216d5f9a1SAndrew Turner * the caller follows the ABI this will load the correct value. 6316d5f9a1SAndrew Turner */ 6416d5f9a1SAndrew Turner #define MCOUNT __asm( \ 6516d5f9a1SAndrew Turner " .text \n" \ 6616d5f9a1SAndrew Turner " .align 6 \n" \ 6716d5f9a1SAndrew Turner " .type .mcount,#function \n" \ 6816d5f9a1SAndrew Turner " .globl .mcount \n" \ 6916d5f9a1SAndrew Turner " .mcount: \n" \ 7016d5f9a1SAndrew Turner " .cfi_startproc \n" \ 71*0590ed09SAndrew Turner /* Allow this to work with BTI, see BTI_C in asm.h */ \ 72*0590ed09SAndrew Turner " hint #34 \n" \ 7316d5f9a1SAndrew Turner /* Load the caller return address as frompc */ \ 7416d5f9a1SAndrew Turner " ldr x0, [x29, #8] \n" \ 7516d5f9a1SAndrew Turner /* Use our return address as selfpc */ \ 7616d5f9a1SAndrew Turner " mov x1, lr \n" \ 7716d5f9a1SAndrew Turner " b _mcount \n" \ 7816d5f9a1SAndrew Turner " .cfi_endproc \n" \ 7916d5f9a1SAndrew Turner " .size .mcount, . - .mcount \n" \ 8016d5f9a1SAndrew Turner ); 8116d5f9a1SAndrew Turner #if 0 8216d5f9a1SAndrew Turner /* 8316d5f9a1SAndrew Turner * If clang passed frompc correctly we could implement it like this, however 8416d5f9a1SAndrew Turner * all clang versions we care about would need to be fixed before we could 8516d5f9a1SAndrew Turner * make this change. 8616d5f9a1SAndrew Turner */ 8716d5f9a1SAndrew Turner void 8816d5f9a1SAndrew Turner mcount(uintfptr_t frompc) 8916d5f9a1SAndrew Turner { 9016d5f9a1SAndrew Turner _mcount(frompc, __builtin_return_address(0)); 9116d5f9a1SAndrew Turner } 9216d5f9a1SAndrew Turner #endif 93412042e2SAndrew Turner 9483961b7eSAndrew Turner #endif /* !_KERNEL */ 95412042e2SAndrew Turner 96412042e2SAndrew Turner #endif /* !_MACHINE_PROFILE_H_ */ 97d5d97bedSMike Karels 98d5d97bedSMike Karels #endif /* !__arm__ */ 99