pkgsrc-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

pkg/43082: gstreamer __uint128_t division on DragonFly x86_64 gcc 4.1.2 undefined reference to __udivti3



>Number:         43082
>Category:       pkg
>Synopsis:       gstreamer __uint128_t division on DragonFly x86_64 gcc 4.1.2 
>undefined reference to __udivti3
>Confidential:   no
>Severity:       serious
>Priority:       high
>Responsible:    pkg-manager
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Tue Mar 30 18:10:00 +0000 2010
>Originator:     David Shao
>Release:        DragonFly 2.7 DEVELOPMENT x86_64
>Organization:
>Environment:
DragonFly  2.7-DEVELOPMENT DragonFly v2.7.0.4.g63c2a-DEVELOPMENT #11: Mon Mar 
29 07:30:32 PDT 2010     root@:/usr/obj/usr/src/sys/X86_64_GENERIC  x86_64

>Description:
pkgsrc gstreamer0.10 on x86_64 DragonFly 2.7-DEVELOPMENT will not build or will 
build depending on the version of gcc compiler chosen.  Using the default gcc 
4.1.2 produces a build error of an undefined reference to __udivti3, while gcc 
4.4 allows the build to finish.

A simpler version of the problem can be reproduced by simply performing 
division of __uint128_t that apparently gets converted to software integer 
routines, the __udivti3 defined for gcc 4.4's version of libgcc but not for gcc 
4.1.2.

There is a workaround to use MAKEFLAGS to choose the gcc 4.4 compiler which 
enables not only gstreamer0.10 but also the entire meta-pkgs/xfce4 to be built 
and to run on x86_64 DragonFly.  However no testing has been done to see if 
gstreamer itself is functional or whether there would be an eventual problem 
mixing gcc 4.1.2 with 4.2 compiled code.
>How-To-Repeat:
Using DragonFly git version of pkgsrc
commit 654d452774504f3d86381ee580dfd9532c7578fc
Author: Charlie <root%crater.dragonflybsd.org@localhost>
Date:   Mon Mar 29 18:48:09 2010 -0700

    update Mon Mar 29 18:37:00 PDT 2010

on x86_64 DragonFly 2.7 DEVELOPMENT
# bmake install
produces

Making all in helpers
  CC    gst_plugin_scanner-gst-plugin-scanner.o
  LINK  gst-plugin-scanner
../../../gst/.libs/libgstreamer-0.10.so: undefined reference to `__udivti3'


The following code can be distilled from similar code in
/usr/pkgsrc/multimedia/gstreamer0.10/work/gstreamer-0.10.28/gst/gstutils.c

$ cat div128.c
#include <inttypes.h>
#include <stdio.h>

int main(void)
{
  __uint128_t num = 1000;
  __uint128_t denom = 10;
  __uint128_t res = num / denom;
  printf("Result = %ju\n", (uintmax_t)res); 
  return 0;
}

which depending on gcc version of Dragonfly x86_64 used produces

$ gcc div128.c
/tmp//ccHUakkJ.o: In function `main':
div128.c:(.text+0x39): undefined reference to `__udivti3'
$ CCVER=gcc44 gcc -Wall -Werror div128.c
$ ./a.out
Result = 100

The gstutils.c code has various branches for integer arithmetic:  apparently 
during configuration gstreamer detects __uint128_t usability and chooses that 
branch.  We believe the __uint128_t division occurs in gstutils.c in the code 
section:

#define GST_MAXUINT128 ((__uint128_t) -1)
static guint64
gst_util_uint64_scale_uint64_unchecked (guint64 val, guint64 num,
    guint64 denom, guint64 correct)
{
  __uint128_t tmp;

  /* Calculate val * num */
  tmp = ((__uint128_t) val) * ((__uint128_t) num);

  /* overflow checks */
  if (G_UNLIKELY (GST_MAXUINT128 - correct < tmp))
    return G_MAXUINT64;

  /* perform rounding correction */
  tmp += correct;

  /* Divide by denom */
  tmp /= denom;


>Fix:
A patch similar to the following is a workaround.  To repeat, it is unknown 
whether the functionality for gstreamer is impaired or even incompatible if 
using a different compiler version.

--- pkgsrc/multimedia/gstreamer0.10/Makefile.orig       2010-03-29 16:04:23 
-0700
+++ pkgsrc/multimedia/gstreamer0.10/Makefile    2010-03-29 16:09:04 -0700
@@ -44,6 +44,11 @@
 
 .include "../../mk/bsd.prefs.mk"
 
+# __udivti3 error otherwise
+.if ${OPSYS} == "DragonFly" && ${MACHINE_ARCH} == "x86_64"
+MAKEFLAGS+=    CCVER=gcc44
+.endif
+
 .if ${OPSYS} == "NetBSD"
 # We must have a glib2 compiled with the RTLD_GLOBAL fix; if not, plugins
 # won't work at all.



Home | Main Index | Thread Index | Old Index