Code Monkey home page Code Monkey logo

riscv-newlib's Introduction

		   README for GNU development tools

This directory contains various GNU compilers, assemblers, linkers, 
debuggers, etc., plus their support routines, definitions, and documentation.

If you are receiving this as part of a GDB release, see the file gdb/README.
If with a binutils release, see binutils/README;  if with a libg++ release,
see libg++/README, etc.  That'll give you info about this
package -- supported targets, how to use it, how to report bugs, etc.

It is now possible to automatically configure and build a variety of
tools with one command.  To build all of the tools contained herein,
run the ``configure'' script here, e.g.:

	./configure 
	make

To install them (by default in /usr/local/bin, /usr/local/lib, etc),
then do:
	make install

(If the configure script can't determine your type of computer, give it
the name as an argument, for instance ``./configure sun4''.  You can
use the script ``config.sub'' to test whether a name is recognized; if
it is, config.sub translates it to a triplet specifying CPU, vendor,
and OS.)

If you have more than one compiler on your system, it is often best to
explicitly set CC in the environment before running configure, and to
also set CC when running make.  For example (assuming sh/bash/ksh):

	CC=gcc ./configure
	make

A similar example using csh:

	setenv CC gcc
	./configure
	make

Much of the code and documentation enclosed is copyright by
the Free Software Foundation, Inc.  See the file COPYING or
COPYING.LIB in the various directories, for a description of the
GNU General Public License terms under which you can copy the files.

REPORTING BUGS: Again, see gdb/README, binutils/README, etc., for info
on where and how to report problems.

riscv-newlib's People

Contributors

aadit0402 avatar amylaar avatar bonzini avatar brianinglis avatar cagney avatar davek-cygwin avatar djdelorierh avatar ebblake avatar fitzsim avatar gingold-adacore avatar github-cygwin avatar haubi avatar hjl-tools avatar hpataxisdotcom avatar jakubjelinek avatar jjohnstn avatar joelsherrill avatar jon-turney avatar joshuadfranklin avatar jsm28 avatar kbrow1i avatar mshawcroft avatar nickclifton avatar rbtcollins avatar rsandifo avatar sebhub avatar thomasp-66 avatar tyan0 avatar vapier avatar yselkowitz avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

riscv-newlib's Issues

Build failure with riscv32-elf gcc 7.0.1

When building the latest riscv-newlib-2.4.0 branch against an upstream gcc configured as riscv32-elf, it will fail to build, complaining about some lp64 subdir trying to use elf64-littleriscv:

https://build.opensuse.org/package/live_build_log/home:a_faerber:riscv/cross-riscv32-newlib-devel/openSUSE_Leap_42.2/x86_64

If using a riscv64-elf gcc, it will succeed to build:

https://build.opensuse.org/package/live_build_log/home:a_faerber:riscv/cross-riscv64-newlib-devel/openSUSE_Leap_42.2/x86_64

I would expect newlib to simply not enter 64-bit directories with a 32-bit only toolchain.

Note that upstream binutils 2.28 does not support a generic riscv-elf target, so it would seem weird to force everyone into using riscv64-elf for 32-bit development.

atexit() can only register 31 functions

Both C and POSIX requires at least 32 functions to be registered by atexit(), but RISC-V already uses one for __libc_fini_array in libgloss, so only 31 functions can be registered by users.

#include <stdlib.h>
#include <stdio.h>

void fn(void) {}

int main(void) {
    for (int i = 0; i < 32; ++i) {
        printf("%d: atexit(fn) = %d\n", i, atexit(fn));
    }

    return 0;
}

Sample output:

0: atexit(fn) = 0
1: atexit(fn) = 0
2: atexit(fn) = 0
...
30: atexit(fn) = 0
31: atexit(fn) = -1

Perhaps we should use other mechanisms to call __libc_fini_array or increase _ATEXIT_SIZE to compensate for that.

nano.specs not using the nano version of the C++ libraries

I've just built a new version of the RISC-V bare-metal toolchain, using GCC 11.3 and the latest newlib, including the newlinb-nano libraries, and I noticed that the nano.spec does not replace the -lstdc++ and -lsupc++ with their size optimised nano versions, as the Arm bare-metal toolchains do.

For example, the arm-none-eabi toolchains uses:

*link:
%(nano_link) %:replace-outfile(-lc -lc_nano) %:replace-outfile(-lg -lg_nano) %:replace-outfile(-lrdimon -lrdimon_nano) %:replace-outfile(-lstdc++ -lstdc++_nano) %:replace-outfile(-lsupc++ -lsupc++_nano)

while the riscv-none-embed toolchain uses:

*link:
%(nano_link) %:replace-outfile(-lc -lc_nano) %:replace-outfile(-lg -lg_nano) %:replace-outfile(-lm -lm_nano)

