Bug 19140 - __star_* and __stop_* symbols show up in dynamic relocation
Summary: __star_* and __stop_* symbols show up in dynamic relocation
Status: RESOLVED INVALID
Alias: None
Product: binutils
Classification: Unclassified
Component: gold (show other bugs)
Version: unspecified
: P2 normal
Target Milestone: ---
Assignee: Cary Coutant
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2015-10-15 19:15 UTC by Rafael Ávila de Espíndola
Modified: 2015-10-16 23:41 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Rafael Ávila de Espíndola 2015-10-15 19:15:42 UTC
Given

        .long __start_bar - .
        .long __init_array_start - .
        .section bar,"a"

gold complains about the first but not the second relocation when creating a shared library:

ld: error: test.o: requires dynamic R_X86_64_PC32 reloc against '__start_bar' which may overflow at runtime; recompile with -fPIC

bfd ld complains about both.

Alternatively, given

        .quad __start_bar
        .quad __init_array_start
        .section bar,"a"

gold creates a dynamic relocation for __start_bar but not __init_array_start. With bfd ld one gets dynamic relocations for both.

Given what these symbols are, gold's behavior with __init_array_start seems the most reasonable.
Comment 1 Rafael Ávila de Espíndola 2015-10-16 19:44:56 UTC
The issue in gold can be avoided by making the declaration hidden:

        .section bar, "a"
        .hidden __start_bar
        .quad __start_bar

Produces a R_X86_64_RELATIVE. Unfortunately that doesn't work with bfd.
Comment 2 Cary Coutant 2015-10-16 21:57:32 UTC
Gold creates the __start_SECTION and __stop_SECTION symbols as section-relative (non-absolute) symbols with default visibility. As such, they are pre-emptible, and we will create a dynamic relocation for any reference to them. The error message appears when trying to create a 32-bit pc-relative dynamic relocation to a pre-emptible symbol, which may indeed overflow at runtime. The absolute reference links cleanly, and we create a RELATIVE dynamic relocation for it.

Declaring the __start_SECTION or __stop_SECTION symbol with hidden visibility alters this behavior, and gold will bind the pc-relative reference at link time, and will not create a dynamic relocation for it. Likewise, linking with -pie instead of -shared eliminates the dynamic relocations for the pc-relative references.

Gold creates the __init_array_start symbol (and others like it) with hidden visibility. If there is a .init_array section, the symbol is a section-relative (non-absolute) symbol; a pc-relative reference to it does not need a dynamic relocation, and an absolute reference generates a RELATIVE dynamic relocation. If there is no .init_array section, gold generates an absolute symbol with value 0; a pc-relative reference will try to generate a dynamic relocation, and an absolute reference will bind at link time.

I believe this is all working as intended.

The Gnu linker, in my experiments:

(a) Generates the PC32 dynamic relocation with no warning.

(b) Generates __start_SECTION and __stop_SECTION symbols with local scope, so they are not pre-emptible.

(c) Does not generate __init_array_start (et al.) in a -shared link. (They are output as undefined symbols if referenced.)

I can see an argument for generating the __start_SECTION and __stop_SECTION symbols with hidden visibility, but I also see value in leaving them global. Please reopen this PR if you think we should make that change.
Comment 3 Cary Coutant 2015-10-16 22:00:44 UTC
(In reply to Rafael Ávila de Espíndola from comment #1)
> The issue in gold can be avoided by making the declaration hidden:
> 
>         .section bar, "a"
>         .hidden __start_bar
>         .quad __start_bar
> 
> Produces a R_X86_64_RELATIVE. Unfortunately that doesn't work with bfd.

It works in my experiments.
Comment 4 Cary Coutant 2015-10-16 22:02:59 UTC
(In reply to Cary Coutant from comment #3)
> (In reply to Rafael Ávila de Espíndola from comment #1)
> > The issue in gold can be avoided by making the declaration hidden:
> > 
> >         .section bar, "a"
> >         .hidden __start_bar
> >         .quad __start_bar
> > 
> > Produces a R_X86_64_RELATIVE. Unfortunately that doesn't work with bfd.
> 
> It works in my experiments.

I should qualify that by saying it "works" in the sense that I see an absolute R_X86_64_64 relocation instead of RELATIVE, but it ought to have the same effect.
Comment 5 Rafael Ávila de Espíndola 2015-10-16 22:34:07 UTC
 > > > Produces a R_X86_64_RELATIVE. Unfortunately that doesn't work with bfd.
> > 
> > It works in my experiments.
> 
> I should qualify that by saying it "works" in the sense that I see an
> absolute R_X86_64_64 relocation instead of RELATIVE, but it ought to have
> the same effect.

That would still be a problem if multiple shared libraries have sections with the same name.

Given that with gold one can use ".hidden __start_foo" to get the desired result, I would call the current behavior odd but workable, so no need to change.
Comment 6 Cary Coutant 2015-10-16 23:41:37 UTC
>> I should qualify that by saying it "works" in the sense that I see an
>> absolute R_X86_64_64 relocation instead of RELATIVE, but it ought to have
>> the same effect.
>
> That would still be a problem if multiple shared libraries have sections with
> the same name.

I don't think so -- the relocation refers to a local symbol, so it
should relocate to the right address either way.

-cary