Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

vf2c [punc] uninit.c fails to build on MIPS architecture #71

Open
drew-parsons opened this issue May 31, 2022 · 16 comments
Open

vf2c [punc] uninit.c fails to build on MIPS architecture #71

drew-parsons opened this issue May 31, 2022 · 16 comments

Comments

@drew-parsons
Copy link

drew-parsons commented May 31, 2022

vf2c (punc component) is failing to build on MIPS architecture (specifically mips64el and 32-bit mipsel) on Debian Linux. The problem arises in uninit.c

There is a __mips section in uninit.c with

#ifdef __mips	/* must link with -lfpe */
#define IEEE0_done
/* code from Eric Grosse */
#include <stdlib.h>
#include <stdio.h>
#include "/usr/include/sigfpe.h"        /* full pathname for lcc -N */
#include "/usr/include/sys/fpu.h"

A standard build attempt fails since these header files don't exist (with gcc on linux). A full build log can be found here.

If I skip that section by patching to

#if defined (__mips) && !defined (__linux__)

then the build fails with

[  9%] Building C object _deps/fetk-build/punc/src/vf2c/CMakeFiles/vf2c.dir/uninit.c.o
cd /<<PKGBUILDDIR>>/obj-mips64el-linux-gnuabi64/_deps/fetk-build/punc/src/vf2c && /usr/bin/cc -Dvf2c_EXPORTS -I/<<PKGBUILDDIR>>/debian/external_deps/fetk/punc/src/vf2c -I/<<PKGBUILDDIR>>/debian/external_deps/fetk/punc/src/vf2c/punc -g -O2 -ffile-prefix-map=/<<PKGBUILDDIR>>=. -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2 -fcommon -Wdate-time -D_FORTIFY_SOURCE=2 -I/usr/include/tirpc -O2 -g -DNDEBUG -fPIC -fPIC -MD -MT _deps/fetk-build/punc/src/vf2c/CMakeFiles/vf2c.dir/uninit.c.o -MF CMakeFiles/vf2c.dir/uninit.c.o.d -o CMakeFiles/vf2c.dir/uninit.c.o -c /<<PKGBUILDDIR>>/debian/external_deps/fetk/punc/src/vf2c/uninit.c
/<<PKGBUILDDIR>>/debian/external_deps/fetk/punc/src/vf2c/uninit.c: In function ‘ieee0’:
/<<PKGBUILDDIR>>/debian/external_deps/fetk/punc/src/vf2c/uninit.c:302:17: error: ‘_FPU_MASK_IM’ undeclared (first use in this function)
  302 |         cw &= ~(_FPU_MASK_IM | _FPU_MASK_ZM | _FPU_MASK_OM);
      |                 ^~~~~~~~~~~~
/<<PKGBUILDDIR>>/debian/external_deps/fetk/punc/src/vf2c/uninit.c:302:17: note: each undeclared identifier is reported only once for each function it appears in
/<<PKGBUILDDIR>>/debian/external_deps/fetk/punc/src/vf2c/uninit.c:302:32: error: ‘_FPU_MASK_ZM’ undeclared (first use in this function)
  302 |         cw &= ~(_FPU_MASK_IM | _FPU_MASK_ZM | _FPU_MASK_OM);
      |                                ^~~~~~~~~~~~
/<<PKGBUILDDIR>>/debian/external_deps/fetk/punc/src/vf2c/uninit.c:302:47: error: ‘_FPU_MASK_OM’ undeclared (first use in this function)
  302 |         cw &= ~(_FPU_MASK_IM | _FPU_MASK_ZM | _FPU_MASK_OM);
      |                                               ^~~~~~~~~~~~
make[3]: *** [_deps/fetk-build/punc/src/vf2c/CMakeFiles/vf2c.dir/build.make:331: _deps/fetk-build/punc/src/vf2c/CMakeFiles/vf2c.dir/uninit.c.o] Error 1
make[3]: Leaving directory '/<<PKGBUILDDIR>>/obj-mips64el-linux-gnuabi64'
make[2]: *** [CMakeFiles/Makefile2:764: _deps/fetk-build/punc/src/vf2c/CMakeFiles/vf2c.dir/all] Error 2

Full build log here. This error also occurs on riscv64.

mipsel (32-bit) gives the same build errors as mips64el.

@drew-parsons
Copy link
Author

drew-parsons commented May 31, 2022

For linux, uninit.c has

#ifdef __linux__
#define IEEE0_done
#include "fpu_control.h"

On standard intel (amd64), /usr/include/x86_64-linux-gnu/fpu_control.h defines the masks in question:

