diff options
author | H.J. Lu <hjl.tools@gmail.com> | 2021-02-15 11:31:12 -0800 |
---|---|---|
committer | H.J. Lu <hjl.tools@gmail.com> | 2021-02-18 13:27:38 -0800 |
commit | 6347f4a0904fce17eedf5c071be6f3c118680290 (patch) | |
tree | 0dfd837ed13bbbe2dece0db65b7cb4c049c14dbe /gcc/varasm.c | |
parent | 1f9db6929d926222aee0628b93f77cd20cf3adc4 (diff) | |
download | gcc-6347f4a0904fce17eedf5c071be6f3c118680290.zip gcc-6347f4a0904fce17eedf5c071be6f3c118680290.tar.gz gcc-6347f4a0904fce17eedf5c071be6f3c118680290.tar.bz2 |
Add retain attribute to place symbols in SHF_GNU_RETAIN section
When building Linux kernel, ld in bninutils 2.36 with GCC 11 generates
thousands of
ld: warning: orphan section `.data.event_initcall_finish' from `init/main.o' being placed in section `.data.event_initcall_finish'
ld: warning: orphan section `.data.event_initcall_start' from `init/main.o' being placed in section `.data.event_initcall_start'
ld: warning: orphan section `.data.event_initcall_level' from `init/main.o' being placed in section `.data.event_initcall_level'
Since these sections are marked with SHF_GNU_RETAIN, they are placed in
separate sections. They become orphan sections since they aren't expected
in the Linux kernel linker script. But orphan sections normally don't work
well with the Linux kernel linker script and the resulting kernel crashed.
Add the "retain" attribute to place symbols in separate SHF_GNU_RETAIN
sections. Issue a warning if the configured assembler/linker doesn't
support SHF_GNU_RETAIN.
gcc/
PR target/99113
* varasm.c (get_section): Replace SUPPORTS_SHF_GNU_RETAIN with
looking up the retain attribute.
(resolve_unique_section): Likewise.
(get_variable_section): Likewise.
(switch_to_section): Likewise. Warn when a symbol without the
retain attribute and a symbol with the retain attribute are
placed in the section with the same name, instead of the used
attribute.
* doc/extend.texi: Document the "retain" attribute.
gcc/c-family/
PR target/99113
* c-attribs.c (c_common_attribute_table): Add the "retain"
attribute.
(handle_retain_attribute): New function.
gcc/testsuite/
PR target/99113
* c-c++-common/attr-retain-1.c: New test.
* c-c++-common/attr-retain-2.c: Likewise.
* c-c++-common/attr-retain-3.c: Likewise.
* c-c++-common/attr-retain-4.c: Likewise.
* c-c++-common/attr-retain-5.c: Likewise.
* c-c++-common/attr-retain-6.c: Likewise.
* c-c++-common/attr-retain-7.c: Likewise.
* c-c++-common/attr-retain-8.c: Likewise.
* c-c++-common/attr-retain-9.c: Likewise.
* c-c++-common/pr99113.c: Likewise.
* gcc.c-torture/compile/attr-retain-1.c: Likewise.
* gcc.c-torture/compile/attr-retain-2.c: Likewise.
* c-c++-common/attr-used.c: Don't expect SHF_GNU_RETAIN section.
* c-c++-common/attr-used-2.c: Likewise.
* c-c++-common/attr-used-3.c: Likewise.
* c-c++-common/attr-used-4.c: Likewise.
* c-c++-common/attr-used-9.c: Likewise.
* gcc.c-torture/compile/attr-used-retain-1.c: Likewise.
* gcc.c-torture/compile/attr-used-retain-2.c: Likewise.
* c-c++-common/attr-used-5.c: Don't expect warning for the used
attribute nor SHF_GNU_RETAIN section.
* c-c++-common/attr-used-6.c: Likewise.
* c-c++-common/attr-used-7.c: Likewise.
* c-c++-common/attr-used-8.c: Likewise.
Diffstat (limited to 'gcc/varasm.c')
-rw-r--r-- | gcc/varasm.c | 22 |
1 files changed, 11 insertions, 11 deletions
diff --git a/gcc/varasm.c b/gcc/varasm.c index 29478ab..8112122 100644 --- a/gcc/varasm.c +++ b/gcc/varasm.c @@ -297,10 +297,9 @@ get_section (const char *name, unsigned int flags, tree decl, slot = section_htab->find_slot_with_hash (name, htab_hash_string (name), INSERT); flags |= SECTION_NAMED; - if (SUPPORTS_SHF_GNU_RETAIN - && decl != nullptr + if (decl != nullptr && DECL_P (decl) - && DECL_PRESERVE_P (decl)) + && lookup_attribute ("retain", DECL_ATTRIBUTES (decl))) flags |= SECTION_RETAIN; if (*slot == NULL) { @@ -487,7 +486,7 @@ resolve_unique_section (tree decl, int reloc ATTRIBUTE_UNUSED, if (DECL_SECTION_NAME (decl) == NULL && targetm_common.have_named_sections && (flag_function_or_data_sections - || (SUPPORTS_SHF_GNU_RETAIN && DECL_PRESERVE_P (decl)) + || lookup_attribute ("retain", DECL_ATTRIBUTES (decl)) || DECL_COMDAT_GROUP (decl))) { targetm.asm_out.unique_section (decl, reloc); @@ -1227,7 +1226,7 @@ get_variable_section (tree decl, bool prefer_noswitch_p) vnode->get_constructor (); if (DECL_COMMON (decl) - && !(SUPPORTS_SHF_GNU_RETAIN && DECL_PRESERVE_P (decl))) + && !lookup_attribute ("retain", DECL_ATTRIBUTES (decl))) { /* If the decl has been given an explicit section name, or it resides in a non-generic address space, then it isn't common, and shouldn't @@ -7761,18 +7760,19 @@ switch_to_section (section *new_section, tree decl) { if (in_section == new_section) { - if (SUPPORTS_SHF_GNU_RETAIN - && (new_section->common.flags & SECTION_NAMED) + bool retain_p; + if ((new_section->common.flags & SECTION_NAMED) && decl != nullptr && DECL_P (decl) - && (!!DECL_PRESERVE_P (decl) + && ((retain_p = !!lookup_attribute ("retain", + DECL_ATTRIBUTES (decl))) != !!(new_section->common.flags & SECTION_RETAIN))) { /* If the SECTION_RETAIN bit doesn't match, switch to a new section. */ tree used_decl, no_used_decl; - if (DECL_PRESERVE_P (decl)) + if (retain_p) { new_section->common.flags |= SECTION_RETAIN; used_decl = decl; @@ -7786,8 +7786,8 @@ switch_to_section (section *new_section, tree decl) no_used_decl = decl; } warning (OPT_Wattributes, - "%+qD without %<used%> attribute and %qD with " - "%<used%> attribute are placed in a section with " + "%+qD without %<retain%> attribute and %qD with " + "%<retain%> attribute are placed in a section with " "the same name", no_used_decl, used_decl); inform (DECL_SOURCE_LOCATION (used_decl), "%qD was declared here", used_decl); |