diff options
author | H.J. Lu <hjl.tools@gmail.com> | 2020-02-03 11:55:43 -0800 |
---|---|---|
committer | H.J. Lu <hjl.tools@gmail.com> | 2020-12-01 16:42:50 -0800 |
commit | 6fbec038f7a7ddf29f074943611b53210d17c40c (patch) | |
tree | 17b1d7fb7010085b8d79deab1e4a07edf51ddf9b /gcc/varasm.c | |
parent | 670f5095e4aacc30099f6b73c1e67c06df76f36b (diff) | |
download | gcc-6fbec038f7a7ddf29f074943611b53210d17c40c.zip gcc-6fbec038f7a7ddf29f074943611b53210d17c40c.tar.gz gcc-6fbec038f7a7ddf29f074943611b53210d17c40c.tar.bz2 |
Use SHF_GNU_RETAIN to preserve symbol definitions
In assemly code, the section flag 'R' sets the SHF_GNU_RETAIN flag to
indicate that the section must be preserved by the linker.
Add SECTION_RETAIN to indicate a section should be retained by the linker
and set SECTION_RETAIN on section for the preserved symbol if assembler
supports SHF_GNU_RETAIN. All retained symbols are placed in separate
sections with
.section .data.rel.local.preserved_symbol,"awR"
preserved_symbol:
...
.section .data.rel.local,"aw"
not_preserved_symbol:
...
to avoid
.section .data.rel.local,"awR"
preserved_symbol:
...
not_preserved_symbol:
...
which places not_preserved_symbol definition in the SHF_GNU_RETAIN
section.
gcc/
2020-12-01 H.J. Lu <hjl.tools@gmail.com>
* configure.ac (HAVE_GAS_SHF_GNU_RETAIN): New. Define 1 if
the assembler supports marking sections with SHF_GNU_RETAIN flag.
* output.h (SECTION_RETAIN): New. Defined as 0x4000000.
(SECTION_MACH_DEP): Changed from 0x4000000 to 0x8000000.
(default_unique_section): Add a bool argument.
* varasm.c (get_section): Set SECTION_RETAIN for the preserved
symbol with HAVE_GAS_SHF_GNU_RETAIN.
(resolve_unique_section): Used named section for the preserved
symbol if assembler supports SHF_GNU_RETAIN.
(get_variable_section): Handle the preserved common symbol with
HAVE_GAS_SHF_GNU_RETAIN.
(default_elf_asm_named_section): Require the full declaration and
use the 'R' flag for SECTION_RETAIN.
* config.in: Regenerated.
* configure: Likewise.
* doc/sourcebuild.texi: Document R_flag_in_section.
gcc/testsuite/
2020-12-01 H.J. Lu <hjl.tools@gmail.com>
Jozef Lawrynowicz <jozef.l@mittosystems.com>
* c-c++-common/attr-used.c: Check the 'R' flag.
* c-c++-common/attr-used-2.c: Likewise.
* c-c++-common/attr-used-3.c: New test.
* c-c++-common/attr-used-4.c: Likewise.
* gcc.c-torture/compile/attr-used-retain-1.c: Likewise.
* gcc.c-torture/compile/attr-used-retain-2.c: Likewise.
* lib/target-supports.exp
(check_effective_target_R_flag_in_section): New proc.
Diffstat (limited to 'gcc/varasm.c')
-rw-r--r-- | gcc/varasm.c | 15 |
1 files changed, 12 insertions, 3 deletions
diff --git a/gcc/varasm.c b/gcc/varasm.c index b92da26..6c13f52 100644 --- a/gcc/varasm.c +++ b/gcc/varasm.c @@ -289,6 +289,10 @@ 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 (HAVE_GAS_SHF_GNU_RETAIN + && decl != nullptr + && DECL_PRESERVE_P (decl)) + flags |= SECTION_RETAIN; if (*slot == NULL) { sect = ggc_alloc<section> (); @@ -469,6 +473,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 + || (HAVE_GAS_SHF_GNU_RETAIN && DECL_PRESERVE_P (decl)) || DECL_COMDAT_GROUP (decl))) { targetm.asm_out.unique_section (decl, reloc); @@ -1207,7 +1212,8 @@ get_variable_section (tree decl, bool prefer_noswitch_p) if (vnode) vnode->get_constructor (); - if (DECL_COMMON (decl)) + if (DECL_COMMON (decl) + && !(HAVE_GAS_SHF_GNU_RETAIN && DECL_PRESERVE_P (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 @@ -6745,9 +6751,10 @@ default_elf_asm_named_section (const char *name, unsigned int flags, /* If we have already declared this section, we can use an abbreviated form to switch back to it -- unless this section is - part of a COMDAT groups, in which case GAS requires the full - declaration every time. */ + part of a COMDAT groups or with SHF_GNU_RETAIN, in which case GAS + requires the full declaration every time. */ if (!(HAVE_COMDAT_GROUP && (flags & SECTION_LINKONCE)) + && !(flags & SECTION_RETAIN) && (flags & SECTION_DECLARED)) { fprintf (asm_out_file, "\t.section\t%s\n", name); @@ -6780,6 +6787,8 @@ default_elf_asm_named_section (const char *name, unsigned int flags, *f++ = TLS_SECTION_ASM_FLAG; if (HAVE_COMDAT_GROUP && (flags & SECTION_LINKONCE)) *f++ = 'G'; + if (flags & SECTION_RETAIN) + *f++ = 'R'; #ifdef MACH_DEP_SECTION_ASM_FLAG if (flags & SECTION_MACH_DEP) *f++ = MACH_DEP_SECTION_ASM_FLAG; |