All of lore.kernel.org
 help / color / mirror / Atom feed
From: Ammar Faizi <ammarfaizi2@gnuweeb.org>
To: Willy Tarreau <w@1wt.eu>
Cc: Ammar Faizi <ammarfaizi2@gnuweeb.org>,
	Shuah Khan <shuah@kernel.org>,
	"Paul E. McKenney" <paulmck@kernel.org>,
	Gilang Fachrezy <gilang4321@gmail.com>,
	Alviro Iskandar Setiawan <alviro.iskandar@gnuweeb.org>,
	GNU/Weeb Mailing List <gwml@vger.gnuweeb.org>,
	Linux Kernel Mailing List <linux-kernel@vger.kernel.org>,
	Linux Kselftest Mailing List  <linux-kselftest@vger.kernel.org>
Subject: [PATCH v2 1/4] nolibc/sys: Implement `sigaction(2)` function
Date: Sun,  8 Jan 2023 20:10:35 +0700	[thread overview]
Message-ID: <20230108131038.841204-2-ammar.faizi@intel.com> (raw)
In-Reply-To: <20230108131038.841204-1-ammar.faizi@intel.com>

From: Ammar Faizi <ammarfaizi2@gnuweeb.org>

This commit adds the initial implementation of nolibc `sigaction()`
function. Currently, this implementation is only available on the
x86-64 arch.

`sigaction()` needs an architecture-dependent "signal trampoline"
function that invokes __rt_sigreturn syscall to resume the process
after a signal gets handled.

The "signal trampoline" function is called `__restore_rt` in this
implementation. The naming `__restore_rt` is important for GDB. It also
has to be given a special optimization attribute "omit-frame-pointer"
to prevent the compiler from creating a stack frame that makes the
`%rsp` value no longer points to the `struct rt_sigframe` that the
kernel constructed.

Link: https://lore.kernel.org/lkml/20221228133513.GA7457@1wt.eu
Suggested-by: Willy Tarreau <w@1wt.eu>
Signed-off-by: Ammar Faizi <ammarfaizi2@gnuweeb.org>
---

Side note:
This has been tested on x86-64 arch and `__restore_rt` generates the
correct code. The `__restore_rt` codegen correctness on other
architectures need to be evaluated as well. If it can't generate the
correct code, it has to be written in inline Assembly.

 tools/include/nolibc/sys.h | 72 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 72 insertions(+)

diff --git a/tools/include/nolibc/sys.h b/tools/include/nolibc/sys.h
index acf7cf438010..7d594155e77f 100644
--- a/tools/include/nolibc/sys.h
+++ b/tools/include/nolibc/sys.h
@@ -1047,6 +1047,78 @@ pid_t setsid(void)
 	return ret;
 }
 
