[PATCH] elf: Hide DT_INIT and DT_FINI functions
Matt Rice
ratmice@gmail.com
Mon Sep 14 20:52:51 GMT 2026
On Sun, Sep 13, 2026 at 5:03 PM Fangrui Song <i@maskray.me> wrote:
>
> On Fri, Sep 11, 2026 at 9:34 PM Matt Rice <ratmice@gmail.com> wrote:
> >
> > On Fri, Sep 11, 2026 at 7:47 PM H.J. Lu <hjl.tools@gmail.com> wrote:
> > >
> > > On Sat, Sep 12, 2026 at 10:12 AM Matt Rice <ratmice@gmail.com> wrote:
> > > >
> > > > On Fri, Sep 11, 2026 at 7:08 PM H.J. Lu <hjl.tools@gmail.com> wrote:
> > > > >
> > > > > On Sat, Sep 12, 2026 at 9:50 AM Matt Rice <ratmice@gmail.com> wrote:
> > > > > >
> > > > > > On Fri, Sep 11, 2026 at 5:16 PM H.J. Lu <hjl.tools@gmail.com> wrote:
> > > > > > >
> > > > > > > On Sat, Sep 12, 2026 at 7:59 AM Matt Rice <ratmice@gmail.com> wrote:
> > > > > > > >
> > > > > > > >
> > > > > > > >
> > > > > > > > On Fri, Sep 11, 2026, 4:38 PM H.J. Lu <hjl.tools@gmail.com> wrote:
> > > > > > > >>
> > > > > > > >> On Sat, Sep 12, 2026 at 7:34 AM Matt Rice <ratmice@gmail.com> wrote:
> > > > > > > >> >
> > > > > > > >> > On Fri, Sep 11, 2026 at 3:55 PM H.J. Lu <hjl.tools@gmail.com> wrote:
> > > > > > > >> > >
> > > > > > > >> > > On Fri, Sep 11, 2026 at 8:10 PM Jan Beulich <jbeulich@suse.com> wrote:
> > > > > > > >> > > >
> > > > > > > >> > > > On 11.09.2026 14:04, H.J. Lu wrote:
> > > > > > > >> > > > > On Fri, Sep 11, 2026 at 7:53 PM Jan Beulich <jbeulich@suse.com> wrote:
> > > > > > > >> > > > >>
> > > > > > > >> > > > >> On 11.09.2026 13:45, H.J. Lu wrote:
> > > > > > > >> > > > >>> On Fri, Sep 11, 2026 at 5:45 PM Jan Beulich <jbeulich@suse.com> wrote:
> > > > > > > >> > > > >>>>
> > > > > > > >> > > > >>>> On 11.09.2026 10:32, H.J. Lu wrote:
> > > > > > > >> > > > >>>>> On Fri, Sep 11, 2026 at 4:10 PM Jan Beulich <jbeulich@suse.com> wrote:
> > > > > > > >> > > > >>>>>>
> > > > > > > >> > > > >>>>>> On 11.09.2026 09:56, H.J. Lu wrote:
> > > > > > > >> > > > >>>>>>> On Fri, Sep 11, 2026 at 2:31 PM Jan Beulich <jbeulich@suse.com> wrote:
> > > > > > > >> > > > >>>>>>>>
> > > > > > > >> > > > >>>>>>>> On 11.09.2026 08:23, H.J. Lu wrote:
> > > > > > > >> > > > >>>>>>>>> On Fri, Sep 11, 2026 at 2:16 PM Jan Beulich <jbeulich@suse.com> wrote:
> > > > > > > >> > > > >>>>>>>>>>
> > > > > > > >> > > > >>>>>>>>>> On 11.09.2026 00:29, H.J. Lu wrote:
> > > > > > > >> > > > >>>>>>>>>>> Hide special functions used by linker to define DT_INIT and DT_FINI in
> > > > > > > >> > > > >>>>>>>>>>> executable and shared library so that they won't be in dynamic symbol
> > > > > > > >> > > > >>>>>>>>>>> table.
> > > > > > > >> > > > >>>>>>>>>>
> > > > > > > >> > > > >>>>>>>>>> I still don't quite understand: In reply to my comment on the original,
> > > > > > > >> > > > >>>>>>>>>> combined patch you said the symbols are hidden. Hidden symbols shouldn't
> > > > > > > >> > > > >>>>>>>>>
> > > > > > > >> > > > >>>>>>>>> I said they are hidden in glibc.
> > > > > > > >> > > > >>>>>>>>
> > > > > > > >> > > > >>>>>>>> Specifically you said "from crti.o in glibc". crti.o is part of what is
> > > > > > > >> > > > >>>>>>>> being linked, so the two symbols being marked hidden there should prevent
> > > > > > > >> > > > >>>>>>>> them from making it into the dynamic symbol table. There must hence be a
> > > > > > > >> > > > >>>>>>>> missing piece.
> > > > > > > >> > > > >>>>>>>
> > > > > > > >> > > > >>>>>>> See:
> > > > > > > >> > > > >>>>>>>
> > > > > > > >> > > > >>>>>>> https://sourceware.org/bugzilla/show_bug.cgi?id=34623
> > > > > > > >> > > > >>>>>>
> > > > > > > >> > > > >>>>>> Adds to the confusion. There you supplied crt.s which doesn't mark the two
> > > > > > > >> > > > >>>>>> symbols hidden. Whereas in said earlier reply you had
> > > > > > > >> > > > >>>>>>
> > > > > > > >> > > > >>>>>> 5: 0000000000000000 0 FUNC GLOBAL HIDDEN 5 _init
> > > > > > > >> > > > >>>>>> 6: 0000000000000000 0 NOTYPE GLOBAL DEFAULT UND _GLOBAL_OFFSET_TABLE_
> > > > > > > >> > > > >>>>>> 7: 0000000000000000 0 FUNC GLOBAL HIDDEN 7 _fini
> > > > > > > >> > > > >>>>>>
> > > > > > > >> > > > >>>>>> How does that fit together? Is what you committed (imo prematurely, despite
> > > > > > > >> > > > >>>>>> Alan having given his okay) merely working around a source bug then? I think
> > > > > > > >> > > > >>>>>> this wants reverting, and if it indeed turns out to be needed, it should be
> > > > > > > >> > > > >>>>>> put back in with a description properly explaining under what conditions
> > > > > > > >> > > > >>>>>> this adjustment (not mandated by the spec) is necessary. After all you
> > > > > > > >> > > > >>>>>> override somebody's decision to deliberately have either of the symbols in
> > > > > > > >> > > > >>>>>> the dynamic symbol table (for whatever good or bad reason).
> > > > > > > >> > > > >>>>>
> > > > > > > >> > > > >>>>> It can be a source code issue:
> > > > > > > >> > > > >>>>>
> > > > > > > >> > > > >>>>> https://sourceware.org/bugzilla/show_bug.cgi?id=23145
> > > > > > > >> > > > >>>>> https://sourceware.org/bugzilla/show_bug.cgi?id=34585
> > > > > > > >> > > > >>>>>
> > > > > > > >> > > > >>>>> But when linker uses a function for DT_INIT, that function shouldn't
> > > > > > > >> > > > >>>>> be global, regardless of whether it is marked hidden.
> > > > > > > >> > > > >>>>
> > > > > > > >> > > > >>>> Says (repeating myself, sorry) which part of the spec? As said - people may
> > > > > > > >> > > > >>>> want to play (good or bad) games, and we shouldn't keep them from doing so.
> > > > > > > >> > > > >>>
> > > > > > > >> > > > >>> Assign info->init_function:
> > > > > > > >> > > > >>>
> > > > > > > >> > > > >>> /* The function to call when the executable or shared object is
> > > > > > > >> > > > >>> loaded. */
> > > > > > > >> > > > >>> const char *init_function;
> > > > > > > >> > > > >>>
> > > > > > > >> > > > >>> /* The function to call when the executable or shared object is
> > > > > > > >> > > > >>> unloaded. */
> > > > > > > >> > > > >>> const char *fini_function;
> > > > > > > >> > > > >>>
> > > > > > > >> > > > >>> to DT_INIT is how GNU ld implements DT_INIT. init_function is
> > > > > > > >> > > > >>> local to an executable or shared object by definition.
> > > > > > > >> > > > >>>
> > > > > > > >> > > > >>> Please study how the C run-time library and ld work together yourself.
> > > > > > > >> > > > >>
> > > > > > > >> > > > >> You already admitted that adding .hidden to the source addresses the issue.
> > > > > > > >> > > > >> You also admitted that nothing in the ELF spec supports the change. I fear
> > > > > > > >> > > > >> I don't see at all what you want to tell me with this newest reply. Again:
> > > > > > > >> > > > >> Please revert. If then you still think the change itself is a good one,
> > > > > > > >> > > > >> re-submit with a much better justification.
> > > > > > > >> > > > >
> > > > > > > >> > > > > ELF spec doesn't deal with implementation details. Mapping _init/_fini to
> > > > > > > >> > > > > DT_INIT and DT_FINI is a linker implementation detail.
> > > > > > > >> > > >
> > > > > > > >> > > > Maybe, yet that still has no effect on the respective symbols' properties.
> > > > > > > >> > > >
> > > > > > > >> > > > > On what basis do you think you are right and others are wrong?
> > > > > > > >> > > >
> > > > > > > >> > > > On the basis that the ELF spec is sufficient here to describe rules on symbol
> > > > > > > >> > > > visibility.
> > > > > > > >> > > >
> > > > > > > >> > >
> > > > > > > >> > > _init and _fini are the part of contract between the run-time and linker to
> > > > > > > >> > > implement DT_INIT and DT_FINI. They are out of scope of ELF spec.
> > > > > > > >> > > They are local to the executable or shared object. They shouldn't
> > > > > > > >> > > be visible outside of the executable or shared object as shown:
> > > > > > > >> > >
> > > > > > > >> > > https://sourceware.org/bugzilla/show_bug.cgi?id=23145
> > > > > > > >> > >
> > > > > > > >> >
> > > > > > > >> > What prevents this from being handled in glibc, by marking these
> > > > > > > >> > symbols with hidden visibility
> > > > > > > >> > rather than by handling these symbol names specially?
> > > > > > > >>
> > > > > > > >> They are handled specially by linker. We just missed it in linker
> > > > > > > >> in the first place. Otherwise, we won't see
> > > > > > > >>
> > > > > > > >> https://sourceware.org/bugzilla/show_bug.cgi?id=23145
> > > > > > > >>
> > > > > > > >> at all.
> > > > > > > >
> > > > > > > >
> > > > > > > > That kind of sidesteps my question, let me ask it slightly differently. Could this be changed in glibc by adding the visibility qualifiers there instead of adding more special cases told?
> > > > > > > >
> > > > > > > > If not why not?
> > > > > > >
> > > > > > > Were you implying that _init and _fini weren't special to linker?
> > > > > >
> > > > > > I wasn't implying anything, I was trying to understand why the fix for
> > > > > > this problem
> > > > > > must be made in the linker itself, and the strength of that argument.
> > > > > >
> > > > > > Whether this is a case of a) for some reason (which I don't
> > > > > > understand) setting the symbol
> > > > > > visibility as hidden in glibc is a non-starter and so it must be fixed in ld.
> > > > > >
> > > > > > or b) this could be fixed in glibc by setting the symbol visibility, but
> > > > > > we can fix this in ld so it applies retroactively to an unpatched glibc,
> > > > > > and further that the bug is so egregious that we should add a special
> > > > > > case to ld.
> > > > >
> > > > > I guess we have a different understanding of what "special case" means.
> > > > > To me, DT_INIT and DT_FINI are special cases in linker. My patch
> > > > > doesn't add new special cases to linker. It updates the existing special cases.
> > > > >
> > > >
> > > > No we don't, but there is an argument to be made that if glibc wants it hidden,
> > > > glibc can arrange by the existing means ld provides to make it hidden.
> > > > If that isn't good enough, if feels like the case for that should be
> > > > made explicitly?
> > > >
> > >
> > > This isn't about what glibc wants. This is what run-time and linker want.
> > > Glibc is one of the run-time libraries.
> >
> > Well... all I can say is I understand the skepticism towards the idea
> > of imposing this
> > from the linker when it appears that the relevant standards the linker
> > follows don't impose the requirement,
> > and it appears the run-time libraries can already let their will be
> > known but do not.
>
> I'm having trouble connecting the idea that "the -init symbol is
> special because it creates a DT_INIT dynamic tag" with the conclusion
> that "it should be marked as hidden".
>
> In the past, it has been perfectly valid for the -init symbol to be
> exported to .dynsym so another component can access it:
>
> ld.bfd -shared -init my_init b.o -o b.so
> ld.bfd a.o b.so # say, a.o has a GOT-generating relocation
> referencing my_init
> # or don't use -init, and let the executable link reference _init
>
> https://sourceware.org/bugzilla/show_bug.cgi?id=34585 does not
> describe a valid issue and should be closed as INVALID.
> It's also an irresponsible report with an overly verbose description.
I don't really disagree with your validity argument. But i'd also argue
that if/when we don't follow the elf standard as written, it'd be a good
idea to have some list of addendum or amendments giving not just a
technical description, but also a justification *why*, so it doesn't get
undone or flagged for the reason of not following the elf specification.
More information about the Binutils
mailing list