NetBSD Problem Report #57021

From www@netbsd.org  Sat Sep 24 08:38:00 2022
Return-Path: <www@netbsd.org>
Received: from mail.netbsd.org (mail.netbsd.org [199.233.217.200])
	(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits))
	(Client CN "mail.NetBSD.org", Issuer "mail.NetBSD.org CA" (not verified))
	by mollari.NetBSD.org (Postfix) with ESMTPS id C445A1A923A
	for <gnats-bugs@gnats.NetBSD.org>; Sat, 24 Sep 2022 08:38:00 +0000 (UTC)
Message-Id: <20220924083759.393171A923B@mollari.NetBSD.org>
Date: Sat, 24 Sep 2022 08:37:59 +0000 (UTC)
From: nia@pkgsrc.org
Reply-To: nia@pkgsrc.org
To: gnats-bugs@NetBSD.org
Subject: libc __trunctfdf2 conflicts with libgcc on aarch64
X-Send-Pr-Version: www-1.0

>Number:         57021
>Category:       lib
>Synopsis:       libc __trunctfdf2 conflicts with libgcc on aarch64
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    lib-bug-people
>State:          closed
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Sat Sep 24 08:40:00 +0000 2022
>Closed-Date:    Sat Oct 22 07:47:46 +0000 2022
>Last-Modified:  Sat Oct 22 07:47:46 +0000 2022
>Originator:     nia
>Release:        NetBSD 9.0
>Organization:
The NetBSD Foundation
>Environment:
>Description:
arch/aarch64/softfloat/qp.c contains a definition of __trunctfdf2.

However, this function is also defined in libgcc, which creates
problems when static linking:

ld: /usr/lib/libc.a(qp.o): in function `__trunctfdf2':
qp.c:(.text+0x110): multiple definition of `__trunctfdf2';
/usr/lib/libgcc.a(trunctfdf2.o):trunctfdf2.c:(.text+0x0): first defined here
>How-To-Repeat:

>Fix:

>Release-Note:

>Audit-Trail:
From: Taylor R Campbell <riastradh@NetBSD.org>
To: nia@pkgsrc.org
Cc: gnats-bugs@NetBSD.org, joerg@NetBSD.org, ryo@NetBSD.org
Subject: Re: kern/57021: libc __trunctfdf2 conflicts with libgcc on aarch64
Date: Sat, 24 Sep 2022 10:52:14 +0000

 lib/libc/arch/aarch64/softfloat/qp.c appears to be entirely redundant
 with libgcc.  I'm not sure why it's there at all.  Every symbol it
 defines is also defined by libgcc and libgcc_s, according to

 % comm -12 <(nm -o --defined-only -g external/gpl3/gcc/lib/libgcc/libgcc/li=
 bgcc.a | awk '{ print $3 }' | sort -u) <(nm -o --defined-only -g lib/libc/q=
 p.o | awk '{ print $3 }' | sort -u)
 __addtf3
 __divtf3
 __extenddftf2
 __extendsftf2
 __fixtfdi
 __fixtfsi
 __floatditf
 __floatsitf
 __floatunditf
 __floatunsitf
 __multf3
 __negtf2
 __subtf3
 __trunctfdf2
 __trunctfsf2
 % comm -13 <(nm -o --defined-only -g external/gpl3/gcc/lib/libgcc/libgcc/li=
 bgcc.a | awk '{ print $3 }' | sort -u) <(nm -o --defined-only -g lib/libc/q=
 p.o | awk '{ print $3 }' | sort -u)
 %=20

 (First comm shows symbols defined by both, second one shows symbols
 defined only by qp.c.)

 The last couple changes to qp.c were to delete various functions:

 __eqtf2
 __getf2
 __gttf2
 __letf2
 __lttf2
 __netf2
 __unordtf2

 So why does qp.c exist?  Can we just nix it?  Or should we keep it and
 nix the definitions in libgcc?

From: Ryo Shimizu <ryo@nerv.org>
To: Taylor R Campbell <riastradh@NetBSD.org>
Cc: nia@pkgsrc.org, gnats-bugs@NetBSD.org, joerg@NetBSD.org,
    ryo@NetBSD.org