/* masking of interrupts */
#define _FPU_MASK_IM  0x01
#define _FPU_MASK_DM  0x02
#define _FPU_MASK_ZM  0x04
#define _FPU_MASK_OM  0x08
#define _FPU_MASK_UM  0x10
#define _FPU_MASK_PM  0x20

On mips (mips64el), /usr/include/mips64el-linux-gnuabi64/fpu_control.h provides different mask definitions:

/* Masks for interrupts.  */
#define _FPU_MASK_V     0x0800  /* Invalid operation */
#define _FPU_MASK_Z     0x0400  /* Division by zero  */
#define _FPU_MASK_O     0x0200  /* Overflow          */
#define _FPU_MASK_U     0x0100  /* Underflow         */
#define _FPU_MASK_I     0x0080  /* Inexact operation */

@drew-parsons
Copy link
Author

We can see the MIPS maskes are essentially the same (in name). The "standard" masks simply append an extra 'M' at the end.
It seems to be sufficient to just provide a mips-specific variant (without the final 'M' in the name) for the cw line at l.302 (on top of skipping the earlier __mips section on linux systems)

@sobolevnrm
Copy link
Member

@nsoblath do you have time to look at this?

@drew-parsons
Copy link
Author

just provide a mips-specific variant

Actually, since riscv64 is also affected, a more general test at l.302 would probably work better, e.g.

#ifdef _FPU_MASK_IM
    cw &= ~(_FPU_MASK_IM | _FPU_MASK_ZM | _FPU_MASK_OM);
#else
    cw &= ~(_FPU_MASK_I | _FPU_MASK_Z | _FPU_MASK_O);
#endif

@nsoblath
Copy link
Collaborator

nsoblath commented Jun 1, 2022

@sobolevnrm Yes, I can work on this.

@yuzibo
Copy link

yuzibo commented Jun 2, 2022

just provide a mips-specific variant

Actually, since riscv64 is also affected, a more general test at l.302 would probably work better, e.g.

#ifdef _FPU_MASK_IM
    cw &= ~(_FPU_MASK_IM | _FPU_MASK_ZM | _FPU_MASK_OM);
#else
    cw &= ~(_FPU_MASK_I | _FPU_MASK_Z | _FPU_MASK_O);
#endif

Aha, this is not work on riscv64:

/<<PKGBUILDDIR>>/debian/external_deps/fetk/punc/src/vf2c/uninit.c:305:17: error: ‘_FPU_MASK_I’ undeclared (first use in this function)
  305 |         cw &= ~(_FPU_MASK_I | _FPU_MASK_Z | _FPU_MASK_O);
      |                 ^~~~~~~~~~~
/<<PKGBUILDDIR>>/debian/external_deps/fetk/punc/src/vf2c/uninit.c:305:17: note: each undeclared identifier is reported only once for each function it appears in
/<<PKGBUILDDIR>>/debian/external_deps/fetk/punc/src/vf2c/uninit.c:305:31: error: ‘_FPU_MASK_Z’ undeclared (first use in this function)
  305 |         cw &= ~(_FPU_MASK_I | _FPU_MASK_Z | _FPU_MASK_O);
      |                               ^~~~~~~~~~~
/<<PKGBUILDDIR>>/debian/external_deps/fetk/punc/src/vf2c/uninit.c:305:45: error: ‘_FPU_MASK_O’ undeclared (first use in this function)
  305 |         cw &= ~(_FPU_MASK_I | _FPU_MASK_Z | _FPU_MASK_O);
      |                                             ^~~~~~~~~~~
make[3]: *** [_deps/fetk-build/punc/src/vf2c/CMakeFiles/vf2c.dir/build.make:331: _deps/fetk-build/punc/src/vf2c/CMakeFiles/vf2c.dir/uninit.c.o] Error 1

@drew-parsons
Copy link
Author

That is a pity. @yuzibo , do you have access to the riscv64 system? It might be possible to figure out what riscv64 needs from the definitions in /usr/include/*/fpu_control.h

@drew-parsons
Copy link
Author

drew-parsons commented Jun 3, 2022

riscv64 might not be so simple. The code can be found in sysdeps/riscv in the glibc source. Their fpu_control.h is just

/* FPU control word bits.  RISC-V version.
   Copyright (C) 1996-2022 Free Software Foundation, Inc.
   This file is part of the GNU C Library.

   The GNU C Library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 of the License, or (at your option) any later version.

   The GNU C Library is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library.  If not, see
   <https://www.gnu.org/licenses/>.  */

#ifndef _FPU_CONTROL_H
#define _FPU_CONTROL_H

#include <features.h>

