Bug 67834 - Local references inside comdat groups
Summary: Local references inside comdat groups
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: target (show other bugs)
Version: 9.2.1
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2015-10-03 21:39 UTC by John David Anglin
Modified: 2020-01-01 23:13 UTC (History)
4 users (show)

See Also:
Host: hppa-unknown-linux-gnu
Target: hppa-unknown-linux-gnu
Build: hppa-unknown-linux-gnu
Known to work:
Known to fail:
Last reconfirmed: 2019-12-27 00:00:00


Attachments
Preprocessed source (450.11 KB, application/x-gzip)
2015-10-03 21:39 UTC, John David Anglin
Details
Patch (732 bytes, patch)
2019-12-30 01:42 UTC, John David Anglin
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description John David Anglin 2015-10-03 21:39:39 UTC
Created attachment 36442 [details]
Preprocessed source

With the switch to gcc-5 on Debian, we are seeing a number of c++ packages
fail to build with the following error:

_ZXXX referenced in section `.data.rel.ro.local' of YYY: defined in discarded section `.text._ZXXX

Here is the assembler code for _ZN3uhd9transport3sphL19handle_overflow_nopEv:

       .section        .text._ZN3uhd9transport3sphL19handle_overflow_nopEv,"axG",@progbits,_ZN3uhd9transport3sph19recv_packet_handler6resizeEj,comdat
       .align 4        .type   _ZN3uhd9transport3sphL19handle_overflow_nopEv, @function
.LFB8296:
       .file 6 "/home/dave/debian/uhd/uhd-3.9.1/host/lib/usrp/usrp1/../../transport/super_recv_packet_handler.hpp"
       .loc 6 61 0
       .cfi_startproc
_ZN3uhd9transport3sphL19handle_overflow_nopEv:
       .PROC
       .CALLINFO FRAME=0,NO_CALLS
       .ENTRY
       bv,n %r0(%r2)
       .EXIT
       .PROCEND        .cfi_endproc
.LFE8296:
       .size   _ZN3uhd9transport3sphL19handle_overflow_nopEv, .-_ZN3uhd9transport3sphL19handle_overflow_nopEv

Subsequently, there is a reference from a plabel in .data.rel.ro.local:

       .section        .data.rel.ro.local
       .align 4
.LC135:
       .word   P%_ZN3uhd9transport3sphL19handle_overflow_nopEv

COMDAT group section [   10] `.group' [_ZN3uhd9transport3sph19recv_packet_handler6resizeEj] contains 2 sections:
   [Index]    Name
   [  581]   .text._ZN3uhd9transport3sphL19handle_overflow_nopEv
   [ 1282]   .text._ZN3uhd9transport3sph19recv_packet_handler6resizeEj

It is my understanding that local references into COMDAT groups are not allowed.
HPPA is probably particularly sensitive to this because of the "P" PLABEL32
reloc.

Compile command:
/usr/bin/c++   -DHAVE_CONFIG_H -DIHEX_USE_STDBOOL -DUHD_DLL_EXPORTS -DUHD_IMAGES_DIR=OFF -DUHD_VERSION=30901 -g -O2 -Wformat -Werror=format-security -D_FORTIFY_SOURCE=2  -fvisibility=hidden -fvisibility-inlines-hidden -fPIC -I/home/dave/debian/uhd/uhd-3.9.1/build/include -I/home/dave/debian/uhd/uhd-3.9.1/host/include -I/home/dave/debian/uhd/uhd-3.9.1/build/lib/ic_reg_maps -I/home/dave/debian/uhd/uhd-3.9.1/host/lib/convert -I/home/dave/debian/uhd/uhd-3.9.1/build/lib/convert -I/home/dave/debian/uhd/uhd-3.9.1/build/lib/transport/nirio/lvbitx -I/usr/include/libusb-1.0 -I/home/dave/debian/uhd/uhd-3.9.1/host/lib/usrp -I/home/dave/debian/uhd/uhd-3.9.1/host/lib/usrp/cores -I/home/dave/debian/uhd/uhd-3.9.1/host/../firmware/fx2/common -I/home/dave/debian/uhd/uhd-3.9.1/host/lib/usrp/common -I/home/dave/debian/uhd/uhd-3.9.1/host/lib/usrp/common/ad9361_driver    -Wall -Wextra -Wsign-compare -o CMakeFiles/uhd.dir/usrp/usrp1/io_impl.cpp.o -c /home/dave/debian/uhd/uhd-3.9.1/host/lib/usrp/usrp1/io_impl.cpp
Comment 1 John David Anglin 2015-10-05 22:16:22 UTC
This issue now breaks gcc build:

`.LC2' referenced in section `.gnu.linkonce.t._ZN21mem_alloc_descriptionI9mem_us
ageED1Ev' of build/hash-table.o: defined in discarded section `.gnu.linkonce.r._
ZN10hash_tableIN8hash_mapIPKv14mem_usage_pairI9mem_usageE21simple_hashmap_traits
I19default_hash_traitsIS2_EEE10hash_entryE11xcallocatorE6expandEv.str1.4' of bui
ld/hash-table.o