Could we add the same substitutions to the RISC-V newlib in order to make applications using newlib-nano benefit from the size optimised versions of the C++ libraries?

If so, what is the procedure to get such a patch accepted upstream?

crt0.S does not get argv[] using SYS_GETCMDLINE

The startup code expects the main() arguments to be processed by someone else and does not call SYS_GETCMDLINE to get them, as specified by Arm semihosting:

This might work on some specific platforms, but generally it fails, since that area is right after the stack, usually an invalid memory region.

The workaround for semihosted applications it to rewrite the startup code.

The solution for newlib is to replicate the logic used by the Arm startup code, which processes the arguments properly.

It might also be a good idea to call SYS_HEAPINFO and properly process the heap/stack.

Programs using fenv do not compile with newlib

I'm trying to compile a simple program for RISCV with newlib that uses fenv to set the rounding mode.

#include <cstdio>
#include <cmath>
#include <cfenv>

int main(int argc, char **argv)
{
    float fs1 = 2.0;
    float fs2 = 3.0;
    float f;

    std::fesetround(FE_TONEAREST);
    f = fs1 / fs2;
    printf("%f\n", f);

    std::fesetround(FE_TOWARDZERO);
    f = fs1 / fs2;
    printf("%f\n", f);

    std::fesetround(FE_UPWARD);
    f = fs1 / fs2;
    printf("%f\n", f);

    std::fesetround(FE_DOWNWARD);
    f = fs1 / fs2;
    printf("%f\n", f);

    return 0;
}

This compiles with the linux/glibc build of the toolchain:

$ riscv64-unknown-linux-gnu-g++ -std=c++11 -o /tmp/log2 /tmp/log2.cc
$

but not with newlib:

$ riscv64-unknown-elf-g++ -std=c++11 -o /tmp/fenv-newlib /tmp/fenv-newlib.cc
/tmp/fenv-newlib.cc: In function 'int main(int, char**)':
/tmp/fenv-newlib.cc:11:10: error: 'fesetround' is not a member of 'std'
     std::fesetround(FE_TONEAREST);
          ^~~~~~~~~~
/tmp/fenv-newlib.cc:11:21: error: 'FE_TONEAREST' was not declared in this scope
     std::fesetround(FE_TONEAREST);
                     ^~~~~~~~~~~~
/tmp/fenv-newlib.cc:15:10: error: 'fesetround' is not a member of 'std'
     std::fesetround(FE_TOWARDZERO);
          ^~~~~~~~~~
/tmp/fenv-newlib.cc:15:21: error: 'FE_TOWARDZERO' was not declared in this scope
     std::fesetround(FE_TOWARDZERO);
                     ^~~~~~~~~~~~~
/tmp/fenv-newlib.cc:19:10: error: 'fesetround' is not a member of 'std'
     std::fesetround(FE_UPWARD);
          ^~~~~~~~~~
/tmp/fenv-newlib.cc:19:21: error: 'FE_UPWARD' was not declared in this scope
     std::fesetround(FE_UPWARD);
                     ^~~~~~~~~
/tmp/fenv-newlib.cc:23:10: error: 'fesetround' is not a member of 'std'
     std::fesetround(FE_DOWNWARD);
          ^~~~~~~~~~
/tmp/fenv-newlib.cc:23:21: error: 'FE_DOWNWARD' was not declared in this scope
     std::fesetround(FE_DOWNWARD);
                     ^~~~~~~~~~~
$

Looking at the preprocessor output reveals that for the newlib toolchain there is no output from processing cfenv:

...
# 3 "/tmp/fenv-newlib.cc" 2
# 1 "/opt/esperanto/minion-sim-toolchains/gcc-newlib/riscv64-unknown-elf/include/c++/7.0.1/cfenv" 1 3
# 32 "/opt/esperanto/minion-sim-toolchains/gcc-newlib/riscv64-unknown-elf/include/c++/7.0.1/cfenv" 3

# 33 "/opt/esperanto/minion-sim-toolchains/gcc-newlib/riscv64-unknown-elf/include/c++/7.0.1/cfenv" 3
# 4 "/tmp/fenv-newlib.cc" 2


# 5 "/tmp/fenv-newlib.cc"
int main(int argc, char **argv)
{
    float fs1 = 2.0;
    float fs2 = 3.0;
    float f;

    std::fesetround(FE_TONEAREST);
    f = fs1 / fs2;
    printf("%f\n", f);

    std::fesetround(FE_TOWARDZERO);
    f = fs1 / fs2;
    printf("%f\n", f);

    std::fesetround(FE_UPWARD);
    f = fs1 / fs2;
    printf("%f\n", f);

    std::fesetround(FE_DOWNWARD);
    f = fs1 / fs2;
    printf("%f\n", f);

    return 0;
}