#ifndef __riscv_flen

# define _FPU_RESERVED 0xffffffff
# define _FPU_DEFAULT  0x00000000
typedef unsigned int fpu_control_t;
# define _FPU_GETCW(cw) (cw) = 0
# define _FPU_SETCW(cw) do { } while (0)
extern fpu_control_t __fpu_control;

#else /* __riscv_flen */

# define _FPU_RESERVED 0
# define _FPU_DEFAULT  0
# define _FPU_IEEE     _FPU_DEFAULT

/* Type of the control word.  */
typedef unsigned int fpu_control_t __attribute__ ((__mode__ (__SI__)));

/* Macros for accessing the hardware control word.  */
# define _FPU_GETCW(cw) __asm__ volatile ("frsr %0" : "=r" (cw))
# define _FPU_SETCW(cw) __asm__ volatile ("fssr %z0" : : "rJ" (cw))

/* Default control word set at startup.  */
extern fpu_control_t __fpu_control;

# define _FCLASS(x) (__extension__ ({ int __res; \
  if (sizeof (x) * 8 > __riscv_flen) __builtin_trap (); \
  if (sizeof (x) == 4) asm ("fclass.s %0, %1" : "=r" (__res) : "f" (x)); \
  else if (sizeof (x) == 8) asm ("fclass.d %0, %1" : "=r" (__res) : "f" (x)); \
  else __builtin_trap (); \
  __res; }))

# define _FCLASS_MINF     (1 << 0)
# define _FCLASS_MNORM    (1 << 1)
# define _FCLASS_MSUBNORM (1 << 2)
# define _FCLASS_MZERO    (1 << 3)
# define _FCLASS_PZERO    (1 << 4)
# define _FCLASS_PSUBNORM (1 << 5)
# define _FCLASS_PNORM    (1 << 6)
# define _FCLASS_PINF     (1 << 7)
# define _FCLASS_SNAN     (1 << 8)
# define _FCLASS_QNAN     (1 << 9)
# define _FCLASS_ZERO     (_FCLASS_MZERO | _FCLASS_PZERO)
# define _FCLASS_SUBNORM  (_FCLASS_MSUBNORM | _FCLASS_PSUBNORM)
# define _FCLASS_NORM     (_FCLASS_MNORM | _FCLASS_PNORM)
# define _FCLASS_INF      (_FCLASS_MINF | _FCLASS_PINF)
# define _FCLASS_NAN      (_FCLASS_SNAN | _FCLASS_QNAN)

#endif /* __riscv_flen */

so it doesn't have the _FPU_MASKs that the other arches have.

@yuzibo
Copy link

yuzibo commented Jun 3, 2022

Hi, I got it work at last to define these macroes in uninit.c, here:
https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1012302
I think it is ok becasue it has passed its test cases on riscv64 also:)

@drew-parsons
Copy link
Author

Thanks @yuzibo . riscv64 seems to build fine with that patch.

@atzlinux
Copy link

Thanks @yuzibo . riscv64 seems to build fine with that patch.

The patch come from yuzibo, Is it need to apply to this repo and release a new version?

@yuzibo
Copy link

yuzibo commented Jun 15, 2022

I am not sure about it.
Does it seem that the fpu_control.h is under glibc? I was wondering if it would be appropriate to forward this to glibc?

@atzlinux
Copy link

atzlinux commented Jun 15, 2022 via email

@sobolevnrm
Copy link
Member

Is this issue still a problem? I'm not sure how to troubleshoot without access to the relevant system. I don't think Docker is an option to mimic the environment and troubleshoot this, right?

@yuzibo
Copy link

yuzibo commented Oct 17, 2022

hi, @sobolevnrm,
On Debian the patch[0] for riscv64 arch has been merged, But I am not sure the repo how to deal with the patch for the upstream.
If you want to access with remotely on real riscv64 hardware on Debian sid, I can suggest you here[1]:
[0]: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1012302
[1]: https://github.com/plctlab/riscv-lab-access
Or do you know how to forward this to upstream?(glibc? I guess).

@KatyushaScarlet
Copy link

These can also be added to support loongarch64

#if defined(__loongarch64)
/* Masks for __loongarch64 interrupts.  */
#define _FPU_MASK_V     0x10 /* Invalid operation */
#define _FPU_MASK_Z     0x08 /* Division by zero  */
#define _FPU_MASK_O     0x04 /* Overflow          */
#define _FPU_MASK_U     0x02 /* Underflow         */
#define _FPU_MASK_I     0x01 /* Inexact operation */
#endif

These masks have been defined since
glibc 2.36

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants