bug-binutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Bug ld/25384] Copy relocations and BIND_NOW on POWER ELFv1 results in c


From: amodra at gmail dot com
Subject: [Bug ld/25384] Copy relocations and BIND_NOW on POWER ELFv1 results in crashes
Date: Tue, 14 Jan 2020 23:25:16 +0000

https://sourceware.org/bugzilla/show_bug.cgi?id=25384

Alan Modra <amodra at gmail dot com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |ASSIGNED
            Version|unspecified                 |2.34 (HEAD)
           Assignee|unassigned at sourceware dot org   |amodra at gmail dot com
   Target Milestone|---                         |2.34

--- Comment #3 from Alan Modra <amodra at gmail dot com> ---
The trigger for this problem is an initialized function pointer in a read-only
section, the function being defined in a shared library.

        .section .rodata
ptr:
        .quad alias
        .weakref alias, implementation

That generates a .dynbss copy and copy reloc via linker code supposed to work
around bugs in very old versions of gcc.  The work-around should have reported
an error

  if (h->plt.plist != NULL)
    {
      /* We should never get here, but unfortunately there are versions
         of gcc out there that improperly (for this ABI) put initialized
         function pointers, vtable refs and suchlike in read-only
         sections.  Allow them to proceed, but warn that this might
         break at runtime.  */
      info->callbacks->einfo
        (_("%P: copy reloc against `%T' requires lazy plt linking; "
           "avoid setting LD_BIND_NOW=1 or upgrade gcc\n"),
         h->root.root.string);
    }

but doesn't due to a lack of a call to "implementation" in the executable. 
(plt.plist is NULL).  That's a linker bug.  The warning is relevant even when
there is no call in the executable.

So we have this .dynbss copy of the "implementation" function descriptor in the
executable:

000000001001fc08  0000000800000013 R_PPC64_COPY           000000001001fc08
implementation + 0

     8: 000000001001fc08    40 FUNC    GLOBAL DEFAULT   18 implementation

Notice that the size (40) is incorrect for a function descriptor.  That's
because   gcc puts the text size of the function on the symbol.  But that means
the .dynbss copy is the wrong size too, a linker and glibc bug if we are to
support .dynbss copies of function descriptors with versions of gcc since 2004
when dot-symbols were removed.  (With dot-symbols, the size of the
"implementation symbol is the size of the function descriptor with the size of
".implementation" being the text size.)

Anyway, a size larger than 16 is OK for copying the descriptor and "works" just
as well for this testcase as if we copied the descriptor.  We just get some
more of .opd copied from the library defining "implementation".

The segfault happens because the PLT slot in liblike-dl.so for "implementation"
is initialized from the function descriptor for "implementation", which is now
the copy in main.  Unfortunately that initialization happens before "main" is
processed to initialize the copy, resulting in the PLT slot being set to zeros.

-- 
You are receiving this mail because:
You are on the CC list for the bug.


reply via email to

[Prev in Thread] Current Thread [Next in Thread]