On Thu, 06 Jul 2023 at 16:33:22 +0000, Thorsten Glaser wrote:
> Simon McVittie dixit:
> >architecture would need to have a new dpkg architecture name, multiarch
> >tuple, GNU tuple (i?86-linux-gnut64?) and canonical ELF linker path.
> 
> Bit of bikeshedding on the name, of course. timet64 (or a shortened
> version) is a possibility but I’d also want off_t to be 64 bit in it
> like the BSDs have been doing for decades, for example.

That's easy, because glibc doesn't support 64-bit time_t without also
having 64-bit off_t (to avoid combinatorial explosion), so there are
three possible 32-bit ABIs instead of the four that you might expect:

1. 32-bit everything
2. large file support (64-bit off_t and inode numbers) but 32-bit time_t
3. large file support as above, and also 64-bit time_t

The current (backwards-compatible) i386 port is (1.) by default. An
opt-in to (2.) is available via -D_FILE_OFFSET_BITS=64 for the subset
of libraries that can support it without breaking ABI, and similarly
-D_FILE_OFFSET_BITS=64 -D_TIME_BITS=64 is an opt-in to (3.).
Specifying -D_TIME_BITS=64 on its own is an error, to avoid creating
a fourth mutually incompatible ABI.

Newer 32-bit ports like x32 started as (2.) or maybe even (3.) by
default.

Your proposed port would be (3.) from the beginning.

On the backwards-compatible i386 port, a lot of libraries already opt-in
to (2.), because it's relatively rare to have off_t or struct stat in
the ABI, therefore a lot of libraries can safely do this without breaking
their own ABI (for example libdbus, GLib and SDL all do this).

*Some* libraries can safely opt-in to (3.) as well (for example I proposed
a merge request for libdbus, and it looks as though SDL is also going
to do this, at least in version 3), but time_t in the ABI seems to be a
lot more common than struct stat in the ABI, so not all libraries can
safely do this (for example, GLib can't do this because unfortunately
it has some time_t in its ABI), hence the need to consider doing this
as a more general transition.

> I would like for things to be coïnstallable, of course. But why would
> the dynamic linker attempt to load the respective foreign libraries…
> oh right, not all are in the M-A path yet

That wasn't actually the reason for my concern. As far as I'm aware, the
glibc dynamic linker doesn't guarantee not to look at libraries from other
architectures' multiarch library directories, or even know which directory
is for which architecture. There's only one /etc/ld.so.conf(.d), which
all architectures share, and similarly there's only one ld.so.cache, so
the dynamic linker needs to be able to distinguish between co-installable
architectures and avoid loading "wrong" libraries.

You can see this by the error message you get if you try to load a
dlopen'd plugin for the wrong architecture, for example running an i386
Vulkan app if you only have amd64 Vulkan drivers: it's often something
like "wrong ELF type", as opposed to the "not found" that you might
expect.

I agree that this is less like amd64 vs x32 vs i386, and more like arm vs
armel vs armhf (all 32-bit ARM and all mutually incompatible). I believe
32-bit mips also has more than one ABI ("o32" and "n32") which might be
useful prior art for what you can and can't do in the ELF header.

(Of course, orthogonally, it would be nice if we could finally stop
shipping shared libraries in the non-multiarch directories before trixie.)

    smcv

Reply via email to