[08/21] ARC: Linux Syscall Interface
Commit Message
Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
---
ChangeLog | 12 ++
sysdeps/unix/sysv/linux/arc/cacheflush.c | 29 +++
sysdeps/unix/sysv/linux/arc/clone.S | 100 ++++++++++
sysdeps/unix/sysv/linux/arc/jmp_buf-macros.h | 6 +
sysdeps/unix/sysv/linux/arc/kernel-features.h | 28 +++
sysdeps/unix/sysv/linux/arc/mmap_internal.h | 26 +++
sysdeps/unix/sysv/linux/arc/profil-counter.h | 2 +
sysdeps/unix/sysv/linux/arc/pt-vfork.S | 1 +
sysdeps/unix/sysv/linux/arc/sigaction.c | 69 +++++++
sysdeps/unix/sysv/linux/arc/syscall.S | 38 ++++
sysdeps/unix/sysv/linux/arc/sysdep.c | 33 ++++
sysdeps/unix/sysv/linux/arc/sysdep.h | 259 ++++++++++++++++++++++++++
sysdeps/unix/sysv/linux/arc/vfork.S | 42 +++++
13 files changed, 645 insertions(+)
create mode 100644 sysdeps/unix/sysv/linux/arc/cacheflush.c
create mode 100644 sysdeps/unix/sysv/linux/arc/clone.S
create mode 100644 sysdeps/unix/sysv/linux/arc/jmp_buf-macros.h
create mode 100644 sysdeps/unix/sysv/linux/arc/kernel-features.h
create mode 100644 sysdeps/unix/sysv/linux/arc/mmap_internal.h
create mode 100644 sysdeps/unix/sysv/linux/arc/profil-counter.h
create mode 100644 sysdeps/unix/sysv/linux/arc/pt-vfork.S
create mode 100644 sysdeps/unix/sysv/linux/arc/sigaction.c
create mode 100644 sysdeps/unix/sysv/linux/arc/syscall.S
create mode 100644 sysdeps/unix/sysv/linux/arc/sysdep.c
create mode 100644 sysdeps/unix/sysv/linux/arc/sysdep.h
create mode 100644 sysdeps/unix/sysv/linux/arc/vfork.S
Comments
On Tue, 18 Dec 2018, Vineet Gupta wrote:
> +/* Flush cache(s). */
> +int
> +_flush_cache (char *addr, const int nbytes, const int op)
> +{
> + return INLINE_SYSCALL (cacheflush, 3, addr, nbytes, op);
> +}
> +weak_alias (_flush_cache, cacheflush)
Can't this use a syscalls.list entry instead of needing its own .c file?
> diff --git a/sysdeps/unix/sysv/linux/arc/pt-vfork.S b/sysdeps/unix/sysv/linux/arc/pt-vfork.S
> new file mode 100644
> index 000000000000..65cc3823ac87
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/arc/pt-vfork.S
> @@ -0,0 +1 @@
> +#include <sysdeps/unix/sysv/linux/alpha/pt-vfork.S>
This does nothing for a new port (it's just defining compat symbols). I'd
expect
/* Not needed. */
instead, as for RISC-V.
> diff --git a/sysdeps/unix/sysv/linux/arc/sigaction.c b/sysdeps/unix/sysv/linux/arc/sigaction.c
Why do you need this, rather than using the unified version (possibly with
a few macros defined first)?
> +/* All syscall handler come here to avoid generated code bloat due to
> + * GOT reference to errno_location or it's equivalent
> + */
> +int __syscall_error(int err_no)
Return type goes on a separate line to the function name in a function
definition. (This is in addition to the formatting issues that have been
noted elsewhere in the patch series, of which this code has at least three
- '*' at start of comment lines, missing '.' at end of comment and missing
space before '('.)
On 12/18/18 3:30 PM, Joseph Myers wrote:
> On Tue, 18 Dec 2018, Vineet Gupta wrote:
>
>> +/* Flush cache(s). */
>> +int
>> +_flush_cache (char *addr, const int nbytes, const int op)
>> +{
>> + return INLINE_SYSCALL (cacheflush, 3, addr, nbytes, op);
>> +}
>> +weak_alias (_flush_cache, cacheflush)
>
> Can't this use a syscalls.list entry instead of needing its own .c file?
Sure it can ! Done now.
>> diff --git a/sysdeps/unix/sysv/linux/arc/pt-vfork.S b/sysdeps/unix/sysv/linux/arc/pt-vfork.S
>> new file mode 100644
>> index 000000000000..65cc3823ac87
>> --- /dev/null
>> +++ b/sysdeps/unix/sysv/linux/arc/pt-vfork.S
>> @@ -0,0 +1 @@
>> +#include <sysdeps/unix/sysv/linux/alpha/pt-vfork.S>
>
> This does nothing for a new port (it's just defining compat symbols). I'd
> expect
>
> /* Not needed. */
>
> instead, as for RISC-V.
Done !
>> diff --git a/sysdeps/unix/sysv/linux/arc/sigaction.c b/sysdeps/unix/sysv/linux/arc/sigaction.c
>
> Why do you need this, rather than using the unified version (possibly with
> a few macros defined first)?
The only syscall ABI requirement is that we pass our our own SA_RESTORER stub
(rather than inject one in kernel, and deal with cache sync etc etc). Indeed the
common code can be used - likely was not the case when I started with ARC port, or
more likely the port that I started ARC port from ;-)
I'll update this.
>> +/* All syscall handler come here to avoid generated code bloat due to
>> + * GOT reference to errno_location or it's equivalent
>> + */
>> +int __syscall_error(int err_no)
>
> Return type goes on a separate line to the function name in a function
> definition.
Oops sorry fixed.
> (This is in addition to the formatting issues that have been
> noted elsewhere in the patch series, of which this code has at least three
> - '*' at start of comment lines, missing '.' at end of comment and missing
> space before '('.)
Sorry again. I can sense your valid frustration, but then a lint file or kernel's
checkpatch style tools ill go a long way. Anyhow for now I've fixed annoyances
(hopefully all of them).
On 12/18/18 6:39 PM, Vineet Gupta wrote:
>>> diff --git a/sysdeps/unix/sysv/linux/arc/sigaction.c b/sysdeps/unix/sysv/linux/arc/sigaction.c
>> Why do you need this, rather than using the unified version (possibly with
>> a few macros defined first)?
>
> The only syscall ABI requirement is that we pass our our own SA_RESTORER stub
> (rather than inject one in kernel, and deal with cache sync etc etc). Indeed the
> common code can be used - likely was not the case when I started with ARC port, or
> more likely the port that I started ARC port from ;-)
>
> I'll update this.
I took a stab at this but not really happy with taking this approach.
(1). Common code assumes disparate kernel and userland sigaction struct even
though there's no reason for a *new* port to be: its not like all glibc code is
shared/common although I agree it is best to do so as much as possible
So this requires explicit copy over of 1 struct into other, when it could have
been avoided altogether for some cases atleast (!SA_RESTORER).
(2) Linux kernel asm-generic syscall ABI expects sigset_t to be 2 words
| kernel: include/uapi/asm-generic/signal.h
|
| #define _NSIG 64
| typedef struct {
| unsigned long sig[_NSIG_WORDS];
| } sigset_t;
And that is what we pretend at the time of syscall itself, e.g. snippet below from
generic sigaction()
| /* XXX The size argument hopefully will have to be changed to the
| real size of the user-level sigset_t. */
| result = INLINE_SYSCALL_CALL (rt_sigaction, sig,
| act ? &kact : NULL,
| oact ? &koact : NULL, STUB(act) _NSIG / 8);
^^^^^^^^^
However glibc assumes sigset_to to be 128 words which is fine, however the memcpy
for 256 words seems pointless when kernel is not supposed to be even looking at
beyond 2nd word (although I realize my SA_RESTORE case was doing the implicit copy
as well)
(3) Consider me a micro-optimization freak :-) but this memcpy seems waste of
cycles and will atleast show up LMBench lat_sig <install> micro-benchmarks.
I don't have strong feelings either ways, but wanted to express my concerns anyways.
Thx,
-Vineet
On Wed, 19 Dec 2018, Vineet Gupta wrote:
> I took a stab at this but not really happy with taking this approach.
>
> (1). Common code assumes disparate kernel and userland sigaction struct even
> though there's no reason for a *new* port to be: its not like all glibc code is
> shared/common although I agree it is best to do so as much as possible
> So this requires explicit copy over of 1 struct into other, when it could have
> been avoided altogether for some cases atleast (!SA_RESTORER).
So make the generic code optimize those cases based on appropriate
conditionals (making sure to verify those conditionals are right for every
architecture in glibc).
Any new architecture having much architecture-specific code for the kernel
interface in glibc, beyond the basic definitions of how to call a syscall,
is suspect, given that the kernel structures should be consistent across
asm-generic architectures; we ought to make the defaults work so they are
genuinely suitable as defaults for new architectures. This may require
changes to the sysdeps/unix/sysv/linux/ code if it's currently "generic"
to old architectures but not so good for asm-generic ones.
On 19/12/2018 15:58, Vineet Gupta wrote:
> On 12/18/18 6:39 PM, Vineet Gupta wrote:
>>>> diff --git a/sysdeps/unix/sysv/linux/arc/sigaction.c b/sysdeps/unix/sysv/linux/arc/sigaction.c
>>> Why do you need this, rather than using the unified version (possibly with
>>> a few macros defined first)?
>>
>> The only syscall ABI requirement is that we pass our our own SA_RESTORER stub
>> (rather than inject one in kernel, and deal with cache sync etc etc). Indeed the
>> common code can be used - likely was not the case when I started with ARC port, or
>> more likely the port that I started ARC port from ;-)
>>
>> I'll update this.
>
> I took a stab at this but not really happy with taking this approach.
>
> (1). Common code assumes disparate kernel and userland sigaction struct even
> though there's no reason for a *new* port to be: its not like all glibc code is
> shared/common although I agree it is best to do so as much as possible
> So this requires explicit copy over of 1 struct into other, when it could have
> been avoided altogether for some cases atleast (!SA_RESTORER).
>
> (2) Linux kernel asm-generic syscall ABI expects sigset_t to be 2 words
>
> | kernel: include/uapi/asm-generic/signal.h
> |
> | #define _NSIG 64
> | typedef struct {
> | unsigned long sig[_NSIG_WORDS];
> | } sigset_t;
>
> And that is what we pretend at the time of syscall itself, e.g. snippet below from
> generic sigaction()
>
> | /* XXX The size argument hopefully will have to be changed to the
> | real size of the user-level sigset_t. */
> | result = INLINE_SYSCALL_CALL (rt_sigaction, sig,
> | act ? &kact : NULL,
> | oact ? &koact : NULL, STUB(act) _NSIG / 8);
> ^^^^^^^^^
>
> However glibc assumes sigset_to to be 128 words which is fine, however the memcpy
> for 256 words seems pointless when kernel is not supposed to be even looking at
> beyond 2nd word (although I realize my SA_RESTORE case was doing the implicit copy
> as well)
>
> (3) Consider me a micro-optimization freak :-) but this memcpy seems waste of
> cycles and will atleast show up LMBench lat_sig <install> micro-benchmarks.
>
>
> I don't have strong feelings either ways, but wanted to express my concerns anyways.
>
One possibility is to define an arch-specific __sigset_t.h with a custom
_SIGSET_NWORDS value and add an optimization on Linux sigaction.c to check
if both kernel_sigaction and glibc sigaction share same size and internal
layout to use the struct as-is for syscall instead of copy to a temporary
value (similar to what we used to have on getdents). ARC would still have
arch-specific code and would be the only ABI to have a different sigset_t
though.
However I *hardly* think sigaction is a hotspot in real world cases, usually
the signal action is defined once or in a very limited number of times. I am
not considering synthetic benchmarks, specially lmbench which in most cases
does not measure any useful metric. Even for other sigset_t usage case I still
think an arch-specific definition should not make much difference:
1. setcontext: it would incur just in larger ucontext_t (kernel get/set
mask is done using kernel expected size). Also, taking in consideration
these interfaces were removed from POSIX.1-2008, the inherent performance
issues (signal set/restore will most likely dominate the overhead), and
some implementation issues (BZ#18135 for instance), I would say to not
bother to optimize it.
2. pselect, ppoll, epoll_pwait, posix_spawn (posix_spawnattr_t), sig*:
for functions that accept sigset as an argument it would incur in just
larger memory utilization without much performance overhead. Again,
runtime for these calls would be mostly dominate by syscall overhead
or kernel wait-time for events.
3. raise, etc: for function that might allocate a sigset_t internally it
will similar to 2.
Now, if ARC intention is just to follow generic glibc linux ABI definitions,
it could just define its sigaction as (not tested):
* sysdeps/unix/sysv/linux/arc/sigaction.c
---
#define SA_RESTORER 0x04000000
#include <kernel_sigaction.h>
extern void restore_rt (void) asm ("__restore_rt") attribute_hidden;
#define SET_SA_RESTORER(kact, act) \
(kact)->sa_flags = (act)->sa_flags | SA_RESTORER; \
(kact)->sa_restorer = &__default_rt_sa_restorer
#define RESET_SA_RESTORER(act, kact) \
(act)->sa_restorer = (kact)->sa_restorer
static void __default_rt_sa_restorer(void)
{
INTERNAL_SYSCALL_DECL (err);
INTERNAL_SYSCALL_CALL (__NR_rt_sigreturn, err);
}
#include <sysdeps/unix/sysv/linux/sigaction.c>
---
On 12/19/18 2:00 PM, Adhemerval Zanella wrote:
>
>
> One possibility is to define an arch-specific __sigset_t.h with a custom
> _SIGSET_NWORDS value and add an optimization on Linux sigaction.c to check
> if both kernel_sigaction and glibc sigaction share same size and internal
> layout to use the struct as-is for syscall instead of copy to a temporary
> value (similar to what we used to have on getdents). ARC would still have
> arch-specific code and would be the only ABI to have a different sigset_t
> though.
I don't like ARC to single out either. But as Joseph suggests could this be
starting point for arches of future. Assuming it does, would rather see this or
the approach Joseph alluded to earlier [1]
[1] http://lists.infradead.org/pipermail/linux-snps-arc/2018-December/005122.html
>
> However I *hardly* think sigaction is a hotspot in real world cases, usually
> the signal action is defined once or in a very limited number of times. I am
> not considering synthetic benchmarks, specially lmbench which in most cases
> does not measure any useful metric.
I tend to disagree. Coming from embedded linux background, I've found it immensely
useful to compare 2 minimal systems: especially when distos, out-of-box packages,
fancy benchmarks don't even exist.
At any rate, my disagreement with status quo is not so much of optimize for ARC,
but rather pointless spending of electrons. When we know that there are 64 signals
at max, which need 64-bits, why bother shuffling around 1k bits, specially when
one is starting afresh and there's no legacy crap getting in the way.
The case of adding more signals in future is indeed theoretically possible but
that will be an ABI change anyways.
> Even for other sigset_t usage case I still
> think an arch-specific definition should not make much difference:
>
> 1. setcontext: it would incur just in larger ucontext_t (kernel get/set
> mask is done using kernel expected size). Also, taking in consideration
> these interfaces were removed from POSIX.1-2008, the inherent performance
> issues (signal set/restore will most likely dominate the overhead), and
> some implementation issues (BZ#18135 for instance), I would say to not
> bother to optimize it.
>
> 2. pselect, ppoll, epoll_pwait, posix_spawn (posix_spawnattr_t), sig*:
> for functions that accept sigset as an argument it would incur in just
> larger memory utilization without much performance overhead. Again,
> runtime for these calls would be mostly dominate by syscall overhead
> or kernel wait-time for events.
>
> 3. raise, etc: for function that might allocate a sigset_t internally it
> will similar to 2.
I agree that that in libc, pretty much anything will be dominated by syscall
overhead, but still...
> Now, if ARC intention is just to follow generic glibc linux ABI definitions,
> it could just define its sigaction as (not tested):
Indeed the ABI is etched in stone and I have a very similar code now, with slight
difference.
> * sysdeps/unix/sysv/linux/arc/sigaction.c
>
> ---
> #define SA_RESTORER 0x04000000
> #include <kernel_sigaction.h>
>
> extern void restore_rt (void) asm ("__restore_rt") attribute_hidden;
>
> #define SET_SA_RESTORER(kact, act) \
> (kact)->sa_flags = (act)->sa_flags | SA_RESTORER; \
> (kact)->sa_restorer = &__default_rt_sa_restorer
+#define SET_SA_RESTORER(kact, act) \
+ ({ \
+ if (!((kact)->sa_flags & SA_RESTORER)) \
+ { \
+ (kact)->sa_restorer = __default_rt_sa_restorer; \
+ (kact)->sa_flags |= SA_RESTORER; \
+ } \
+ else \
+ (kact)->sa_restorer = (act)->sa_restorer; \
+ })
>
> #define RESET_SA_RESTORER(act, kact) \
> (act)->sa_restorer = (kact)->sa_restorer
>
> static void __default_rt_sa_restorer(void)
> {
> INTERNAL_SYSCALL_DECL (err);
> INTERNAL_SYSCALL_CALL (__NR_rt_sigreturn, err);
> }
>
> #include <sysdeps/unix/sysv/linux/sigaction.c>
On 19/12/2018 20:23, Vineet Gupta wrote:
> On 12/19/18 2:00 PM, Adhemerval Zanella wrote:
>>
>>
>> One possibility is to define an arch-specific __sigset_t.h with a custom
>> _SIGSET_NWORDS value and add an optimization on Linux sigaction.c to check
>> if both kernel_sigaction and glibc sigaction share same size and internal
>> layout to use the struct as-is for syscall instead of copy to a temporary
>> value (similar to what we used to have on getdents). ARC would still have
>> arch-specific code and would be the only ABI to have a different sigset_t
>> though.
>
> I don't like ARC to single out either. But as Joseph suggests could this be
> starting point for arches of future. Assuming it does, would rather see this or
> the approach Joseph alluded to earlier [1]
>
> [1] http://lists.infradead.org/pipermail/linux-snps-arc/2018-December/005122.html
>
>>
>> However I *hardly* think sigaction is a hotspot in real world cases, usually
>> the signal action is defined once or in a very limited number of times. I am
>> not considering synthetic benchmarks, specially lmbench which in most cases
>> does not measure any useful metric.
>
> I tend to disagree. Coming from embedded linux background, I've found it immensely
> useful to compare 2 minimal systems: especially when distos, out-of-box packages,
> fancy benchmarks don't even exist.
>
> At any rate, my disagreement with status quo is not so much of optimize for ARC,
> but rather pointless spending of electrons. When we know that there are 64 signals
> at max, which need 64-bits, why bother shuffling around 1k bits, specially when
> one is starting afresh and there's no legacy crap getting in the way.
>
> The case of adding more signals in future is indeed theoretically possible but
> that will be an ABI change anyways.
The only advantage of using a larger sigset_t from glibc standpoint is if
kernel ever change it maximum number of supported signals it would not be
a ABI change (it would be if glibc provided sigset_t need to be extended).
My point was that this change would hardly help in performance or memory
utilization due the signal set common utilization in exported and internal
API. But at the same time the signal set hasn't been changed for a *long* time
and I don't see indication that it will any time soon. So a new architecture
might indeed assume it won't change and set its default to follow Linux user
ABI.
>
>> Even for other sigset_t usage case I still
>> think an arch-specific definition should not make much difference:
>>
>> 1. setcontext: it would incur just in larger ucontext_t (kernel get/set
>> mask is done using kernel expected size). Also, taking in consideration
>> these interfaces were removed from POSIX.1-2008, the inherent performance
>> issues (signal set/restore will most likely dominate the overhead), and
>> some implementation issues (BZ#18135 for instance), I would say to not
>> bother to optimize it.
>>
>> 2. pselect, ppoll, epoll_pwait, posix_spawn (posix_spawnattr_t), sig*:
>> for functions that accept sigset as an argument it would incur in just
>> larger memory utilization without much performance overhead. Again,
>> runtime for these calls would be mostly dominate by syscall overhead
>> or kernel wait-time for events.
>>
>> 3. raise, etc: for function that might allocate a sigset_t internally it
>> will similar to 2.
>
> I agree that that in libc, pretty much anything will be dominated by syscall
> overhead, but still...
>
>
>> Now, if ARC intention is just to follow generic glibc linux ABI definitions,
>> it could just define its sigaction as (not tested):
>
> Indeed the ABI is etched in stone and I have a very similar code now, with slight
> difference.
>
>> * sysdeps/unix/sysv/linux/arc/sigaction.c
>>
>> ---
>> #define SA_RESTORER 0x04000000
>> #include <kernel_sigaction.h>
>>
>> extern void restore_rt (void) asm ("__restore_rt") attribute_hidden;
>>
>> #define SET_SA_RESTORER(kact, act) \
>> (kact)->sa_flags = (act)->sa_flags | SA_RESTORER; \
>> (kact)->sa_restorer = &__default_rt_sa_restorer
>
> +#define SET_SA_RESTORER(kact, act) \
> + ({ \
> + if (!((kact)->sa_flags & SA_RESTORER)) \
> + { \
> + (kact)->sa_restorer = __default_rt_sa_restorer; \
> + (kact)->sa_flags |= SA_RESTORER; \
> + } \
> + else \
> + (kact)->sa_restorer = (act)->sa_restorer; \
> + })
What is so special about ARC sa_restorer that an application should provide
an specialized one? Can't it follow other abi where they issue __NR_sigreturn
for !SA_SIGINFO or __NR_rt_sigreturn otherwise?
As for other architecture I do think we should hide the sa_restorer usage
from application.
>
>>
>> #define RESET_SA_RESTORER(act, kact) \
>> (act)->sa_restorer = (kact)->sa_restorer
>>
>> static void __default_rt_sa_restorer(void)
>> {
>> INTERNAL_SYSCALL_DECL (err);
>> INTERNAL_SYSCALL_CALL (__NR_rt_sigreturn, err);
>> }
>>
>> #include <sysdeps/unix/sysv/linux/sigaction.c>
>
>
On Thu, Dec 20, 2018 at 12:19 PM Adhemerval Zanella
<adhemerval.zanella@linaro.org> wrote:
> On 19/12/2018 20:23, Vineet Gupta wrote:
> > On 12/19/18 2:00 PM, Adhemerval Zanella wrote:
> >> One possibility is to define an arch-specific __sigset_t.h with a custom
> >> _SIGSET_NWORDS value and add an optimization on Linux sigaction.c to check
> >> if both kernel_sigaction and glibc sigaction share same size and internal
> >> layout to use the struct as-is for syscall instead of copy to a temporary
> >> value (similar to what we used to have on getdents). ARC would still have
> >> arch-specific code and would be the only ABI to have a different sigset_t
> >> though.
> >
> > I don't like ARC to single out either. But as Joseph suggests could this be
> > starting point for arches of future. Assuming it does, would rather see this or
> > the approach Joseph alluded to earlier [1]
> >
> > [1] http://lists.infradead.org/pipermail/linux-snps-arc/2018-December/005122.html
> >
> >>
> >> However I *hardly* think sigaction is a hotspot in real world cases, usually
> >> the signal action is defined once or in a very limited number of times. I am
> >> not considering synthetic benchmarks, specially lmbench which in most cases
> >> does not measure any useful metric.
> >
> > I tend to disagree. Coming from embedded linux background, I've found it immensely
> > useful to compare 2 minimal systems: especially when distos, out-of-box packages,
> > fancy benchmarks don't even exist.
> >
> > At any rate, my disagreement with status quo is not so much of optimize for ARC,
> > but rather pointless spending of electrons. When we know that there are 64 signals
> > at max, which need 64-bits, why bother shuffling around 1k bits, specially when
> > one is starting afresh and there's no legacy crap getting in the way.
> >
> > The case of adding more signals in future is indeed theoretically possible but
> > that will be an ABI change anyways.
>
> The only advantage of using a larger sigset_t from glibc standpoint is if
> kernel ever change it maximum number of supported signals it would not be
> a ABI change (it would be if glibc provided sigset_t need to be extended).
>
> My point was that this change would hardly help in performance or memory
> utilization due the signal set common utilization in exported and internal
> API. But at the same time the signal set hasn't been changed for a *long* time
> and I don't see indication that it will any time soon. So a new architecture
> might indeed assume it won't change and set its default to follow Linux user
> ABI.
I just checked again what we actually use in the kernel.
With very few exceptions, all architectures in current kernels use
#define _NSIG 64
#define _NSIG_WORDS (_NSIG / _NSIG_BPW)
typedef struct {
/* this sucks for big-endian 32-bit compat mode */
unsigned long sig[_NSIG_WORDS];
} sigset_t;
The only two exceptions I see are:
- alpha uses a scalar 'unsigned long' instead of the struct+array, but
the effect is the same layout.
- For unknown reasons, all three MIPS ABIs now use _NSIG=128.
This changed during linux-2.1.x from 65, to 32 and then the current
value...
All users of sigset_t that I could find in the kernel just check
the size argument to ensure it matches _NSIG, and return
EINVAL otherwise.
Arnd
* Adhemerval Zanella:
> The only advantage of using a larger sigset_t from glibc standpoint is if
> kernel ever change it maximum number of supported signals it would not be
> a ABI change (it would be if glibc provided sigset_t need to be extended).
It's not just the kernel. We might want to restore additional state in
sigsetjmp, and historically, the excess signal space in sigset_t has
provided a way to do that even if there is no other space left in the
jump buffer.
Thanks,
Florian
On 12/20/18 4:40 AM, Florian Weimer wrote:
> * Adhemerval Zanella:
>
>> The only advantage of using a larger sigset_t from glibc standpoint is if
>> kernel ever change it maximum number of supported signals it would not be
>> a ABI change (it would be if glibc provided sigset_t need to be extended).
> It's not just the kernel. We might want to restore additional state in
> sigsetjmp, and historically, the excess signal space in sigset_t has
> provided a way to do that even if there is no other space left in the
> jump buffer.
And that additional state is architectural state (more FPU regs etc etc) or
something libc generic. On both counts, that doesn't sound like a clean interface
design !
On 12/20/18 3:19 AM, Adhemerval Zanella wrote:
>>> #define SET_SA_RESTORER(kact, act) \
>>> (kact)->sa_flags = (act)->sa_flags | SA_RESTORER; \
>>> (kact)->sa_restorer = &__default_rt_sa_restorer
>> +#define SET_SA_RESTORER(kact, act) \
>> + ({ \
>> + if (!((kact)->sa_flags & SA_RESTORER)) \
>> + { \
>> + (kact)->sa_restorer = __default_rt_sa_restorer; \
>> + (kact)->sa_flags |= SA_RESTORER; \
>> + } \
>> + else \
>> + (kact)->sa_restorer = (act)->sa_restorer; \
>> + })
> What is so special about ARC sa_restorer that an application should provide
> an specialized one?
Its the other way around. Only if application provides it's own restorer, we honor
it, otherwise default restorer is used. This logic goes back many many years ago
to how ARC uClibc did this and likely inherited it from the port it was copied
from. But I don't know if say POSIX allows apps to provide their own restorer or
not. We could very well remove it; although per other discussion if we intend to
use the same struct sigaction for kernel/userland, the placeholder would exist and
we could choose to just ignore it.
> Can't it follow other abi where they issue __NR_sigreturn
> for !SA_SIGINFO or __NR_rt_sigreturn otherwise?
With Linux UAPI ABI, __NR_sigreturn doesn't exist, but your concern is about
restorer ?
> As for other architecture I do think we should hide the sa_restorer usage
> from application.
As mentioned above, the placeholder could exist, we can choose to ignore it.
On 12/20/18 4:07 AM, Arnd Bergmann wrote:
> All users of sigset_t that I could find in the kernel just check
> the size argument to ensure it matches _NSIG, and return
> EINVAL otherwise.
Indeed that was one of the very first problem ARC glibc port ran into with stock
sizeof(sigset_t) passed in sigaction syscall.
On 20/12/2018 17:23, Vineet Gupta wrote:
> On 12/20/18 3:19 AM, Adhemerval Zanella wrote:
>>>> #define SET_SA_RESTORER(kact, act) \
>>>> (kact)->sa_flags = (act)->sa_flags | SA_RESTORER; \
>>>> (kact)->sa_restorer = &__default_rt_sa_restorer
>>> +#define SET_SA_RESTORER(kact, act) \
>>> + ({ \
>>> + if (!((kact)->sa_flags & SA_RESTORER)) \
>>> + { \
>>> + (kact)->sa_restorer = __default_rt_sa_restorer; \
>>> + (kact)->sa_flags |= SA_RESTORER; \
>>> + } \
>>> + else \
>>> + (kact)->sa_restorer = (act)->sa_restorer; \
>>> + })
>> What is so special about ARC sa_restorer that an application should provide
>> an specialized one?
>
> Its the other way around. Only if application provides it's own restorer, we honor
> it, otherwise default restorer is used. This logic goes back many many years ago
> to how ARC uClibc did this and likely inherited it from the port it was copied
> from. But I don't know if say POSIX allows apps to provide their own restorer or
> not. We could very well remove it; although per other discussion if we intend to
> use the same struct sigaction for kernel/userland, the placeholder would exist and
> we could choose to just ignore it.
>
The 'should' should be indeed 'might' in my question. And SA_RESTORER is a Linux
specific ABI not intended to be used by applications, so my question is in fact
what kind of specialized sa_restorer applications might provided that would
require the libc to honour it.
The placeholder existence is not an issue itself (POSIX states the minimum
fields sigaction should provide, not its specific fields neither their
layout).
>
>> Can't it follow other abi where they issue __NR_sigreturn
>> for !SA_SIGINFO or __NR_rt_sigreturn otherwise?
>
> With Linux UAPI ABI, __NR_sigreturn doesn't exist, but your concern is about
> restorer ?
Right, so ARC at least is not pulling old compat stuff. Is it safe to just zero
the sa_restorer for sa_flags without SA_RESTORER?
>
>> As for other architecture I do think we should hide the sa_restorer usage
>> from application.
>
> As mentioned above, the placeholder could exist, we can choose to ignore it.
On 12/20/18 12:06 PM, Adhemerval Zanella wrote:
>
>
> On 20/12/2018 17:23, Vineet Gupta wrote:
>> On 12/20/18 3:19 AM, Adhemerval Zanella wrote:
>>>>> #define SET_SA_RESTORER(kact, act) \
>>>>> (kact)->sa_flags = (act)->sa_flags | SA_RESTORER; \
>>>>> (kact)->sa_restorer = &__default_rt_sa_restorer
>>>> +#define SET_SA_RESTORER(kact, act) \
>>>> + ({ \
>>>> + if (!((kact)->sa_flags & SA_RESTORER)) \
>>>> + { \
>>>> + (kact)->sa_restorer = __default_rt_sa_restorer; \
>>>> + (kact)->sa_flags |= SA_RESTORER; \
>>>> + } \
>>>> + else \
>>>> + (kact)->sa_restorer = (act)->sa_restorer; \
>>>> + })
>>> What is so special about ARC sa_restorer that an application should provide
>>> an specialized one?
>>
>> Its the other way around. Only if application provides it's own restorer, we honor
>> it, otherwise default restorer is used. This logic goes back many many years ago
>> to how ARC uClibc did this and likely inherited it from the port it was copied
>> from. But I don't know if say POSIX allows apps to provide their own restorer or
>> not. We could very well remove it; although per other discussion if we intend to
>> use the same struct sigaction for kernel/userland, the placeholder would exist and
>> we could choose to just ignore it.
>>
>
> The 'should' should be indeed 'might' in my question. And SA_RESTORER is a Linux
> specific ABI not intended to be used by applications,
What do u mean here. It is ABI between userspace and kernel, but not necessarily
between applications and glibc, although the same "carrier" sa_flags is in play ?
IOW, SA_RESTORER is not intended to be set by applications, but only by glibc ?
> so my question is in fact
> what kind of specialized sa_restorer applications might provided that would
> require the libc to honour it.
Indeed, applications should not be allowed to change it. The exact signature of
default sigreturn is hardwired in signal unwinding etc etc and any deviation from
that is recipe for issues: but like I mentioned I didn't invent that interface for
ARC.
> The placeholder existence is not an issue itself (POSIX states the minimum
> fields sigaction should provide, not its specific fields neither their
> layout).
OK !
>>> Can't it follow other abi where they issue __NR_sigreturn
>>> for !SA_SIGINFO or __NR_rt_sigreturn otherwise?
>>
>> With Linux UAPI ABI, __NR_sigreturn doesn't exist, but your concern is about
>> restorer ?
>
> Right, so ARC at least is not pulling old compat stuff. Is it safe to just zero
> the sa_restorer for sa_flags without SA_RESTORER?
Thing is ARC signal return depends on a restorer. Meaning !SA_RESTORER doesn't
effectively exist (between libc and kernel). We currently honor user provided
value, instead we could simply overwrite it with default_rt_restorer and on the
way out, zero it out to avoid leaking the glibc guts to curious users.
On 20/12/2018 18:46, Vineet Gupta wrote:
> On 12/20/18 12:06 PM, Adhemerval Zanella wrote:
>>
>>
>> On 20/12/2018 17:23, Vineet Gupta wrote:
>>> On 12/20/18 3:19 AM, Adhemerval Zanella wrote:
>>>>>> #define SET_SA_RESTORER(kact, act) \
>>>>>> (kact)->sa_flags = (act)->sa_flags | SA_RESTORER; \
>>>>>> (kact)->sa_restorer = &__default_rt_sa_restorer
>>>>> +#define SET_SA_RESTORER(kact, act) \
>>>>> + ({ \
>>>>> + if (!((kact)->sa_flags & SA_RESTORER)) \
>>>>> + { \
>>>>> + (kact)->sa_restorer = __default_rt_sa_restorer; \
>>>>> + (kact)->sa_flags |= SA_RESTORER; \
>>>>> + } \
>>>>> + else \
>>>>> + (kact)->sa_restorer = (act)->sa_restorer; \
>>>>> + })
>>>> What is so special about ARC sa_restorer that an application should provide
>>>> an specialized one?
>>>
>>> Its the other way around. Only if application provides it's own restorer, we honor
>>> it, otherwise default restorer is used. This logic goes back many many years ago
>>> to how ARC uClibc did this and likely inherited it from the port it was copied
>>> from. But I don't know if say POSIX allows apps to provide their own restorer or
>>> not. We could very well remove it; although per other discussion if we intend to
>>> use the same struct sigaction for kernel/userland, the placeholder would exist and
>>> we could choose to just ignore it.
>>>
>>
>> The 'should' should be indeed 'might' in my question. And SA_RESTORER is a Linux
>> specific ABI not intended to be used by applications,
>
> What do u mean here. It is ABI between userspace and kernel, but not necessarily
> between applications and glibc, although the same "carrier" sa_flags is in play ?
> IOW, SA_RESTORER is not intended to be set by applications, but only by glibc ?
AFAIK SA_RESTORER is meant to be used by libc or alike environments to setup
the required code to handle signal handling, it should not be up to programs
to mess up with sa_restorer to provide custom routines.
>
>> so my question is in fact
>> what kind of specialized sa_restorer applications might provided that would
>> require the libc to honour it.
>
> Indeed, applications should not be allowed to change it. The exact signature of
> default sigreturn is hardwired in signal unwinding etc etc and any deviation from
> that is recipe for issues: but like I mentioned I didn't invent that interface for
> ARC.
So my suggestion is not allow user code to mess with sa_restore regardless
if sa_flags contain SA_RESTORER. If kernel allows it to be zero in case of
!SA_RESTORER, set it to zero as other architectures. If it requires an
special routine, add an arch-specific one within glibc.
>
>> The placeholder existence is not an issue itself (POSIX states the minimum
>> fields sigaction should provide, not its specific fields neither their
>> layout).
>
> OK !
>
>>>> Can't it follow other abi where they issue __NR_sigreturn
>>>> for !SA_SIGINFO or __NR_rt_sigreturn otherwise?
>>>
>>> With Linux UAPI ABI, __NR_sigreturn doesn't exist, but your concern is about
>>> restorer ?
>>
>> Right, so ARC at least is not pulling old compat stuff. Is it safe to just zero
>> the sa_restorer for sa_flags without SA_RESTORER?
>
> Thing is ARC signal return depends on a restorer. Meaning !SA_RESTORER doesn't
> effectively exist (between libc and kernel). We currently honor user provided
> value, instead we could simply overwrite it with default_rt_restorer and on the
> way out, zero it out to avoid leaking the glibc guts to curious users.
>
Yes, this is what I suggest ARC should do.
* Vineet Gupta:
> On 12/20/18 4:40 AM, Florian Weimer wrote:
>> * Adhemerval Zanella:
>>
>>> The only advantage of using a larger sigset_t from glibc standpoint is if
>>> kernel ever change it maximum number of supported signals it would not be
>>> a ABI change (it would be if glibc provided sigset_t need to be extended).
>> It's not just the kernel. We might want to restore additional state in
>> sigsetjmp, and historically, the excess signal space in sigset_t has
>> provided a way to do that even if there is no other space left in the
>> jump buffer.
>
> And that additional state is architectural state (more FPU regs etc
> etc) or something libc generic. On both counts, that doesn't sound
> like a clean interface design !
Sure, setjmp/longjmp is quite horrible as an interface, considering that
register files do evolve. But it's what we have in C, and it's good to
have at least some extension space there (but it could be expressed in a
better way, definitely).
Thanks,
Florian
On 12/21/18 4:05 AM, Adhemerval Zanella wrote:
>> Thing is ARC signal return depends on a restorer. Meaning !SA_RESTORER doesn't
>> effectively exist (between libc and kernel). We currently honor user provided
>> value, instead we could simply overwrite it with default_rt_restorer and on the
>> way out, zero it out to avoid leaking the glibc guts to curious users.
>>
> Yes, this is what I suggest ARC should do.
So I was able to
(1) switch ARC to __sigset_t [2] vs. [128]
(2) create a generic patch to breakout struct sigaction into bits/sigaction-arch.h
(3) update generic __libc_sigaction to avoid itemized copy if sa_mask, sa_flags et
al offsets matched for struct kernel_signal and struct sigaction
(4) create arc/bits/sigaction-arch.h
However it turned out to be futile as the passthru won't work anyways :-(
@act in sigaction(sig, act, oact) is a const and can't be modified in place for
sticking in sa_restorer for kernel, thus needs to be copied over anyways.
This means we have [1] but have to drop [2-4]. Oh well !
@@ -44,6 +44,18 @@
* sysdeps/arc/nofpu/math-tests-exception.h: New file.
* sysdeps/arc/nofpu/math-tests-rounding.h: New file.
* sysdeps/arc/sfp-machine.h: New file.
+ * sysdeps/unix/sysv/linux/arc/cacheflush.c: New file.
+ * sysdeps/unix/sysv/linux/arc/clone.S: New file.
+ * sysdeps/unix/sysv/linux/arc/jmp_buf-macros.h: New file.
+ * sysdeps/unix/sysv/linux/arc/kernel-features.h: New file.
+ * sysdeps/unix/sysv/linux/arc/mmap_internal.h: New file.
+ * sysdeps/unix/sysv/linux/arc/profil-counter.h: New file.
+ * sysdeps/unix/sysv/linux/arc/pt-vfork.S: New file.
+ * sysdeps/unix/sysv/linux/arc/sigaction.c: New file.
+ * sysdeps/unix/sysv/linux/arc/syscall.S: New file.
+ * sysdeps/unix/sysv/linux/arc/sysdep.c: New file.
+ * sysdeps/unix/sysv/linux/arc/sysdep.h: New file.
+ * sysdeps/unix/sysv/linux/arc/vfork.S: New file.
2018-12-17 Joseph Myers <joseph@codesourcery.com>
new file mode 100644
@@ -0,0 +1,29 @@
+/* cacheflush system call for ARC Linux.
+ Copyright (C) 2017-2018 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
+ <http://www.gnu.org/licenses/>. */
+
+#include <sysdep.h>
+#include <stddef.h>
+#include <unistd.h>
+
+/* Flush cache(s). */
+int
+_flush_cache (char *addr, const int nbytes, const int op)
+{
+ return INLINE_SYSCALL (cacheflush, 3, addr, nbytes, op);
+}
+weak_alias (_flush_cache, cacheflush)
new file mode 100644
@@ -0,0 +1,100 @@
+/* clone() implementation for ARC.
+ Copyright (C) 2008-2018 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Andrew Jenner <andrew@codesourcery.com>, 2008.
+
+ 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
+ <http://www.gnu.org/licenses/>. */
+
+
+#include <sysdep.h>
+#define _ERRNO_H 1
+#include <bits/errno.h>
+#include <tcb-offsets.h>
+
+#define CLONE_SETTLS 0x00080000
+
+; int clone(int (*fn)(void *), void *child_stack,
+; int flags, void *arg, ...
+; /* pid_t *ptid, struct user_desc *tls, pid_t *ctid */);
+;
+; NOTE: I'm assuming that the last 3 args are NOT var-args and in case all
+; 3 are not relevant, caller will nevertheless pass those as NULL.
+; Current (Jul 2012) upstream powerpc/clone.S assumes similarly.
+; Our LTP (from 2007) doesn't seem to have tests to prove otherwise
+
+; clone syscall in kernel (ABI: CONFIG_CLONE_BACKWARDS)
+;
+; int sys_clone(unsigned long clone_flags,
+; unsigned long newsp,
+; int __user *parent_tidptr,
+; void *tls,
+; int __user *child_tidptr)
+
+ENTRY(__clone)
+ cmp r0, 0 ; @fn can't be NULL
+ cmp.ne r1, 0 ; @child_stack can't be NULL
+ bz .L__sys_err
+
+ ; save some of the orig args
+ ; r0 containg @fn will be clobbered AFTER syscall (with ret val)
+ ; rest are clobbered BEFORE syscall due to different arg ordering
+ mov r10, r0 ; @fn
+ mov r11, r3 ; @args
+ mov r12, r2 ; @clone_flags
+ mov r9, r5 ; @tls
+
+ ; adjust libc args for syscall
+
+ mov r0, r2 ; libc @flags is 1st syscall arg
+ mov r2, r4 ; libc @ptid
+ mov r3, r5 ; libc @tls
+ mov r4, r6 ; libc @ctid
+ mov r8, __NR_clone
+ ARC_TRAP_INSN
+
+ cmp r0, 0 ; return code : 0 new process, !0 parent
+ blt .L__sys_err2 ; < 0 (signed) error
+ jnz [blink] ; Parent returns
+
+ ; ----- child starts here ---------
+
+ ; Setup TP register (only recent kernels v4.19+ do that)
+ and.f 0, r12, CLONE_SETTLS
+ mov.nz r25, r9
+
+ ; child jumps off to @fn with @arg as argument, and returns here
+ jl.d [r10]
+ mov r0, r11
+
+ ; exit() with result from @fn (already in r0)
+ mov r8, __NR_exit
+ ARC_TRAP_INSN
+ ; In case it ever came back
+ flag 1
+
+.L__sys_err:
+ mov r0, -EINVAL
+.L__sys_err2:
+ ; (1) No need to make -ve kernel error code as positive errno
+ ; __syscall_error expects the -ve error code returned by kernel
+ ; (2) r0 still had orig -ve kernel error code
+ ; (3) Tail call to __syscall_error so we dont have to come back
+ ; here hence instead of jmp-n-link (reg push/pop) we do jmp
+ ; (4) No need to route __syscall_error via PLT, B is inherently
+ ; position independent
+ b __syscall_error
+PSEUDO_END (__clone)
+libc_hidden_def (__clone)
+weak_alias (__clone, clone)
new file mode 100644
@@ -0,0 +1,6 @@
+#define JMP_BUF_SIZE (32 + 1 + 1024/32) * 4
+#define SIGJMP_BUF_SIZE (32 + 1 + 1024/32) * 4
+#define JMP_BUF_ALIGN 4
+#define SIGJMP_BUF_ALIGN 4
+#define MASK_WAS_SAVED_OFFSET 32 * 4
+#define SAVED_MASK_OFFSET 33 * 4
new file mode 100644
@@ -0,0 +1,28 @@
+/* Set flags signalling availability of kernel features based on given
+ kernel version number.
+
+ Copyright (C) 2009-2018 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
+ <http://www.gnu.org/licenses/>. */
+
+/* The minimum supported kernel version for ARC is 3.9,
+ guaranteeing many kernel features. */
+
+#include_next <kernel-features.h>
+
+#undef __ASSUME_CLONE_DEFAULT
+#define __ASSUME_CLONE_BACKWARDS 1
new file mode 100644
@@ -0,0 +1,26 @@
+/* mmap - map files or devices into memory. Linux/ARC version.
+ Copyright (C) 2017-2018 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
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef MMAP_ARC_INTERNAL_H
+#define MMAP_ARC_INTERNAL_H
+
+#define MMAP2_PAGE_UNIT 8192ULL /* 8K page is default for ARC */
+
+#include_next <mmap_internal.h>
+
+#endif
new file mode 100644
@@ -0,0 +1,2 @@
+/* We can use the ix86 version. */
+#include <sysdeps/unix/sysv/linux/i386/profil-counter.h>
new file mode 100644
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/alpha/pt-vfork.S>
new file mode 100644
@@ -0,0 +1,69 @@
+/* ARC specific sigaction and signal restorer
+ Copyright (C) 1997-2018 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
+ <http://www.gnu.org/licenses/>. */
+
+#include <sysdep.h>
+#include <errno.h>
+#include <signal.h>
+#include <string.h>
+#include <sys/syscall.h>
+
+/*
+ * Default sigretrun stub if user doesn't specify SA_RESTORER
+ */
+static void __default_rt_sa_restorer(void)
+{
+ INTERNAL_SYSCALL_NCS(__NR_rt_sigreturn, , 0);
+}
+
+#define SA_RESTORER 0x04000000
+
+/* If @act is not NULL, change the action for @sig to @act.
+ If @oact is not NULL, put the old action for @sig in @oact. */
+int
+__libc_sigaction (int sig, const struct sigaction *act, struct sigaction *oact)
+{
+ struct sigaction kact;
+ const struct sigaction *arg;
+
+ /*
+ * SA_RESTORER is only relevant for act != NULL case
+ * (!act means caller only wants to know @oact)
+ */
+ if (act && !(act->sa_flags & SA_RESTORER)) {
+ kact.sa_restorer = __default_rt_sa_restorer;
+ kact.sa_flags = act->sa_flags | SA_RESTORER;
+
+ kact.sa_handler = act->sa_handler;
+ kact.sa_mask = act->sa_mask;
+
+ arg = &kact;
+ } else {
+ arg = act;
+ }
+
+ /*
+ * syscall also expects sizeof(sa_mask) and asm-generic kernel syscall
+ * ABI mandates it be 2 words (8 bytes below) although glibc defines
+ * sigset_to be much larger (1024 / 32 == 64 bytes)
+ */
+ return INLINE_SYSCALL(rt_sigaction, 4, sig, arg, oact, _NSIG / 8);
+}
+
+libc_hidden_def (__libc_sigaction)
+
+#include <nptl/sigaction.c>
new file mode 100644
@@ -0,0 +1,38 @@
+/* syscall - indirect system call.
+ Copyright (C) 2017-2018 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
+ <http://www.gnu.org/licenses/>. */
+
+#include <sysdep.h>
+
+ENTRY (syscall)
+ mov_s r8, r0
+ mov_s r0, r1
+ mov_s r1, r2
+ mov_s r2, r3
+ mov_s r3, r4
+#ifdef __ARC700__
+ mov r4, r5
+ mov r5, r6
+#else
+ mov_s r4, r5
+ mov_s r5, r6
+#endif
+
+ ARC_TRAP_INSN
+ brhi r0, -1024, .Lcall_syscall_err
+ j [blink]
+PSEUDO_END (syscall)
new file mode 100644
@@ -0,0 +1,33 @@
+/* ARC wrapper for setting errno
+ Copyright (C) 1997-2018 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
+ <http://www.gnu.org/licenses/>. */
+
+#include <sysdep.h>
+#include <errno.h>
+
+/* All syscall handler come here to avoid generated code bloat due to
+ * GOT reference to errno_location or it's equivalent
+ */
+int __syscall_error(int err_no)
+{
+ __set_errno(-err_no);
+ return -1;
+}
+
+#if IS_IN (libc)
+hidden_def (__syscall_error)
+#endif
new file mode 100644
@@ -0,0 +1,259 @@
+/* Assembler macros for ARC.
+ Copyright (C) 2000-2018 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
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef _LINUX_ARC_SYSDEP_H
+#define _LINUX_ARC_SYSDEP_H 1
+
+#include <asm/unistd.h>
+#include <sysdeps/arc/sysdep.h>
+#include <sysdeps/unix/sysv/linux/generic/sysdep.h>
+
+/* For RTLD_PRIVATE_ERRNO. */
+#include <dl-sysdep.h>
+
+#include <tls.h>
+
+#undef SYS_ify
+#define SYS_ify(syscall_name) __NR_##syscall_name
+
+#ifdef __ASSEMBLER__
+
+/* This is a "normal" system call stub: if there is an error,
+ it returns -1 and sets errno. */
+
+# undef PSEUDO
+# define PSEUDO(name, syscall_name, args) \
+ PSEUDO_NOERRNO(name, syscall_name, args) ASM_LINE_SEP \
+ brhi r0, -1024, .Lcall_syscall_err ASM_LINE_SEP
+
+#define ret j [blink]
+
+# undef PSEUDO_END
+# define PSEUDO_END(name) \
+ SYSCALL_ERROR_HANDLER ASM_LINE_SEP \
+ END (name)
+
+/* --------- helper for SYSCALL_NOERRNO ----------- */
+
+/* This kind of system call stub never returns an error.
+ We return the return value register to the caller unexamined. */
+
+# undef PSEUDO_NOERRNO
+# define PSEUDO_NOERRNO(name, syscall_name, args) \
+ .text ASM_LINE_SEP \
+ ENTRY (name) ASM_LINE_SEP \
+ DO_CALL (syscall_name, args) ASM_LINE_SEP \
+
+/* return the return value register unexamined
+ * r0 is both syscall return reg and function return reg, so no need to do
+ * anything
+ */
+# define ret_NOERRNO \
+ j_s [blink] ASM_LINE_SEP
+
+# undef PSEUDO_END_NOERRNO
+# define PSEUDO_END_NOERRNO(name) \
+ END (name)
+
+/* --------- helper for SYSCALL_ERRVAL ----------- */
+
+/* This kind of system call stub returns the errno code as its return
+ value, or zero for success. We may massage the kernel's return value
+ to meet that ABI, but we never set errno here. */
+
+# undef PSEUDO_ERRVAL
+# define PSEUDO_ERRVAL(name, syscall_name, args) \
+ PSEUDO_NOERRNO(name, syscall_name, args) ASM_LINE_SEP
+
+/* don't set errno, return kernel error (in errno form) or zero */
+# define ret_ERRVAL \
+ rsub r0, r0, 0 ASM_LINE_SEP \
+ ret_NOERRNO
+
+# undef PSEUDO_END_ERRVAL
+# define PSEUDO_END_ERRVAL(name) \
+ END (name)
+
+
+/* To reduce the code footprint, we confine the actual errno access
+ * to single place in __syscall_error()
+ * this takes raw kernel error value, sets errno and returns -1
+ */
+#if IS_IN (libc)
+#define CALL_ERRNO_SETTER_C bl PLTJMP(HIDDEN_JUMPTARGET(__syscall_error))
+#else
+#define CALL_ERRNO_SETTER_C bl PLTJMP(__syscall_error)
+#endif
+
+# define SYSCALL_ERROR_HANDLER \
+.Lcall_syscall_err: ASM_LINE_SEP \
+ st.a blink, [sp, -4] ASM_LINE_SEP \
+ cfi_adjust_cfa_offset (4) ASM_LINE_SEP \
+ cfi_rel_offset (blink, 0) ASM_LINE_SEP \
+ CALL_ERRNO_SETTER_C ASM_LINE_SEP \
+ ld.ab blink, [sp, 4] ASM_LINE_SEP \
+ cfi_adjust_cfa_offset (-4) ASM_LINE_SEP \
+ cfi_restore (blink) ASM_LINE_SEP \
+ j [blink]
+
+# define DO_CALL(syscall_name, args) \
+ mov r8, SYS_ify (syscall_name) ASM_LINE_SEP \
+ ARC_TRAP_INSN ASM_LINE_SEP
+
+#define ARC_TRAP_INSN trap_s 0
+
+#else /* !__ASSEMBLER__ */
+
+# define SINGLE_THREAD_BY_GLOBAL 1
+
+/* In order to get __set_errno() definition in INLINE_SYSCALL. */
+#include <errno.h>
+
+extern int __syscall_error (int);
+
+#if IS_IN (libc)
+hidden_proto (__syscall_error)
+#define CALL_ERRNO_SETTER "bl __syscall_error \n\t"
+#else
+#define CALL_ERRNO_SETTER "bl __syscall_error@plt \n\t"
+#endif
+
+
+/* Define a macro which expands into the inline wrapper code for a system
+ call. */
+#undef INLINE_SYSCALL
+#define INLINE_SYSCALL(name, nr_args, args...) \
+({ \
+ register int __res __asm__("r0"); \
+ __res = INTERNAL_SYSCALL_NCS(__NR_##name, , nr_args, args); \
+ if (__builtin_expect (INTERNAL_SYSCALL_ERROR_P ((__res), ), 0)) \
+ { \
+ asm volatile ("st.a blink, [sp, -4] \n\t" \
+ CALL_ERRNO_SETTER \
+ "ld.ab blink, [sp, 4] \n\t" \
+ :"+r" (__res) \
+ : \
+ :"r1","r2","r3","r4","r5","r6", \
+ "r7","r8","r9","r10","r11","r12"); \
+ } \
+ __res; \
+})
+
+#undef INTERNAL_SYSCALL_DECL
+#define INTERNAL_SYSCALL_DECL(err) do { } while (0)
+
+#undef INTERNAL_SYSCALL_ERRNO
+# define INTERNAL_SYSCALL_ERRNO(val, err) (-(val))
+
+/* -1 to -1023 are valid errno values */
+#undef INTERNAL_SYSCALL_ERROR_P
+#define INTERNAL_SYSCALL_ERROR_P(val, err) \
+ ((unsigned int) (val) > -1024U)
+
+#define ARC_TRAP_INSN "trap_s 0 \n\t"
+
+#undef INTERNAL_SYSCALL_RAW
+#define INTERNAL_SYSCALL_RAW(name, err, nr_args, args...) \
+({ \
+ /* Per ABI, r0 is 1st arg and return reg */ \
+ register int __ret __asm__("r0"); \
+ register int _sys_num __asm__("r8"); \
+ \
+ LOAD_ARGS_##nr_args (name, args) \
+ \
+ __asm__ volatile ( \
+ ARC_TRAP_INSN \
+ : "+r" (__ret) \
+ : "r"(_sys_num) ASM_ARGS_##nr_args \
+ : "memory"); \
+ \
+ __ret; \
+})
+
+/* Macros for setting up inline __asm__ input regs */
+#define ASM_ARGS_0
+#define ASM_ARGS_1 ASM_ARGS_0, "r" (__ret)
+#define ASM_ARGS_2 ASM_ARGS_1, "r" (_arg2)
+#define ASM_ARGS_3 ASM_ARGS_2, "r" (_arg3)
+#define ASM_ARGS_4 ASM_ARGS_3, "r" (_arg4)
+#define ASM_ARGS_5 ASM_ARGS_4, "r" (_arg5)
+#define ASM_ARGS_6 ASM_ARGS_5, "r" (_arg6)
+#define ASM_ARGS_7 ASM_ARGS_6, "r" (_arg7)
+
+/* Macros for converting sys-call wrapper args into sys call args */
+#define LOAD_ARGS_0(nm, arg) \
+ _sys_num = (int) (nm);
+
+#define LOAD_ARGS_1(nm, arg1) \
+ __ret = (int) (arg1); \
+ LOAD_ARGS_0 (nm, arg1)
+
+/*
+ * Note that the use of _tmpX might look superflous, however it is needed
+ * to ensure that register variables are not clobbered if arg happens to be
+ * a function call itself. e.g. sched_setaffinity() calling getpid() for arg2
+ *
+ * Also this specific order of recursive calling is important to segregate
+ * the tmp args evaluation (function call case described above) and assigment
+ * of register variables
+ */
+#define LOAD_ARGS_2(nm, arg1, arg2) \
+ int _tmp2 = (int) (arg2); \
+ LOAD_ARGS_1 (nm, arg1) \
+ register int _arg2 __asm__ ("r1") = _tmp2;
+
+#define LOAD_ARGS_3(nm, arg1, arg2, arg3) \
+ int _tmp3 = (int) (arg3); \
+ LOAD_ARGS_2 (nm, arg1, arg2) \
+ register int _arg3 __asm__ ("r2") = _tmp3;
+
+#define LOAD_ARGS_4(nm, arg1, arg2, arg3, arg4) \
+ int _tmp4 = (int) (arg4); \
+ LOAD_ARGS_3 (nm, arg1, arg2, arg3) \
+ register int _arg4 __asm__ ("r3") = _tmp4;
+
+#define LOAD_ARGS_5(nm, arg1, arg2, arg3, arg4, arg5) \
+ int _tmp5 = (int) (arg5); \
+ LOAD_ARGS_4 (nm, arg1, arg2, arg3, arg4) \
+ register int _arg5 __asm__ ("r4") = _tmp5;
+
+#define LOAD_ARGS_6(nm, arg1, arg2, arg3, arg4, arg5, arg6) \
+ int _tmp6 = (int) (arg6); \
+ LOAD_ARGS_5 (nm, arg1, arg2, arg3, arg4, arg5) \
+ register int _arg6 __asm__ ("r5") = _tmp6;
+
+#define LOAD_ARGS_7(nm, arg1, arg2, arg3, arg4, arg5, arg6, arg7)\
+ int _tmp7 = (int) (arg7); \
+ LOAD_ARGS_6 (nm, arg1, arg2, arg3, arg4, arg5, arg6) \
+ register int _arg7 __asm__ ("r6") = _tmp7;
+
+#undef INTERNAL_SYSCALL
+#define INTERNAL_SYSCALL(name, err, nr, args...) \
+ INTERNAL_SYSCALL_RAW(SYS_ify(name), err, nr, args)
+
+#undef INTERNAL_SYSCALL_NCS
+#define INTERNAL_SYSCALL_NCS(number, err, nr, args...) \
+ INTERNAL_SYSCALL_RAW(number, err, nr, args)
+
+/* Pointer mangling not yet supported */
+# define PTR_MANGLE(var) (void) (var)
+# define PTR_DEMANGLE(var) (void) (var)
+
+#endif /* !__ASSEMBLER__ */
+
+#endif /* linux/arc/sysdep.h */
new file mode 100644
@@ -0,0 +1,42 @@
+/* vfork for ARC Linux.
+ Copyright (C) 2005-2018 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
+ <http://www.gnu.org/licenses/>. */
+
+#include <sys/syscall.h>
+#include <sysdep.h>
+#include <tcb-offsets.h>
+#define _SIGNAL_H
+#include <bits/signum.h> /* For SIGCHLD */
+
+#define CLONE_VM 0x00000100
+#define CLONE_VFORK 0x00004000
+#define CLONE_FLAGS_FOR_VFORK (CLONE_VM|CLONE_VFORK|SIGCHLD)
+
+ENTRY(__vfork)
+ mov r0, CLONE_FLAGS_FOR_VFORK
+ mov_s r1, sp
+ mov r8, __NR_clone
+ ARC_TRAP_INSN
+
+ cmp r0, 0
+ jge [blink] ; child continues
+
+ b __syscall_error
+PSEUDO_END (__vfork)
+libc_hidden_def (__vfork)
+
+weak_alias (__vfork, vfork)