lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Date:   Mon,  7 Aug 2023 01:35:12 +0800
From:   Zhangjin Wu <falcon@...ylab.org>
To:     w@....eu
Cc:     falcon@...ylab.org, arnd@...db.de, david.laight@...lab.com,
        linux-kernel@...r.kernel.org, linux-kselftest@...r.kernel.org,
        thomas@...ch.de
Subject: [PATCH v2] tools/nolibc: fix up size inflate regression

Hi, Willy

> [...]
> before:
> 
>     // ppc64le
>     $ size nolibc-test
>        text	   data	    bss	    dec	    hex	filename
>       27916	      8	     80	  28004	   6d64	nolibc-test
> 
>     // mips
>     $ size nolibc-test
>        text	   data	    bss	    dec	    hex	filename
>       23276	     64	     64	  23404	   5b6c	nolibc-test
> 
> after:
> 
>     // ppc64le
>     $ size nolibc-test
>        text	   data	    bss	    dec	    hex	filename
>       27736	      8	     80	  27824	   6cb0	nolibc-test
> 
>     // mips
>     $ size nolibc-test
>        text	   data	    bss	    dec	    hex	filename
>       23036	     64	     64	  23164	   5a7c	nolibc-test
> 
> Suggested-by: Willy Tarreau <w@....eu>
> Link: https://lore.kernel.org/lkml/20230806095846.GB10627@1wt.eu/
> Link: https://lore.kernel.org/lkml/20230806134348.GA19145@1wt.eu/
> Signed-off-by: Zhangjin Wu <falcon@...ylab.org>
> ---
> 
> v2 here is further fix up argument with 'const' in the type and also
> support "void *" argument, v1 is [1].
> 
> Tested on many architectures (i386, x86_64, mips, ppc64) and gcc version
> (from gcc 4.8-13.1.0), compiles well without any warning and errors and
> also with smaller size.
> 
> [1]: https://lore.kernel.org/lkml/20230806131921.52453-1-falcon@tinylab.org/
> 
> ---
>  tools/include/nolibc/sys.h | 52 ++++++++++++++++++++++++++++++--------
>  1 file changed, 41 insertions(+), 11 deletions(-)
> 
> diff --git a/tools/include/nolibc/sys.h b/tools/include/nolibc/sys.h
> index 56f63eb48a1b..9c7448ae19e2 100644
> --- a/tools/include/nolibc/sys.h
> +++ b/tools/include/nolibc/sys.h
> @@ -35,15 +35,45 @@
>   * (src/internal/syscall_ret.c) and glibc (sysdeps/unix/sysv/linux/sysdep.h)
>   */
>  
> -static __inline__ __attribute__((unused, always_inline))
> -long __sysret(unsigned long ret)
> -{
> -	if (ret >= (unsigned long)-MAX_ERRNO) {
> -		SET_ERRNO(-(long)ret);
> -		return -1;
> -	}
> -	return ret;
> -}
> +/*
> + * Whether 'type' is a signed type or an unsigned type. Supports scalar types,
> + * bool and also pointer types. (from include/linux/compiler.h)
> + */
> +#define __is_signed_type(type) (((type)(-1)) < (type)1)
> +
> +/* __auto_type is used instead of __typeof__ to workaround the build error
> + * 'error: assignment of read-only variable' when the argument has 'const' in
> + * the type, but __auto_type is a new feature from newer version and it only
> + * work with 'const' from gcc 11.0 (__GXX_ABI_VERSION = 1016)
> + * https://gcc.gnu.org/legacy-ml/gcc-patches/2013-11/msg01378.html
> + */
> +
> +#if __GXX_ABI_VERSION < 1016
> +#define __typeofdecl(arg) long
> +#define __typeofconv1(arg) (long)
> +#define __typeofconv2(arg) (long)
> +#else
> +#define __typeofdecl(arg) __auto_type
> +#define __typeofconv1(arg)
> +#define __typeofconv2(arg) (__typeof__(arg))
> +#endif
>

With nolibc-test, we did more tests.

for ppc64le (long better):

    // __auto_type
    $ size nolibc-test
       text	   data	    bss	    dec	    hex	filename
      27736	      8	     80	  27824	   6cb0	nolibc-test

    // long
    $ size nolibc-test
       text	   data	    bss	    dec	    hex	filename
      27612	      8	     80	  27700	   6c34	nolibc-test

