[PATCH] Introduce <elf-initfini.h> and ELF_INITFINI for all architectures
Florian Weimer
fweimer@redhat.com
Fri Feb 21 12:41:00 GMT 2020
* Jim Wilson:
> On Thu, Feb 20, 2020 at 10:53 AM Florian Weimer <fweimer@redhat.com> wrote:
>> That's because libc.so.6 still has DT_INIT, from which _environ and
>> other variables are set up. I assumed binutils would convert that into
>> DT_INITARRAY because the architecture is not supposed to have DT_INIT.
>> Without that, it's hard to declare that there is no DT_INIT, and the
>> patch essentially breaks ABI (because DT_INIT processing is gone).
>
> DT_INIT is a function address. DT_INITARRAY is a pointer to a table
> of addresses. I don't see how the linker can easily convert between
> them. We would have to increase the size of the init_array table at
> link time, and I don't think we have any linker support for that.
> Maybe we could modify the startfiles to put a weak reference to _init
> at the end of init_array, right before the zero that normally ends the
> list, and fix the linker to stop creating DT_INIT for _init. But that
> sounds a little risky, and defeats the purpose of dropping support for
> _init to reduce code size. I would prefer that glibc not create an
> _init function in the first place.
I'm not worried about glibc here. It's easy to make glibc consistent
with itself. The patch I posted seems to do the trick, without
regressing anywhere else.
What I don't know is whether this binutils bug has resulted in DT_INIT
being used *elsewhere*. I don't have a RISC-V distribution to analyze,
so I really don't know. Fedora RISC-V seems dead, this hasn't been
updated in a while:
<https://dl.fedoraproject.org/pub/alt/risc-v/repo/fedora/rawhide/latest/riscv64/>
(I have existing tools for RPM-based distributions, so having one would
be most useful to me to check for DT_INIT references.)
>> But I'm no longer sure if RISC-V is actually an !ELF_INITFINI
>> architecture.
>
> gcc will not create .init sections. Newlib does not create them or
> run them in the startfiles. The linux kernel does not run DT_INIT.
The kernel never runs DT_INIT on any architecture as far as I know, but
currently released glibc does, even on RISC-V.
> That is probably why your patch failed for Andreas.
Yes, looks like it.
> But there is a problem with GNU ld which automatically creates DT_INIT
> when it sees a function called _init. We missed that. This is in
> target dependent code. The default function name can be overridden
> but that isn't quite right for RISC-V either. Maybe we should give a
> linker error if someone gives a _init or _fini function to the linker?
> That way they get a link time error instead of a run-time error.
I would expect the toolchain to treat _init just like any other
function, so without DT_INIT support, it would turn into dead code.
Thanks,
Florian
More information about the Libc-alpha
mailing list