aboutsummaryrefslogtreecommitdiff
path: root/bfd
diff options
context:
space:
mode:
Diffstat (limited to 'bfd')
-rw-r--r--bfd/ChangeLog10
-rw-r--r--bfd/bfd-in2.h4
-rw-r--r--bfd/elflink.c23
-rw-r--r--bfd/section.c4
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;
.