Message ID | 20231215082640.2088490-1-stli@linux.ibm.com |
---|---|
State | New |
Headers | show |
Series | s390: Set psw addr field in getcontext and friends. | expand |
* Stefan Liebler: > So far if the ucontext structure was obtained by getcontext and co, > the return address was stored in general purpose register 14 as > it is defined as return address in the ABI. > > In contrast, the context passed to a signal handler contains the address > in psw.addr field. > > If somebody e.g. wants to dump the address of the context, the origin > needs to be known. > > Now this patch adjusts getcontext and friends and stores the return address > also in psw.addr field. > > Note that setcontext isn't adjusted and it is not supported to pass a > ucontext structure from signal-handler to setcontext. We are not able to > restore all registers and branching to psw.addr without clobbering one > register. > --- > sysdeps/unix/sysv/linux/s390/s390-32/getcontext.S | 6 ++++++ > sysdeps/unix/sysv/linux/s390/s390-32/makecontext.c | 5 +++++ > sysdeps/unix/sysv/linux/s390/s390-32/swapcontext.S | 6 ++++++ > sysdeps/unix/sysv/linux/s390/s390-64/getcontext.S | 6 ++++++ > sysdeps/unix/sysv/linux/s390/s390-64/makecontext.c | 5 +++++ > sysdeps/unix/sysv/linux/s390/s390-64/swapcontext.S | 6 ++++++ > 6 files changed, 34 insertions(+) I guess this makes sense. Please feel empowered to push this as the S/390 maintainer. Thanks, Florian
On 18.12.23 15:18, Florian Weimer wrote: > * Stefan Liebler: > >> So far if the ucontext structure was obtained by getcontext and co, >> the return address was stored in general purpose register 14 as >> it is defined as return address in the ABI. >> >> In contrast, the context passed to a signal handler contains the address >> in psw.addr field. >> >> If somebody e.g. wants to dump the address of the context, the origin >> needs to be known. >> >> Now this patch adjusts getcontext and friends and stores the return address >> also in psw.addr field. >> >> Note that setcontext isn't adjusted and it is not supported to pass a >> ucontext structure from signal-handler to setcontext. We are not able to >> restore all registers and branching to psw.addr without clobbering one >> register. >> --- >> sysdeps/unix/sysv/linux/s390/s390-32/getcontext.S | 6 ++++++ >> sysdeps/unix/sysv/linux/s390/s390-32/makecontext.c | 5 +++++ >> sysdeps/unix/sysv/linux/s390/s390-32/swapcontext.S | 6 ++++++ >> sysdeps/unix/sysv/linux/s390/s390-64/getcontext.S | 6 ++++++ >> sysdeps/unix/sysv/linux/s390/s390-64/makecontext.c | 5 +++++ >> sysdeps/unix/sysv/linux/s390/s390-64/swapcontext.S | 6 ++++++ >> 6 files changed, 34 insertions(+) > > I guess this makes sense. Please feel empowered to push this as the > S/390 maintainer. > > Thanks, > Florian > Sure. I've just committed it. Yes, even as maintainer, I post it and wait a bit in order to give others the chance for review. Thanks, Stefan
diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/getcontext.S b/sysdeps/unix/sysv/linux/s390/s390-32/getcontext.S index 8bef183fed..de969dd990 100644 --- a/sysdeps/unix/sysv/linux/s390/s390-32/getcontext.S +++ b/sysdeps/unix/sysv/linux/s390/s390-32/getcontext.S @@ -71,6 +71,12 @@ ENTRY(__getcontext) /* Store general purpose registers. */ stm %r0,%r15,SC_GPRS(%r1) + /* Store psw mask to 0x0 and addr to return address. Then the address + can be retrieved from the ucontext structure in the same way as if it + is created by kernel and passed to a signal-handler. */ + st %r2,SC_PSW+0(%r1) + st %r14,SC_PSW+4(%r1) + /* Return. */ br %r14 END(__getcontext) diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/makecontext.c b/sysdeps/unix/sysv/linux/s390/s390-32/makecontext.c index 1f35ffa5eb..6458ca5f3d 100644 --- a/sysdeps/unix/sysv/linux/s390/s390-32/makecontext.c +++ b/sysdeps/unix/sysv/linux/s390/s390-32/makecontext.c @@ -60,6 +60,11 @@ __makecontext (ucontext_t *ucp, void (*func) (void), int argc, ...) /* Set the return address to trampoline. */ ucp->uc_mcontext.gregs[14] = (long int) __makecontext_ret; + /* Store psw mask to 0x0 and addr to trampoline. Then the address + can be retrieved from the ucontext structure in the same way as if it + is created by kernel and passed to a signal-handler. */ + ucp->uc_mcontext.psw.addr = (long int) __makecontext_ret; + ucp->uc_mcontext.psw.mask = 0; /* Set register parameters. */ va_start (ap, argc); diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/swapcontext.S b/sysdeps/unix/sysv/linux/s390/s390-32/swapcontext.S index b3f2a8b344..ccf4d7a935 100644 --- a/sysdeps/unix/sysv/linux/s390/s390-32/swapcontext.S +++ b/sysdeps/unix/sysv/linux/s390/s390-32/swapcontext.S @@ -66,6 +66,12 @@ ENTRY(__swapcontext) /* Store general purpose registers. */ stm %r0,%r15,SC_GPRS(%r1) + /* Store psw mask to 0x0 and addr to return address. Then the address + can be retrieved from the ucontext structure in the same way as if it + is created by kernel and passed to a signal-handler. */ + st %r2,SC_PSW+0(%r1) + st %r14,SC_PSW+4(%r1) + /* rt_sigprocmask (SIG_SETMASK, &ucp->uc_sigmask, &oucp->uc_sigmask, sigsetsize). */ la %r2,SIG_SETMASK diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/getcontext.S b/sysdeps/unix/sysv/linux/s390/s390-64/getcontext.S index bda313cb23..683f8bb985 100644 --- a/sysdeps/unix/sysv/linux/s390/s390-64/getcontext.S +++ b/sysdeps/unix/sysv/linux/s390/s390-64/getcontext.S @@ -71,6 +71,12 @@ ENTRY(__getcontext) /* Store general purpose registers. */ stmg %r0,%r15,SC_GPRS(%r1) + /* Store psw mask to 0x0 and addr to return address. Then the address + can be retrieved from the ucontext structure in the same way as if it + is created by kernel and passed to a signal-handler. */ + stg %r2,SC_PSW+0(%r1) + stg %r14,SC_PSW+8(%r1) + /* Return. */ br %r14 END(__getcontext) diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/makecontext.c b/sysdeps/unix/sysv/linux/s390/s390-64/makecontext.c index 1dc1af8dc9..b69ff5a136 100644 --- a/sysdeps/unix/sysv/linux/s390/s390-64/makecontext.c +++ b/sysdeps/unix/sysv/linux/s390/s390-64/makecontext.c @@ -60,6 +60,11 @@ __makecontext (ucontext_t *ucp, void (*func) (void), int argc, ...) /* Set the return address to trampoline. */ ucp->uc_mcontext.gregs[14] = (long int) __makecontext_ret; + /* Store psw mask to 0x0 and addr to trampoline. Then the address + can be retrieved from the ucontext structure in the same way as if it + is created by kernel and passed to a signal-handler. */ + ucp->uc_mcontext.psw.addr = (long int) __makecontext_ret; + ucp->uc_mcontext.psw.mask = 0; /* Set register parameters. */ va_start (ap, argc); diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/swapcontext.S b/sysdeps/unix/sysv/linux/s390/s390-64/swapcontext.S index eaa4f3ba19..4bf85c152c 100644 --- a/sysdeps/unix/sysv/linux/s390/s390-64/swapcontext.S +++ b/sysdeps/unix/sysv/linux/s390/s390-64/swapcontext.S @@ -66,6 +66,12 @@ ENTRY(__swapcontext) /* Store general purpose registers. */ stmg %r0,%r15,SC_GPRS(%r1) + /* Store psw mask to 0x0 and addr to return address. Then the address + can be retrieved from the ucontext structure in the same way as if it + is created by kernel and passed to a signal-handler. */ + stg %r2,SC_PSW+0(%r1) + stg %r14,SC_PSW+8(%r1) + /* rt_sigprocmask (SIG_SETMASK, &ucp->uc_sigmask, &oucp->uc_sigmask, sigsetsize). */ la %r2,SIG_SETMASK