android_kernel_xiaomi_sm8350/include/linux/linkage.h
Jiri Slaby 840d8c9b3e linkage: Introduce new macros for assembler symbols
commit ffedeeb780dc554eff3d3b16e6a462a26a41d7ec upstream.

Introduce new C macros for annotations of functions and data in
assembly. There is a long-standing mess in macros like ENTRY, END,
ENDPROC and similar. They are used in different manners and sometimes
incorrectly.

So introduce macros with clear use to annotate assembly as follows:

a) Support macros for the ones below
   SYM_T_FUNC -- type used by assembler to mark functions
   SYM_T_OBJECT -- type used by assembler to mark data
   SYM_T_NONE -- type used by assembler to mark entries of unknown type

   They are defined as STT_FUNC, STT_OBJECT, and STT_NOTYPE
   respectively. According to the gas manual, this is the most portable
   way. I am not sure about other assemblers, so this can be switched
   back to %function and %object if this turns into a problem.
   Architectures can also override them by something like ", @function"
   if they need.

   SYM_A_ALIGN, SYM_A_NONE -- align the symbol?
   SYM_L_GLOBAL, SYM_L_WEAK, SYM_L_LOCAL -- linkage of symbols

b) Mostly internal annotations, used by the ones below
   SYM_ENTRY -- use only if you have to (for non-paired symbols)
   SYM_START -- use only if you have to (for paired symbols)
   SYM_END -- use only if you have to (for paired symbols)

c) Annotations for code
   SYM_INNER_LABEL_ALIGN -- only for labels in the middle of code
   SYM_INNER_LABEL -- only for labels in the middle of code

   SYM_FUNC_START_LOCAL_ALIAS -- use where there are two local names for
	one function
   SYM_FUNC_START_ALIAS -- use where there are two global names for one
	function
   SYM_FUNC_END_ALIAS -- the end of LOCAL_ALIASed or ALIASed function

   SYM_FUNC_START -- use for global functions
   SYM_FUNC_START_NOALIGN -- use for global functions, w/o alignment
   SYM_FUNC_START_LOCAL -- use for local functions
   SYM_FUNC_START_LOCAL_NOALIGN -- use for local functions, w/o
	alignment
   SYM_FUNC_START_WEAK -- use for weak functions
   SYM_FUNC_START_WEAK_NOALIGN -- use for weak functions, w/o alignment
   SYM_FUNC_END -- the end of SYM_FUNC_START_LOCAL, SYM_FUNC_START,
	SYM_FUNC_START_WEAK, ...

   For functions with special (non-C) calling conventions:
   SYM_CODE_START -- use for non-C (special) functions
   SYM_CODE_START_NOALIGN -- use for non-C (special) functions, w/o
	alignment
   SYM_CODE_START_LOCAL -- use for local non-C (special) functions
   SYM_CODE_START_LOCAL_NOALIGN -- use for local non-C (special)
	functions, w/o alignment
   SYM_CODE_END -- the end of SYM_CODE_START_LOCAL or SYM_CODE_START

d) For data
   SYM_DATA_START -- global data symbol
   SYM_DATA_START_LOCAL -- local data symbol
   SYM_DATA_END -- the end of the SYM_DATA_START symbol
   SYM_DATA_END_LABEL -- the labeled end of SYM_DATA_START symbol
   SYM_DATA -- start+end wrapper around simple global data
   SYM_DATA_LOCAL -- start+end wrapper around simple local data

==========

The macros allow to pair starts and ends of functions and mark functions
correctly in the output ELF objects.

All users of the old macros in x86 are converted to use these in further
patches.

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Signed-off-by: Borislav Petkov <bp@suse.de>
Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Andrey Ryabinin <aryabinin@virtuozzo.com>
Cc: Boris Ostrovsky <boris.ostrovsky@oracle.com>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Jonathan Corbet <corbet@lwn.net>
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
Cc: Juergen Gross <jgross@suse.com>
Cc: Len Brown <len.brown@intel.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: linux-arch@vger.kernel.org
Cc: linux-doc@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
Cc: linux-pm@vger.kernel.org
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Pavel Machek <pavel@ucw.cz>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Will Deacon <will@kernel.org>
Cc: x86-ml <x86@kernel.org>
Cc: xen-devel@lists.xenproject.org
Link: https://lkml.kernel.org/r/20191011115108.12392-2-jslaby@suse.cz
Cc: Jian Cai <jiancai@google.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2020-11-10 12:37:24 +01:00

