public inbox for glibc-cvs@sourceware.org
help / color / mirror / Atom feed
From: Szabolcs Nagy <nsz@sourceware.org>
To: glibc-cvs@sourceware.org
Subject: [glibc/arm/morello/main] TODO(ddc): aarch64: morello: purecap support in the CSU
Date: Fri,  5 Aug 2022 19:33:18 +0000 (GMT)	[thread overview]
Message-ID: <20220805193318.6D3B23858294@sourceware.org> (raw)

https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=d77736297ac6c980a70fa8537bab7e11a414140a

commit d77736297ac6c980a70fa8537bab7e11a414140a
Author: Carlos Eduardo Seo <carlos.seo@arm.com>
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
+   <https://www.gnu.org/licenses/>.  */
+
+/* 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 <sysdep.h>
+#include <libc-symbols.h>
+
+#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
+   <https://www.gnu.org/licenses/>.  */
+
+/* crtn.S puts function epilogues in the .init and .fini sections
+   corresponding to the prologues in crti.S. */
+
+#include <sysdep.h>
+
+	.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
+   <https://www.gnu.org/licenses/>.  */
+
+#include <sysdep.h>
+#include <linux/auxvec.h>
+#include <cheri_perms.h>
+
+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


                 reply	other threads:[~2022-08-05 19:33 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20220805193318.6D3B23858294@sourceware.org \
    --to=nsz@sourceware.org \
    --cc=glibc-cvs@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).