From patchwork Sat Oct 19 20:49:42 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Carlos Santos X-Patchwork-Id: 1179897 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=uclibc-ng.org (client-ip=89.238.66.15; helo=helium.openadk.org; envelope-from=devel-bounces@uclibc-ng.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="kvN2oJ8K"; dkim-atps=neutral Received: from helium.openadk.org (helium.openadk.org [89.238.66.15]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 46wZls0hRSz9sPT for ; Sun, 20 Oct 2019 07:49:58 +1100 (AEDT) Received: from helium.openadk.org (localhost [IPv6:::1]) by helium.openadk.org (Postfix) with ESMTP id 8502C1017C; Sat, 19 Oct 2019 22:49:51 +0200 (CEST) X-Original-To: devel@uclibc-ng.org Delivered-To: devel@helium.openadk.org Received: from mail-qt1-f194.google.com (mail-qt1-f194.google.com [209.85.160.194]) by helium.openadk.org (Postfix) with ESMTPS id 455B41017C for ; Sat, 19 Oct 2019 22:49:49 +0200 (CEST) Received: by mail-qt1-f194.google.com with SMTP id g50so309952qtb.4 for ; Sat, 19 Oct 2019 13:49:51 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id; bh=mgVmTj9qO8v4moABArAv9b8mRz0JihPbkxjj4thQcug=; b=kvN2oJ8KVGiPs3kdJh1Re7z8r8k1EULOxdxcmdOQai2i8euzYYtCLx0ns5XAGkppwQ wtaZyb7U5dNAy1Y8R/mTEFcBZ8CW3CYwosWlMoD8/buZaV845hjFL1HU/Z8z/xlmIL9e PFQWG1txSJGxkkjdRCN4zZTirR4kWOkd2rAHxsd+o2rTa+WO3mCDxihl976B+K2uXb0b NV7qq2vUKdjDvVUZnMg3vo34nYYsCND1t9Ss005QtLSE1/XRy+o9RqDQZMW7J/RSY7Nh 4ra+XxavvDujeK4qdLWK07oyx0M0Mx/r/VCunR9UzYXrvkRmXzHeJnMMJ1LW4riJTnCd ZF+g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=mgVmTj9qO8v4moABArAv9b8mRz0JihPbkxjj4thQcug=; b=hyJ16jc7KDTkY2FdFTuv74KGi4MKmi/DRV1AAeOdZCwYs0MdhkZcUdKdblAI7/QSSm VmdYWv9EzW6anHI9MCJKP1CYgzmype7rR/q2/FQ0d0M64hGEt+wshMg1XC6GcL6l94Nk OizBQqPm5gzrX8dig9/hhXbUqfYBUD5nOHvOv6Rb5ElERsl5aLW+DU58uTJ0GVdZFvEK A2nXysW4VCaWl53YARuwHxZf0qm/NF0k2yvXRzr25O35ubz4elCkq7z35r7UoDwAvol2 nyALBeMiEeTyN97Mi3TvZgU+41hK3BRCyTWk9J/iQo49sp8YHeH7tpON0oExUsna2xzK pxCg== X-Gm-Message-State: APjAAAUEqe0BhZslBwHzEUrFMLK56v0FIgHQc+IowzBB60i0I1WVmL3X 3XL8OrPMTpQFGGkHUVSBn95MUVRB X-Google-Smtp-Source: APXvYqy5xeg6dTORzeXy7jsBW7LGOF8BMbCj4GUMqffAMwFo8sEAC+ZC6pru+o/oqyJm/GT9J0HR6g== X-Received: by 2002:ac8:862:: with SMTP id x31mr16853917qth.58.1571518188763; Sat, 19 Oct 2019 13:49:48 -0700 (PDT) Received: from casantos.casantos.org ([179.176.188.90]) by smtp.gmail.com with ESMTPSA id y29sm2892313qtc.8.2019.10.19.13.49.46 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 19 Oct 2019 13:49:48 -0700 (PDT) From: unixmania@gmail.com To: devel@uclibc-ng.org Date: Sat, 19 Oct 2019 17:49:42 -0300 Message-Id: <20191019204942.2736-1-unixmania@gmail.com> X-Mailer: git-send-email 2.18.1 Subject: [uclibc-ng-devel] [PATCH RFC] Make __syscall_error return long, as expected by syscall() callers X-BeenThere: devel@uclibc-ng.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: uClibc-ng Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: devel-bounces@uclibc-ng.org Sender: "devel" From: Carlos Santos The return type of syscall() is long so __syscall_error, which is jumped to by syscall handlers to stash an error number into errno, must return long too otherwhise it returs 4294967295L instead of -1L. For example, syscall for x86_64 is defined in libc/sysdeps/linux/x86_64/syscall.S as syscall: movq %rdi, %rax /* Syscall number -> rax. */ movq %rsi, %rdi /* shift arg1 - arg5. */ movq %rdx, %rsi movq %rcx, %rdx movq %r8, %r10 movq %r9, %r8 movq 8(%rsp),%r9 /* arg6 is on the stack. */ syscall /* Do the system call. */ cmpq $-4095, %rax /* Check %rax for error. */ jae __syscall_error /* Branch forward if it failed. */ ret /* Return to caller. */ In libc/sysdeps/linux/x86_64/__syscall_error.c, __syscall_error is defined as int __syscall_error(void) attribute_hidden; int __syscall_error(void) { register int err_no __asm__ ("%rcx"); __asm__ ("mov %rax, %rcx\n\t" "neg %rcx"); __set_errno(err_no); return -1; } So __syscall_error returns -1 as a 32-bit int in a 64-bit register, %rax (0x00000000ffffffff, whose decimal value is decimal 4294967295) and a test like this always returns false: if (syscall(number, ...) == -1) foo(); Fix the error by making __syscall_error return a long, like syscall(). The problem can be circumvented by the caller by coercing the returned value to int before comparing it to -1: if ((int) syscall(number, ...) == -1) foo(); The same problem probably occurs on other 64-bit systems but so far only x86_64 was tested, so this change must be considered experimental. Signed-off-by: Carlos Santos --- libc/sysdeps/linux/aarch64/__syscall_error.c | 4 ++-- libc/sysdeps/linux/alpha/__syscall_error.c | 2 +- libc/sysdeps/linux/arc/__syscall_error.c | 2 +- libc/sysdeps/linux/arm/__syscall_error.c | 4 ++-- libc/sysdeps/linux/csky/__syscall_error.c | 2 +- libc/sysdeps/linux/csky/clone.c | 2 +- libc/sysdeps/linux/frv/sysdep.c | 2 +- libc/sysdeps/linux/hppa/__syscall_error.c | 4 ++-- libc/sysdeps/linux/i386/__syscall_error.c | 4 ++-- libc/sysdeps/linux/ia64/__syscall_error.c | 4 ++-- libc/sysdeps/linux/m68k/__syscall_error.c | 4 ++-- libc/sysdeps/linux/metag/__syscall_error.c | 4 ++-- libc/sysdeps/linux/microblaze/__syscall_error.c | 4 ++-- libc/sysdeps/linux/mips/__syscall_error.c | 4 ++-- libc/sysdeps/linux/nds32/__syscall_error.c | 4 ++-- libc/sysdeps/linux/nios2/__syscall_error.c | 4 ++-- libc/sysdeps/linux/or1k/__syscall_error.c | 4 ++-- libc/sysdeps/linux/powerpc/__syscall_error.c | 4 ++-- libc/sysdeps/linux/riscv64/__syscall_error.c | 4 ++-- libc/sysdeps/linux/sparc/__syscall_error.c | 4 ++-- libc/sysdeps/linux/sparc64/__syscall_error.c | 4 ++-- libc/sysdeps/linux/tile/__syscall_error.c | 2 +- libc/sysdeps/linux/x86_64/__syscall_error.c | 4 ++-- libc/sysdeps/linux/xtensa/__syscall_error.c | 4 ++-- libpthread/nptl/sysdeps/unix/sysv/linux/__syscall_error.c | 4 ++-- 25 files changed, 44 insertions(+), 44 deletions(-) diff --git a/libc/sysdeps/linux/aarch64/__syscall_error.c b/libc/sysdeps/linux/aarch64/__syscall_error.c index 2b642e816..c682aae49 100644 --- a/libc/sysdeps/linux/aarch64/__syscall_error.c +++ b/libc/sysdeps/linux/aarch64/__syscall_error.c @@ -10,8 +10,8 @@ /* This routine is jumped to by all the syscall handlers, to stash * an error number into errno. */ -int __syscall_error(int err_no) attribute_hidden; -int __syscall_error(int err_no) +long __syscall_error(int err_no) attribute_hidden; +long __syscall_error(int err_no) { __set_errno(-err_no); return -1; diff --git a/libc/sysdeps/linux/alpha/__syscall_error.c b/libc/sysdeps/linux/alpha/__syscall_error.c index 7c081f3b5..c986e484d 100644 --- a/libc/sysdeps/linux/alpha/__syscall_error.c +++ b/libc/sysdeps/linux/alpha/__syscall_error.c @@ -8,7 +8,7 @@ /* This routine is jumped to by all the syscall handlers, to stash an error number into errno. */ -int attribute_hidden __syscall_error (void) +long attribute_hidden __syscall_error (void) { register int err_no __asm__("$0"); __set_errno (err_no); diff --git a/libc/sysdeps/linux/arc/__syscall_error.c b/libc/sysdeps/linux/arc/__syscall_error.c index 962d743e4..7f30485a8 100644 --- a/libc/sysdeps/linux/arc/__syscall_error.c +++ b/libc/sysdeps/linux/arc/__syscall_error.c @@ -8,7 +8,7 @@ #include #include -int __syscall_error(int err_no) +long __syscall_error(int err_no) { __set_errno(-err_no); return -1; diff --git a/libc/sysdeps/linux/arm/__syscall_error.c b/libc/sysdeps/linux/arm/__syscall_error.c index 2b642e816..c682aae49 100644 --- a/libc/sysdeps/linux/arm/__syscall_error.c +++ b/libc/sysdeps/linux/arm/__syscall_error.c @@ -10,8 +10,8 @@ /* This routine is jumped to by all the syscall handlers, to stash * an error number into errno. */ -int __syscall_error(int err_no) attribute_hidden; -int __syscall_error(int err_no) +long __syscall_error(int err_no) attribute_hidden; +long __syscall_error(int err_no) { __set_errno(-err_no); return -1; diff --git a/libc/sysdeps/linux/csky/__syscall_error.c b/libc/sysdeps/linux/csky/__syscall_error.c index cc1fb5977..c6a4a14eb 100644 --- a/libc/sysdeps/linux/csky/__syscall_error.c +++ b/libc/sysdeps/linux/csky/__syscall_error.c @@ -8,7 +8,7 @@ #include #include -int __syscall_error(int err_no) +long __syscall_error(int err_no) { __set_errno(-err_no); return -1; diff --git a/libc/sysdeps/linux/csky/clone.c b/libc/sysdeps/linux/csky/clone.c index 991cb8962..f0fcc257b 100644 --- a/libc/sysdeps/linux/csky/clone.c +++ b/libc/sysdeps/linux/csky/clone.c @@ -9,7 +9,7 @@ #include #include -extern int __syscall_error(int err_no); +extern long __syscall_error(int err_no); extern int __csky_clone ( int flags, diff --git a/libc/sysdeps/linux/frv/sysdep.c b/libc/sysdeps/linux/frv/sysdep.c index bfae12100..28beb418f 100644 --- a/libc/sysdeps/linux/frv/sysdep.c +++ b/libc/sysdeps/linux/frv/sysdep.c @@ -19,7 +19,7 @@ /* This routine is jumped to by all the syscall handlers, to stash an error number into errno. */ -int __syscall_error (int err_no) +long __syscall_error (int err_no) { __set_errno (-err_no); return -1; diff --git a/libc/sysdeps/linux/hppa/__syscall_error.c b/libc/sysdeps/linux/hppa/__syscall_error.c index 5e109a83b..af26cf6ab 100644 --- a/libc/sysdeps/linux/hppa/__syscall_error.c +++ b/libc/sysdeps/linux/hppa/__syscall_error.c @@ -10,8 +10,8 @@ /* This routine is jumped to by all the syscall handlers, to stash * an error number into errno. */ -int __syscall_error(int err_no) attribute_hidden; -int __syscall_error(int err_no) +long __syscall_error(int err_no) attribute_hidden; +long __syscall_error(int err_no) { __set_errno(err_no); return -1; diff --git a/libc/sysdeps/linux/i386/__syscall_error.c b/libc/sysdeps/linux/i386/__syscall_error.c index 36946bc6d..102ebbedb 100644 --- a/libc/sysdeps/linux/i386/__syscall_error.c +++ b/libc/sysdeps/linux/i386/__syscall_error.c @@ -25,8 +25,8 @@ #include #include -int __syscall_error(void) attribute_hidden; -int __syscall_error(void) +long __syscall_error(void) attribute_hidden; +long __syscall_error(void) { register int eax __asm__ ("%eax"); int _errno = -eax; diff --git a/libc/sysdeps/linux/ia64/__syscall_error.c b/libc/sysdeps/linux/ia64/__syscall_error.c index 0727b2b53..cc2b13450 100644 --- a/libc/sysdeps/linux/ia64/__syscall_error.c +++ b/libc/sysdeps/linux/ia64/__syscall_error.c @@ -10,8 +10,8 @@ /* This routine is jumped to by all the syscall handlers, to stash * an error number into errno. */ -int __syscall_error(void) attribute_hidden; -int __syscall_error(void) +long __syscall_error(void) attribute_hidden; +long __syscall_error(void) { register int err_no __asm__("%r8"); __set_errno(err_no); diff --git a/libc/sysdeps/linux/m68k/__syscall_error.c b/libc/sysdeps/linux/m68k/__syscall_error.c index a29f6ffd6..2d2677521 100644 --- a/libc/sysdeps/linux/m68k/__syscall_error.c +++ b/libc/sysdeps/linux/m68k/__syscall_error.c @@ -10,8 +10,8 @@ /* This routine is jumped to by all the syscall handlers, to stash * an error number into errno. */ -int __syscall_error(void) attribute_hidden; -int __syscall_error(void) +long __syscall_error(void) attribute_hidden; +long __syscall_error(void) { register int err_no __asm__("%d0"); __set_errno(-err_no); diff --git a/libc/sysdeps/linux/metag/__syscall_error.c b/libc/sysdeps/linux/metag/__syscall_error.c index f97cd0126..3e82abe0d 100644 --- a/libc/sysdeps/linux/metag/__syscall_error.c +++ b/libc/sysdeps/linux/metag/__syscall_error.c @@ -10,8 +10,8 @@ /* This routine is jumped to by all the syscall handlers, to stash * an error number into errno. */ -int __syscall_error(int err_no) attribute_hidden; -int __syscall_error(int err_no) +long __syscall_error(int err_no) attribute_hidden; +long __syscall_error(int err_no) { __set_errno(-err_no); return -1; diff --git a/libc/sysdeps/linux/microblaze/__syscall_error.c b/libc/sysdeps/linux/microblaze/__syscall_error.c index 2b642e816..c682aae49 100644 --- a/libc/sysdeps/linux/microblaze/__syscall_error.c +++ b/libc/sysdeps/linux/microblaze/__syscall_error.c @@ -10,8 +10,8 @@ /* This routine is jumped to by all the syscall handlers, to stash * an error number into errno. */ -int __syscall_error(int err_no) attribute_hidden; -int __syscall_error(int err_no) +long __syscall_error(int err_no) attribute_hidden; +long __syscall_error(int err_no) { __set_errno(-err_no); return -1; diff --git a/libc/sysdeps/linux/mips/__syscall_error.c b/libc/sysdeps/linux/mips/__syscall_error.c index 5e109a83b..af26cf6ab 100644 --- a/libc/sysdeps/linux/mips/__syscall_error.c +++ b/libc/sysdeps/linux/mips/__syscall_error.c @@ -10,8 +10,8 @@ /* This routine is jumped to by all the syscall handlers, to stash * an error number into errno. */ -int __syscall_error(int err_no) attribute_hidden; -int __syscall_error(int err_no) +long __syscall_error(int err_no) attribute_hidden; +long __syscall_error(int err_no) { __set_errno(err_no); return -1; diff --git a/libc/sysdeps/linux/nds32/__syscall_error.c b/libc/sysdeps/linux/nds32/__syscall_error.c index 2aa6903e2..c8e6044a7 100644 --- a/libc/sysdeps/linux/nds32/__syscall_error.c +++ b/libc/sysdeps/linux/nds32/__syscall_error.c @@ -8,8 +8,8 @@ /* This routine is jumped to by all the syscall handlers, to stash * an error number into errno. */ -int __syscall_error(int err_no) attribute_hidden; -int __syscall_error(int err_no) +long __syscall_error(int err_no) attribute_hidden; +long __syscall_error(int err_no) { __set_errno(err_no); return -1; diff --git a/libc/sysdeps/linux/nios2/__syscall_error.c b/libc/sysdeps/linux/nios2/__syscall_error.c index 2b642e816..c682aae49 100644 --- a/libc/sysdeps/linux/nios2/__syscall_error.c +++ b/libc/sysdeps/linux/nios2/__syscall_error.c @@ -10,8 +10,8 @@ /* This routine is jumped to by all the syscall handlers, to stash * an error number into errno. */ -int __syscall_error(int err_no) attribute_hidden; -int __syscall_error(int err_no) +long __syscall_error(int err_no) attribute_hidden; +long __syscall_error(int err_no) { __set_errno(-err_no); return -1; diff --git a/libc/sysdeps/linux/or1k/__syscall_error.c b/libc/sysdeps/linux/or1k/__syscall_error.c index 1b7e8a394..7d1e09d91 100644 --- a/libc/sysdeps/linux/or1k/__syscall_error.c +++ b/libc/sysdeps/linux/or1k/__syscall_error.c @@ -17,11 +17,11 @@ #include -int __syscall_error (int err_no); +long __syscall_error (int err_no); /* This routine is jumped to by all the syscall handlers, to stash * an error number into errno. */ -int __syscall_error (int err_no) +long __syscall_error (int err_no) { __set_errno (err_no); return -1; diff --git a/libc/sysdeps/linux/powerpc/__syscall_error.c b/libc/sysdeps/linux/powerpc/__syscall_error.c index 5e109a83b..af26cf6ab 100644 --- a/libc/sysdeps/linux/powerpc/__syscall_error.c +++ b/libc/sysdeps/linux/powerpc/__syscall_error.c @@ -10,8 +10,8 @@ /* This routine is jumped to by all the syscall handlers, to stash * an error number into errno. */ -int __syscall_error(int err_no) attribute_hidden; -int __syscall_error(int err_no) +long __syscall_error(int err_no) attribute_hidden; +long __syscall_error(int err_no) { __set_errno(err_no); return -1; diff --git a/libc/sysdeps/linux/riscv64/__syscall_error.c b/libc/sysdeps/linux/riscv64/__syscall_error.c index 2b642e816..c682aae49 100644 --- a/libc/sysdeps/linux/riscv64/__syscall_error.c +++ b/libc/sysdeps/linux/riscv64/__syscall_error.c @@ -10,8 +10,8 @@ /* This routine is jumped to by all the syscall handlers, to stash * an error number into errno. */ -int __syscall_error(int err_no) attribute_hidden; -int __syscall_error(int err_no) +long __syscall_error(int err_no) attribute_hidden; +long __syscall_error(int err_no) { __set_errno(-err_no); return -1; diff --git a/libc/sysdeps/linux/sparc/__syscall_error.c b/libc/sysdeps/linux/sparc/__syscall_error.c index 5e109a83b..af26cf6ab 100644 --- a/libc/sysdeps/linux/sparc/__syscall_error.c +++ b/libc/sysdeps/linux/sparc/__syscall_error.c @@ -10,8 +10,8 @@ /* This routine is jumped to by all the syscall handlers, to stash * an error number into errno. */ -int __syscall_error(int err_no) attribute_hidden; -int __syscall_error(int err_no) +long __syscall_error(int err_no) attribute_hidden; +long __syscall_error(int err_no) { __set_errno(err_no); return -1; diff --git a/libc/sysdeps/linux/sparc64/__syscall_error.c b/libc/sysdeps/linux/sparc64/__syscall_error.c index 5e109a83b..af26cf6ab 100644 --- a/libc/sysdeps/linux/sparc64/__syscall_error.c +++ b/libc/sysdeps/linux/sparc64/__syscall_error.c @@ -10,8 +10,8 @@ /* This routine is jumped to by all the syscall handlers, to stash * an error number into errno. */ -int __syscall_error(int err_no) attribute_hidden; -int __syscall_error(int err_no) +long __syscall_error(int err_no) attribute_hidden; +long __syscall_error(int err_no) { __set_errno(err_no); return -1; diff --git a/libc/sysdeps/linux/tile/__syscall_error.c b/libc/sysdeps/linux/tile/__syscall_error.c index a91fdff3a..31cab3799 100644 --- a/libc/sysdeps/linux/tile/__syscall_error.c +++ b/libc/sysdeps/linux/tile/__syscall_error.c @@ -6,7 +6,7 @@ #include #include -int __syscall_error(int err_no) +long __syscall_error(int err_no) { __set_errno(-err_no); return -1; diff --git a/libc/sysdeps/linux/x86_64/__syscall_error.c b/libc/sysdeps/linux/x86_64/__syscall_error.c index 448f50983..7f0f388c4 100644 --- a/libc/sysdeps/linux/x86_64/__syscall_error.c +++ b/libc/sysdeps/linux/x86_64/__syscall_error.c @@ -10,8 +10,8 @@ /* This routine is jumped to by all the syscall handlers, to stash * an error number into errno. */ -int __syscall_error(void) attribute_hidden; -int __syscall_error(void) +long __syscall_error(void) attribute_hidden; +long __syscall_error(void) { register int err_no __asm__ ("%rcx"); __asm__ ("mov %rax, %rcx\n\t" diff --git a/libc/sysdeps/linux/xtensa/__syscall_error.c b/libc/sysdeps/linux/xtensa/__syscall_error.c index 2b642e816..c682aae49 100644 --- a/libc/sysdeps/linux/xtensa/__syscall_error.c +++ b/libc/sysdeps/linux/xtensa/__syscall_error.c @@ -10,8 +10,8 @@ /* This routine is jumped to by all the syscall handlers, to stash * an error number into errno. */ -int __syscall_error(int err_no) attribute_hidden; -int __syscall_error(int err_no) +long __syscall_error(int err_no) attribute_hidden; +long __syscall_error(int err_no) { __set_errno(-err_no); return -1; diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/__syscall_error.c b/libpthread/nptl/sysdeps/unix/sysv/linux/__syscall_error.c index 5e109a83b..af26cf6ab 100644 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/__syscall_error.c +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/__syscall_error.c @@ -10,8 +10,8 @@ /* This routine is jumped to by all the syscall handlers, to stash * an error number into errno. */ -int __syscall_error(int err_no) attribute_hidden; -int __syscall_error(int err_no) +long __syscall_error(int err_no) attribute_hidden; +long __syscall_error(int err_no) { __set_errno(err_no); return -1;