aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2020-06-15 12:10:06 +0930
committerAlan Modra <amodra@gmail.com>2020-06-15 12:10:06 +0930
commit75cfe082c067db0b12fb982de0833309e454a8e2 (patch)
tree849f43dd0057e20e947e5f5fd8b7f80c7382e645
parentcda58d5f970d0257749d549aee9c0e2bfb4a1fe8 (diff)
downloadbinutils-75cfe082c067db0b12fb982de0833309e454a8e2.zip
binutils-75cfe082c067db0b12fb982de0833309e454a8e2.tar.gz
binutils-75cfe082c067db0b12fb982de0833309e454a8e2.tar.bz2
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.
-rw-r--r--bfd/ChangeLog12
-rw-r--r--bfd/cofflink.c18
-rw-r--r--bfd/elflink.c12
-rw-r--r--bfd/libcoff-in.h5
-rw-r--r--bfd/libcoff.h5
5 files changed, 45 insertions, 7 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 6159d3a..fe04699 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,15 @@
+2020-06-15 Alan Modra <amodra@gmail.com>
+
+ 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 <amodra@gmail.com>
PR 26107
diff --git a/bfd/cofflink.c b/bfd/cofflink.c
index 27ac20e..63bdcde 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 3e56a29..ac00f29 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 3f0227c..b7fcea3 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 d7e0548..df32c86 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. */