Subject: Re: kern/57021: libc __trunctfdf2 conflicts with libgcc on aarch64
Date: Sat, 24 Sep 2022 21:56:11 +0900 (JST)

 >So why does qp.c exist?  Can we just nix it?  Or should we keep it and
 >nix the definitions in libgcc?

 Matt's initial commit originated.
 I wasn't sure either, so I removed only the parts that have caused problems.
 (src/lib/libc/arch/aarch64/softfloat/qp.c r1.2 and r1.3)

 Perhaps removing the whole thing would not be a problem.

 -- 
 ryo shimizu

From: Taylor R Campbell <riastradh@NetBSD.org>
To: nia@pkgsrc.org
Cc: gnats-bugs@NetBSD.org, joerg@NetBSD.org, ryo@NetBSD.org
Subject: Re: lib/57021: libc __trunctfdf2 conflicts with libgcc on aarch64
Date: Mon, 26 Sep 2022 11:35:21 +0000

 joerg@ says this can be fixed by defining each function in a separate
 file, which can also be done by enabling the compiler-rt versions of
 each function in libc instead of using qp.c (which would incidentally
 allow us to delete some code!).

From: nia <nia@NetBSD.org>
To: gnats-bugs@netbsd.org
Cc: 
Subject: Re: lib/57021: libc __trunctfdf2 conflicts with libgcc on aarch64
Date: Mon, 3 Oct 2022 13:03:16 +0000

 On Mon, Sep 26, 2022 at 11:40:02AM +0000, Taylor R Campbell wrote:
 >  joerg@ says this can be fixed by defining each function in a separate
 >  file, which can also be done by enabling the compiler-rt versions of
 >  each function in libc instead of using qp.c (which would incidentally
 >  allow us to delete some code!).
 >  

 I tried this out, and built an aarch64 image using the compiler_rt
 versions. Instead of failing for other reasons, the test program
 now fails with undefined reference to "__floattidf", which seems
 to be a GCC-specific function unavailable in compiler-rt.