350 lines
9.1 KiB
C

/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _LINUX_LINKAGE_H
#define _LINUX_LINKAGE_H
#include <linux/compiler_types.h>
#include <linux/stringify.h>
#include <linux/export.h>
#include <asm/linkage.h>
/* Some toolchains use other characters (e.g. '`') to mark new line in macro */
#ifndef ASM_NL
#define ASM_NL ;
#endif
#ifdef __cplusplus
#define CPP_ASMLINKAGE extern "C"
#else
#define CPP_ASMLINKAGE
#endif
#ifndef asmlinkage
#define asmlinkage CPP_ASMLINKAGE
#endif
#ifndef cond_syscall
#define cond_syscall(x) asm( \
".weak " __stringify(x) "\n\t" \
".set " __stringify(x) "," \
__stringify(sys_ni_syscall))
#endif
#ifndef SYSCALL_ALIAS
#define SYSCALL_ALIAS(alias, name) asm( \
".globl " __stringify(alias) "\n\t" \
".set " __stringify(alias) "," \
__stringify(name))
#endif
#define __page_aligned_data __section(.data..page_aligned) __aligned(PAGE_SIZE)
#define __page_aligned_bss __section(.bss..page_aligned) __aligned(PAGE_SIZE)
/*
* For assembly routines.
*
* Note when using these that you must specify the appropriate
* alignment directives yourself
*/
#define __PAGE_ALIGNED_DATA .section ".data..page_aligned", "aw"
#define __PAGE_ALIGNED_BSS .section ".bss..page_aligned", "aw"
/*
* This is used by architectures to keep arguments on the stack
* untouched by the compiler by keeping them live until the end.
* The argument stack may be owned by the assembly-language
* caller, not the callee, and gcc doesn't always understand
* that.
*
* We have the return value, and a maximum of six arguments.
*
* This should always be followed by a "return ret" for the
* protection to work (ie no more work that the compiler might
* end up needing stack temporaries for).
*/
/* Assembly files may be compiled with -traditional .. */
#ifndef __ASSEMBLY__
#ifndef asmlinkage_protect
# define asmlinkage_protect(n, ret, args...) do { } while (0)
#endif
#endif
#ifndef __ALIGN
#define __ALIGN .align 4,0x90
#define __ALIGN_STR ".align 4,0x90"
#endif
#ifdef __ASSEMBLY__
/* SYM_T_FUNC -- type used by assembler to mark functions */
#ifndef SYM_T_FUNC
#define SYM_T_FUNC STT_FUNC
#endif
/* SYM_T_OBJECT -- type used by assembler to mark data */
#ifndef SYM_T_OBJECT
#define SYM_T_OBJECT STT_OBJECT
#endif
/* SYM_T_NONE -- type used by assembler to mark entries of unknown type */
#ifndef SYM_T_NONE
#define SYM_T_NONE STT_NOTYPE
#endif
/* SYM_A_* -- align the symbol? */
#define SYM_A_ALIGN ALIGN
#define SYM_A_NONE /* nothing */
/* SYM_L_* -- linkage of symbols */
#define SYM_L_GLOBAL(name) .globl name
#define SYM_L_WEAK(name) .weak name
#define SYM_L_LOCAL(name) /* nothing */
#ifndef LINKER_SCRIPT
#define ALIGN __ALIGN
#define ALIGN_STR __ALIGN_STR
/* === DEPRECATED annotations === */
#ifndef GLOBAL
/* deprecated, use SYM_DATA*, SYM_ENTRY, or similar */
#define GLOBAL(name) \
.globl name ASM_NL \
name:
#endif
#ifndef ENTRY
/* deprecated, use SYM_FUNC_START */
#define ENTRY(name) \
SYM_FUNC_START(name)
#endif
#endif /* LINKER_SCRIPT */
#ifndef WEAK
/* deprecated, use SYM_FUNC_START_WEAK* */
#define WEAK(name) \
SYM_FUNC_START_WEAK(name)
#endif
#ifndef END
/* deprecated, use SYM_FUNC_END, SYM_DATA_END, or SYM_END */
#define END(name) \
.size name, .-name
#endif
/* If symbol 'name' is treated as a subroutine (gets called, and returns)
* then please use ENDPROC to mark 'name' as STT_FUNC for the benefit of
* static analysis tools such as stack depth analyzer.
*/
#ifndef ENDPROC
/* deprecated, use SYM_FUNC_END */
#define ENDPROC(name) \
SYM_FUNC_END(name)
#endif
/* === generic annotations === */
/* SYM_ENTRY -- use only if you have to for non-paired symbols */
#ifndef SYM_ENTRY
#define SYM_ENTRY(name, linkage, align...) \
linkage(name) ASM_NL \
align ASM_NL \
name:
#endif
/* SYM_START -- use only if you have to */
#ifndef SYM_START
#define SYM_START(name, linkage, align...) \
SYM_ENTRY(name, linkage, align)
#endif
/* SYM_END -- use only if you have to */
#ifndef SYM_END
#define SYM_END(name, sym_type) \
.type name sym_type ASM_NL \
.size name, .-name
#endif
/* === code annotations === */
/*
* FUNC -- C-like functions (proper stack frame etc.)
* CODE -- non-C code (e.g. irq handlers with different, special stack etc.)
*
* Objtool validates stack for FUNC, but not for CODE.
* Objtool generates debug info for both FUNC & CODE, but needs special
* annotations for each CODE's start (to describe the actual stack frame).
*
* ALIAS -- does not generate debug info -- the aliased function will
*/
/* SYM_INNER_LABEL_ALIGN -- only for labels in the middle of code */
#ifndef SYM_INNER_LABEL_ALIGN
#define SYM_INNER_LABEL_ALIGN(name, linkage) \
.type name SYM_T_NONE ASM_NL \
SYM_ENTRY(name, linkage, SYM_A_ALIGN)
#endif
/* SYM_INNER_LABEL -- only for labels in the middle of code */
#ifndef SYM_INNER_LABEL
#define SYM_INNER_LABEL(name, linkage) \
.type name SYM_T_NONE ASM_NL \
SYM_ENTRY(name, linkage, SYM_A_NONE)
#endif
/*
* SYM_FUNC_START_LOCAL_ALIAS -- use where there are two local names for one
* function
*/
#ifndef SYM_FUNC_START_LOCAL_ALIAS
#define SYM_FUNC_START_LOCAL_ALIAS(name) \
SYM_START(name, SYM_L_LOCAL, SYM_A_ALIGN)
#endif
/*
* SYM_FUNC_START_ALIAS -- use where there are two global names for one
* function
*/
#ifndef SYM_FUNC_START_ALIAS
#define SYM_FUNC_START_ALIAS(name) \
SYM_START(name, SYM_L_GLOBAL, SYM_A_ALIGN)
#endif
/* SYM_FUNC_START -- use for global functions */
#ifndef SYM_FUNC_START
/*
* The same as SYM_FUNC_START_ALIAS, but we will need to distinguish these two
* later.
*/
#define SYM_FUNC_START(name) \
SYM_START(name, SYM_L_GLOBAL, SYM_A_ALIGN)
#endif
/* SYM_FUNC_START_NOALIGN -- use for global functions, w/o alignment */
#ifndef SYM_FUNC_START_NOALIGN
#define SYM_FUNC_START_NOALIGN(name) \
SYM_START(name, SYM_L_GLOBAL, SYM_A_NONE)
#endif
/* SYM_FUNC_START_LOCAL -- use for local functions */
#ifndef SYM_FUNC_START_LOCAL
/* the same as SYM_FUNC_START_LOCAL_ALIAS, see comment near SYM_FUNC_START */
#define SYM_FUNC_START_LOCAL(name) \
SYM_START(name, SYM_L_LOCAL, SYM_A_ALIGN)
#endif
/* SYM_FUNC_START_LOCAL_NOALIGN -- use for local functions, w/o alignment */
#ifndef SYM_FUNC_START_LOCAL_NOALIGN
#define SYM_FUNC_START_LOCAL_NOALIGN(name) \
SYM_START(name, SYM_L_LOCAL, SYM_A_NONE)
#endif
/* SYM_FUNC_START_WEAK -- use for weak functions */
#ifndef SYM_FUNC_START_WEAK
#define SYM_FUNC_START_WEAK(name) \
SYM_START(name, SYM_L_WEAK, SYM_A_ALIGN)
#endif
/* SYM_FUNC_START_WEAK_NOALIGN -- use for weak functions, w/o alignment */
#ifndef SYM_FUNC_START_WEAK_NOALIGN
#define SYM_FUNC_START_WEAK_NOALIGN(name) \
SYM_START(name, SYM_L_WEAK, SYM_A_NONE)
#endif
/* SYM_FUNC_END_ALIAS -- the end of LOCAL_ALIASed or ALIASed function */
#ifndef SYM_FUNC_END_ALIAS
#define SYM_FUNC_END_ALIAS(name) \
SYM_END(name, SYM_T_FUNC)
#endif
/*
* SYM_FUNC_END -- the end of SYM_FUNC_START_LOCAL, SYM_FUNC_START,
* SYM_FUNC_START_WEAK, ...
*/
#ifndef SYM_FUNC_END
/* the same as SYM_FUNC_END_ALIAS, see comment near SYM_FUNC_START */
#define SYM_FUNC_END(name) \
SYM_END(name, SYM_T_FUNC)
#endif
/* SYM_CODE_START -- use for non-C (special) functions */
#ifndef SYM_CODE_START
#define SYM_CODE_START(name) \
SYM_START(name, SYM_L_GLOBAL, SYM_A_ALIGN)
#endif
/* SYM_CODE_START_NOALIGN -- use for non-C (special) functions, w/o alignment */
#ifndef SYM_CODE_START_NOALIGN
#define SYM_CODE_START_NOALIGN(name) \
SYM_START(name, SYM_L_GLOBAL, SYM_A_NONE)
#endif
/* SYM_CODE_START_LOCAL -- use for local non-C (special) functions */
#ifndef SYM_CODE_START_LOCAL
#define SYM_CODE_START_LOCAL(name) \
SYM_START(name, SYM_L_LOCAL, SYM_A_ALIGN)
#endif
/*
* SYM_CODE_START_LOCAL_NOALIGN -- use for local non-C (special) functions,
* w/o alignment
*/
#ifndef SYM_CODE_START_LOCAL_NOALIGN
#define SYM_CODE_START_LOCAL_NOALIGN(name) \
SYM_START(name, SYM_L_LOCAL, SYM_A_NONE)
#endif
/* SYM_CODE_END -- the end of SYM_CODE_START_LOCAL, SYM_CODE_START, ... */
#ifndef SYM_CODE_END
#define SYM_CODE_END(name) \
SYM_END(name, SYM_T_NONE)
#endif
/* === data annotations === */
/* SYM_DATA_START -- global data symbol */
#ifndef SYM_DATA_START
#define SYM_DATA_START(name) \
SYM_START(name, SYM_L_GLOBAL, SYM_A_NONE)
#endif
/* SYM_DATA_START -- local data symbol */
#ifndef SYM_DATA_START_LOCAL
#define SYM_DATA_START_LOCAL(name) \
SYM_START(name, SYM_L_LOCAL, SYM_A_NONE)
#endif
/* SYM_DATA_END -- the end of SYM_DATA_START symbol */
#ifndef SYM_DATA_END
#define SYM_DATA_END(name) \
SYM_END(name, SYM_T_OBJECT)
#endif
/* SYM_DATA_END_LABEL -- the labeled end of SYM_DATA_START symbol */
#ifndef SYM_DATA_END_LABEL
#define SYM_DATA_END_LABEL(name, linkage, label) \
linkage(label) ASM_NL \
.type label SYM_T_OBJECT ASM_NL \
label: \
SYM_END(name, SYM_T_OBJECT)
#endif
/* SYM_DATA -- start+end wrapper around simple global data */
#ifndef SYM_DATA
#define SYM_DATA(name, data...) \
SYM_DATA_START(name) ASM_NL \
data ASM_NL \
SYM_DATA_END(name)
#endif
/* SYM_DATA_LOCAL -- start+end wrapper around simple local data */
#ifndef SYM_DATA_LOCAL
#define SYM_DATA_LOCAL(name, data...) \
SYM_DATA_START_LOCAL(name) ASM_NL \
data ASM_NL \
SYM_DATA_END(name)
#endif
#endif /* __ASSEMBLY__ */
#endif /* _LINUX_LINKAGE_H */