[PATCH] elf: Hide DT_INIT and DT_FINI functions

H.J. Lu hjl.tools@gmail.com
Sat Sep 12 00:16:22 GMT 2026


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?  But
_init and _fini are special to run-time and linker.  They should be made
local when used to implement DT_INIT and DT_FINI.   Linker should
make them local so that a run-time implementation doesn't have to do it.
When linker didn't do it,  run-time had no choice:

commit 67c0579669ba1fc265d770252fab31babf887329
Author:     H.J. Lu <hjl.tools@gmail.com>
AuthorDate: Fri Jun 8 10:28:38 2018 -0700
Commit:     H.J. Lu <hjl.tools@gmail.com>
CommitDate: Fri Jun 8 10:28:52 2018 -0700

    Mark _init and _fini as hidden [BZ #23145]

    _init and _fini are special functions provided by glibc for linker to
    define DT_INIT and DT_FINI in executable and shared library.  They
    should never be put in dynamic symbol table.  This patch marks them as
    hidden to remove them from dynamic symbol table.

If linker had made them local in the first place, we wouldn't
run into this glibc bug.   Linker change prevents another issue
of a different run-time library like the glibc bug.

-- 
H.J.


More information about the Binutils mailing list