From 8892a73f72e101bf1afc36c87610debc05374922 Mon Sep 17 00:00:00 2001 From: Mathieu Desnoyers Date: Wed, 28 Feb 2024 16:49:43 -0500 Subject: [PATCH] s390: Introduce code deduplication macros Introduce RSEQ_ASM_U64_PTR() which expresses the type and instance of the defined variable, allowing deduplication of the following macros: - __RSEQ_ASM_DEFINE_TABLE, - RSEQ_ASM_DEFINE_EXIT_POINT. Separate load/store/op helper macros, RSEQ_ASM_STORE_RSEQ_CS, and RSEQ_ASM_U64_PTR into their respective ifdef regions, as the resulting documentation is clearer (and not duplicated). Signed-off-by: Mathieu Desnoyers Change-Id: I37c481c9eb726b49dfdf00539c42d68bb500b2c7 --- include/rseq/arch/s390.h | 139 +++++++++++++++------------------------ 1 file changed, 53 insertions(+), 86 deletions(-) diff --git a/include/rseq/arch/s390.h b/include/rseq/arch/s390.h index e76bb70..ae80f7f 100644 --- a/include/rseq/arch/s390.h +++ b/include/rseq/arch/s390.h @@ -54,81 +54,69 @@ do { \ RSEQ_WRITE_ONCE(*(p), v); \ } while (0) -#ifdef RSEQ_ARCH_S390X - /* - * Helper macros to access a variable of pointer type stored in a 64-bit - * integer. Only used internally in rseq headers. + * Helper macros to access a variable of long integer type. Only used + * internally in rseq headers. */ -#define RSEQ_ASM_LONG_L "lg" -#define RSEQ_ASM_LONG_S "stg" -#define RSEQ_ASM_LONG_LT_R "ltgr" -#define RSEQ_ASM_LONG_CMP "cg" -#define RSEQ_ASM_LONG_CMP_R "cgr" -#define RSEQ_ASM_LONG_ADDI "aghi" -#define RSEQ_ASM_LONG_ADD_R "agr" +#ifdef RSEQ_ARCH_S390X +# define RSEQ_ASM_LONG_L "lg" +# define RSEQ_ASM_LONG_S "stg" +# define RSEQ_ASM_LONG_LT_R "ltgr" +# define RSEQ_ASM_LONG_CMP "cg" +# define RSEQ_ASM_LONG_CMP_R "cgr" +# define RSEQ_ASM_LONG_ADDI "aghi" +# define RSEQ_ASM_LONG_ADD_R "agr" +#else +# define RSEQ_ASM_LONG_L "l" +# define RSEQ_ASM_LONG_S "st" +# define RSEQ_ASM_LONG_LT_R "ltr" +# define RSEQ_ASM_LONG_CMP "c" +# define RSEQ_ASM_LONG_CMP_R "cr" +# define RSEQ_ASM_LONG_ADDI "ahi" +# define RSEQ_ASM_LONG_ADD_R "ar" +#endif + +#ifdef RSEQ_ARCH_S390X +# define RSEQ_ASM_U64_PTR(x) ".quad " x +#else +/* 32-bit only supported on big endian. */ +# define RSEQ_ASM_U64_PTR(x) ".long 0x0, " x +#endif /* Only used in RSEQ_ASM_DEFINE_TABLE. */ -#define __RSEQ_ASM_DEFINE_TABLE(label, version, flags, \ - start_ip, post_commit_offset, abort_ip) \ - ".pushsection __rseq_cs, \"aw\"\n\t" \ - ".balign 32\n\t" \ - __rseq_str(label) ":\n\t" \ - ".long " __rseq_str(version) ", " __rseq_str(flags) "\n\t" \ - ".quad " __rseq_str(start_ip) ", " __rseq_str(post_commit_offset) ", " __rseq_str(abort_ip) "\n\t" \ - ".popsection\n\t" \ - ".pushsection __rseq_cs_ptr_array, \"aw\"\n\t" \ - ".quad " __rseq_str(label) "b\n\t" \ +#define __RSEQ_ASM_DEFINE_TABLE(label, version, flags, \ + start_ip, post_commit_offset, abort_ip) \ + ".pushsection __rseq_cs, \"aw\"\n\t" \ + ".balign 32\n\t" \ + __rseq_str(label) ":\n\t" \ + ".long " __rseq_str(version) ", " __rseq_str(flags) "\n\t" \ + RSEQ_ASM_U64_PTR(__rseq_str(start_ip)) "\n\t" \ + RSEQ_ASM_U64_PTR(__rseq_str(post_commit_offset)) "\n\t" \ + RSEQ_ASM_U64_PTR(__rseq_str(abort_ip)) "\n\t" \ + ".popsection\n\t" \ + ".pushsection __rseq_cs_ptr_array, \"aw\"\n\t" \ + RSEQ_ASM_U64_PTR(__rseq_str(label) "b") "\n\t" \ ".popsection\n\t" /* - * Define the @exit_ip pointer as an exit point for the sequence of consecutive - * assembly instructions at @start_ip. + * Define an rseq critical section structure of version 0 with no flags. * + * @label: + * Local label for the beginning of the critical section descriptor + * structure. * @start_ip: * Pointer to the first instruction of the sequence of consecutive assembly * instructions. - * @exit_ip: - * Pointer to an exit point instruction. - * - * Exit points of a rseq critical section consist of all instructions outside - * of the critical section where a critical section can either branch to or - * reach through the normal course of its execution. The abort IP and the - * post-commit IP are already part of the __rseq_cs section and should not be - * explicitly defined as additional exit points. Knowing all exit points is - * useful to assist debuggers stepping over the critical section. - */ -#define RSEQ_ASM_DEFINE_EXIT_POINT(start_ip, exit_ip) \ - ".pushsection __rseq_exit_point_array, \"aw\"\n\t" \ - ".quad " __rseq_str(start_ip) ", " __rseq_str(exit_ip) "\n\t" \ - ".popsection\n\t" - -#else /* #ifdef RSEQ_ARCH_S390X */ - -/* - * Helper macros to access a variable of pointer type stored in a 64-bit - * integer. Only used internally in rseq headers. + * @post_commit_ip: + * Pointer to the instruction after the last instruction of the sequence of + * consecutive assembly instructions. + * @abort_ip: + * Pointer to the instruction where to move the execution flow in case of + * abort of the sequence of consecutive assembly instructions. */ -#define RSEQ_ASM_LONG_L "l" -#define RSEQ_ASM_LONG_S "st" -#define RSEQ_ASM_LONG_LT_R "ltr" -#define RSEQ_ASM_LONG_CMP "c" -#define RSEQ_ASM_LONG_CMP_R "cr" -#define RSEQ_ASM_LONG_ADDI "ahi" -#define RSEQ_ASM_LONG_ADD_R "ar" - -/* Only used in RSEQ_ASM_DEFINE_TABLE. */ -#define __RSEQ_ASM_DEFINE_TABLE(label, version, flags, \ - start_ip, post_commit_offset, abort_ip) \ - ".pushsection __rseq_cs, \"aw\"\n\t" \ - ".balign 32\n\t" \ - __rseq_str(label) ":\n\t" \ - ".long " __rseq_str(version) ", " __rseq_str(flags) "\n\t" \ - ".long 0x0, " __rseq_str(start_ip) ", 0x0, " __rseq_str(post_commit_offset) ", 0x0, " __rseq_str(abort_ip) "\n\t" \ - ".popsection\n\t" \ - ".pushsection __rseq_cs_ptr_array, \"aw\"\n\t" \ - ".long 0x0, " __rseq_str(label) "b\n\t" \ - ".popsection\n\t" +#define RSEQ_ASM_DEFINE_TABLE(label, start_ip, post_commit_ip, abort_ip) \ + __RSEQ_ASM_DEFINE_TABLE(label, 0x0, 0x0, start_ip, \ + (post_commit_ip) - (start_ip), abort_ip) /* * Define the @exit_ip pointer as an exit point for the sequence of consecutive @@ -149,31 +137,10 @@ do { \ */ #define RSEQ_ASM_DEFINE_EXIT_POINT(start_ip, exit_ip) \ ".pushsection __rseq_exit_point_array, \"aw\"\n\t" \ - ".long 0x0, " __rseq_str(start_ip) ", 0x0, " __rseq_str(exit_ip) "\n\t" \ + RSEQ_ASM_U64_PTR(__rseq_str(start_ip)) "\n\t" \ + RSEQ_ASM_U64_PTR(__rseq_str(exit_ip)) "\n\t" \ ".popsection\n\t" -#endif /* #ifdef RSEQ_ARCH_S390X */ - -/* - * Define an rseq critical section structure of version 0 with no flags. - * - * @label: - * Local label for the beginning of the critical section descriptor - * structure. - * @start_ip: - * Pointer to the first instruction of the sequence of consecutive assembly - * instructions. - * @post_commit_ip: - * Pointer to the instruction after the last instruction of the sequence of - * consecutive assembly instructions. - * @abort_ip: - * Pointer to the instruction where to move the execution flow in case of - * abort of the sequence of consecutive assembly instructions. - */ -#define RSEQ_ASM_DEFINE_TABLE(label, start_ip, post_commit_ip, abort_ip) \ - __RSEQ_ASM_DEFINE_TABLE(label, 0x0, 0x0, start_ip, \ - (post_commit_ip) - (start_ip), abort_ip) - /* * Define a critical section abort handler. * -- 2.34.1