From patchwork Wed Jan 30 01:25:47 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vineet Gupta X-Patchwork-Id: 1033150 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=sourceware.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=libc-alpha-return-99602-incoming=patchwork.ozlabs.org@sourceware.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=synopsys.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; secure) header.d=sourceware.org header.i=@sourceware.org header.b="maGDJ5p3"; dkim=pass (2048-bit key; unprotected) header.d=synopsys.com header.i=@synopsys.com header.b="mSuTm/Gp"; dkim-atps=neutral Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 43q5Md2K0jz9sBQ for ; Wed, 30 Jan 2019 12:27:41 +1100 (AEDT) DomainKey-Signature: a=rsa-sha1; c=nofws; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-type; q=dns; s=default; b=RZV2W FTOzm/k+J9xklwLhSZgaR1nA6bT3whdD+YnjmIZsWl6P2b+ERS+oUKHGrROszgTy hcYp8HDguTyX6hvUTh/1j3aeJbMHK7gguGUgFYVQvyYMHwY3YzlBQfkq13Bbywnh oLrcOWeczK6OXlQP83/z+7c95Fe5C/WzfpckvU= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-type; s=default; bh=5B9HhVpQC8I F3eu1I5LsPcwplMU=; b=maGDJ5p3tFN3bhTXfUMvY/4u5Eepr2VI37uFbtebYOg lrB+gcj9aGvthI+9qcHWtKGl+UEYawmrVWfWSS43S8ssP7yYionzEhhtNb957OJZ FjvTwrrJkYmm6/0XzJyP7+m7RWiVKbNWGhKLKeBeqiFjU5VnnqJURyklmH9+WnhQ = Received: (qmail 3778 invoked by alias); 30 Jan 2019 01:27:29 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 3664 invoked by uid 89); 30 Jan 2019 01:27:29 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-26.9 required=5.0 tests=BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_SHORT, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.2 spammy=UD:nz, massage X-HELO: smtprelay.synopsys.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=synopsys.com; s=mail; t=1548811642; bh=1hz06hYh13Qyj0JxLk6Qu6NRMM6rLZr8fHhWGmic5zs=; h=From:To:CC:Subject:Date:In-Reply-To:References:From; b=mSuTm/Gp9FwL22BSm956xqDc0GenpO6KF7/o+K74beMnOdUzJNPz9PcGkoiKDKPY1 hxtXtqX+vDyAM6lF2qqG+cDaUfSf47G7HIdeBqkbrOjsniAu3Vdhhza842M6KwHAYy p8NlND2yFKiq3/hbckNTQVHJ6SEszfW8QdJBp/lQFCmCJnlbALbpy8FQg5LzNl0yHY N08go17o7IH8utkcxtEHLrEaY49qP6uZnq6srsaWfr73j2/ecGJuTTvisqeUdGQ3G3 IrXkjJ7zwGgrrX0s+AUeHuWn8dbigSNU+9BELTSZF1gHUZl2ZOaPlXsf/ulZifeB45 LfkjT36K24LqQ== From: Vineet Gupta To: CC: , Vineet Gupta Subject: [PATCH v2 07/15] ARC: Linux Syscall Interface Date: Tue, 29 Jan 2019 17:25:47 -0800 Message-ID: <1548811555-24373-8-git-send-email-vgupta@synopsys.com> In-Reply-To: <1548811555-24373-1-git-send-email-vgupta@synopsys.com> References: <1548811555-24373-1-git-send-email-vgupta@synopsys.com> MIME-Version: 1.0 Signed-off-by: Vineet Gupta --- ChangeLog | 13 ++ sysdeps/unix/sysv/linux/arc/clone.S | 98 ++++++++++ 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 | 27 +++ 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 | 31 ++++ sysdeps/unix/sysv/linux/arc/sigrestorer.S | 29 +++ sysdeps/unix/sysv/linux/arc/syscall.S | 38 ++++ sysdeps/unix/sysv/linux/arc/syscalls.list | 3 + sysdeps/unix/sysv/linux/arc/sysdep.c | 33 ++++ sysdeps/unix/sysv/linux/arc/sysdep.h | 251 ++++++++++++++++++++++++++ sysdeps/unix/sysv/linux/arc/vfork.S | 42 +++++ 14 files changed, 602 insertions(+) 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/sigrestorer.S create mode 100644 sysdeps/unix/sysv/linux/arc/syscall.S create mode 100644 sysdeps/unix/sysv/linux/arc/syscalls.list 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 diff --git a/ChangeLog b/ChangeLog index 1cf28bbbf96f..b5da8c28e64c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -39,6 +39,19 @@ * sysdeps/arc/nofpu/math-tests-exceptions.h: New file. * sysdeps/arc/nofpu/math-tests-rounding.h: New file. * sysdeps/arc/sfp-machine.h: 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/sigrestorer.S: New file. + * sysdeps/unix/sysv/linux/arc/syscall.S: New file. + * sysdeps/unix/sysv/linux/arc/syscalls.list: 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. 2019-01-25 Siddhesh Poyarekar diff --git a/sysdeps/unix/sysv/linux/arc/clone.S b/sysdeps/unix/sysv/linux/arc/clone.S new file mode 100644 index 000000000000..55c2a2b60ed8 --- /dev/null +++ b/sysdeps/unix/sysv/linux/arc/clone.S @@ -0,0 +1,98 @@ +/* clone() implementation for ARC. + Copyright (C) 2008-2019 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Andrew Jenner , 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 + . */ + + +#include +#define _ERRNO_H 1 +#include +#include + +#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. + + clone syscall in kernel (ABI: CONFIG_CLONE_BACKWARDS) + + int sys_clone(unsigned long int clone_flags, + unsigned long int 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) diff --git a/sysdeps/unix/sysv/linux/arc/jmp_buf-macros.h b/sysdeps/unix/sysv/linux/arc/jmp_buf-macros.h new file mode 100644 index 000000000000..6c129398483a --- /dev/null +++ b/sysdeps/unix/sysv/linux/arc/jmp_buf-macros.h @@ -0,0 +1,6 @@ +#define JMP_BUF_SIZE (32 + 1 + 64/(8 * sizeof (unsigned long int))) * sizeof (unsigned long int) +#define SIGJMP_BUF_SIZE (32 + 1 + 64/(8 * sizeof (unsigned long int))) * sizeof (unsigned long int) +#define JMP_BUF_ALIGN __alignof__ (unsigned long int) +#define SIGJMP_BUF_ALIGN __alignof__ (unsigned long int) +#define MASK_WAS_SAVED_OFFSET (32 * sizeof (unsigned long int)) +#define SAVED_MASK_OFFSET (33 * sizeof (unsigned long int)) diff --git a/sysdeps/unix/sysv/linux/arc/kernel-features.h b/sysdeps/unix/sysv/linux/arc/kernel-features.h new file mode 100644 index 000000000000..00255337bc8c --- /dev/null +++ b/sysdeps/unix/sysv/linux/arc/kernel-features.h @@ -0,0 +1,28 @@ +/* Set flags signalling availability of kernel features based on given + kernel version number. + + Copyright (C) 2009-2019 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 + . */ + +/* The minimum supported kernel version for ARC is 3.9, + guaranteeing many kernel features. */ + +#include_next + +#undef __ASSUME_CLONE_DEFAULT +#define __ASSUME_CLONE_BACKWARDS 1 diff --git a/sysdeps/unix/sysv/linux/arc/mmap_internal.h b/sysdeps/unix/sysv/linux/arc/mmap_internal.h new file mode 100644 index 000000000000..3f28f352d91d --- /dev/null +++ b/sysdeps/unix/sysv/linux/arc/mmap_internal.h @@ -0,0 +1,27 @@ +/* mmap - map files or devices into memory. Linux/ARC version. + Copyright (C) 2017-2019 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 + . */ + +#ifndef MMAP_ARC_INTERNAL_H +#define MMAP_ARC_INTERNAL_H + +/* 8K page is default for ARC. */ +#define MMAP2_PAGE_UNIT 8192ULL + +#include_next + +#endif diff --git a/sysdeps/unix/sysv/linux/arc/profil-counter.h b/sysdeps/unix/sysv/linux/arc/profil-counter.h new file mode 100644 index 000000000000..8a6a0bcf3d59 --- /dev/null +++ b/sysdeps/unix/sysv/linux/arc/profil-counter.h @@ -0,0 +1,2 @@ +/* We can use the ix86 version. */ +#include 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..1cc893170070 --- /dev/null +++ b/sysdeps/unix/sysv/linux/arc/pt-vfork.S @@ -0,0 +1 @@ +/* Not needed. */ diff --git a/sysdeps/unix/sysv/linux/arc/sigaction.c b/sysdeps/unix/sysv/linux/arc/sigaction.c new file mode 100644 index 000000000000..db7293865f3a --- /dev/null +++ b/sysdeps/unix/sysv/linux/arc/sigaction.c @@ -0,0 +1,31 @@ +/* ARC specific sigaction. + Copyright (C) 1997-2019 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 + . */ + +#define SA_RESTORER 0x04000000 + +extern void __default_rt_sa_restorer (void); + +#define SET_SA_RESTORER(kact, act) \ + ({ \ + (kact)->sa_restorer = __default_rt_sa_restorer; \ + (kact)->sa_flags |= SA_RESTORER; \ + }) + +#define RESET_SA_RESTORER(act, kact) + +#include diff --git a/sysdeps/unix/sysv/linux/arc/sigrestorer.S b/sysdeps/unix/sysv/linux/arc/sigrestorer.S new file mode 100644 index 000000000000..573b54e36cfb --- /dev/null +++ b/sysdeps/unix/sysv/linux/arc/sigrestorer.S @@ -0,0 +1,29 @@ +/* Default sigreturn stub for ARC Linux. + Copyright (C) 2005-2019 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 + +/* Note the NOP has to be outside body. */ + nop +ENTRY (__default_rt_sa_restorer) + mov r8, __NR_rt_sigreturn + ARC_TRAP_INSN + j_s [blink] +PSEUDO_END_NOERRNO (__default_rt_sa_restorer) diff --git a/sysdeps/unix/sysv/linux/arc/syscall.S b/sysdeps/unix/sysv/linux/arc/syscall.S new file mode 100644 index 000000000000..3fe5fcdd0413 --- /dev/null +++ b/sysdeps/unix/sysv/linux/arc/syscall.S @@ -0,0 +1,38 @@ +/* syscall - indirect system call. + Copyright (C) 2017-2019 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 + +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) diff --git a/sysdeps/unix/sysv/linux/arc/syscalls.list b/sysdeps/unix/sysv/linux/arc/syscalls.list new file mode 100644 index 000000000000..d0ef5977ee06 --- /dev/null +++ b/sysdeps/unix/sysv/linux/arc/syscalls.list @@ -0,0 +1,3 @@ +# File name Caller Syscall name Args Strong name Weak names + +cacheflush - cacheflush i:pii _flush_cache cacheflush diff --git a/sysdeps/unix/sysv/linux/arc/sysdep.c b/sysdeps/unix/sysv/linux/arc/sysdep.c new file mode 100644 index 000000000000..5618f3785159 --- /dev/null +++ b/sysdeps/unix/sysv/linux/arc/sysdep.c @@ -0,0 +1,33 @@ +/* ARC wrapper for setting errno. + Copyright (C) 1997-2019 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 + +/* 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 diff --git a/sysdeps/unix/sysv/linux/arc/sysdep.h b/sysdeps/unix/sysv/linux/arc/sysdep.h new file mode 100644 index 000000000000..9ad95d97ae10 --- /dev/null +++ b/sysdeps/unix/sysv/linux/arc/sysdep.h @@ -0,0 +1,251 @@ +/* Assembler macros for ARC. + Copyright (C) 2000-2019 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 + . */ + +#ifndef _LINUX_ARC_SYSDEP_H +#define _LINUX_ARC_SYSDEP_H 1 + +#include +#include +#include + +/* For RTLD_PRIVATE_ERRNO. */ +#include + +#include + +#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. Since r0 is both + syscall return reg and function return reg, no work needed. */ +# 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 + +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 */ diff --git a/sysdeps/unix/sysv/linux/arc/vfork.S b/sysdeps/unix/sysv/linux/arc/vfork.S new file mode 100644 index 000000000000..7f981d0681c8 --- /dev/null +++ b/sysdeps/unix/sysv/linux/arc/vfork.S @@ -0,0 +1,42 @@ +/* vfork for ARC Linux. + Copyright (C) 2005-2019 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 +#define _SIGNAL_H +#include /* 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)