From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from linux.microsoft.com (linux.microsoft.com [13.77.154.182]) by sourceware.org (Postfix) with ESMTP id EF8943987968 for ; Fri, 15 Jan 2021 18:47:06 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org EF8943987968 Received: from x64host.home (unknown [47.187.219.45]) by linux.microsoft.com (Postfix) with ESMTPSA id 2DAA020B6C43; Fri, 15 Jan 2021 10:47:06 -0800 (PST) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com 2DAA020B6C43 From: madvenka@linux.microsoft.com To: libffi-discuss@sourceware.org Cc: green@moxielogic.com, fweimer@redhat.com, dj@redhat.com, madvenka@linux.microsoft.com Subject: [RFC PATCH v3 4/5] arm64: Support for Static Trampolines Date: Fri, 15 Jan 2021 12:46:52 -0600 Message-Id: <20210115184653.124913-5-madvenka@linux.microsoft.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210115184653.124913-1-madvenka@linux.microsoft.com> References: <1ef5c7e1c9a6ebb140a476ba555ec955681f4fba> <20210115184653.124913-1-madvenka@linux.microsoft.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-27.2 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, ENV_AND_HDR_SPF_MATCH, GIT_PATCH_0, SPF_HELO_PASS, SPF_PASS, TXREP, USER_IN_DEF_DKIM_WL, USER_IN_DEF_SPF_WL autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: libffi-discuss@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libffi-discuss mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 15 Jan 2021 18:47:08 -0000 From: "Madhavan T. Venkataraman" - Define the arch-specific initialization function ffi_tramp_arch () that returns trampoline size information to common code. - Define the trampoline code mapping and data mapping sizes. - Define the trampoline code table statically. - Introduce a tiny prolog for each ABI handling function. The ABI handlers addressed are: - ffi_closure_SYSV - ffi_closure_SYSV_V The prolog functions are called: - ffi_closure_SYSV_alt - ffi_closure_SYSV_V_alt The legacy trampoline jumps to the ABI handler. The static trampoline jumps to the prolog function. The prolog function uses the information provided by the static trampoline, sets things up for the ABI handler and then jumps to the ABI handler. - Call ffi_closure_tramp_init () in ffi_prep_closure_loc () to initialize static trampoline parameters. Signed-off-by: Madhavan T. Venkataraman --- src/aarch64/ffi.c | 36 ++++++++++++++++++++-- src/aarch64/internal.h | 10 +++++++ src/aarch64/sysv.S | 68 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 111 insertions(+), 3 deletions(-) diff --git a/src/aarch64/ffi.c b/src/aarch64/ffi.c index ef09f4d..0d7d8ac 100644 --- a/src/aarch64/ffi.c +++ b/src/aarch64/ffi.c @@ -781,7 +781,9 @@ ffi_call_go (ffi_cif *cif, void (*fn) (void), void *rvalue, /* Build a trampoline. */ extern void ffi_closure_SYSV (void) FFI_HIDDEN; +extern void ffi_closure_SYSV_alt (void) FFI_HIDDEN; extern void ffi_closure_SYSV_V (void) FFI_HIDDEN; +extern void ffi_closure_SYSV_V_alt (void) FFI_HIDDEN; ffi_status ffi_prep_closure_loc (ffi_closure *closure, @@ -794,11 +796,18 @@ ffi_prep_closure_loc (ffi_closure *closure, return FFI_BAD_ABI; void (*start)(void); + void (*start_alt)(void); if (cif->flags & AARCH64_FLAG_ARG_V) - start = ffi_closure_SYSV_V; + { + start = ffi_closure_SYSV_V; + start_alt = ffi_closure_SYSV_V_alt; + } else - start = ffi_closure_SYSV; + { + start = ffi_closure_SYSV; + start_alt = ffi_closure_SYSV_alt; + } #if FFI_EXEC_TRAMPOLINE_TABLE #ifdef __MACH__ @@ -816,7 +825,15 @@ ffi_prep_closure_loc (ffi_closure *closure, 0x00, 0x02, 0x1f, 0xd6 /* br x16 */ }; char *tramp = closure->tramp; - + + if (ffi_tramp_is_present(closure)) + { + /* Initialize the static trampoline's parameters. */ + ffi_tramp_set_parms (closure->ftramp, start_alt, closure); + goto out; + } + + /* Initialize the dynamic trampoline. */ memcpy (tramp, trampoline, sizeof(trampoline)); *(UINT64 *)(tramp + 16) = (uintptr_t)start; @@ -832,6 +849,7 @@ ffi_prep_closure_loc (ffi_closure *closure, unsigned char *tramp_code = ffi_data_to_code_pointer (tramp); #endif ffi_clear_cache (tramp_code, tramp_code + FFI_TRAMPOLINE_SIZE); +out: #endif closure->cif = cif; @@ -1022,4 +1040,16 @@ ffi_closure_SYSV_inner (ffi_cif *cif, return flags; } +#if defined(FFI_EXEC_STATIC_TRAMP) +void * +ffi_tramp_arch (size_t *tramp_size, size_t *map_size) +{ + extern void *trampoline_code_table; + + *tramp_size = AARCH64_TRAMP_SIZE; + *map_size = AARCH64_TRAMP_MAP_SIZE; + return &trampoline_code_table; +} +#endif + #endif /* (__aarch64__) || defined(__arm64__)|| defined (_M_ARM64)*/ diff --git a/src/aarch64/internal.h b/src/aarch64/internal.h index 3d4d035..de55755 100644 --- a/src/aarch64/internal.h +++ b/src/aarch64/internal.h @@ -66,3 +66,13 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #define N_X_ARG_REG 8 #define N_V_ARG_REG 8 #define CALL_CONTEXT_SIZE (N_V_ARG_REG * 16 + N_X_ARG_REG * 8) + +#if defined(FFI_EXEC_STATIC_TRAMP) +/* + * For the trampoline code table mapping, a mapping size of 16K is chosen to + * cover the base page sizes of 4K and 16K. + */ +#define AARCH64_TRAMP_MAP_SHIFT 14 +#define AARCH64_TRAMP_MAP_SIZE (1 << AARCH64_TRAMP_MAP_SHIFT) +#define AARCH64_TRAMP_SIZE 32 +#endif diff --git a/src/aarch64/sysv.S b/src/aarch64/sysv.S index b720a92..a7ba3cc 100644 --- a/src/aarch64/sysv.S +++ b/src/aarch64/sysv.S @@ -252,6 +252,19 @@ CNAME(ffi_closure_SYSV_V): .size CNAME(ffi_closure_SYSV_V), . - CNAME(ffi_closure_SYSV_V) #endif + .align 4 +CNAME(ffi_closure_SYSV_V_alt): + ldr x17, [sp, #8] + add sp, sp, #16 + b CNAME(ffi_closure_SYSV_V) + + .globl CNAME(ffi_closure_SYSV_V_alt) + FFI_HIDDEN(CNAME(ffi_closure_SYSV_V_alt)) +#ifdef __ELF__ + .type CNAME(ffi_closure_SYSV_V_alt), #function + .size CNAME(ffi_closure_SYSV_V_alt), . - CNAME(ffi_closure_SYSV_V_alt) +#endif + .align 4 cfi_startproc CNAME(ffi_closure_SYSV): @@ -367,6 +380,61 @@ CNAME(ffi_closure_SYSV): .size CNAME(ffi_closure_SYSV), . - CNAME(ffi_closure_SYSV) #endif + .align 4 +CNAME(ffi_closure_SYSV_alt): + ldr x17, [sp, #8] + add sp, sp, #16 + b CNAME(ffi_closure_SYSV) + + .globl CNAME(ffi_closure_SYSV_alt) + FFI_HIDDEN(CNAME(ffi_closure_SYSV_alt)) +#ifdef __ELF__ + .type CNAME(ffi_closure_SYSV_alt), #function + .size CNAME(ffi_closure_SYSV_alt), . - CNAME(ffi_closure_SYSV_alt) +#endif + +#if defined(FFI_EXEC_STATIC_TRAMP) +/* + * Below is the definition of the trampoline code table. Each element in + * the code table is a trampoline. + */ +/* + * The trampoline uses register x17. It saves the original value of x17 on + * the stack. + * + * The trampoline has two parameters - target code to jump to and data for + * the target code. The trampoline extracts the parameters from its parameter + * block (see tramp_table_map()). The trampoline saves the data address on + * the stack. Finally, it jumps to the target code. + * + * The target code can choose to: + * + * - restore the value of x17 + * - load the data address in a register + * - restore the stack pointer to what it was when the trampoline was invoked. + */ + .align AARCH64_TRAMP_MAP_SHIFT +CNAME(trampoline_code_table): + .rept AARCH64_TRAMP_MAP_SIZE / AARCH64_TRAMP_SIZE + sub sp, sp, #16 /* Make space on the stack */ + str x17, [sp] /* Save x17 on stack */ + adr x17, #16376 /* Get data address */ + ldr x17, [x17] /* Copy data into x17 */ + str x17, [sp, #8] /* Save data on stack */ + adr x17, #16372 /* Get code address */ + ldr x17, [x17] /* Load code address into x17 */ + br x17 /* Jump to code */ + .endr + + .globl CNAME(trampoline_code_table) + FFI_HIDDEN(CNAME(trampoline_code_table)) +#ifdef __ELF__ + .type CNAME(trampoline_code_table), #function + .size CNAME(trampoline_code_table), . - CNAME(trampoline_code_table) +#endif + .align AARCH64_TRAMP_MAP_SHIFT +#endif /* FFI_EXEC_STATIC_TRAMP */ + #if FFI_EXEC_TRAMPOLINE_TABLE #ifdef __MACH__ -- 2.25.1