Looking at the header file, it appears to be expecting the _GLIBCXX_USE_C99_FENV_TR1 macro to be defined:

$ less .../riscv-tools-newlib-stock/riscv64-unknown-elf/include/c++/7.1.1/cfenv
...
#if _GLIBCXX_USE_C99_FENV_TR1
...
namespace std
{
  // types
  using ::fenv_t;
  using ::fexcept_t;

  // functions
  using ::feclearexcept;
  using ::fegetexceptflag;
  using ::feraiseexcept;
  using ::fesetexceptflag;
  using ::fetestexcept;

  using ::fegetround;
  using ::fesetround;

  using ::fegetenv;
  using ::feholdexcept;
  using ::fesetenv;
  using ::feupdateenv;
} // namespace std

#endif // _GLIBCXX_USE_C99_FENV_TR1
...

newlib 2.5.0 and upstreaming

As discussed at FOSDEM with @arunthomas, for Linux distros like openSUSE to pick up RISC-V toolchains, your target support needs to be in the respective upstream projects (and released tarballs).

At present, binutils 2.28 and gcc 7.0.1 do contain RISC-V target support, but apparently not yet newlib, without which no riscv64-elf gcc cross-toolchain can be packaged by us yet, despite all other pieces being present.

Of course getting such things merged may take time, but there not being a 2.5.0 based branch here yet makes me doubt this is in progress already... Is anything in particular holding this up? I thought only glibc and Linux are blocked by the non-final Privileged ISA Specification, which should not impact, e.g., the HiFive1 board that newlib would be used for?

More general, https://riscv.org/software-tools/risc-v-gnu-compiler-toolchain/ does not seem to textually track the upstreaming progress anywhere, in terms of links to patchsets or done vs. to-do lists? It exclusively refers to your GitHub based projects, no direct instructions for how to configure the official tarballs where upstreaming is completed, and the last toolchain related news items were in early 2015. As convenient as your submodule projects may be for early RISC-V users building toolchains themselves, please understand that your submodules are not suitable for distribution and that they hide important configuration details in your riscv-gnu-toolchain Makefile.in and configure.ac files that would be really useful to clearly state somewhere on the official RISC-V site.

printf() returns positive sign for negative value

The %f, %g and %e format specifiers for sprintf() and printf() fail to return the proper sign. The result varies depending upon the mix of printf() calls...

The following produces the incorrect sign for all three of the printf() calls:

$ cat /tmp/negfloat.c

#include <stdio.h>
#include <stdint.h>

int main(int argc, char **argv)
{
    char buf[1024];
    float minusOnePtOne = -1.1;

    printf("%+f\n", minusOnePtOne);
    printf("%+g\n", minusOnePtOne);
    printf("%+e\n", minusOnePtOne);

}
$ riscv64-unknown-elf-gcc -o /tmp/negfloat-rv64 /tmp/negfloat.c
$ spike pk /tmp/negfloat-rv64 
+1.100000
+1.1
+1.100000e+00
$

It appears that just adding a single sprintf() call before the printf() calls forces them to return the correct results:

$ cat /tmp/negfloat.c

#include <stdio.h>
#include <stdint.h>

int main(int argc, char **argv)
{
    char buf[1024];
    float minusOnePtOne = -1.1;

    sprintf(buf, "%+f", minusOnePtOne);

    printf("%+f\n", minusOnePtOne);
    printf("%+g\n", minusOnePtOne);
    printf("%+e\n", minusOnePtOne);

}
$ riscv64-unknown-elf-gcc -o /tmp/negfloat-rv64 /tmp/negfloat.c
$ spike pk /tmp/negfloat-rv64
-1.100000
-1.1
-1.100000e+00
$

And moving the sprintf() between the first two printf() calls produces the correct result for the second two printf() calls:

$ cat /tmp/negfloat.c 

#include <stdio.h>
#include <stdint.h>

int main(int argc, char **argv)
{
    char buf[1024];
    float minusOnePtOne = -1.1;

    printf("%+f\n", minusOnePtOne);

    sprintf(buf, "%+f", minusOnePtOne);

    printf("%+g\n", minusOnePtOne);
    printf("%+e\n", minusOnePtOne);

}
$ riscv64-unknown-elf-gcc -o /tmp/negfloat-rv64 /tmp/negfloat.c
$ spike pk /tmp/negfloat-rv64
+1.100000
-1.1
-1.100000e+00
$

This is the version of GCC being used:

$ riscv64-unknown-elf-gcc --version
riscv64-unknown-elf-gcc (GCC) 7.1.1 20170509
Copyright (C) 2017 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

$

How is the stack pointer set in the newlib library?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.