aboutsummaryrefslogtreecommitdiff
path: root/bfd/elflink.c
diff options
context:
space:
mode:
Diffstat (limited to 'bfd/elflink.c')
-rw-r--r--bfd/elflink.c390
1 files changed, 220 insertions, 170 deletions
diff --git a/bfd/elflink.c b/bfd/elflink.c
index 309b4d7..666399b 100644
--- a/bfd/elflink.c
+++ b/bfd/elflink.c
@@ -96,22 +96,64 @@ _bfd_elf_link_keep_memory (struct bfd_link_info *info)
return true;
}
-asection *
-_bfd_elf_section_for_symbol (struct elf_reloc_cookie *cookie,
- unsigned long r_symndx,
- bool discard)
+static struct elf_link_hash_entry *
+get_link_hash_entry (struct elf_link_hash_entry ** sym_hashes,
+ unsigned int symndx,
+ unsigned int ext_sym_start)
+{
+ if (sym_hashes == NULL
+ /* Guard against corrupt input. See PR 32636 for an example. */
+ || symndx < ext_sym_start)
+ return NULL;
+
+ struct elf_link_hash_entry *h = sym_hashes[symndx - ext_sym_start];
+
+ /* The hash might be empty. See PR 32641 for an example of this. */
+ if (h == NULL)
+ return NULL;
+
+ while (h->root.type == bfd_link_hash_indirect
+ || h->root.type == bfd_link_hash_warning)
+ h = (struct elf_link_hash_entry *) h->root.u.i.link;
+
+ return h;
+}
+
+struct elf_link_hash_entry *
+_bfd_elf_get_link_hash_entry (struct elf_link_hash_entry ** sym_hashes,
+ unsigned int symndx,
+ Elf_Internal_Shdr * symtab_hdr)
{
+ if (symtab_hdr == NULL)
+ return NULL;
+
+ return get_link_hash_entry (sym_hashes, symndx, symtab_hdr->sh_info);
+}
+
+static struct elf_link_hash_entry *
+get_ext_sym_hash_from_cookie (struct elf_reloc_cookie *cookie, unsigned long r_symndx)
+{
+ if (cookie == NULL || cookie->sym_hashes == NULL)
+ return NULL;
+
if (r_symndx >= cookie->locsymcount
|| ELF_ST_BIND (cookie->locsyms[r_symndx].st_info) != STB_LOCAL)
- {
- struct elf_link_hash_entry *h;
+ return get_link_hash_entry (cookie->sym_hashes, r_symndx, cookie->extsymoff);
- h = cookie->sym_hashes[r_symndx - cookie->extsymoff];
+ return NULL;
+}
- while (h->root.type == bfd_link_hash_indirect
- || h->root.type == bfd_link_hash_warning)
- h = (struct elf_link_hash_entry *) h->root.u.i.link;
+asection *
+_bfd_elf_section_for_symbol (struct elf_reloc_cookie *cookie,
+ unsigned long r_symndx,
+ bool discard)
+{
+ struct elf_link_hash_entry *h;
+ h = get_ext_sym_hash_from_cookie (cookie, r_symndx);
+
+ if (h != NULL)
+ {
if ((h->root.type == bfd_link_hash_defined
|| h->root.type == bfd_link_hash_defweak)
&& discarded_section (h->root.u.def.section))
@@ -119,21 +161,20 @@ _bfd_elf_section_for_symbol (struct elf_reloc_cookie *cookie,
else
return NULL;
}
- else
- {
- /* It's not a relocation against a global symbol,
- but it could be a relocation against a local
- symbol for a discarded section. */
- asection *isec;
- Elf_Internal_Sym *isym;
- /* Need to: get the symbol; get the section. */
- isym = &cookie->locsyms[r_symndx];
- isec = bfd_section_from_elf_index (cookie->abfd, isym->st_shndx);
- if (isec != NULL
- && discard ? discarded_section (isec) : 1)
- return isec;
- }
+ /* It's not a relocation against a global symbol,
+ but it could be a relocation against a local
+ symbol for a discarded section. */
+ asection *isec;
+ Elf_Internal_Sym *isym;
+
+ /* Need to: get the symbol; get the section. */
+ isym = &cookie->locsyms[r_symndx];
+ isec = bfd_section_from_elf_index (cookie->abfd, isym->st_shndx);
+ if (isec != NULL
+ && discard ? discarded_section (isec) : 1)
+ return isec;
+
return NULL;
}
@@ -198,8 +239,7 @@ _bfd_elf_create_got_section (bfd *abfd, struct bfd_link_info *info)
s = bfd_make_section_anyway_with_flags (abfd,
(bed->rela_plts_and_copies_p
? ".rela.got" : ".rel.got"),
- (bed->dynamic_sec_flags
- | SEC_READONLY));
+ flags | SEC_READONLY);
if (s == NULL
|| !bfd_set_section_alignment (s, bed->s->log_file_align))
return false;
@@ -397,8 +437,7 @@ _bfd_elf_link_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info)
if (info->enable_dt_relr)
{
s = bfd_make_section_anyway_with_flags (abfd, ".relr.dyn",
- (bed->dynamic_sec_flags
- | SEC_READONLY));
+ flags | SEC_READONLY);
if (s == NULL
|| !bfd_set_section_alignment (s, bed->s->log_file_align))
return false;
@@ -3345,12 +3384,9 @@ _bfd_elf_adjust_dynamic_copy (struct bfd_link_info *info,
--power_of_two;
}
- if (power_of_two > bfd_section_alignment (dynbss))
- {
- /* Adjust the section alignment if needed. */
- if (!bfd_set_section_alignment (dynbss, power_of_two))
- return false;
- }
+ /* Adjust the section alignment if needed. */
+ if (!bfd_link_align_section (dynbss, power_of_two))
+ return false;
/* We make sure that the symbol will be aligned properly. */
dynbss->size = BFD_ALIGN (dynbss->size, mask + 1);
@@ -3570,7 +3606,7 @@ _bfd_elf_tls_setup (bfd *obfd, struct bfd_link_info *info)
/* Ensure the alignment of the first section (usually .tdata) is the largest
alignment, so that the tls segment starts aligned. */
if (tls != NULL)
- tls->alignment_power = align;
+ (void) bfd_link_align_section (tls, align);
return tls;
}
@@ -4323,8 +4359,8 @@ elf_link_add_to_first_hash (bfd *abfd, struct bfd_link_info *info,
= ((struct elf_link_first_hash_entry *)
bfd_hash_lookup (htab->first_hash, name, true, copy));
if (e == NULL)
- info->callbacks->einfo
- (_("%F%P: %pB: failed to add %s to first hash\n"), abfd, name);
+ info->callbacks->fatal
+ (_("%P: %pB: failed to add %s to first hash\n"), abfd, name);
if (e->abfd == NULL)
/* Store ABFD in abfd. */
@@ -4391,8 +4427,8 @@ elf_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info)
|| !bfd_hash_table_init
(htab->first_hash, elf_link_first_hash_newfunc,
sizeof (struct elf_link_first_hash_entry)))
- info->callbacks->einfo
- (_("%F%P: first_hash failed to create: %E\n"));
+ info->callbacks->fatal
+ (_("%P: first_hash failed to create: %E\n"));
}
}
else
@@ -4929,6 +4965,7 @@ elf_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info)
asection *sec, *new_sec;
flagword flags;
const char *name;
+ const char *defvername;
bool must_copy_name = false;
struct elf_link_hash_entry *h;
struct elf_link_hash_entry *hi;
@@ -5105,6 +5142,7 @@ elf_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info)
old_alignment = 0;
old_bfd = NULL;
new_sec = sec;
+ defvername = NULL;
if (is_elf_hash_table (&htab->root))
{
@@ -5223,7 +5261,7 @@ elf_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info)
default version of the symbol. */
if ((iver.vs_vers & VERSYM_HIDDEN) == 0
&& isym->st_shndx != SHN_UNDEF)
- *p++ = ELF_VER_CHR;
+ *p++ = ELF_VER_CHR, defvername = name;
memcpy (p, verstr, verlen + 1);
name = newname;
@@ -5673,9 +5711,15 @@ elf_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info)
}
else if (dynamic
&& h->root.u.def.section->owner == abfd)
- /* Add this symbol to first hash if this shared
- object has the first definition. */
- elf_link_add_to_first_hash (abfd, info, name, must_copy_name);
+ {
+ /* Add this symbol to first hash if this shared
+ object has the first definition. */
+ elf_link_add_to_first_hash (abfd, info, name, must_copy_name);
+ /* And if it was the default symbol version definition,
+ also add the short name. */
+ if (defvername)
+ elf_link_add_to_first_hash (abfd, info, defvername, false);
+ }
}
}
}
@@ -6237,12 +6281,30 @@ elf_link_add_archive_symbols (bfd *abfd, struct bfd_link_info *info)
if (h->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 (is_elf_hash_table (info->hash)
- && ((struct elf_link_hash_entry *) h)->indx == -3)
- continue;
+ if (is_elf_hash_table (info->hash))
+ {
+ /* 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 elf_link_hash_entry *) h)->indx == -3)
+ continue;
+
+ /* In the pre-LTO-plugin pass we must not mistakenly
+ include this archive member if an earlier shared
+ library defined this symbol. */
+ struct elf_link_hash_table *htab = elf_hash_table (info);
+ if (htab->first_hash)
+ {
+ struct elf_link_first_hash_entry *e
+ = ((struct elf_link_first_hash_entry *)
+ bfd_hash_lookup (htab->first_hash, symdef->name,
+ false, false));
+ if (e
+ && (e->abfd->flags & DYNAMIC) != 0
+ && e->abfd != abfd)
+ continue;
+ }
+ }
}
else if (h->type == bfd_link_hash_common)
{
@@ -9072,7 +9134,6 @@ set_symbol_value (bfd *bfd_with_globals,
size_t symidx,
bfd_vma val)
{
- struct elf_link_hash_entry **sym_hashes;
struct elf_link_hash_entry *h;
size_t extsymoff = locsymcount;
@@ -9095,12 +9156,12 @@ set_symbol_value (bfd *bfd_with_globals,
/* It is a global symbol: set its link type
to "defined" and give it a value. */
-
- sym_hashes = elf_sym_hashes (bfd_with_globals);
- h = sym_hashes [symidx - extsymoff];
- while (h->root.type == bfd_link_hash_indirect
- || h->root.type == bfd_link_hash_warning)
- h = (struct elf_link_hash_entry *) h->root.u.i.link;
+ h = get_link_hash_entry (elf_sym_hashes (bfd_with_globals), symidx, extsymoff);
+ if (h == NULL)
+ {
+ /* FIXMEL What should we do ? */
+ return;
+ }
h->root.type = bfd_link_hash_defined;
h->root.u.def.value = val;
h->root.u.def.section = bfd_abs_section_ptr;
@@ -11578,10 +11639,19 @@ elf_link_input_bfd (struct elf_final_link_info *flinfo, bfd *input_bfd)
|| (elf_bad_symtab (input_bfd)
&& flinfo->sections[symndx] == NULL))
{
- struct elf_link_hash_entry *h = sym_hashes[symndx - extsymoff];
- while (h->root.type == bfd_link_hash_indirect
- || h->root.type == bfd_link_hash_warning)
- h = (struct elf_link_hash_entry *) h->root.u.i.link;
+ struct elf_link_hash_entry *h;
+
+ h = get_link_hash_entry (sym_hashes, symndx, extsymoff);
+ if (h == NULL)
+ {
+ _bfd_error_handler
+ /* xgettext:c-format */
+ (_("error: %pB: unable to create group section symbol"),
+ input_bfd);
+ bfd_set_error (bfd_error_bad_value);
+ return false;
+ }
+
/* Arrange for symbol to be output. */
h->indx = -2;
elf_section_data (osec)->this_hdr.sh_info = -2;
@@ -11716,7 +11786,7 @@ elf_link_input_bfd (struct elf_final_link_info *flinfo, bfd *input_bfd)
|| (elf_bad_symtab (input_bfd)
&& flinfo->sections[r_symndx] == NULL))
{
- h = sym_hashes[r_symndx - extsymoff];
+ h = get_link_hash_entry (sym_hashes, r_symndx, extsymoff);
/* Badly formatted input files can contain relocs that
reference non-existant symbols. Check here so that
@@ -11725,17 +11795,13 @@ elf_link_input_bfd (struct elf_final_link_info *flinfo, bfd *input_bfd)
{
_bfd_error_handler
/* xgettext:c-format */
- (_("error: %pB contains a reloc (%#" PRIx64 ") for section %pA "
+ (_("error: %pB contains a reloc (%#" PRIx64 ") for section '%pA' "
"that references a non-existent global symbol"),
input_bfd, (uint64_t) rel->r_info, o);
bfd_set_error (bfd_error_bad_value);
return false;
}
- while (h->root.type == bfd_link_hash_indirect
- || h->root.type == bfd_link_hash_warning)
- h = (struct elf_link_hash_entry *) h->root.u.i.link;
-
s_type = h->type;
/* If a plugin symbol is referenced from a non-IR file,
@@ -11951,7 +12017,6 @@ elf_link_input_bfd (struct elf_final_link_info *flinfo, bfd *input_bfd)
&& flinfo->sections[r_symndx] == NULL))
{
struct elf_link_hash_entry *rh;
- unsigned long indx;
/* This is a reloc against a global symbol. We
have not yet output all the local symbols, so
@@ -11960,15 +12025,16 @@ elf_link_input_bfd (struct elf_final_link_info *flinfo, bfd *input_bfd)
reloc to point to the global hash table entry
for this symbol. The symbol index is then
set at the end of bfd_elf_final_link. */
- indx = r_symndx - extsymoff;
- rh = elf_sym_hashes (input_bfd)[indx];
- while (rh->root.type == bfd_link_hash_indirect
- || rh->root.type == bfd_link_hash_warning)
- rh = (struct elf_link_hash_entry *) rh->root.u.i.link;
-
- /* Setting the index to -2 tells
- elf_link_output_extsym that this symbol is
- used by a reloc. */
+ rh = get_link_hash_entry (elf_sym_hashes (input_bfd),
+ r_symndx, extsymoff);
+ if (rh == NULL)
+ {
+ /* FIXME: Generate an error ? */
+ continue;
+ }
+
+ /* Setting the index to -2 tells elf_link_output_extsym
+ that this symbol is used by a reloc. */
BFD_ASSERT (rh->indx < 0);
rh->indx = -2;
*rel_hash = rh;
@@ -12166,9 +12232,9 @@ elf_link_input_bfd (struct elf_final_link_info *flinfo, bfd *input_bfd)
break;
case SEC_INFO_TYPE_SFRAME:
{
- /* Merge .sframe sections into the ctf frame encoder
- context of the output_bfd's section. The final .sframe
- output section will be written out later. */
+ /* Merge SFrame section into the SFrame encoder context of the
+ output_bfd's section. The final .sframe output section will
+ be written out later. */
if (!_bfd_elf_merge_section_sframe (output_bfd, flinfo->info,
o, contents))
return false;
@@ -12570,9 +12636,6 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info)
size_t relr_entsize;
asection *reldyn = 0;
bfd_size_type amt;
- asection *attr_section = NULL;
- bfd_vma attr_size = 0;
- const char *std_attrs_section;
struct elf_link_hash_table *htab = elf_hash_table (info);
bool sections_removed;
@@ -12618,12 +12681,12 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info)
sections from the link, and set the contents of the output
section. */
sections_removed = false;
- std_attrs_section = get_elf_backend_data (abfd)->obj_attrs_section;
+ const char *obj_attrs_section = get_elf_backend_data (abfd)->obj_attrs_section;
for (o = abfd->sections; o != NULL; o = o->next)
{
bool remove_section = false;
- if ((std_attrs_section && strcmp (o->name, std_attrs_section) == 0)
+ if ((obj_attrs_section && strcmp (o->name, obj_attrs_section) == 0)
|| strcmp (o->name, ".gnu.attributes") == 0)
{
for (p = o->map_head.link_order; p != NULL; p = p->next)
@@ -12638,12 +12701,16 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info)
input_section->flags &= ~SEC_HAS_CONTENTS;
}
- attr_size = bfd_elf_obj_attr_size (abfd);
- bfd_set_section_size (o, attr_size);
/* Skip this section later on. */
o->map_head.link_order = NULL;
- if (attr_size)
- attr_section = o;
+
+ bfd_vma attr_size = bfd_elf_obj_attr_size (abfd);
+ /* Once ELF headers have been written, the size of a section is
+ frozen. We need to set the size of the attribute section before
+ _bfd_elf_compute_section_file_positions. */
+ bfd_set_section_size (o, attr_size);
+ if (attr_size > 0)
+ elf_obj_build_attributes (abfd) = o;
else
remove_section = true;
}
@@ -13079,8 +13146,8 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info)
if (info->enable_dt_relr
&& bed->finish_relative_relocs
&& !bed->finish_relative_relocs (info))
- info->callbacks->einfo
- (_("%F%P: %pB: failed to finish relative relocations\n"), abfd);
+ info->callbacks->fatal
+ (_("%P: %pB: failed to finish relative relocations\n"), abfd);
/* Since ELF permits relocations to be against local symbols, we
must have the local symbols available when we do the relocations.
@@ -13758,21 +13825,14 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info)
if (! _bfd_elf_write_section_sframe (abfd, info))
goto error_return;
+ if (! _bfd_elf_write_section_build_attributes (abfd, info))
+ goto error_ret2;
+
if (info->callbacks->emit_ctf)
info->callbacks->emit_ctf ();
elf_final_link_free (abfd, &flinfo);
- if (attr_section)
- {
- bfd_byte *contents = (bfd_byte *) bfd_malloc (attr_size);
- if (contents == NULL)
- goto error_ret2;
- bfd_elf_set_obj_attr_contents (abfd, contents, attr_size);
- bfd_set_section_contents (abfd, attr_section, contents, 0, attr_size);
- free (contents);
- }
-
if (info->unique_symbol)
bfd_hash_table_free (&flinfo.local_hash_table);
return true;
@@ -13932,25 +13992,21 @@ _bfd_elf_gc_mark_hook (asection *sec,
struct elf_link_hash_entry *h,
Elf_Internal_Sym *sym)
{
- if (h != NULL)
+ if (h == NULL)
+ return bfd_section_from_elf_index (sec->owner, sym->st_shndx);
+
+ switch (h->root.type)
{
- switch (h->root.type)
- {
- case bfd_link_hash_defined:
- case bfd_link_hash_defweak:
- return h->root.u.def.section;
+ case bfd_link_hash_defined:
+ case bfd_link_hash_defweak:
+ return h->root.u.def.section;
- case bfd_link_hash_common:
- return h->root.u.c.p->section;
+ case bfd_link_hash_common:
+ return h->root.u.c.p->section;
- default:
- break;
- }
+ default:
+ return NULL;
}
- else
- return bfd_section_from_elf_index (sec->owner, sym->st_shndx);
-
- return NULL;
}
/* Return the debug definition section. */
@@ -13999,56 +14055,49 @@ _bfd_elf_gc_mark_rsec (struct bfd_link_info *info, asection *sec,
if (r_symndx == STN_UNDEF)
return NULL;
- if (r_symndx >= cookie->locsymcount
- || ELF_ST_BIND (cookie->locsyms[r_symndx].st_info) != STB_LOCAL)
+ h = get_ext_sym_hash_from_cookie (cookie, r_symndx);
+ if (h == NULL)
{
- bool was_marked;
+ /* A corrupt input file can lead to a situation where the index
+ does not reference either a local or an external symbol. */
+ if (r_symndx >= cookie->locsymcount)
+ return NULL;
- h = cookie->sym_hashes[r_symndx - cookie->extsymoff];
- if (h == NULL)
- {
- info->callbacks->einfo (_("%F%P: corrupt input: %pB\n"),
- sec->owner);
- return NULL;
- }
- while (h->root.type == bfd_link_hash_indirect
- || h->root.type == bfd_link_hash_warning)
- h = (struct elf_link_hash_entry *) h->root.u.i.link;
+ return (*gc_mark_hook) (sec, info, cookie->rel, NULL,
+ &cookie->locsyms[r_symndx]);
+ }
- was_marked = h->mark;
- h->mark = 1;
- /* Keep all aliases of the symbol too. If an object symbol
- needs to be copied into .dynbss then all of its aliases
- should be present as dynamic symbols, not just the one used
- on the copy relocation. */
- hw = h;
- while (hw->is_weakalias)
- {
- hw = hw->u.alias;
- hw->mark = 1;
- }
+ bool was_marked = h->mark;
- if (!was_marked && h->start_stop && !h->root.ldscript_def)
- {
- if (info->start_stop_gc)
- return NULL;
+ h->mark = 1;
+ /* Keep all aliases of the symbol too. If an object symbol
+ needs to be copied into .dynbss then all of its aliases
+ should be present as dynamic symbols, not just the one used
+ on the copy relocation. */
+ hw = h;
+ while (hw->is_weakalias)
+ {
+ hw = hw->u.alias;
+ hw->mark = 1;
+ }
- /* To work around a glibc bug, mark XXX input sections
- when there is a reference to __start_XXX or __stop_XXX
- symbols. */
- else if (start_stop != NULL)
- {
- asection *s = h->u2.start_stop_section;
- *start_stop = true;
- return s;
- }
- }
+ if (!was_marked && h->start_stop && !h->root.ldscript_def)
+ {
+ if (info->start_stop_gc)
+ return NULL;
- return (*gc_mark_hook) (sec, info, cookie->rel, h, NULL);
+ /* To work around a glibc bug, mark XXX input sections
+ when there is a reference to __start_XXX or __stop_XXX
+ symbols. */
+ else if (start_stop != NULL)
+ {
+ asection *s = h->u2.start_stop_section;
+ *start_stop = true;
+ return s;
+ }
}
- return (*gc_mark_hook) (sec, info, cookie->rel, NULL,
- &cookie->locsyms[r_symndx]);
+ return (*gc_mark_hook) (sec, info, cookie->rel, h, NULL);
}
/* COOKIE->rel describes a relocation against section SEC, which is
@@ -14260,7 +14309,7 @@ _bfd_elf_gc_mark_extra_sections (struct bfd_link_info *info,
else if (strcmp (bfd_section_name (isec),
"__patchable_function_entries") == 0
&& elf_linked_to_section (isec) == NULL)
- info->callbacks->einfo (_("%F%P: %pB(%pA): error: "
+ info->callbacks->fatal (_("%P: %pB(%pA): error: "
"need linked-to section "
"for --gc-sections\n"),
isec->owner, isec);
@@ -14361,7 +14410,8 @@ elf_gc_sweep (bfd *abfd, struct bfd_link_info *info)
if (o->flags & SEC_GROUP)
{
asection *first = elf_next_in_group (o);
- o->gc_mark = first->gc_mark;
+ if (first != NULL)
+ o->gc_mark = first->gc_mark;
}
if (o->gc_mark)
@@ -15069,17 +15119,12 @@ bfd_elf_reloc_symbol_deleted_p (bfd_vma offset, void *cookie)
if (r_symndx == STN_UNDEF)
return true;
- if (r_symndx >= rcookie->locsymcount
- || ELF_ST_BIND (rcookie->locsyms[r_symndx].st_info) != STB_LOCAL)
- {
- struct elf_link_hash_entry *h;
-
- h = rcookie->sym_hashes[r_symndx - rcookie->extsymoff];
-
- while (h->root.type == bfd_link_hash_indirect
- || h->root.type == bfd_link_hash_warning)
- h = (struct elf_link_hash_entry *) h->root.u.i.link;
+ struct elf_link_hash_entry *h;
+ h = get_ext_sym_hash_from_cookie (rcookie, r_symndx);
+
+ if (h != NULL)
+ {
if ((h->root.type == bfd_link_hash_defined
|| h->root.type == bfd_link_hash_defweak)
&& (h->root.u.def.section->owner != rcookie->abfd
@@ -15089,6 +15134,10 @@ bfd_elf_reloc_symbol_deleted_p (bfd_vma offset, void *cookie)
}
else
{
+ if (r_symndx >= rcookie->locsymcount)
+ /* This can happen with corrupt input. */
+ return false;
+
/* It's not a relocation against a global symbol,
but it could be a relocation against a local
symbol for a discarded section. */
@@ -15103,6 +15152,7 @@ bfd_elf_reloc_symbol_deleted_p (bfd_vma offset, void *cookie)
|| discarded_section (isec)))
return true;
}
+
return false;
}
return false;
@@ -15437,7 +15487,7 @@ _bfd_elf_section_already_linked (bfd *abfd,
/* This is the first section with this name. Record it. */
if (!bfd_section_already_linked_table_insert (already_linked_list, sec))
- info->callbacks->einfo (_("%F%P: already_linked_table: %E\n"));
+ info->callbacks->fatal (_("%P: already_linked_table: %E\n"));
return sec->output_section == bfd_abs_section_ptr;
}