From: nia <nia@NetBSD.org>
To: gnats-bugs@netbsd.org
Cc: 
Subject: Re: lib/57021: libc __trunctfdf2 conflicts with libgcc on aarch64
Date: Mon, 3 Oct 2022 13:58:22 +0000

 --i5uHp3FnpYo+Tghf
 Content-Type: text/plain; charset=us-ascii
 Content-Disposition: inline

 On Mon, Oct 03, 2022 at 01:05:02PM +0000, nia wrote:
 >  On Mon, Sep 26, 2022 at 11:40:02AM +0000, Taylor R Campbell wrote:
 >  >  joerg@ says this can be fixed by defining each function in a separate
 >  >  file, which can also be done by enabling the compiler-rt versions of
 >  >  each function in libc instead of using qp.c (which would incidentally
 >  >  allow us to delete some code!).
 >  >  
 >  
 >  I tried this out, and built an aarch64 image using the compiler_rt
 >  versions. Instead of failing for other reasons, the test program
 >  now fails with undefined reference to "__floattidf", which seems
 >  to be a GCC-specific function unavailable in compiler-rt.
 >  

 Never mind, this works.

 --i5uHp3FnpYo+Tghf
 Content-Type: text/plain; charset=us-ascii
 Content-Disposition: attachment; filename="softfloat.diff"

 Index: lib/libc/compiler_rt/Makefile.inc
 ===================================================================
 RCS file: /cvsroot/src/lib/libc/compiler_rt/Makefile.inc,v
 retrieving revision 1.40
 diff -u -p -u -r1.40 Makefile.inc
 --- lib/libc/compiler_rt/Makefile.inc	16 Jun 2021 05:21:08 -0000	1.40
 +++ lib/libc/compiler_rt/Makefile.inc	3 Oct 2022 13:57:06 -0000
 @@ -133,7 +133,11 @@ GENERIC_SRCS+= \
  .endif


 -.if ${MACHINE_CPU} != "aarch64"
 +.if ${MACHINE_CPU} == "aarch64"
 +GENERIC_SRCS+= \
 +	comparetf2.c
 +.endif
 +
  GENERIC_SRCS+= \
  	fixunsdfti.c \
  	fixunssfti.c \
 @@ -145,10 +149,6 @@ GENERIC_SRCS+= \
  	floatuntidf.c \
  	floatuntisf.c \
  	floatuntixf.c
 -.else
 -GENERIC_SRCS+= \
 -	comparetf2.c
 -.endif

  # These have h/w instructions which are always used.
  .if ${LIBC_MACHINE_ARCH} != "alpha" && ${LIBC_MACHINE_CPU} != "aarch64" \
 @@ -250,7 +250,22 @@ GENERIC_SRCS+= \

  .if ${LIBC_MACHINE_CPU} == "aarch64"
  GENERIC_SRCS+= \
 -	clear_cache.c
 +	clear_cache.c \
 +	addtf3.c \
 +	divtf3.c \
 +	multf3.c \
 +	subtf3.c \
 +	trunctfsf2.c \
 +	trunctfdf2.c \
 +	fixdfti.c \
 +	fixtfsi.c \
 +	fixtfdi.c \
 +	extendsftf2.c \
 +	extenddftf2.c \
 +	floatunsitf.c \
 +	floatunditf.c \
 +	floatsitf.c \
 +	floatditf.c
  .endif

  .if ${LIBC_MACHINE_ARCH} == "powerpc" || ${LIBC_MACHINE_ARCH} == "powerpc64"
 Index: lib/libc/arch/aarch64/softfloat/qp.c
 ===================================================================
 RCS file: /cvsroot/src/lib/libc/arch/aarch64/softfloat/qp.c,v
 retrieving revision 1.3
 diff -u -p -u -r1.3 qp.c
 --- lib/libc/arch/aarch64/softfloat/qp.c	27 Aug 2018 16:46:13 -0000	1.3
 +++ lib/libc/arch/aarch64/softfloat/qp.c	3 Oct 2022 13:57:06 -0000
 @@ -38,39 +38,12 @@
   * invoke them directly since long double arguments are passed in FP/SIMD
   * as well as being returned in them while float128 arguments are passed
   * in normal registers.
 + *
 + * XXX: we're using compiler_rt for this now. Only one function remains
 + * that is missing from compiler_rt.
   */

 -long double __addtf3(long double, long double);
 -long double __divtf3(long double, long double);
 -long double __modtf3(long double, long double);
 -long double __multf3(long double, long double);
  long double __negtf2(long double);
 -long double __subtf3(long double, long double);
 -
 -double __trunctfdf2(long double);
 -float __trunctfsf2(long double);
 -
 -long double __extendsftf2(float);
 -long double __extenddftf2(double);
 -
 -long double __floatsitf(int32_t);
 -long double __floatditf(int64_t);
 -
 -long double __floatunsitf(uint32_t);
 -long double __floatunditf(uint64_t);
 -
 -int32_t __fixtfsi(long double);
 -int64_t __fixtfdi(long double);
 -
 -uint32_t __fixuntfsi(long double);
 -uint64_t __fixuntfdi(long double);
 -
 -#if 0
 -long double __floattitf(int128_t);
 -long double __floatuntitf(uint128_t);
 -int128_t __fixtfti(long double);
 -uint128_t __fixuntfti(long double);
 -#endif

  union sf_ieee_flt_u {
  	float fltu_f;
 @@ -88,42 +61,6 @@ union sf_ieee_ldbl_u {
  };

  long double
 -__addtf3(long double ld_a, long double ld_b)
 -{
 -	const union sf_ieee_ldbl_u a = { .ldblu_ld = ld_a };
 -	const union sf_ieee_ldbl_u b = { .ldblu_ld = ld_b };
 -	const union sf_ieee_ldbl_u c = {
 -	    .ldblu_f128 = float128_add(a.ldblu_f128, b.ldblu_f128)
 -	};
 -
 -	return c.ldblu_ld;
 -}
 -
 -long double
 -__divtf3(long double ld_a, long double ld_b)
 -{
 -	const union sf_ieee_ldbl_u a = { .ldblu_ld = ld_a };
 -	const union sf_ieee_ldbl_u b = { .ldblu_ld = ld_b };
 -	const union sf_ieee_ldbl_u c = {
 -	    .ldblu_f128 = float128_div(a.ldblu_f128, b.ldblu_f128)
 -	};
 -
 -	return c.ldblu_ld;
 -}
 -
 -long double
 -__multf3(long double ld_a, long double ld_b)
 -{
 -	const union sf_ieee_ldbl_u a = { .ldblu_ld = ld_a };
 -	const union sf_ieee_ldbl_u b = { .ldblu_ld = ld_b };
 -	const union sf_ieee_ldbl_u c = {
 -	    .ldblu_f128 = float128_mul(a.ldblu_f128, b.ldblu_f128)
 -	};
 -
 -	return c.ldblu_ld;
 -}
 -
 -long double
  __negtf2(long double ld_a)
  {
  	const union sf_ieee_ldbl_u zero = { .ldblu_ld = 0.0 };
 @@ -134,168 +71,3 @@ __negtf2(long double ld_a)

  	return b.ldblu_ld;
  }
 -
 -long double
 -__subtf3(long double ld_a, long double ld_b)
 -{
 -	const union sf_ieee_ldbl_u a = { .ldblu_ld = ld_a };
 -	const union sf_ieee_ldbl_u b = { .ldblu_ld = ld_b };
 -	const union sf_ieee_ldbl_u c = {
 -	    .ldblu_f128 = float128_sub(a.ldblu_f128, b.ldblu_f128)
 -	};
 -
 -	return c.ldblu_ld;
 -}
 -
 -#if 0
 -int
 -__cmptf3(float128 *a, float128 *b)
 -{
 -	const union sf_ieee_ldbl_u a = { .ldblu_ld = ld_a };
 -	const union sf_ieee_ldbl_u b = { .ldblu_ld = ld_b };
 -
 -	if (float128_eq(*a, *b))
 -		return 0;
 -
 -	if (float128_le(*a, *b))
 -		return 1;
 -
 -	return 2;
 -}
 -
 -
 -/*
 - * XXX 
 - */
 -int
 -_Qp_cmpe(float128 *a, float128 *b)
 -{
 -	return _Qp_cmp(a, b);
 -}
 -#endif
 -
 -float
 -__trunctfsf2(long double ld_a)
 -{
 -	const union sf_ieee_ldbl_u a = { .ldblu_ld = ld_a };
 -	const union sf_ieee_flt_u c = {
 -		.fltu_f32 = float128_to_float32(a.ldblu_f128),
 -	};
 -
 -	return c.fltu_f;
 -}
 -
 -double
 -__trunctfdf2(long double ld_a)
 -{
 -	const union sf_ieee_ldbl_u a = { .ldblu_ld = ld_a };
 -	const union sf_ieee_dbl_u c = {
 -		.dblu_f64 = float128_to_float64(a.ldblu_f128),
 -	};
 -
 -	return c.dblu_d;
 -}
 -
 -int32_t
 -__fixtfsi(long double ld_a)
 -{
 -	const union sf_ieee_ldbl_u a = { .ldblu_ld = ld_a };
 -	return float128_to_int32_round_to_zero(a.ldblu_f128);
 -}
 -
 -int64_t
 -__fixtfdi(long double ld_a)
 -{
 -	const union sf_ieee_ldbl_u a = { .ldblu_ld = ld_a };
 -
 -	return float128_to_int64_round_to_zero(a.ldblu_f128);
 -}
 -
 -#if 0
 -uint32_t
 -__fixuntfsi(long double ld_a)
 -{
 -	const union sf_ieee_ldbl_u a = { .ldblu_ld = ld_a };
 -
 -	return float128_to_uint32_round_to_zero(a.ldblu_f128);
 -}
 -
 -uint64_t
 -__fixuntfdi(long double ld_a)
 -{
 -	const union sf_ieee_ldbl_u a = { .ldblu_ld = ld_a };
 -
 -	return float128_to_uint64_round_to_zero(a.ldblu_f128);
 -}
 -#endif
 -
 -long double
 -__extendsftf2(float f_a)
 -{
 -	const union sf_ieee_flt_u a = { .fltu_f = f_a };
 -	const union sf_ieee_ldbl_u c = {
 -		.ldblu_f128 = float32_to_float128(a.fltu_f32)
 -	};
 -
 -	return c.ldblu_ld;
 -}
 -
 -long double
 -__extenddftf2(double d_a)
 -{
 -	const union sf_ieee_dbl_u a = { .dblu_d = d_a };
 -	const union sf_ieee_ldbl_u c = {
 -		.ldblu_f128 = float64_to_float128(a.dblu_f64)
 -	};
 -
 -	return c.ldblu_ld;
 -}
 -
 -long double
 -__floatunsitf(uint32_t a)
 -{
 -	const union sf_ieee_ldbl_u c = {
 -		.ldblu_f128 = int64_to_float128(a)
 -	};
 -
 -	return c.ldblu_ld;
 -}
 -
 -long double
 -__floatunditf(uint64_t a)
 -{
 -	union sf_ieee_ldbl_u c;
 -	const uint64_t msb64 = 1LL << 63;
 -
 -	if (a & msb64) {
 -		static const union sf_ieee_ldbl_u two63 = {
 -			.ldblu_ld = 0x1.0p63
 -		};
 -		
 -		c.ldblu_f128 = int64_to_float128(a ^ msb64);
 -		c.ldblu_f128 = float128_add(c.ldblu_f128, two63.ldblu_f128);
 -	} else {
 -		c.ldblu_f128 = int64_to_float128(a);
 -	}
 -	return c.ldblu_ld;
 -}
 -
 -long double
 -__floatsitf(int32_t a)
 -{
 -	const union sf_ieee_ldbl_u c = {
 -		.ldblu_f128 = int64_to_float128(a)
 -	};
 -
 -	return c.ldblu_ld;
 -}
 -
 -long double
 -__floatditf(int64_t a)
 -{
 -	const union sf_ieee_ldbl_u c = {
 -		.ldblu_f128 = int64_to_float128(a)
 -	};
 -
 -	return c.ldblu_ld;
 -}

 --i5uHp3FnpYo+Tghf--

From: "Nia Alarie" <nia@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc: 
Subject: PR/57021 CVS commit: src/lib/libc
Date: Wed, 5 Oct 2022 10:28:19 +0000

 Module Name:	src
 Committed By:	nia
 Date:		Wed Oct  5 10:28:19 UTC 2022

 Modified Files:
 	src/lib/libc/arch/aarch64/softfloat: qp.c
 	src/lib/libc/compiler_rt: Makefile.inc

 Log Message:
 libc: switch aarch64 to use softfloat functions from compiler_rt

 The old definitions in qp.c being all grouped together in one file
 causes problems when static linking with libgcc (i.e. cc --static-libgcc)
 due to functions like __trunctfdf2 conflicting with libgcc, as seen in
 PR 57021

 We can also add some missing functions like __fixdfti for converting
 a double to an int128_t, the lack of which is currently preventing webkit
 from linking on aarch64, as seen in PR 57022

 Unclear to me if libc is the right place for these functions, but
 we can avoid breaking compatibility right now and maintain the status
 quo while avoiding some obvious immediate problems.
 nm output for libc shows no functions being removed by this change.


 To generate a diff of this commit:
 cvs rdiff -u -r1.3 -r1.4 src/lib/libc/arch/aarch64/softfloat/qp.c
 cvs rdiff -u -r1.40 -r1.41 src/lib/libc/compiler_rt/Makefile.inc

 Please note that diffs are not public domain; they are subject to the
 copyright notices on the relevant files.

State-Changed-From-To: open->closed
State-Changed-By: nia@NetBSD.org
State-Changed-When: Sat, 22 Oct 2022 07:47:46 +0000
State-Changed-Why:
I think we don't want to pull this up because it'll break compat
along the netbsd-9 branch in an annoying way, and a workarond
is available (don't use static libgcc).


>Unformatted:

NetBSD Home
NetBSD PR Database Search

(Contact us) $NetBSD: query-full-pr,v 1.47 2022/09/11 19:34:41 kim Exp $
$NetBSD: gnats_config.sh,v 1.9 2014/08/02 14:16:04 spz Exp $
Copyright © 1994-2022 The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.