From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 1944) id 6D3B23858294; Fri, 5 Aug 2022 19:33:18 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 6D3B23858294 Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: Szabolcs Nagy To: glibc-cvs@sourceware.org Subject: [glibc/arm/morello/main] TODO(ddc): aarch64: morello: purecap support in the CSU X-Act-Checkin: glibc X-Git-Author: Carlos Eduardo Seo X-Git-Refname: refs/heads/arm/morello/main X-Git-Oldrev: 2d0278e6d7ed487d940be0df2b06383db1fcde7a X-Git-Newrev: d77736297ac6c980a70fa8537bab7e11a414140a Message-Id: <20220805193318.6D3B23858294@sourceware.org> Date: Fri, 5 Aug 2022 19:33:18 +0000 (GMT) X-BeenThere: glibc-cvs@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Glibc-cvs mailing list List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 05 Aug 2022 19:33:18 -0000 https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=d77736297ac6c980a70fa8537bab7e11a414140a commit d77736297ac6c980a70fa8537bab7e11a414140a Author: Carlos Eduardo Seo Date: Thu Mar 18 15:02:54 2021 -0300 TODO(ddc): aarch64: morello: purecap support in the CSU Purecap ABI versions of start.S, crti.S and crtn.S. TODO: must not use ddc but caps from auxv TODO: start.S: dynamic linked case is now detected by x0 != 0 (ld.so passes __rtld_fini there), but the value of c0 on entry is not abi, just that it has to be passed back to the libc start code in c5, so ideally the linker should be fixed to reliably emit __rela_dyn_start when a static exe must self relocate. Diff: --- sysdeps/aarch64/morello/crti.S | 93 +++++++++++++++++ sysdeps/aarch64/morello/crtn.S | 48 +++++++++ sysdeps/aarch64/morello/start.S | 216 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 357 insertions(+) diff --git a/sysdeps/aarch64/morello/crti.S b/sysdeps/aarch64/morello/crti.S new file mode 100644 index 0000000000..b8b201031b --- /dev/null +++ b/sysdeps/aarch64/morello/crti.S @@ -0,0 +1,93 @@ +/* Special .init and .fini section support for Morello. + Copyright (C) 1995-2022 Free Software Foundation, Inc. + + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + In addition to the permissions in the GNU Lesser General Public + License, the Free Software Foundation gives you unlimited + permission to link the compiled version of this file with other + programs, and to distribute those programs without any restriction + coming from the use of this file. (The GNU Lesser General Public + License restrictions do apply in other respects; for example, they + cover modification of the file, and distribution when not linked + into another program.) + + Note that people who make modified versions of this file are not + obligated to grant this special exception for their modified + versions; it is their choice whether to do so. The GNU Lesser + General Public License gives permission to release a modified + version without this exception; this exception also makes it + possible to release a modified version which carries forward this + exception. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +/* crti.S puts a function prologue at the beginning of the .init and + .fini sections and defines global symbols for those addresses, so + they can be called as functions. The symbols _init and _fini are + magic and cause the linker to emit DT_INIT and DT_FINI. */ + +#include +#include + +#ifndef PREINIT_FUNCTION +# define PREINIT_FUNCTION __gmon_start__ +#endif + +#ifndef PREINIT_FUNCTION_WEAK +# define PREINIT_FUNCTION_WEAK 1 +#endif + +#if PREINIT_FUNCTION_WEAK + weak_extern (PREINIT_FUNCTION) +#else + .hidden PREINIT_FUNCTION +#endif + +#if PREINIT_FUNCTION_WEAK + .align 2 + .type call_weak_fn, %function +call_weak_fn: + adrp c0, :got:PREINIT_FUNCTION + ldr c0, [c0, #:got_lo12:PREINIT_FUNCTION] + cbz x0, 1f + b PREINIT_FUNCTION +1: + RET + .size call_weak_fn, .-call_weak_fn +#endif + + .section .init,"ax",%progbits + .align 2 + .global _init + .hidden _init + .type _init, %function +_init: + stp c29, c30, [csp, -32]! + mov c29, csp +#if PREINIT_FUNCTION_WEAK + bl call_weak_fn +#else + bl PREINIT_FUNCTION +#endif + + .section .fini,"ax",%progbits + .align 2 + .global _fini + .hidden _fini + .type _fini, %function +_fini: + stp c29, c30, [csp, -32]! + mov c29, csp diff --git a/sysdeps/aarch64/morello/crtn.S b/sysdeps/aarch64/morello/crtn.S new file mode 100644 index 0000000000..f405accee1 --- /dev/null +++ b/sysdeps/aarch64/morello/crtn.S @@ -0,0 +1,48 @@ +/* Special .init and .fini section support for Morello. + Copyright (C) 1995-2022 Free Software Foundation, Inc. + + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + In addition to the permissions in the GNU Lesser General Public + License, the Free Software Foundation gives you unlimited + permission to link the compiled version of this file with other + programs, and to distribute those programs without any restriction + coming from the use of this file. (The GNU Lesser General Public + License restrictions do apply in other respects; for example, they + cover modification of the file, and distribution when not linked + into another program.) + + Note that people who make modified versions of this file are not + obligated to grant this special exception for their modified + versions; it is their choice whether to do so. The GNU Lesser + General Public License gives permission to release a modified + version without this exception; this exception also makes it + possible to release a modified version which carries forward this + exception. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +/* crtn.S puts function epilogues in the .init and .fini sections + corresponding to the prologues in crti.S. */ + +#include + + .section .init,"ax",%progbits + ldp c29, c30, [csp], 32 + RET + + .section .fini,"ax",%progbits + ldp c29, c30, [csp], 32 + RET diff --git a/sysdeps/aarch64/morello/start.S b/sysdeps/aarch64/morello/start.S new file mode 100644 index 0000000000..27060198f3 --- /dev/null +++ b/sysdeps/aarch64/morello/start.S @@ -0,0 +1,216 @@ +/* Copyright (C) 2022 Free Software Foundation, Inc. + + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library. If not, see + . */ + +#include +#include +#include + +weak_extern (__rela_dyn_start) +weak_extern (__rela_dyn_end) + +/* This is the canonical entry point, usually the first thing in the text + segment. + + Note that the code in the .init section has already been run. + This includes _init and _libc_init + + + At this entry point, most registers' values are unspecified, except: + + x0/w0 Contains a function pointer to be registered with `atexit'. + This is how the dynamic linker arranges to have DT_FINI + functions called for shared libraries that have been loaded + before this code runs. + + sp The stack contains the arguments and environment: + 0(sp) argc + 8(sp) argv[0] + ... + (8*argc)(sp) NULL + (8*(argc+1))(sp) envp[0] + ... + NULL + */ + + .text +ENTRY(_start) + + /* Create an initial frame with 0 LR and FP */ + cfi_undefined (c30) + mov c29, czr + mov c30, czr + + /* TODO: Use the presence of __rela_dyn_start. */ + mov c5, c0 + cbnz x0, L(rtld_done) + + /* Initialize capabilities. */ +#ifndef SHARED + /* The GNU Linker emits a R_MORELLO_RELATIVE relocation along with + __rela_dyn_start and __rela_dyn_end symbols around the relocation section. + r_offset contains the location, size and permissions: + + capability location // offset 0 (64 bits) + length // offset 8 (56 bits) + permissions // (8 bits) + addend (capability offset) // offset 16 + + according to the ABI document in: + https://github.com/ARM-software/abi-aa/blob/main/aaelf64-morello/aaelf64-morello.rst#dynamic-linking-with-morello + + The addend is the capability offset. + + Note that this will not work with clang, since lld emits a __cap_relocs + struct that has a different layout. If we need to support clang+lld, then + we need to copy the capability initialization steps from Bionic, in: + libc/arch-morello/bionic/__morello_init_static.S. */ + + adrp c0, __rela_dyn_start + add c0, c0, #:lo12:__rela_dyn_start + adrp c1, __rela_dyn_end + add c1, c1, #:lo12:__rela_dyn_end + +1: + /* No capabilities to initialize. Skip to stack adjustment. */ + cmp c0, c1 + b.eq 3f + + /* Load the address of capability. */ + ldr x2, [c0, #0] + + /* Construct capability location from DDC and r_offset. */ + cvtd c2, x2 + + /* Base in x3. */ + ldr x3, [c2] + + /* Length + permissions in x5. */ + ldr x5, [c2, #8] + + /* Permissions in x6. */ + lsr x6, x5, #56 + + /* Permissions encoded as: + 4 = X (executable) + 2 = W (read/write) + 1 = R (read only) + + Permissions to clear in x8 and x11. */ + mov x8, (CAP_PERM_STORE_CAP | CAP_PERM_EXECUTE) + movk x8, (CAP_PERM_STORE >> 16), lsl #16 + mov x9, (CAP_PERM_EXECUTE) + mov x10, (CAP_PERM_STORE_CAP) + movk x10, (CAP_PERM_STORE >> 16), lsl #16 + mov x11, (CAP_PERM_UNSEAL | CAP_PERM_SEAL | CAP_PERM_COMPARTMENT_ID) + cmp x6, #0x2 + csel x8, x9, x8, eq + cmp x6, #0x4 + csel x8, x10, x8, eq + + /* Length in x5. */ + and x5, x5, #0xffffffffffffff + + /* Offset in x7. */ + ldr x7, [c0, #16] + + /* Construct capability from DDC with value equal to base. */ + cvtd c3, x3 + + /* Set bounds to [base ; base + length]. */ + scbndse c3, c3, x5 + + /* Compute the capability value from addend. */ + add c3, c3, x7 + + /* Clear permissions. */ + clrperm c3, c3, x8 + clrperm c3, c3, x11 + + /* Seal capabilities, which provide execute permission, with MORELLO_RB */ + tst x8, #CAP_PERM_EXECUTE + b.ne 2f + + seal c3, c3, rb + +2: + /* Store the constructed capability to the target location. */ + str c3, [c2] + + /* Move to the next __rela_dyn entry. */ + add c0, c0, #24 + b 1b + +3: +#endif /* !SHARED */ + + /* Setup rtld_fini in argument register */ + mov c5, czr + +L(rtld_done): + + /* Load argc and a pointer to argv */ + ldr c1, [csp, #0] + add c2, csp, #16 + + /* Setup stack limit in argument register */ + mov c6, csp + +#ifdef PIC +# ifdef SHARED + adrp c0, :got:main + ldr c0, [c0, #:got_lo12:main] +# else + adrp c0, __wrap_main + add c0, c0, :lo12:__wrap_main +# endif /* SHARED */ +#else + /* Set up the other arguments in registers */ + MOVL (0, main) + cvtd c0, x0 +#endif /* PIC */ + + mov x3, #0 /* Used to be init. */ + mov x4, #0 /* Used to be fini. */ + + /* __libc_start_main (main, argc, argv, init, fini, rtld_fini, + stack_end) */ + + /* Let the libc call main and exit with its return code. */ + bl __libc_start_main + + /* should never get here....*/ + bl abort +END(_start) + +#if defined PIC && !defined SHARED + /* When main is not defined in the executable but in a shared library + then a wrapper is needed in crt1.o of the static-pie enabled libc, + because crt1.o and rcrt1.o share code and the later must avoid the + use of GOT relocations before __libc_start_main is called. */ +ENTRY(__wrap_main) + b main +END(__wrap_main) +#endif + + /* Define a symbol for the first piece of initialized data. */ + .data + .globl __data_start +__data_start: + .long 0 + .weak data_start + data_start = __data_start