-
Notifications
You must be signed in to change notification settings - Fork 1.2k
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
Linux glibc multilib issue with different "march" #1393
Comments
Can you clarify what exactly you mean by this please? FWIW, in my opinion and experience the whole area of multilibs and trying to have a single toolchain that supports multiple I'm leaning towards the approach of building separate toolchains for each specific |
Thanks for your reply. I mean after linux toolchain built, there is only one libc.so in "install_dir/sysroot/lib64/lp64d". But after newlib toolchain built, there are several libc.a, for example in "install_dir/newlib_tuple/lib/rv64imafd/lp64d" and "install_dir/newlib_tuple/lib/rv64imafdc/lp64d". If I disassemble libc.so in "/sysroot/lib64/lp64d" using objdump, I found that in its functions, such as "printf", it used compressed C instructions. If I want to statically compile my program and run it on a risc-v machine without C extension support. The newlib multilib build is fine, but the glibc multilib build will be crash. I known I can fix the problem by build glibc without multilib and with default march=rv64imafd. Thanks |
Maybe because the default set of multilibs enabled by I think that these defaults are used because in the RISC-V world there is a general assumption that a Linux target will support the C (compressed instructions) extension (or more specifically something like Unfortunately the old way of simply regenerating Maybe you can hand edit |
You might get there before me but try this... Change this line:
so that it also specifies
and then build as usual:
This doesn't do exactly what you mentioned in your first post - i.e. building |
Never mind - as I suspected earlier I tried this before and it doesn't work. In spite of changing the list of multilibs in
So only these multilibs:
and no sign of this:
|
If you do this then you get a toolchain with support for the following
But it still doesn't address your question about why the Linux multilibs are organised on disk as they are and why, unlike the bare-metal/newlib toolchain, this doesn't seem to allow for multilibs distinguished by additional extension support... |
I suspect that this is an issue that needs to be flagged/discussed and maybe addressed upstream in the GCC project. |
FWIW the issue is sort of covered here indirectly from the issue that I originally flagged: |
I used to have the confusion. After working on these for years, my understandings are: Newlib is for bare-metal (embedded) platforms, which usually have an optimized, limited hardware (to reduce cost) for a specific use case. Say hardware-1 is (and only) used for scenario-1 that needs rv32imac, hardware-2 only for scenario-2 that needs rv32imafdc, etc. Thus the toolchain needs to build different multi-libs for those requirements. And we don't want to just build a super compatible multilib (say rv32i), since embedded systems usually have many concerns (like code size).
Note that different march/mabi have multlib path encoding. Glibc is for platforms that has OS, which is usually for PCs and servers. These platforms are general purpose, powerful and are able to support different scenarios. There are less concerns comparing with embedded systems. For example, your PC probably have floating point support, but not all the applications running on the PC uses floating points. (This is not the case for embedded systems. The application doesn't need FP? Remove FP support from the hardware!) Also the OS and Glibc are able to choose suitable implementations base on the hardware capabilities at run time. That means a Glibc might have Plus Glibc toolchain usually packaged with OS distributions. So Ubuntu has it's own toolchain package, Arch linux has it's own toolchain package. The OS distributions decide which extensions are the best.
With all the reasons above, we don't need complex multlib path encoding like embedded systems. So we only encodes
Note that different march share the same multlib path encoding. You might already read the great blog post written by @palmer-dabbelt: |
For the newlib multilib build, there are different dirs such as rv64ima, rv64imafd, rv64imafdc.
However, for linux glibc multilib build, the multilib dir name only contains lib(XLEN)/ABI, there is no march dirs.
For example, I built with glibc_multilib_names="rv64imafd-lp64d rv64imafdc-lp64d", and generate t-linux-multilib with "multilib-generator rv64imafd-lp64d--c", then "make linux -j16".
There is only one "libc.a" in "lib64/lp64d/".
However, for newlib build, there are difference libc.a in “rv64imafd/lp64d/” and “rv64imafdc/lp64d/”.
If I build a program with -march=rv64gc or -march=rv64g, the "march" option only affects my code, the code in libc.a is not affected. It cannot choose a libc.a with or without "c" extension.
I found this is in "gcc/gcc/config/riscv/t-linux":
# Only XLEN and ABI affect Linux multilib dir names, e.g. /lib32/ilp32d/
MULTILIB_DIRNAMES := $(patsubst rv32%,lib32,$(patsubst rv64%,lib64,$(MULTILIB_DIRNAMES)))
It will change all rv64xxx into lib64.
Does anyone know why glibc is designed this way?
Why doesn't the multilib directory distinguish between marchs?
Given the current design, how can we statically compile glibc for different -march options?
Thanks
The text was updated successfully, but these errors were encountered: