From 75cfe082c067db0b12fb982de0833309e454a8e2 Mon Sep 17 00:00:00 2001 From: Alan Modra Date: Mon, 15 Jun 2020 12:10:06 +0930 Subject: [PATCH] PR26103, Assertion failure with symbols defined in link-once sections PR 26103 * elflink.c (elf_link_add_archive_symbols): Exclude undefined symbols that were defined in discarded sections. * cofflink.c (coff_link_check_archive_element): Likewise. (coff_link_add_symbols): Set indx to -3 for symbols defined in discarded sections. (_bfd_coff_write_global_sym): Don't emit such symbols. libcoff-in.h (struct coff_link_hash_entry): Update indx comment. libcoff.h: Regenerate. --- bfd/ChangeLog | 12 ++++++++++++ bfd/cofflink.c | 18 +++++++++++++++++- bfd/elflink.c | 12 ++++++++++-- bfd/libcoff-in.h | 5 +++-- bfd/libcoff.h | 5 +++-- 5 files changed, 45 insertions(+), 7 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 6159d3aea3..fe04699b45 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,15 @@ +2020-06-15 Alan Modra + + PR 26103 + * elflink.c (elf_link_add_archive_symbols): Exclude undefined + symbols that were defined in discarded sections. + * cofflink.c (coff_link_check_archive_element): Likewise. + (coff_link_add_symbols): Set indx to -3 for symbols defined in + discarded sections. + (_bfd_coff_write_global_sym): Don't emit such symbols. + libcoff-in.h (struct coff_link_hash_entry): Update indx comment. + libcoff.h: Regenerate. + 2020-06-11 Alan Modra PR 26107 diff --git a/bfd/cofflink.c b/bfd/cofflink.c index 27ac20e80d..63bdcde115 100644 --- a/bfd/cofflink.c +++ b/bfd/cofflink.c @@ -212,6 +212,12 @@ coff_link_check_archive_element (bfd *abfd, if (h->type != bfd_link_hash_undefined) return TRUE; + /* If the archive element has already been loaded then one + of the symbols defined by that element might have been + made undefined due to being in a discarded section. */ + if (((struct coff_link_hash_entry *) h)->indx == -3) + return TRUE; + /* PR 22369 - Skip non COFF objects in the archive. */ if (! bfd_family_coff (abfd)) return TRUE; @@ -286,6 +292,7 @@ coff_link_add_symbols (bfd *abfd, asection *section; bfd_vma value; bfd_boolean addit; + bfd_boolean discarded = FALSE; /* This symbol is externally visible. */ @@ -311,7 +318,10 @@ coff_link_add_symbols (bfd *abfd, flags = BSF_EXPORT | BSF_GLOBAL; section = coff_section_from_bfd_index (abfd, sym.n_scnum); if (discarded_section (section)) - section = bfd_und_section_ptr; + { + discarded = TRUE; + section = bfd_und_section_ptr; + } else if (! obj_pe (abfd)) value -= section->vma; break; @@ -408,6 +418,9 @@ coff_link_add_symbols (bfd *abfd, (const char *) NULL, copy, FALSE, (struct bfd_link_hash_entry **) sym_hash))) goto error_return; + + if (discarded) + (*sym_hash)->indx = -3; } if (obj_pe (abfd) && (flags & BSF_SECTION_SYM) != 0) @@ -2567,6 +2580,9 @@ _bfd_coff_write_global_sym (struct bfd_hash_entry *bh, void *data) return FALSE; case bfd_link_hash_undefined: + if (h->indx == -3) + return TRUE; + /* Fall through. */ case bfd_link_hash_undefweak: isym.n_scnum = N_UNDEF; isym.n_value = 0; diff --git a/bfd/elflink.c b/bfd/elflink.c index 3e56a297f6..ac00f2984e 100644 --- a/bfd/elflink.c +++ b/bfd/elflink.c @@ -5813,7 +5813,15 @@ elf_link_add_archive_symbols (bfd *abfd, struct bfd_link_info *info) if (h == NULL) continue; - if (h->root.type == bfd_link_hash_common) + if (h->root.type == bfd_link_hash_undefined) + { + /* If the archive element has already been loaded then one + of the symbols defined by that element might have been + made undefined due to being in a discarded section. */ + if (h->indx == -3) + continue; + } + else if (h->root.type == bfd_link_hash_common) { /* We currently have a common symbol. The archive map contains a reference to this symbol, so we may want to include it. We @@ -5830,7 +5838,7 @@ elf_link_add_archive_symbols (bfd *abfd, struct bfd_link_info *info) if (! elf_link_is_defined_archive_symbol (abfd, symdef)) continue; } - else if (h->root.type != bfd_link_hash_undefined) + else { if (h->root.type != bfd_link_hash_undefweak) /* Symbol must be defined. Don't check it again. */ diff --git a/bfd/libcoff-in.h b/bfd/libcoff-in.h index 3f0227c4ac..b7fcea30bb 100644 --- a/bfd/libcoff-in.h +++ b/bfd/libcoff-in.h @@ -243,8 +243,9 @@ struct coff_link_hash_entry { struct bfd_link_hash_entry root; - /* Symbol index in output file. Set to -1 initially. Set to -2 if - there is a reloc against this symbol. */ + /* Symbol index in output file. This is initialized to -1. It is + set to -2 if the symbol is used by a reloc. It is set to -3 if + this symbol is defined in a discarded section. */ long indx; /* Symbol type. */ diff --git a/bfd/libcoff.h b/bfd/libcoff.h index d7e0548bc5..df32c8604e 100644 --- a/bfd/libcoff.h +++ b/bfd/libcoff.h @@ -247,8 +247,9 @@ struct coff_link_hash_entry { struct bfd_link_hash_entry root; - /* Symbol index in output file. Set to -1 initially. Set to -2 if - there is a reloc against this symbol. */ + /* Symbol index in output file. This is initialized to -1. It is + set to -2 if the symbol is used by a reloc. It is set to -3 if + this symbol is defined in a discarded section. */ long indx; /* Symbol type. */