diff options
author | H.J. Lu <hjl.tools@gmail.com> | 2020-02-06 18:04:58 -0800 |
---|---|---|
committer | H.J. Lu <hjl.tools@gmail.com> | 2020-02-06 18:05:10 -0800 |
commit | b7d072167715829eed0622616f6ae0182900de3e (patch) | |
tree | 5015f461be45da594a9a8b5e80356e083033224e /bfd | |
parent | 3c83b08abfff01d45ce78cabd29e83923b270c3b (diff) | |
download | fsf-binutils-gdb-b7d072167715829eed0622616f6ae0182900de3e.zip fsf-binutils-gdb-b7d072167715829eed0622616f6ae0182900de3e.tar.gz fsf-binutils-gdb-b7d072167715829eed0622616f6ae0182900de3e.tar.bz2 |
ELF: Support the section flag 'o' in .section directive
As shown in
https://sourceware.org/bugzilla/show_bug.cgi?id=25490
--gc-sections will silently remove __patchable_function_entries section
and generate corrupt result. This patch adds the section flag 'o' to
.section directive:
.section __patchable_function_entries,"awo",@progbits,foo
.section __patchable_function_entries,"awoG",@progbits,foo,foo,comdat
.section __patchable_function_entries,"awo",@progbits,bar,unique,4
.section __patchable_function_entries,"awoG",@progbits,foo,foo,comdat,unique,1
which specifies the symbol name which the section references. Assmebler
will set its elf_linked_to_section to a local section where the symbol
is defined.
Linker is updated to call mark_hook if gc_mark of any of its linked-to
sections is set after all sections, except for backend specific ones,
have been garbage collected.
bfd/
PR gas/25381
* bfd-in2.h: Regenerated.
* elflink.c (_bfd_elf_gc_mark_extra_sections): Call mark_hook
on section if gc_mark of any of its linked-to sections is set
and don't set gc_mark again.
* section.c (asection): Add linked_to_symbol_name to map_head
union.
gas/
PR gas/25381
* config/obj-elf.c (get_section): Also check
linked_to_symbol_name.
(obj_elf_change_section): Also set map_head.linked_to_symbol_name.
(obj_elf_parse_section_letters): Handle the 'o' flag.
(build_group_lists): Renamed to ...
(build_additional_section_info): This. Set elf_linked_to_section
from map_head.linked_to_symbol_name.
(elf_adjust_symtab): Updated.
* config/obj-elf.h (elf_section_match): Add linked_to_symbol_name.
* doc/as.texi: Document the 'o' flag.
* testsuite/gas/elf/elf.exp: Run PR gas/25381 tests.
* testsuite/gas/elf/section18.d: New file.
* testsuite/gas/elf/section18.s: Likewise.
* testsuite/gas/elf/section19.d: Likewise.
* testsuite/gas/elf/section19.s: Likewise.
* testsuite/gas/elf/section20.d: Likewise.
* testsuite/gas/elf/section20.s: Likewise.
* testsuite/gas/elf/section21.d: Likewise.
* testsuite/gas/elf/section21.l: Likewise.
* testsuite/gas/elf/section21.s: Likewise.
ld/
PR ld/24526
PR ld/25021
PR ld/25490
* testsuite/ld-elf/elf.exp: Run PR ld/25490 tests.
* testsuite/ld-elf/pr24526.d: New file.
* testsuite/ld-elf/pr24526.s: Likewise.
* testsuite/ld-elf/pr25021.d: Likewise.
* testsuite/ld-elf/pr25021.s: Likewise.
* testsuite/ld-elf/pr25490-2-16.rd: Likewise.
* testsuite/ld-elf/pr25490-2-32.rd: Likewise.
* testsuite/ld-elf/pr25490-2-64.rd: Likewise.
* testsuite/ld-elf/pr25490-2.s: Likewise.
* testsuite/ld-elf/pr25490-3-16.rd: Likewise.
* testsuite/ld-elf/pr25490-3-32.rd: Likewise.
* testsuite/ld-elf/pr25490-3-64.rd: Likewise.
* testsuite/ld-elf/pr25490-3.s: Likewise.
* testsuite/ld-elf/pr25490-4-16.rd: Likewise.
* testsuite/ld-elf/pr25490-4-32.rd: Likewise.
* testsuite/ld-elf/pr25490-4-64.rd: Likewise.
* testsuite/ld-elf/pr25490-4.s: Likewise.
* testsuite/ld-elf/pr25490-5-16.rd: Likewise.
* testsuite/ld-elf/pr25490-5-32.rd: Likewise.
* testsuite/ld-elf/pr25490-5-64.rd: Likewise.
* testsuite/ld-elf/pr25490-5.s: Likewise.
* testsuite/ld-elf/pr25490-6-16.rd: Likewise.
* testsuite/ld-elf/pr25490-6-32.rd: Likewise.
* testsuite/ld-elf/pr25490-6-64.rd: Likewise.
* testsuite/ld-elf/pr25490-6.s: Likewise.
Diffstat (limited to 'bfd')
-rw-r--r-- | bfd/ChangeLog | 10 | ||||
-rw-r--r-- | bfd/bfd-in2.h | 4 | ||||
-rw-r--r-- | bfd/elflink.c | 23 | ||||
-rw-r--r-- | bfd/section.c | 4 |
4 files changed, 36 insertions, 5 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 95152ad..9971885 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,13 @@ +2020-02-06 H.J. Lu <hongjiu.lu@intel.com> + + PR gas/25381 + * bfd-in2.h: Regenerated. + * elflink.c (_bfd_elf_gc_mark_extra_sections): Call mark_hook + on section if gc_mark of any of its linked-to sections is set + and don't set gc_mark again. + * section.c (asection): Add linked_to_symbol_name to map_head + union. + 2020-02-06 Maciej W. Rozycki <macro@wdc.com> * elf32-v850.c (v850_elf_relax_section): Fix the index used for diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h index 09a5a39..2d26b81 100644 --- a/bfd/bfd-in2.h +++ b/bfd/bfd-in2.h @@ -1185,10 +1185,12 @@ typedef struct bfd_section /* Early in the link process, map_head and map_tail are used to build a list of input sections attached to an output section. Later, output sections use these fields for a list of bfd_link_order - structs. */ + structs. The linked_to_symbol_name field is for ELF assembler + internal use. */ union { struct bfd_link_order *link_order; struct bfd_section *s; + const char *linked_to_symbol_name; } map_head, map_tail; } asection; diff --git a/bfd/elflink.c b/bfd/elflink.c index 5217528..30a572d 100644 --- a/bfd/elflink.c +++ b/bfd/elflink.c @@ -13316,7 +13316,7 @@ _bfd_elf_gc_mark_debug_special_section_group (asection *grp) bfd_boolean _bfd_elf_gc_mark_extra_sections (struct bfd_link_info *info, - elf_gc_mark_hook_fn mark_hook ATTRIBUTE_UNUSED) + elf_gc_mark_hook_fn mark_hook) { bfd *ibfd; @@ -13345,6 +13345,21 @@ _bfd_elf_gc_mark_extra_sections (struct bfd_link_info *info, && (isec->flags & SEC_ALLOC) != 0 && elf_section_type (isec) != SHT_NOTE) some_kept = TRUE; + else + { + /* Since all sections, except for backend specific ones, + have been garbage collected, call mark_hook on this + section if any of its linked-to sections is marked. */ + asection *linked_to_sec = elf_linked_to_section (isec); + for (; linked_to_sec != NULL; + linked_to_sec = elf_linked_to_section (linked_to_sec)) + if (linked_to_sec->gc_mark) + { + if (!_bfd_elf_gc_mark (info, isec, mark_hook)) + return FALSE; + break; + } + } if (!debug_frag_seen && (isec->flags & SEC_DEBUGGING) @@ -13359,14 +13374,16 @@ _bfd_elf_gc_mark_extra_sections (struct bfd_link_info *info, /* Keep debug and special sections like .comment when they are not part of a group. Also keep section groups that contain - just debug sections or special sections. */ + just debug sections or special sections. NB: Sections with + linked-to section has been handled above. */ for (isec = ibfd->sections; isec != NULL; isec = isec->next) { if ((isec->flags & SEC_GROUP) != 0) _bfd_elf_gc_mark_debug_special_section_group (isec); else if (((isec->flags & SEC_DEBUGGING) != 0 || (isec->flags & (SEC_ALLOC | SEC_LOAD | SEC_RELOC)) == 0) - && elf_next_in_group (isec) == NULL) + && elf_next_in_group (isec) == NULL + && elf_linked_to_section (isec) == NULL) isec->gc_mark = 1; if (isec->gc_mark && (isec->flags & SEC_DEBUGGING) != 0) has_kept_debug_info = TRUE; diff --git a/bfd/section.c b/bfd/section.c index 0c15a0d..7de0a2d 100644 --- a/bfd/section.c +++ b/bfd/section.c @@ -544,10 +544,12 @@ CODE_FRAGMENT . {* Early in the link process, map_head and map_tail are used to build . a list of input sections attached to an output section. Later, . output sections use these fields for a list of bfd_link_order -. structs. *} +. structs. The linked_to_symbol_name field is for ELF assembler +. internal use. *} . union { . struct bfd_link_order *link_order; . struct bfd_section *s; +. const char *linked_to_symbol_name; . } map_head, map_tail; .} asection; . |