Message ID | 11fd815773f7d202d329ac2c64cd6980b32e4fcf.1688739492.git.falcon@tinylab.org |
---|---|
State | New |
Headers |
Return-Path: <linux-kernel-owner@vger.kernel.org> Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:9f45:0:b0:3ea:f831:8777 with SMTP id v5csp3338918vqx; Fri, 7 Jul 2023 08:12:20 -0700 (PDT) X-Google-Smtp-Source: APBJJlHWcoT2YvGtpaQKNehWPcAlO8PudC4Zm35OOFA/huHp5lyVwudh41UAy7euix8JM7VuYVy8 X-Received: by 2002:a9d:6b11:0:b0:6b8:8db9:af9b with SMTP id g17-20020a9d6b11000000b006b88db9af9bmr6130160otp.22.1688742740466; Fri, 07 Jul 2023 08:12:20 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1688742740; cv=none; d=google.com; s=arc-20160816; b=jTLFBTA7q3fjqXkz6bfIZbvimJ8WvIwLJ1+oV3ktY8kgFgzOoEjS7e8oH48TraJb1h Dv50cvcu6uPOtRlSgrIz+VtcFFKGj4c+fCTwHeVl4uXLEUtTGaPaxjcKb/nghVWyFHU0 Y4537gbXvZPGRqWevwpUyFFlMJ+S+5qklIdNhNtEIiD3YhnRUGiJO4M9qrY7xn2ib6/3 7ktsJIKhI4fFiydV22ayAf+j0j+o8LDGFDT+ytj0xwrjPrEQJ7Kw2twvjnT5TqJ+LF0V oxEtI3rBKx6CxcmauMciSujb4lmfnqhwJplCJ56fQ2jLUbj1l7OYHI9Y+xvwAT2bOPyr nRrA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:feedback-id:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:cc:to :from; bh=VgyTp88Z4MZWOXUMpeaIs6q9qAe9PED5a1HufWI2wyg=; fh=ax1FgZyG7i67GJPCk3XF/rGe9KgNTtvXUm/PZGF9PXA=; b=M/OCOmrT4AA9574Cuu5ZbtDD3GkWv5/eZ59lFUvO/0i5U3gAtKv+Gbkya1gr5EB5tV kcdB6nsiTj4gPY28d1z9qisYqbHDNDU4VDFB2rWL33tfXFP5Z9zdVbPDo2wVPgEZjoi9 Ry1krgpxvOud+g08c602cUxwwjLByw1Wle+sNa7Ip4ncEdm7+X3P0elAQY2m0lNB8HEh v1M7jO39cAPZNPIJn5rzasfNKIhEKZtWbdt5mezhJzNP+qvAKwrEzddoonRmyidbIIyx qMP5MRAjfCgW+2bifJ4WJqnG/aj3j4hold4VA1PRXvd6594G56ayJsB2dlA+/+Y1KD3s ikpQ== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id l187-20020a6325c4000000b0055bc257504fsi4332258pgl.497.2023.07.07.08.12.07; Fri, 07 Jul 2023 08:12:20 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233151AbjGGO5e (ORCPT <rfc822;hadasmailinglist@gmail.com> + 99 others); Fri, 7 Jul 2023 10:57:34 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41224 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229586AbjGGO5d (ORCPT <rfc822;linux-kernel@vger.kernel.org>); Fri, 7 Jul 2023 10:57:33 -0400 Received: from bg4.exmail.qq.com (bg4.exmail.qq.com [43.154.54.12]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 2ACFA210A; Fri, 7 Jul 2023 07:57:31 -0700 (PDT) X-QQ-mid: bizesmtp65t1688741838t0f6f5rq Received: from linux-lab-host.localdomain ( [116.30.131.119]) by bizesmtp.qq.com (ESMTP) with id ; Fri, 07 Jul 2023 22:57:17 +0800 (CST) X-QQ-SSF: 01200000000000D0W000000A0000000 X-QQ-FEAT: 6/K5pWSRdGp5l3PoSnsEr+W6n/O4GVkW2LsupZpOaCCnabhC9drJ+DsHTHGGa rpPAydJpCLVE4Yu5xjNNf886fcd75eYPy4f1CJVneC7/0vFizOlY/8RavL9cQLH+5qlBKdY T26RBSYkIWrac+plKyZyFDAQHOazNAOnx1T7kOiVneWS5f/wr8Ez5VRxQvzZvQxdei7uftr G8bYJAdCFUoNytCFtmfyt9XZohqeJxoGQaPP3fHRTj28Ly8xD8BkFYsPULycHa/6IDvJuAN MqUK5SPN9/+jB5l4g/5XTC9L51uz2CBdxApWKXmcHXt6PfAwJmgYn/9kDGGQLO0EvowDYOC tj5RprGXjtRiusZgLAzassh26B9m6zPartP8HLPVFF77FEdqu/QC8BNCz0T6GLu2e8ZMYia X-QQ-GoodBg: 0 X-BIZMAIL-ID: 6279798532617974938 From: Zhangjin Wu <falcon@tinylab.org> To: w@1wt.eu Cc: falcon@tinylab.org, arnd@arndb.de, david.laight@aculab.com, linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-riscv@lists.infradead.org, thomas@t-8ch.de, David Laight <David.Laight@ACULAB.COM> Subject: [PATCH v6 06/15] tools/nolibc: __sysret: support syscalls who return a pointer Date: Fri, 7 Jul 2023 22:56:59 +0800 Message-Id: <11fd815773f7d202d329ac2c64cd6980b32e4fcf.1688739492.git.falcon@tinylab.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <cover.1688739492.git.falcon@tinylab.org> References: <cover.1688739492.git.falcon@tinylab.org> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-QQ-SENDSIZE: 520 Feedback-ID: bizesmtp:tinylab.org:qybglogicsvrgz:qybglogicsvrgz5a-1 X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,RCVD_IN_MSPIKE_H2, SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: <linux-kernel.vger.kernel.org> X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1770775107384032955?= X-GMAIL-MSGID: =?utf-8?q?1770775107384032955?= |
Series |
tools/nolibc: add a new syscall helper
|
|
Commit Message
Zhangjin Wu
July 7, 2023, 2:56 p.m. UTC
No official reference states the errno range, here aligns with musl and
glibc and uses [-MAX_ERRNO, -1] instead of all negative ones.
- musl: src/internal/syscall_ret.c
- glibc: sysdeps/unix/sysv/linux/sysdep.h
The MAX_ERRNO used by musl and glibc is 4095, just like the one nolibc
defined in tools/include/nolibc/errno.h.
Suggested-by: Willy Tarreau <w@1wt.eu>
Link: https://lore.kernel.org/lkml/ZKKdD%2Fp4UkEavru6@1wt.eu/
Suggested-by: David Laight <David.Laight@ACULAB.COM>
Link: https://lore.kernel.org/linux-riscv/94dd5170929f454fbc0a10a2eb3b108d@AcuMS.aculab.com/
Signed-off-by: Zhangjin Wu <falcon@tinylab.org>
---
tools/include/nolibc/sys.h | 17 ++++++++++++-----
1 file changed, 12 insertions(+), 5 deletions(-)
Comments
Hi Zhangjin, On Fri, Jul 07, 2023 at 10:56:59PM +0800, Zhangjin Wu wrote: > No official reference states the errno range, here aligns with musl and > glibc and uses [-MAX_ERRNO, -1] instead of all negative ones. > > - musl: src/internal/syscall_ret.c > - glibc: sysdeps/unix/sysv/linux/sysdep.h > > The MAX_ERRNO used by musl and glibc is 4095, just like the one nolibc > defined in tools/include/nolibc/errno.h. > > Suggested-by: Willy Tarreau <w@1wt.eu> > Link: https://lore.kernel.org/lkml/ZKKdD%2Fp4UkEavru6@1wt.eu/ > Suggested-by: David Laight <David.Laight@ACULAB.COM> > Link: https://lore.kernel.org/linux-riscv/94dd5170929f454fbc0a10a2eb3b108d@AcuMS.aculab.com/ > Signed-off-by: Zhangjin Wu <falcon@tinylab.org> > --- > tools/include/nolibc/sys.h | 17 ++++++++++++----- > 1 file changed, 12 insertions(+), 5 deletions(-) > > diff --git a/tools/include/nolibc/sys.h b/tools/include/nolibc/sys.h > index 53bc3ad6593e..3479f54d7957 100644 > --- a/tools/include/nolibc/sys.h > +++ b/tools/include/nolibc/sys.h > @@ -28,13 +28,20 @@ > #include "errno.h" > #include "types.h" > > -/* Syscall return helper, set errno as -ret when ret < 0 */ > + > +/* Syscall return helper for library routines, set errno as -ret when ret is in > + * range of [-MAX_ERRNO, -1] > + * > + * Note, No official reference states the errno range here aligns with musl > + * (src/internal/syscall_ret.c) and glibc (sysdeps/unix/sysv/linux/sysdep.h) > + */ > + > static __inline__ __attribute__((unused, always_inline)) > -long __sysret(long ret) > +long __sysret(unsigned long ret) > { > - if (ret < 0) { > - SET_ERRNO(-ret); > - ret = -1; > + if (ret >= (unsigned long)-MAX_ERRNO) { > + SET_ERRNO(-(long)ret); > + return -1; > } > return ret; > } While running some regression tests, I found that my programs increased in size by 3-4% overall, which was solely attributed to this helper that significantly increased the size of many syscalls (particularly those returning ints). Let's consider this simple function: void unlink_exit(const char *name) { int ret = unlink(name); exit(ret < 0 ? errno : 0); } Before: $ nm --size unlink.o | grep unli 0000000000000030 T unlink_exit $ objdump -d -j .text --disassemble=unlink_exit unlink.o 000000000000003b <unlink_exit>: 3b: 48 89 fe mov %rdi,%rsi 3e: b8 07 01 00 00 mov $0x107,%eax 43: 31 d2 xor %edx,%edx 45: 48 c7 c7 9c ff ff ff mov $0xffffffffffffff9c,%rdi 4c: 0f 05 syscall 4e: 31 ff xor %edi,%edi 50: 85 c0 test %eax,%eax 52: 79 0a jns 5e <unlink_exit+0x23> 54: 89 c7 mov %eax,%edi 56: f7 df neg %edi 58: 89 3d 00 00 00 00 mov %edi,0x0(%rip) # 5e <unlink_exit+0x23> 5e: b8 3c 00 00 00 mov $0x3c,%eax 63: 40 0f b6 ff movzbl %dil,%edi 67: 0f 05 syscall 69: eb fe jmp 69 <unlink_exit+0x2e> After: $ nm --size unlink.o | grep unli 0000000000000042 T unlink_exit $ objdump -d -j .text --disassemble=unlink_exit unlink.o 0000000000000051 <unlink_exit>: 51: 48 89 fe mov %rdi,%rsi 54: b8 07 01 00 00 mov $0x107,%eax 59: 31 d2 xor %edx,%edx 5b: 48 c7 c7 9c ff ff ff mov $0xffffffffffffff9c,%rdi 62: 0f 05 syscall 64: 48 63 d0 movslq %eax,%rdx 67: 48 81 fa 00 f0 ff ff cmp $0xfffffffffffff000,%rdx 6e: 76 0a jbe 7a <unlink_exit+0x29> 70: f7 da neg %edx 72: 89 15 00 00 00 00 mov %edx,0x0(%rip) # 78 <unlink_exit+0x27> 78: eb 06 jmp 80 <unlink_exit+0x2f> 7a: 31 ff xor %edi,%edi 7c: 85 c0 test %eax,%eax 7e: 79 06 jns 86 <unlink_exit+0x35> 80: 8b 3d 00 00 00 00 mov 0x0(%rip),%edi # 86 <unlink_exit+0x35> 86: b8 3c 00 00 00 mov $0x3c,%eax 8b: 40 0f b6 ff movzbl %dil,%edi 8f: 0f 05 syscall 91: eb fe jmp 91 <unlink_exit+0x40> => that's 18 bytes added to retrieve the result of a syscall. There are several reasons involved: - the "unsigned long" argument to __sysret() forces a sign extension from all sys_* functions that used to return int (the movslq above). - the comparison with the error range now has to be performed on a long instead of an int - the return value from __sysret() is a long (note, a signed long) which then has to be turned back to an int before being returned by the caller to satisfy the caller's prototype. I could recover a part of it by replacing the __sysret() function with a macro that preserves the input type and avoids these useless conversions: #define __sysret(arg) ({ \ typeof(arg) __sysret_arg = (arg); \ if ((unsigned long)__sysret_arg >= (unsigned long)-MAX_ERRNO) { \ SET_ERRNO(-(int)__sysret_arg); \ __sysret_arg = -1L; \ } \ __sysret_arg; \ }) But the remaining part is the comparison to -MAX_ERRNO inflicted on all integer returns where we could previously keep a simple sign comparison: 51: 48 89 fe mov %rdi,%rsi 54: b8 07 01 00 00 mov $0x107,%eax 59: 31 d2 xor %edx,%edx 5b: 48 c7 c7 9c ff ff ff mov $0xffffffffffffff9c,%rdi 62: 0f 05 syscall 64: 3d 00 f0 ff ff cmp $0xfffff000,%eax 69: 76 0a jbe 75 <unlink_exit+0x24> 6b: f7 d8 neg %eax 6d: 89 05 00 00 00 00 mov %eax,0x0(%rip) # 73 <unlink_exit+0x22> 73: eb 06 jmp 7b <unlink_exit+0x2a> 75: 31 ff xor %edi,%edi 77: 85 c0 test %eax,%eax 79: 79 06 jns 81 <unlink_exit+0x30> 7b: 8b 3d 00 00 00 00 mov 0x0(%rip),%edi # 81 <unlink_exit+0x30> 81: b8 3c 00 00 00 mov $0x3c,%eax 86: 40 0f b6 ff movzbl %dil,%edi 8a: 0f 05 syscall 8c: eb fe jmp 8c <unlink_exit+0x3b> And given that the vast majority of the syscalls return integers, I think we should specialize these sysret functions so that we don't add needless complexity for all those for which we know they're returning ints (it's written in the caller's prototype anyway). I.e. we can have __sysret_int() that is the low-overhead version and keep __sysret() the expensive one doing the comparison (and possibly through the macro like above if needed in order to avoid multiple casts). I'm not going to change all that now, that's too late, but I'm a bit sad to see my binaries inflate just because of this, so I hope we can get back to this later after the current queue is flushed. Regards, Willy
> Hi Zhangjin, > > On Fri, Jul 07, 2023 at 10:56:59PM +0800, Zhangjin Wu wrote: > > No official reference states the errno range, here aligns with musl and > > glibc and uses [-MAX_ERRNO, -1] instead of all negative ones. > > > > - musl: src/internal/syscall_ret.c > > - glibc: sysdeps/unix/sysv/linux/sysdep.h > > > > The MAX_ERRNO used by musl and glibc is 4095, just like the one nolibc > > defined in tools/include/nolibc/errno.h. > > > > Suggested-by: Willy Tarreau <w@1wt.eu> > > Link: https://lore.kernel.org/lkml/ZKKdD%2Fp4UkEavru6@1wt.eu/ > > Suggested-by: David Laight <David.Laight@ACULAB.COM> > > Link: https://lore.kernel.org/linux-riscv/94dd5170929f454fbc0a10a2eb3b108d@AcuMS.aculab.com/ > > Signed-off-by: Zhangjin Wu <falcon@tinylab.org> > > --- > > tools/include/nolibc/sys.h | 17 ++++++++++++----- > > 1 file changed, 12 insertions(+), 5 deletions(-) > > > > diff --git a/tools/include/nolibc/sys.h b/tools/include/nolibc/sys.h > > index 53bc3ad6593e..3479f54d7957 100644 > > --- a/tools/include/nolibc/sys.h > > +++ b/tools/include/nolibc/sys.h > > @@ -28,13 +28,20 @@ > > #include "errno.h" > > #include "types.h" > > > > -/* Syscall return helper, set errno as -ret when ret < 0 */ > > + > > +/* Syscall return helper for library routines, set errno as -ret when ret is in > > + * range of [-MAX_ERRNO, -1] > > + * > > + * Note, No official reference states the errno range here aligns with musl > > + * (src/internal/syscall_ret.c) and glibc (sysdeps/unix/sysv/linux/sysdep.h) > > + */ > > + > > static __inline__ __attribute__((unused, always_inline)) > > -long __sysret(long ret) > > +long __sysret(unsigned long ret) > > { > > - if (ret < 0) { > > - SET_ERRNO(-ret); > > - ret = -1; > > + if (ret >= (unsigned long)-MAX_ERRNO) { > > + SET_ERRNO(-(long)ret); > > + return -1; > > } > > return ret; > > } > > While running some regression tests, I found that my programs increased > in size by 3-4% overall, which was solely attributed to this helper that > significantly increased the size of many syscalls (particularly those > returning ints). Let's consider this simple function: > I'm very sad to learn this, so sorry, but we do need a test suite for the coverage on different toolchains, on O0/1/2/3/s, on generated size ... > void unlink_exit(const char *name) > { > int ret = unlink(name); > exit(ret < 0 ? errno : 0); > } > > Before: > $ nm --size unlink.o | grep unli > 0000000000000030 T unlink_exit > > $ objdump -d -j .text --disassemble=unlink_exit unlink.o > 000000000000003b <unlink_exit>: > 3b: 48 89 fe mov %rdi,%rsi > 3e: b8 07 01 00 00 mov $0x107,%eax > 43: 31 d2 xor %edx,%edx > 45: 48 c7 c7 9c ff ff ff mov $0xffffffffffffff9c,%rdi > 4c: 0f 05 syscall > 4e: 31 ff xor %edi,%edi > 50: 85 c0 test %eax,%eax > 52: 79 0a jns 5e <unlink_exit+0x23> > 54: 89 c7 mov %eax,%edi > 56: f7 df neg %edi > 58: 89 3d 00 00 00 00 mov %edi,0x0(%rip) # 5e <unlink_exit+0x23> > 5e: b8 3c 00 00 00 mov $0x3c,%eax > 63: 40 0f b6 ff movzbl %dil,%edi > 67: 0f 05 syscall > 69: eb fe jmp 69 <unlink_exit+0x2e> > > After: > $ nm --size unlink.o | grep unli > 0000000000000042 T unlink_exit > > $ objdump -d -j .text --disassemble=unlink_exit unlink.o > 0000000000000051 <unlink_exit>: > 51: 48 89 fe mov %rdi,%rsi > 54: b8 07 01 00 00 mov $0x107,%eax > 59: 31 d2 xor %edx,%edx > 5b: 48 c7 c7 9c ff ff ff mov $0xffffffffffffff9c,%rdi > 62: 0f 05 syscall > 64: 48 63 d0 movslq %eax,%rdx > 67: 48 81 fa 00 f0 ff ff cmp $0xfffffffffffff000,%rdx > 6e: 76 0a jbe 7a <unlink_exit+0x29> > 70: f7 da neg %edx > 72: 89 15 00 00 00 00 mov %edx,0x0(%rip) # 78 <unlink_exit+0x27> > 78: eb 06 jmp 80 <unlink_exit+0x2f> > 7a: 31 ff xor %edi,%edi > 7c: 85 c0 test %eax,%eax > 7e: 79 06 jns 86 <unlink_exit+0x35> > 80: 8b 3d 00 00 00 00 mov 0x0(%rip),%edi # 86 <unlink_exit+0x35> > 86: b8 3c 00 00 00 mov $0x3c,%eax > 8b: 40 0f b6 ff movzbl %dil,%edi > 8f: 0f 05 syscall > 91: eb fe jmp 91 <unlink_exit+0x40> > > => that's 18 bytes added to retrieve the result of a syscall. > > There are several reasons involved: > - the "unsigned long" argument to __sysret() forces a sign extension > from all sys_* functions that used to return int (the movslq above). > > - the comparison with the error range now has to be performed on a > long instead of an int > > - the return value from __sysret() is a long (note, a signed long) > which then has to be turned back to an int before being returned > by the caller to satisfy the caller's prototype. > > I could recover a part of it by replacing the __sysret() function with > a macro that preserves the input type and avoids these useless > conversions: > > #define __sysret(arg) ({ \ > typeof(arg) __sysret_arg = (arg); \ > if ((unsigned long)__sysret_arg >= (unsigned long)-MAX_ERRNO) { \ > SET_ERRNO(-(int)__sysret_arg); \ > __sysret_arg = -1L; \ > } \ > __sysret_arg; \ > }) > > But the remaining part is the comparison to -MAX_ERRNO inflicted on all > integer returns where we could previously keep a simple sign comparison: > > 51: 48 89 fe mov %rdi,%rsi > 54: b8 07 01 00 00 mov $0x107,%eax > 59: 31 d2 xor %edx,%edx > 5b: 48 c7 c7 9c ff ff ff mov $0xffffffffffffff9c,%rdi > 62: 0f 05 syscall > 64: 3d 00 f0 ff ff cmp $0xfffff000,%eax > 69: 76 0a jbe 75 <unlink_exit+0x24> > 6b: f7 d8 neg %eax > 6d: 89 05 00 00 00 00 mov %eax,0x0(%rip) # 73 <unlink_exit+0x22> > 73: eb 06 jmp 7b <unlink_exit+0x2a> > 75: 31 ff xor %edi,%edi > 77: 85 c0 test %eax,%eax > 79: 79 06 jns 81 <unlink_exit+0x30> > 7b: 8b 3d 00 00 00 00 mov 0x0(%rip),%edi # 81 <unlink_exit+0x30> > 81: b8 3c 00 00 00 mov $0x3c,%eax > 86: 40 0f b6 ff movzbl %dil,%edi > 8a: 0f 05 syscall > 8c: eb fe jmp 8c <unlink_exit+0x3b> > > And given that the vast majority of the syscalls return integers, I think > we should specialize these sysret functions so that we don't add needless > complexity for all those for which we know they're returning ints (it's > written in the caller's prototype anyway). I.e. we can have __sysret_int() > that is the low-overhead version and keep __sysret() the expensive one > doing the comparison (and possibly through the macro like above if needed > in order to avoid multiple casts). > Based on your macro version, I tried to use the is_signed_type() from kernel, it seems works. A simple test shows, before: // ppc64 $ size nolibc-test text data bss dec hex filename 27308 1880 80 29268 7254 nolibc-test // mips $ size nolibc-test text data bss dec hex filename 23276 64 64 23404 5b6c nolibc-test After: // ppc64 $ size nolibc-test text data bss dec hex filename 27136 1880 80 29096 71a8 nolibc-test // mips $ size nolibc-test text data bss dec hex filename 23036 64 64 23164 5a7c nolibc-test > I'm not going to change all that now, that's too late, but I'm a bit sad > to see my binaries inflate just because of this, so I hope we can get back > to this later after the current queue is flushed. > Ok, will send a patch with is_signed_type() for more discuss soon. Thanks, Willy > Regards, > Willy
From: Zhangjin Wu > Sent: 06 August 2023 13:34 ... > Based on your macro version, I tried to use the is_signed_type() from kernel, > it seems works. You'll find that (void *)0 isn't 'constant enough' for is_constexpr() - so is_constexpr((type)0) can be used to detect pointer types. Probably requires an 'is_pointer_type()' define. This also rather means that is_signed_type() needs to be wrapped in is_constexpr() - probably generating header file inclusion hell. I'm going to add a comment on v3 of the patch... David - Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK Registration No: 1397386 (Wales)
diff --git a/tools/include/nolibc/sys.h b/tools/include/nolibc/sys.h index 53bc3ad6593e..3479f54d7957 100644 --- a/tools/include/nolibc/sys.h +++ b/tools/include/nolibc/sys.h @@ -28,13 +28,20 @@ #include "errno.h" #include "types.h" -/* Syscall return helper, set errno as -ret when ret < 0 */ + +/* Syscall return helper for library routines, set errno as -ret when ret is in + * range of [-MAX_ERRNO, -1] + * + * Note, No official reference states the errno range here aligns with musl + * (src/internal/syscall_ret.c) and glibc (sysdeps/unix/sysv/linux/sysdep.h) + */ + static __inline__ __attribute__((unused, always_inline)) -long __sysret(long ret) +long __sysret(unsigned long ret) { - if (ret < 0) { - SET_ERRNO(-ret); - ret = -1; + if (ret >= (unsigned long)-MAX_ERRNO) { + SET_ERRNO(-(long)ret); + return -1; } return ret; }