[Bug c++/67834] Local references inside comdat groups

danglin at gcc dot gnu.org gcc-bugzilla@gcc.gnu.org
Fri Dec 27 16:31:00 GMT 2019


https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67834

John David Anglin <danglin at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|RESOLVED                    |REOPENED
   Last reconfirmed|                            |2019-12-27
            Version|5.2.1                       |9.2.1
         Resolution|FIXED                       |---
   Target Milestone|5.5                         |---
     Ever confirmed|0                           |1

--- Comment #9 from John David Anglin <danglin at gcc dot gnu.org> ---
This problem has reappeared since pa_reloc_rw_mask() was changed to allow
relocs in readonly data.

See this binutils bugzilla:
https://sourceware.org/bugzilla/show_bug.cgi?id=25315

We have a plabel relocation to the local symbol __tcf_0 in a comdat section.

It is setup here:

start_cleanup_fn (void)
{
  char name[32];
  tree fntype;
  tree fndecl;
  bool use_cxa_atexit = flag_use_cxa_atexit
                        && !targetm.cxx.use_atexit_for_cxa_atexit ();

  push_to_top_level ();

  /* No need to mangle this.  */
  push_lang_context (lang_name_c);

  /* Build the name of the function.  */
  sprintf (name, "__tcf_%d", start_cleanup_cnt++);
  /* Build the function declaration.  */
  fntype = TREE_TYPE (get_atexit_fn_ptr_type ());
  fndecl = build_lang_decl (FUNCTION_DECL, get_identifier (name), fntype);
  /* It's a function with internal linkage, generated by the
     compiler.  */
  TREE_PUBLIC (fndecl) = 0;
  DECL_ARTIFICIAL (fndecl) = 1;
  /* Make the function `inline' so that it is only emitted if it is
     actually needed.  It is unlikely that it will be inlined, since
     it is only called via a function pointer, but we avoid unnecessary
     emissions this way.  */
  DECL_DECLARED_INLINE_P (fndecl) = 1;
  DECL_INTERFACE_KNOWN (fndecl) = 1;

The original problem was worked around with this binutils change:

static unsigned int
elf_hppa_action_discarded (asection *sec)
{
  /* Ignore relocations in .data.rel.ro.local.  This section can contain
     PLABEL32 relocations to functions in discarded COMDAT groups.  */
  if (strcmp (".data.rel.ro.local", sec->name) == 0)
    return 0;


More information about the Gcc-bugs mailing list