for ppc64 (long better):

    // __auto_type
    $ size nolibc-test
       text	   data	    bss	    dec	    hex	filename
      27136	   1880	     80	  29096	   71a8	nolibc-test

    // long
    $ size nolibc-test
       text	   data	    bss	    dec	    hex	filename
      27012	   1880	     80	  28972	   712c	nolibc-test

A further test on x86_64 (__auto_type better):

     // __auto_type
     $ size nolibc-test
       text	   data	    bss	    dec	    hex	filename
      22206	      8	     88	  22302	   571e	nolibc-test

     // long
     $ size nolibc-test
       text	   data	    bss	    dec	    hex	filename
      22347	      8	     88	  22443	   57ab	nolibc-test

And i386 (almost the same):

     // __auto_type
     $ size nolibc-test
       text	   data	    bss	    dec	    hex	filename
      19718	      4	     52	  19774	   4d3e	nolibc-test

     // long
     $ size nolibc-test
       text	   data	    bss	    dec	    hex	filename
      19717	      4	     52	  19773	   4d3d	nolibc-test

arm64 (__auto_type better):
    // __auto_type
    $ size nolibc-test
       text	   data	    bss	    dec	    hex	filename
      25764	      8	     80	  25852	   64fc	nolibc-test

    // long
    $ size nolibc-test
       text	   data	    bss	    dec	    hex	filename
      26004	      8	     80	  26092	   65ec	nolibc-test

arm (the same):

    // __auto_type
    $ size nolibc-test
       text	   data	    bss	    dec	    hex	filename
      19595	      0	     52	  19647	   4cbf	nolibc-test

    // long
    $ size nolibc-test
       text	   data	    bss	    dec	    hex	filename
      19595	      0	     52	  19647	   4cbf	nolibc-test


riscv64 (__auto_type better):

    // __auto_type
    $ size nolibc-test
       text	   data	    bss	    dec	    hex	filename
      21814	      8	     80	  21902	   558e	nolibc-test

    // long
    $ size nolibc-test
       text	   data	    bss	    dec	    hex	filename
      21912	      8	     80	  22000	   55f0	nolibc-test

s390 (__auto_type better):

    // __auto_type
    $ size nolibc-test
       text	   data	    bss	    dec	    hex	filename
      22302	      0	     80	  22382	   576e	nolibc-test

    // long
    $ size nolibc-test
       text	   data	    bss	    dec	    hex	filename
      22438	      0	     80	  22518	   57f6	nolibc-test

As a summary, in nolibc-test, for 32-bit architectures, __auto_type has the
same as long, for 64-bit architecture, __auto_type has less size than long,
only ppc64/ppc64le has reverse result.

BR,
Zhangjin

> +#define __sysret(arg)                                                           \
> +({                                                                              \
> +	__typeofdecl(arg) __sysret_arg = __typeofconv1(arg)(arg);               \
> +	if (__is_signed_type(__typeof__(arg))) {                                \
> +		if (__sysret_arg < 0) {                                         \
> +			SET_ERRNO(-(long)__sysret_arg);                         \
> +			__sysret_arg = __typeofconv2(arg)(-1L);                 \
> +		}                                                               \
> +	} else {                                                                \
> +		if ((unsigned long)__sysret_arg >= (unsigned long)-MAX_ERRNO) { \
> +			SET_ERRNO(-(long)__sysret_arg);                         \
> +			__sysret_arg = __typeofconv2(arg)(-1L);                 \
> +		}                                                               \
> +	}                                                                       \
> +	(__typeof__(arg))__sysret_arg;                                          \
> +})
>  
>  /* Functions in this file only describe syscalls. They're declared static so
>   * that the compiler usually decides to inline them while still being allowed
> @@ -94,7 +124,7 @@ void *sbrk(intptr_t inc)
>  	if (ret && sys_brk(ret + inc) == ret + inc)
>  		return ret + inc;
>  
> -	return (void *)__sysret(-ENOMEM);
> +	return __sysret((void *)-ENOMEM);
>  }
>  
>  
> @@ -682,7 +712,7 @@ void *sys_mmap(void *addr, size_t length, int prot, int flags, int fd,
>  static __attribute__((unused))
>  void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset)
>  {
> -	return (void *)__sysret((unsigned long)sys_mmap(addr, length, prot, flags, fd, offset));
> +	return __sysret(sys_mmap(addr, length, prot, flags, fd, offset));
>  }
>  
>  static __attribute__((unused))
> -- 
> 2.25.1
> 
> 

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