+typedef void (*sighandler_t)(int sig);
+
+/*
+ * int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);
+ */
+
+static __attribute__((unused))
+int sys_sigaction(int signum, const struct sigaction *act,
+		  struct sigaction *oldact)
+{
+	return my_syscall4(__NR_rt_sigaction, signum, act, oldact,
+			   sizeof(sigset_t));
+}
+
+__attribute__((weak,unused,noreturn,optimize("omit-frame-pointer"),section(".text.__restore_rt")))
+void __restore_rt(void)
+{
+	my_syscall0(__NR_rt_sigreturn);
+	__builtin_unreachable();
+}
+
+static __attribute__((unused))
+int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact)
+{
+	struct sigaction act2 = *act;
+	int ret;
+
+	/*
+	 * On Linux x86-64, libc's sigaction() always sets the
+	 * @act->sa_restorer when the caller passes a NULL.
+	 *
+	 * @act->sa_restorer is an arch-specific function used
+	 * as a "signal trampoline".
+	 *
+	 * @act->sa_handler is a signal handler provided by the
+	 * user.
+	 *
+	 * When the handled signal is caught, the %rip jumps to
+	 * @act->sa_handler with user stack already set by the
+	 * kernel as below:
+	 *
+	 *         |--------------------|
+	 * %rsp -> |  act->sa_restorer  | (return address)
+	 *         |--------------------|
+	 *         | struct rt_sigframe | (process context info)
+	 *         |                    |
+	 *         |                    |
+	 *          ....................
+	 *
+	 * Once this signal handler executes the "ret" instruction,
+	 * the %rip jumps to @act->sa_restorer. The sa_restorer
+	 * function has to invoke the __rt_sigreturn syscall with
+	 * %rsp pointing to the `struct rt_sigframe` that the kernel
+	 * constructed previously to resume the process.
+	 *
+	 * `struct rt_sigframe` contains the registers' value before
+	 * the signal is caught.
+	 *
+	 */
+	if (!act2.sa_restorer) {
+		act2.sa_flags |= SA_RESTORER;
+		act2.sa_restorer = __restore_rt;
+	}
+
+	ret = sys_sigaction(signum, &act2, oldact);
+	if (ret < 0) {
+		SET_ERRNO(-ret);
+		ret = -1;
+	}
+	return ret;
+}
+
 
 /*
  * int stat(const char *path, struct stat *buf);
-- 
Ammar Faizi


  reply	other threads:[~2023-01-08 13:11 UTC|newest]

Thread overview: 35+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-12-22  3:51 [RFC PATCH v1 0/8] nolibc signal handling support Ammar Faizi
2022-12-22  3:51 ` [RFC PATCH v1 1/8] nolibc/sys: Implement `sigaction(2)` function Ammar Faizi
2022-12-22  3:51 ` [RFC PATCH v1 2/8] nolibc/sys: Implement `signal(2)` function Ammar Faizi
2022-12-22  3:51 ` [RFC PATCH v1 3/8] nolibc/sys: Implement `getpagesize(2)` function Ammar Faizi
2022-12-22  3:51 ` [RFC PATCH v1 4/8] selftests/nolibc: Add `-Wall` and `-Wno-unsed-function` to the CFLAGS Ammar Faizi
2022-12-22  3:51 ` [RFC PATCH v1 5/8] selftests/nolibc: Add `fork(2)` selftest Ammar Faizi
2022-12-22  3:51 ` [RFC PATCH v1 6/8] selftests/nolibc: Add `sigaction(2)` selftest Ammar Faizi
2022-12-22  3:51 ` [RFC PATCH v1 7/8] selftests/nolibc: Add `signal(2)` selftest Ammar Faizi
2022-12-22  3:51 ` [RFC PATCH v1 8/8] selftests/nolibc: Add `getpagesize(2)` selftest Ammar Faizi
2022-12-22  4:34 ` [RFC PATCH v1 0/8] nolibc signal handling support Willy Tarreau
2022-12-22 13:46   ` Ammar Faizi
2022-12-27  6:26     ` Willy Tarreau
2022-12-27 13:32       ` Ammar Faizi
2022-12-27 13:36         ` Ammar Faizi
2022-12-27 18:58           ` Willy Tarreau
2022-12-28 12:23             ` Ammar Faizi
2022-12-27 18:49         ` Willy Tarreau
2022-12-28 12:01           ` Ammar Faizi
2022-12-28 13:35             ` Willy Tarreau
2022-12-29 11:41               ` Ammar Faizi
2023-01-03  3:51                 ` Alviro Iskandar Setiawan
2023-01-03  3:54                   ` Willy Tarreau
2023-01-03  3:59                     ` Ammar Faizi
2023-01-08 13:08                       ` [PATCH v1 0/3] nolibc auxiliary vector retrieval support Ammar Faizi
2023-01-08 13:08                         ` [PATCH v1 1/3] nolibc/stdlib: Implement `getauxval(3)` function Ammar Faizi
2023-01-08 13:08                         ` [PATCH v1 2/3] nolibc/sys: Implement `getpagesize(2)` function Ammar Faizi
2023-01-08 13:08                         ` [PATCH v1 3/3] selftests/nolibc: Add `getpagesize(2)` selftest Ammar Faizi
2023-01-08 13:10                       ` [PATCH v2 0/4] nolibc signal handling support Ammar Faizi
2023-01-08 13:10                         ` Ammar Faizi [this message]
2023-01-08 13:10                         ` [PATCH v2 2/4] nolibc/sys: Implement `signal(2)` function Ammar Faizi
2023-01-08 13:10                         ` [PATCH v2 3/4] selftests/nolibc: Add `fork(2)` selftest Ammar Faizi
2023-01-08 13:10                         ` [PATCH v2 4/4] selftests/nolibc: Add `sigaction(2)` selftest Ammar Faizi
2023-01-08 13:28                         ` [PATCH v2 0/4] nolibc signal handling support Alviro Iskandar Setiawan
2023-01-08 13:31                           ` Ammar Faizi
2023-01-08 13:39                             ` Ammar Faizi

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=20230108131038.841204-2-ammar.faizi@intel.com \
    --to=ammarfaizi2@gnuweeb.org \
    --cc=alviro.iskandar@gnuweeb.org \
    --cc=gilang4321@gmail.com \
    --cc=gwml@vger.gnuweeb.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-kselftest@vger.kernel.org \
    --cc=paulmck@kernel.org \
    --cc=shuah@kernel.org \
    --cc=w@1wt.eu \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.