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.
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.
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.
(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.
(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.
> > > 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.
>> 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