/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _LINUX_ANNOTATE_H
#define _LINUX_ANNOTATE_H

#include <linux/objtool_types.h>

#ifdef CONFIG_OBJTOOL

#define __ASM_ANNOTATE(section, label, type)				\
	.pushsection section, "M", @progbits, 8;			\
	.long label - ., type;						\
	.popsection

#ifndef __ASSEMBLY__

#define ASM_ANNOTATE_LABEL(label, type)					\
	__stringify(__ASM_ANNOTATE(.discard.annotate_insn, label, type))

#define ASM_ANNOTATE(type)						\
	"911: "								\
	__stringify(__ASM_ANNOTATE(.discard.annotate_insn, 911b, type))

#define ASM_ANNOTATE_DATA(type)						\
	"912: "								\
	__stringify(__ASM_ANNOTATE(.discard.annotate_data, 912b, type))

#else 

.macro ANNOTATE type
.Lhere_\@:
	__ASM_ANNOTATE(.discard.annotate_insn, .Lhere_\@, \type)
.endm

.macro ANNOTATE_DATA type
.Lhere_\@:
	__ASM_ANNOTATE(.discard.annotate_data, .Lhere_\@, \type)
.endm

#endif 

#else 
#ifndef __ASSEMBLY__
#define ASM_ANNOTATE_LABEL(label, type) ""
#define ASM_ANNOTATE(type)
#define ASM_ANNOTATE_DATA(type)
#else 
.macro ANNOTATE type
.endm
.macro ANNOTATE_DATA type
.endm
#endif 
#endif 

#ifndef __ASSEMBLY__


#define ANNOTATE_NOENDBR		ASM_ANNOTATE(ANNOTYPE_NOENDBR)
#define ANNOTATE_NOENDBR_SYM(sym)	asm(ASM_ANNOTATE_LABEL(sym, ANNOTYPE_NOENDBR))


#define ANNOTATE_RETPOLINE_SAFE		ASM_ANNOTATE(ANNOTYPE_RETPOLINE_SAFE)

#define ANNOTATE_INSTR_BEGIN(label)	ASM_ANNOTATE_LABEL(label, ANNOTYPE_INSTR_BEGIN)
#define ANNOTATE_INSTR_END(label)	ASM_ANNOTATE_LABEL(label, ANNOTYPE_INSTR_END)

#define ANNOTATE_IGNORE_ALTERNATIVE	ASM_ANNOTATE(ANNOTYPE_IGNORE_ALTS)

#define ANNOTATE_INTRA_FUNCTION_CALL	ASM_ANNOTATE(ANNOTYPE_INTRA_FUNCTION_CALL)

#define ANNOTATE_UNRET_BEGIN		ASM_ANNOTATE(ANNOTYPE_UNRET_BEGIN)

#define ANNOTATE_REACHABLE(label)	ASM_ANNOTATE_LABEL(label, ANNOTYPE_REACHABLE)

#define ANNOTATE_NOCFI_SYM(sym)		asm(ASM_ANNOTATE_LABEL(sym, ANNOTYPE_NOCFI))


#define ANNOTATE_DATA_SPECIAL		ASM_ANNOTATE_DATA(ANNOTYPE_DATA_SPECIAL)

#else 
#define ANNOTATE_NOENDBR		ANNOTATE type=ANNOTYPE_NOENDBR
#define ANNOTATE_RETPOLINE_SAFE		ANNOTATE type=ANNOTYPE_RETPOLINE_SAFE


#define ANNOTATE_IGNORE_ALTERNATIVE	ANNOTATE type=ANNOTYPE_IGNORE_ALTS
#define ANNOTATE_INTRA_FUNCTION_CALL	ANNOTATE type=ANNOTYPE_INTRA_FUNCTION_CALL
#define ANNOTATE_UNRET_BEGIN		ANNOTATE type=ANNOTYPE_UNRET_BEGIN
#define ANNOTATE_REACHABLE		ANNOTATE type=ANNOTYPE_REACHABLE
#define ANNOTATE_NOCFI_SYM		ANNOTATE type=ANNOTYPE_NOCFI
#define ANNOTATE_DATA_SPECIAL		ANNOTATE_DATA type=ANNOTYPE_DATA_SPECIAL
#endif 

#endif 
