Multiple glibc arches in the same image?

Hi, I wanted to know if it is possible to have more than one permutation of multilibs(glibc, libgcc, libstdc++…) in a single final image, or more specifically one compiled with -march=rv64imafdc -mabi=lp64d and the other with -march=rv64imac -mabi=lp64.

Kinda like riscv-gnu-toolchain allows you to do by building all the libraries again, with different CFLAGS and installing libc for example, in $PREFIX/sysroot/lib64/lp64d or $PREFIX/sysroot/lib64/lp64

I found this in the yocto project docs, explaining how to combine 64 and 32 multilibs into a single image, but I’m not sure if and how I can use that for my goal.

Cheers,
Amit

An embedded compiler can be multilibbed because it is self contained. A linux compiler is not. it depends on system libraries like glibc, and it also depends on the kernel. So you have to multilib the OS first, then you can create a compiler that supports the multilib OS.

There are two different ways to multilib linux. There is the old system used by most linux distros (I think). Then there is the multi-arch system designed by Debian which is similar but different, and hence also used by Ubuntu. I don’t know if this is used by any other distros. How you multilib the OS will depend on which distro you are using.

So for instance, a 64-bit x86 linux system might have the original 32-bit libraries in /lib, the 64-bit libraries in /lib64, and the x32 libraries in /lib32. And a gcc binary that can produce code that works with any of the 3 ABIs depending on command line options.

Linux has full support for RISC-V rv64imafdc/lp64d. There was rv32gc/ilp32d support originally for embedded, but it might be bit-rotted as I don’t know if anyone is using it. Desktop linux uses only rv64gc/lp64d. Actually, gentoo was talking about adding 32-bit support a few years ago but I don’t know if they ever got it working. If you want a rv64imac/lp64 linux system, you may have to do some porting work in glibc, linux kernel, and other apps to get it working.

Once you have rv64imac/lp64 working, then you need to figure out how to build a multilib or multiarch OS. Then you can build a gcc that works for that multilib or multiarch OS, which may require gcc patches. Also, I think the multiarch support requires patches that Debian hasn’t upstreamed yet, at least that was the case a few years ago when I last looked.

Yes, in theory, you can use Yocto to build a multilib RISC-V distro that supports both 64-bit and 32-bit libraries. But this is likely to be a major project.

Hi Jim,
I wish to add a query… let us assume the program that we wish to compile under the linux OS can use/not use float (due to power consumption issues, performance, clustering, etc…). In this case, the supper set will be rv64imafdc and the sub-permutation will be rv64imac.
In this case, I think multilib for glibc is a good practice solution, won’t you say?
The target supports the multi-set but can also work with a subset.

The fact that you want rv64imafdc and rv64imac doesn’t change anything. It is a lot of work to multilib a linux system. You still need two copies of every system library, and a way to choose between them. There are also other possible complications.

Consider a context switch. The kernel needs to save all integer and FP registers for the currently running program. But if there is no FP registers, then we need different code to save a process context. And what about the form of the process context, does it have a hole in the middle where the FP registers should be, or do we change the size of the process context to eliminate them? An rv64imac program running on rv64imacfd hardware could save FP registers, but rv64imac code running on rv64imac can’t. If we change the size of the process context without FP regs then a process context saved on a rv64imac machine perhaps can’t be loaded on a rv64imacfd machine which breaks clustering, unless maybe there is a way for the kernel to recognize the two different kinds of process contexts and handle them if possible. Either way, we need kernel changes to make this work.

Consider a program like gdb. If the user asks to print the fp registers, what does it do? We might need a new extension to the ptrace system call to indicate whether FP regs exist of not. And if we have rv64imac code on a rv64imacfd system, and the users tries to write to an FP register, do we allow that? What does that even mean? We might need more code to handle that.

The ISA already has a way to indicate whether a program has used the FP regs or not. The FP regs have a dirty bit to indicate whether they have been used. So a program that doesn’t use FP regs doesn’t have to save/restore on context switch. It isn’t clear that compiling for rv64imac actually saves anything.

1 Like

I agree the main concern is “way to choose between them”, I wonder if multiarch will solve that (like 32 vs 64 arch).

On fp, the kernel needs to check dirty on the context switch. Since the kernel was compiled with rv64imafdc when doing a call to “non using fp program (rv64imac program)” the dirty will not be set, and no save/restore is needed.

For gdb, it should know that the elf it is using dont contain a tag for float, right?

Either debian multiarch or the traditional linux multilib should work. It is just a lot of work to get either one working. The details will have to be worked out by the people doing the work.

If you want info on multiarch, try looking at these. But note that only Debian and descendents (like Ubuntu) use multiarch.
https://wiki.ubuntu.com/MultiarchSpec
https://wiki.debian.org/Multiarch/HOWTO

I’m not sure if there is any good docs for the older scheme, but it is a lot simpler. See for instance the /lib section of the Linux Filesystem Hierarchy Standard.
https://refspecs.linuxfoundation.org/FHS_3.0/fhs/ch03s10.html

2 Likes

Thank you for sharing this..