This is with trunk revision 228461.  Occurs in stage2.
Comment 2 John David Anglin 2015-10-05 22:29:29 UTC
Re comment #2, this is with --disable-comdat added to configure command:

../gcc/configure --with-gnu-as --with-gnu-ld --enable-shared --enable-multiarch --enable-linker-build-id --build=hppa-linux-gnu --host=hppa-linux-gnu --target=hppa-linux-gnu --prefix=/home/dave/opt/gnu/gcc/gcc-6 --with-local-prefix=/home/dave/opt/gnu --disable-comdat --enable-threads=posix --enable-__cxa_atexit --build=hppa-linux-gnu --enable-clocale=gnu --enable-java-gc=boehm --enable-languages="c,c++,objc,fortran,obj-c++,java,ada,lto"
Comment 3 John David Anglin 2015-10-11 22:08:01 UTC
The ELF specification says "To facilitate removing a group without leaving dangling references and with only minimal processing of the symbol table, the following rules are followed.

    References to the sections comprising a group from sections outside of the group must be made through symbol table entries with STB_GLOBAL or STB_WEAK binding and section index SHN_UNDEF."

The label _ZN3uhd9transport3sphL19handle_overflow_nopEv is not globalized.

Probably, TREE_PUBLIC is not being set or there needs to be an addition
check added to assemble_start_function to globalize COMDAT functions.  Jason,
could you take a look?
Comment 4 John David Anglin 2015-10-12 14:27:26 UTC
I suppose this is a package bug but it is present in a number
of packages:

static inline void handle_overflow_nop(void){}

class recv_packet_handler{
public:
  ...
private:
    vrt_unpacker_type _vrt_unpacker;
    size_t _header_offset_words32;
    double _tick_rate, _samp_rate;
    bool _queue_error_for_next_call;
    size_t _alignment_faulure_threshold;
    rx_metadata_t _queue_metadata;
    struct xport_chan_props_type{
        xport_chan_props_type(void):
            packet_count(0),
            handle_overflow(&handle_overflow_nop),
            fc_update_window(0)
        {}
        get_buff_type get_buff;
        issue_stream_cmd_type issue_stream_cmd;
        size_t packet_count;
        handle_overflow_type handle_overflow;
        handle_flowctrl_type handle_flowctrl;
        size_t fc_update_window;
    };
    ...
};

Should there be a warning about a potential dangling reference?
Comment 5 Richard Biener 2015-12-04 10:43:08 UTC
GCC 5.3 is being released, adjusting target milestone.
Comment 6 Richard Biener 2016-06-03 10:03:26 UTC
GCC 5.4 is being released, adjusting target milestone.
Comment 7 Jakub Jelinek 2017-10-10 14:00:00 UTC
The 5 branch has been closed, it is unclear what the state of this PR is on supported branches.
Comment 8 John David Anglin 2017-10-10 23:11:08 UTC
The test case now compiles successfully with 5.4.1 20171003 (Debian 5.4.1-14), g++-6 and g++-7.
Comment 9 John David Anglin 2019-12-27 16:31:17 UTC
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;
Comment 10 John David Anglin 2019-12-30 01:42:17 UTC
Created attachment 47564 [details]
Patch

Untested fix.
Comment 11 John David Anglin 2020-01-01 22:58:26 UTC
Author: danglin
Date: Wed Jan  1 22:57:54 2020
New Revision: 279823

URL: https://gcc.gnu.org/viewcvs?rev=279823&root=gcc&view=rev
Log:
	PR target/67834
	* config/pa/pa.c (pa_elf_select_rtx_section): New.  Put references to
	COMDAT group function labels in .data.rel.ro.local section.
	* config/pa/pa32-linux.h (TARGET_ASM_SELECT_RTX_SECTION): Define.


Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/config/pa/pa.c
    trunk/gcc/config/pa/pa32-linux.h
Comment 12 John David Anglin 2020-01-01 23:01:32 UTC
Author: danglin
Date: Wed Jan  1 23:00:58 2020
New Revision: 279824

URL: https://gcc.gnu.org/viewcvs?rev=279824&root=gcc&view=rev
Log:
	PR target/67834
	* config/pa/pa.c (pa_elf_select_rtx_section): New.  Put references to
	COMDAT group function labels in .data.rel.ro.local section.
	* config/pa/pa32-linux.h (TARGET_ASM_SELECT_RTX_SECTION): Define.


Modified:
    branches/gcc-9-branch/gcc/ChangeLog
    branches/gcc-9-branch/gcc/config/pa/pa.c
    branches/gcc-9-branch/gcc/config/pa/pa32-linux.h
Comment 13 John David Anglin 2020-01-01 23:13:48 UTC
Resolved.