mirror of
https://git.proxmox.com/git/mirror_ubuntu-kernels.git
synced 2025-12-07 20:54:50 +00:00
Currently aliasing an asm function requires adding START and END annotations for each name, as per Documentation/asm-annotations.rst: SYM_FUNC_START_ALIAS(__memset) SYM_FUNC_START(memset) ... asm insns ... SYM_FUNC_END(memset) SYM_FUNC_END_ALIAS(__memset) This is more painful than necessary to maintain, especially where a function has many aliases, some of which we may wish to define conditionally. For example, arm64's memcpy/memmove implementation (which uses some arch-specific SYM_*() helpers) has: SYM_FUNC_START_ALIAS(__memmove) SYM_FUNC_START_ALIAS_WEAK_PI(memmove) SYM_FUNC_START_ALIAS(__memcpy) SYM_FUNC_START_WEAK_PI(memcpy) ... asm insns ... SYM_FUNC_END_PI(memcpy) EXPORT_SYMBOL(memcpy) SYM_FUNC_END_ALIAS(__memcpy) EXPORT_SYMBOL(__memcpy) SYM_FUNC_END_ALIAS_PI(memmove) EXPORT_SYMBOL(memmove) SYM_FUNC_END_ALIAS(__memmove) EXPORT_SYMBOL(__memmove) SYM_FUNC_START(name) It would be much nicer if we could define the aliases *after* the standard function definition. This would avoid the need to specify each symbol name twice, and would make it easier to spot the canonical function definition. This patch adds new macros to allow us to do so, which allows the above example to be rewritten more succinctly as: SYM_FUNC_START(__pi_memcpy) ... asm insns ... SYM_FUNC_END(__pi_memcpy) SYM_FUNC_ALIAS(__memcpy, __pi_memcpy) EXPORT_SYMBOL(__memcpy) SYM_FUNC_ALIAS_WEAK(memcpy, __memcpy) EXPORT_SYMBOL(memcpy) SYM_FUNC_ALIAS(__pi_memmove, __pi_memcpy) SYM_FUNC_ALIAS(__memmove, __pi_memmove) EXPORT_SYMBOL(__memmove) SYM_FUNC_ALIAS_WEAK(memmove, __memmove) EXPORT_SYMBOL(memmove) The reduction in duplication will also make it possible to replace some uses of WEAK with more accurate Kconfig guards, e.g. #ifndef CONFIG_KASAN SYM_FUNC_ALIAS(memmove, __memmove) EXPORT_SYMBOL(memmove) #endif ... which should make it easier to ensure that symbols are neither used nor overidden unexpectedly. The existing SYM_FUNC_START_ALIAS() and SYM_FUNC_START_LOCAL_ALIAS() are marked as deprecated, and will be removed once existing users are moved over to the new scheme. The tools/perf/ copy of linkage.h is updated to match. A subsequent patch will depend upon this when updating the x86 asm annotations. Signed-off-by: Mark Rutland <mark.rutland@arm.com> Acked-by: Ard Biesheuvel <ardb@kernel.org> Acked-by: Josh Poimboeuf <jpoimboe@redhat.com> Acked-by: Mark Brown <broonie@kernel.org> Cc: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: Borislav Petkov <bp@alien8.de> Cc: Jiri Slaby <jslaby@suse.cz> Cc: Peter Zijlstra <peterz@infradead.org> Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org> Link: https://lore.kernel.org/r/20220216162229.1076788-2-mark.rutland@arm.com Signed-off-by: Will Deacon <will@kernel.org>
140 lines
3.5 KiB
C
140 lines
3.5 KiB
C
/* SPDX-License-Identifier: GPL-2.0 */
|
|
|
|
#ifndef PERF_LINUX_LINKAGE_H_
|
|
#define PERF_LINUX_LINKAGE_H_
|
|
|
|
/* linkage.h ... for including arch/x86/lib/memcpy_64.S */
|
|
|
|
/* Some toolchains use other characters (e.g. '`') to mark new line in macro */
|
|
#ifndef ASM_NL
|
|
#define ASM_NL ;
|
|
#endif
|
|
|
|
#ifndef __ALIGN
|
|
#define __ALIGN .align 4,0x90
|
|
#define __ALIGN_STR ".align 4,0x90"
|
|
#endif
|
|
|
|
/* SYM_T_FUNC -- type used by assembler to mark functions */
|
|
#ifndef SYM_T_FUNC
|
|
#define SYM_T_FUNC STT_FUNC
|
|
#endif
|
|
|
|
/* SYM_A_* -- align the symbol? */
|
|
#define SYM_A_ALIGN ALIGN
|
|
|
|
/* 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 */
|
|
|
|
#define ALIGN __ALIGN
|
|
|
|
/* === 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 \
|
|
.set .L__sym_size_##name, .-name ASM_NL \
|
|
.size name, .-name
|
|
#endif
|
|
|
|
/* SYM_ALIAS -- use only if you have to */
|
|
#ifndef SYM_ALIAS
|
|
#define SYM_ALIAS(alias, name, sym_type, linkage) \
|
|
linkage(alias) ASM_NL \
|
|
.set alias, name ASM_NL \
|
|
.type alias sym_type ASM_NL \
|
|
.set .L__sym_size_##alias, .L__sym_size_##name ASM_NL \
|
|
.size alias, .L__sym_size_##alias
|
|
#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_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_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_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_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_FUNC_ALIAS -- define a global alias for an existing function
|
|
*/
|
|
#ifndef SYM_FUNC_ALIAS
|
|
#define SYM_FUNC_ALIAS(alias, name) \
|
|
SYM_ALIAS(alias, name, SYM_T_FUNC, SYM_L_GLOBAL)
|
|
#endif
|
|
|
|
/*
|
|
* SYM_FUNC_ALIAS_LOCAL -- define a local alias for an existing function
|
|
*/
|
|
#ifndef SYM_FUNC_ALIAS_LOCAL
|
|
#define SYM_FUNC_ALIAS_LOCAL(alias, name) \
|
|
SYM_ALIAS(alias, name, SYM_T_FUNC, SYM_L_LOCAL)
|
|
#endif
|
|
|
|
/*
|
|
* SYM_FUNC_ALIAS_WEAK -- define a weak global alias for an existing function
|
|
*/
|
|
#ifndef SYM_FUNC_ALIAS_WEAK
|
|
#define SYM_FUNC_ALIAS_WEAK(alias, name) \
|
|
SYM_ALIAS(alias, name, SYM_T_FUNC, SYM_L_WEAK)
|
|
#endif
|
|
|
|
#endif /* PERF_LINUX_LINKAGE_H_ */
|