X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=bfd%2Felf.c;h=9ca42e10d8e5b28090d6ce73cc65fbd456210123;hb=refs%2Fheads%2Fconcurrent-displaced-stepping-2020-04-01;hp=2d0001b46395ef3ad4a206628a1532e5b188cb29;hpb=666318230c54a348763927c80d085542d9890c42;p=deliverable%2Fbinutils-gdb.git diff --git a/bfd/elf.c b/bfd/elf.c index 2d0001b463..9ca42e10d8 100644 --- a/bfd/elf.c +++ b/bfd/elf.c @@ -513,17 +513,14 @@ bfd_elf_get_elf_syms (bfd *ibfd, _bfd_error_handler (_("%pB symbol number %lu references" " nonexistent SHT_SYMTAB_SHNDX section"), ibfd, (unsigned long) symoffset); - if (alloc_intsym != NULL) - free (alloc_intsym); + free (alloc_intsym); intsym_buf = NULL; goto out; } out: - if (alloc_ext != NULL) - free (alloc_ext); - if (alloc_extshndx != NULL) - free (alloc_extshndx); + free (alloc_ext); + free (alloc_extshndx); return intsym_buf; } @@ -857,11 +854,10 @@ _bfd_elf_setup_sections (bfd *abfd) if (elfsec == 0) { const struct elf_backend_data *bed = get_elf_backend_data (abfd); - if (bed->link_order_error_handler) - bed->link_order_error_handler - /* xgettext:c-format */ - (_("%pB: warning: sh_link not set for section `%pA'"), - abfd, s); + bed->link_order_error_handler + /* xgettext:c-format */ + (_("%pB: warning: sh_link not set for section `%pA'"), + abfd, s); } else { @@ -1424,9 +1420,8 @@ copy_special_section_fields (const bfd *ibfd, } /* Allow the target a chance to decide how these fields should be set. */ - if (bed->elf_backend_copy_special_section_fields != NULL - && bed->elf_backend_copy_special_section_fields - (ibfd, obfd, iheader, oheader)) + if (bed->elf_backend_copy_special_section_fields (ibfd, obfd, + iheader, oheader)) return TRUE; /* We have an iheader which might match oheader, and which has non-zero @@ -1610,8 +1605,8 @@ _bfd_elf_copy_private_bfd_data (bfd *ibfd, bfd *obfd) { /* Final attempt. Call the backend copy function with a NULL input section. */ - if (bed->elf_backend_copy_special_section_fields != NULL) - (void) bed->elf_backend_copy_special_section_fields (ibfd, obfd, NULL, oheader); + (void) bed->elf_backend_copy_special_section_fields (ibfd, obfd, + NULL, oheader); } } @@ -1880,15 +1875,16 @@ _bfd_elf_print_private_bfd_data (bfd *abfd, void *farg) return TRUE; error_return: - if (dynbuf != NULL) - free (dynbuf); + free (dynbuf); return FALSE; } -/* Get version string. */ +/* Get version name. If BASE_P is TRUE, return "Base" for VER_FLG_BASE + and return symbol version for symbol version itself. */ const char * _bfd_elf_get_symbol_version_string (bfd *abfd, asymbol *symbol, + bfd_boolean base_p, bfd_boolean *hidden) { const char *version_string = NULL; @@ -1906,10 +1902,18 @@ _bfd_elf_get_symbol_version_string (bfd *abfd, asymbol *symbol, && (vernum > elf_tdata (abfd)->cverdefs || (elf_tdata (abfd)->verdef[0].vd_flags == VER_FLG_BASE))) - version_string = "Base"; + version_string = base_p ? "Base" : ""; else if (vernum <= elf_tdata (abfd)->cverdefs) - version_string = - elf_tdata (abfd)->verdef[vernum - 1].vd_nodename; + { + const char *nodename + = elf_tdata (abfd)->verdef[vernum - 1].vd_nodename; + version_string = ""; + if (base_p + || nodename == NULL + || symbol->name == NULL + || strcmp (symbol->name, nodename) != 0) + version_string = nodename; + } else { Elf_Internal_Verneed *t; @@ -1990,6 +1994,7 @@ bfd_elf_print_symbol (bfd *abfd, /* If we have version information, print it. */ version_string = _bfd_elf_get_symbol_version_string (abfd, symbol, + TRUE, &hidden); if (version_string) { @@ -2062,9 +2067,13 @@ bfd_section_from_shdr (bfd *abfd, unsigned int shindex) if (sections_being_created == NULL) { size_t amt = elf_numsections (abfd) * sizeof (bfd_boolean); - sections_being_created = (bfd_boolean *) bfd_zalloc (abfd, amt); + + /* PR 26005: Do not use bfd_zalloc here as the memory might + be released before the bfd has been fully scanned. */ + sections_being_created = (bfd_boolean *) bfd_malloc (amt); if (sections_being_created == NULL) return FALSE; + memset (sections_being_created, FALSE, amt); sections_being_created_abfd = abfd; } if (sections_being_created [shindex]) @@ -2462,12 +2471,12 @@ bfd_section_from_shdr (bfd *abfd, unsigned int shindex) sections. */ if (*p_hdr != NULL) { - if (bed->init_secondary_reloc_section == NULL - || ! bed->init_secondary_reloc_section (abfd, hdr, name, shindex)) + if (!bed->init_secondary_reloc_section (abfd, hdr, name, shindex)) { _bfd_error_handler /* xgettext:c-format */ - (_("%pB: warning: secondary relocation section '%s' for section %pA found - ignoring"), + (_("%pB: warning: secondary relocation section '%s' " + "for section %pA found - ignoring"), abfd, name, target_sect); } goto success; @@ -2602,8 +2611,9 @@ bfd_section_from_shdr (bfd *abfd, unsigned int shindex) sections_being_created [shindex] = FALSE; if (-- nesting == 0) { + free (sections_being_created); sections_being_created = NULL; - sections_being_created_abfd = abfd; + sections_being_created_abfd = NULL; } return ret; } @@ -3533,8 +3543,13 @@ bfd_elf_set_group_contents (bfd *abfd, asection *sec, void *failedptrarg) if (symindx == 0) { /* If called from the assembler, swap_out_syms will have set up - elf_section_syms. */ - BFD_ASSERT (elf_section_syms (abfd) != NULL); + elf_section_syms. + PR 25699: A corrupt input file could contain bogus group info. */ + if (elf_section_syms (abfd) == NULL) + { + *failedptr = TRUE; + return; + } symindx = elf_section_syms (abfd)[sec->index]->udata.i; } elf_section_data (sec)->this_hdr.sh_info = symindx; @@ -3935,11 +3950,10 @@ assign_section_numbers (bfd *abfd, struct bfd_link_info *link_info) where s is NULL. */ const struct elf_backend_data *bed = get_elf_backend_data (abfd); - if (bed->link_order_error_handler) - bed->link_order_error_handler - /* xgettext:c-format */ - (_("%pB: warning: sh_link not set for section `%pA'"), - abfd, sec); + bed->link_order_error_handler + /* xgettext:c-format */ + (_("%pB: warning: sh_link not set for section `%pA'"), + abfd, sec); } } @@ -3989,9 +4003,7 @@ assign_section_numbers (bfd *abfd, struct bfd_link_info *link_info) elf_section_data (s)->this_hdr.sh_link = d->this_idx; /* This is a .stab section. */ - if (elf_section_data (s)->this_hdr.sh_entsize == 0) - elf_section_data (s)->this_hdr.sh_entsize - = 4 + 2 * bfd_get_arch_size (abfd) / 8; + elf_section_data (s)->this_hdr.sh_entsize = 12; } } break; @@ -5196,9 +5208,12 @@ _bfd_elf_map_sections_to_segments (bfd *abfd, struct bfd_link_info *info) { i = m->count; while (--i != (unsigned) -1) - if ((m->sections[i]->flags & (SEC_LOAD | SEC_HAS_CONTENTS)) - == (SEC_LOAD | SEC_HAS_CONTENTS)) - break; + { + if (m->sections[i]->size > 0 + && (m->sections[i]->flags & (SEC_LOAD | SEC_HAS_CONTENTS)) + == (SEC_LOAD | SEC_HAS_CONTENTS)) + break; + } if (i != (unsigned) -1) break; @@ -5233,8 +5248,7 @@ _bfd_elf_map_sections_to_segments (bfd *abfd, struct bfd_link_info *info) return TRUE; error_return: - if (sections != NULL) - free (sections); + free (sections); return FALSE; } @@ -5312,19 +5326,25 @@ elf_sort_segments (const void *arg1, const void *arg2) return m1->no_sort_lma ? -1 : 1; if (m1->p_type == PT_LOAD && !m1->no_sort_lma) { - unsigned int opb = bfd_octets_per_byte (m1->sections[0]->owner, - m1->sections[0]); - bfd_vma lma1, lma2; /* Bytes. */ + bfd_vma lma1, lma2; /* Octets. */ lma1 = 0; if (m1->p_paddr_valid) - lma1 = m1->p_paddr / opb; + lma1 = m1->p_paddr; else if (m1->count != 0) - lma1 = m1->sections[0]->lma + m1->p_vaddr_offset; + { + unsigned int opb = bfd_octets_per_byte (m1->sections[0]->owner, + m1->sections[0]); + lma1 = (m1->sections[0]->lma + m1->p_vaddr_offset) * opb; + } lma2 = 0; if (m2->p_paddr_valid) - lma2 = m2->p_paddr / opb; + lma2 = m2->p_paddr; else if (m2->count != 0) - lma2 = m2->sections[0]->lma + m2->p_vaddr_offset; + { + unsigned int opb = bfd_octets_per_byte (m2->sections[0]->owner, + m2->sections[0]); + lma2 = (m2->sections[0]->lma + m2->p_vaddr_offset) * opb; + } if (lma1 != lma2) return lma1 < lma2 ? -1 : 1; } @@ -5815,10 +5835,11 @@ assign_file_positions_for_load_sections (bfd *abfd, } p->p_memsz += adjust; - if (this_hdr->sh_type != SHT_NOBITS) + if (p->p_type == PT_LOAD) { - if (p->p_type == PT_LOAD) + if (this_hdr->sh_type != SHT_NOBITS) { + off_adjust = 0; if (p->p_filesz + adjust < p->p_memsz) { /* We have a PROGBITS section following NOBITS ones. @@ -5828,10 +5849,25 @@ assign_file_positions_for_load_sections (bfd *abfd, if (!write_zeros (abfd, off, adjust)) return FALSE; } + } + /* We only adjust sh_offset in SHT_NOBITS sections + as would seem proper for their address when the + section is first in the segment. sh_offset + doesn't really have any significance for + SHT_NOBITS anyway, apart from a notional position + relative to other sections. Historically we + didn't bother with adjusting sh_offset and some + programs depend on it not being adjusted. See + pr12921 and pr25662. */ + if (this_hdr->sh_type != SHT_NOBITS || i == 0) + { off += adjust; + if (this_hdr->sh_type == SHT_NOBITS) + off_adjust += adjust; } - p->p_filesz += adjust; } + if (this_hdr->sh_type != SHT_NOBITS) + p->p_filesz += adjust; } if (p->p_type == PT_NOTE && bfd_get_format (abfd) == bfd_core) @@ -7895,19 +7931,34 @@ _bfd_elf_fixup_group_sections (bfd *ibfd, asection *discarded) elf_section_flags (s->output_section) &= ~SHF_GROUP; elf_group_name (s->output_section) = NULL; } - /* Conversely, if the member section is not being output - but the SHT_GROUP section is, then adjust its size. */ - else if (s->output_section == discarded - && isec->output_section != discarded) + else { struct bfd_elf_section_data *elf_sec = elf_section_data (s); - removed += 4; - if (elf_sec->rel.hdr != NULL - && (elf_sec->rel.hdr->sh_flags & SHF_GROUP) != 0) - removed += 4; - if (elf_sec->rela.hdr != NULL - && (elf_sec->rela.hdr->sh_flags & SHF_GROUP) != 0) - removed += 4; + if (s->output_section == discarded + && isec->output_section != discarded) + { + /* Conversely, if the member section is not being + output but the SHT_GROUP section is, then adjust + its size. */ + removed += 4; + if (elf_sec->rel.hdr != NULL + && (elf_sec->rel.hdr->sh_flags & SHF_GROUP) != 0) + removed += 4; + if (elf_sec->rela.hdr != NULL + && (elf_sec->rela.hdr->sh_flags & SHF_GROUP) != 0) + removed += 4; + } + else + { + /* Also adjust for zero-sized relocation member + section. */ + if (elf_sec->rel.hdr != NULL + && elf_sec->rel.hdr->sh_size == 0) + removed += 4; + if (elf_sec->rela.hdr != NULL + && elf_sec->rela.hdr->sh_size == 0) + removed += 4; + } } s = elf_next_in_group (s); if (s == first) @@ -8452,9 +8503,23 @@ _bfd_elf_get_dynamic_symtab_upper_bound (bfd *abfd) } long -_bfd_elf_get_reloc_upper_bound (bfd *abfd ATTRIBUTE_UNUSED, - sec_ptr asect) +_bfd_elf_get_reloc_upper_bound (bfd *abfd, sec_ptr asect) { + if (asect->reloc_count != 0) + { + /* Sanity check reloc section size. */ + struct bfd_elf_section_data *d = elf_section_data (asect); + Elf_Internal_Shdr *rel_hdr = &d->this_hdr; + bfd_size_type ext_rel_size = rel_hdr->sh_size; + ufile_ptr filesize = bfd_get_file_size (abfd); + + if (filesize != 0 && ext_rel_size > filesize) + { + bfd_set_error (bfd_error_file_truncated); + return -1; + } + } + #if SIZEOF_LONG == SIZEOF_INT if (asect->reloc_count >= LONG_MAX / sizeof (arelent *)) { @@ -8520,7 +8585,7 @@ _bfd_elf_canonicalize_dynamic_symtab (bfd *abfd, long _bfd_elf_get_dynamic_reloc_upper_bound (bfd *abfd) { - bfd_size_type count; + bfd_size_type count, ext_rel_size; asection *s; if (elf_dynsymtab (abfd) == 0) @@ -8530,11 +8595,18 @@ _bfd_elf_get_dynamic_reloc_upper_bound (bfd *abfd) } count = 1; + ext_rel_size = 0; for (s = abfd->sections; s != NULL; s = s->next) if (elf_section_data (s)->this_hdr.sh_link == elf_dynsymtab (abfd) && (elf_section_data (s)->this_hdr.sh_type == SHT_REL || elf_section_data (s)->this_hdr.sh_type == SHT_RELA)) { + ext_rel_size += s->size; + if (ext_rel_size < s->size) + { + bfd_set_error (bfd_error_file_truncated); + return -1; + } count += s->size / elf_section_data (s)->this_hdr.sh_entsize; if (count > LONG_MAX / sizeof (arelent *)) { @@ -8542,6 +8614,16 @@ _bfd_elf_get_dynamic_reloc_upper_bound (bfd *abfd) return -1; } } + if (count > 1) + { + /* Sanity check reloc section sizes. */ + ufile_ptr filesize = bfd_get_file_size (abfd); + if (filesize != 0 && ext_rel_size > filesize) + { + bfd_set_error (bfd_error_file_truncated); + return -1; + } + } return count * sizeof (arelent *); } @@ -8950,8 +9032,7 @@ _bfd_elf_slurp_version_tables (bfd *abfd, bfd_boolean default_imported_symver) return TRUE; error_return: - if (contents != NULL) - free (contents); + free (contents); return FALSE; } @@ -9357,7 +9438,9 @@ bfd_boolean _bfd_elf_close_and_cleanup (bfd *abfd) { struct elf_obj_tdata *tdata = elf_tdata (abfd); - if (bfd_get_format (abfd) == bfd_object && tdata != NULL) + if (tdata != NULL + && (bfd_get_format (abfd) == bfd_object + || bfd_get_format (abfd) == bfd_core)) { if (elf_tdata (abfd)->o != NULL && elf_shstrtab (abfd) != NULL) _bfd_elf_strtab_free (elf_shstrtab (abfd)); @@ -9814,6 +9897,12 @@ elfcore_grok_aarch_pauth (bfd *abfd, Elf_Internal_Note *note) return elfcore_make_note_pseudosection (abfd, ".reg-aarch-pauth", note); } +static bfd_boolean +elfcore_grok_arc_v2 (bfd *abfd, Elf_Internal_Note *note) +{ + return elfcore_make_note_pseudosection (abfd, ".reg-arc-v2", note); +} + #if defined (HAVE_PRPSINFO_T) typedef prpsinfo_t elfcore_psinfo_t; #if defined (HAVE_PRPSINFO32_T) /* Sparc64 cross Sparc32 */ @@ -10373,6 +10462,13 @@ elfcore_grok_note (bfd *abfd, Elf_Internal_Note *note) else return TRUE; + case NT_ARC_V2: + if (note->namesz == 6 + && strcmp (note->namedata, "LINUX") == 0) + return elfcore_grok_arc_v2 (abfd, note); + else + return TRUE; + case NT_ARM_VFP: if (note->namesz == 6 && strcmp (note->namedata, "LINUX") == 0) @@ -10749,12 +10845,18 @@ elfcore_grok_netbsd_note (bfd *abfd, Elf_Internal_Note *note) case NT_NETBSDCORE_AUXV: /* NetBSD-specific Elf Auxiliary Vector data. */ return elfcore_make_auxv_note_section (abfd, note, 4); +#endif +#ifdef NT_NETBSDCORE_LWPSTATUS + case NT_NETBSDCORE_LWPSTATUS: + return elfcore_make_note_pseudosection (abfd, + ".note.netbsdcore.lwpstatus", + note); #endif default: break; } - /* As of March 2017 there are no other machine-independent notes + /* As of March 2020 there are no other machine-independent notes defined for NetBSD core files. If the note type is less than the start of the machine-dependent note types, we don't understand it. */ @@ -10768,6 +10870,7 @@ elfcore_grok_netbsd_note (bfd *abfd, Elf_Internal_Note *note) /* On the Alpha, SPARC (32-bit and 64-bit), PT_GETREGS == mach+0 and PT_GETFPREGS == mach+2. */ + case bfd_arch_aarch64: case bfd_arch_alpha: case bfd_arch_sparc: switch (note->type) @@ -11777,6 +11880,18 @@ elfcore_write_aarch_pauth (bfd *abfd, note_name, NT_ARM_PAC_MASK, aarch_pauth, size); } +char * +elfcore_write_arc_v2 (bfd *abfd, + char *buf, + int *bufsiz, + const void *arc_v2, + int size) +{ + char *note_name = "LINUX"; + return elfcore_write_note (abfd, buf, bufsiz, + note_name, NT_ARC_V2, arc_v2, size); +} + char * elfcore_write_register_note (bfd *abfd, char *buf, @@ -11859,6 +11974,8 @@ elfcore_write_register_note (bfd *abfd, return elfcore_write_aarch_sve (abfd, buf, bufsiz, data, size); if (strcmp (section, ".reg-aarch-pauth") == 0) return elfcore_write_aarch_pauth (abfd, buf, bufsiz, data, size); + if (strcmp (section, ".reg-arc-v2") == 0) + return elfcore_write_arc_v2 (abfd, buf, bufsiz, data, size); return NULL; } @@ -12441,6 +12558,7 @@ _bfd_elf_slurp_secondary_reloc_section (bfd * abfd, reloc_count = NUM_SHDR_ENTRIES (hdr); if (_bfd_mul_overflow (reloc_count, sizeof (arelent), & amt)) { + free (native_relocs); bfd_set_error (bfd_error_file_too_big); result = FALSE; continue; @@ -12459,7 +12577,8 @@ _bfd_elf_slurp_secondary_reloc_section (bfd * abfd, != hdr->sh_size)) { free (native_relocs); - free (internal_relocs); + /* The internal_relocs will be freed when + the memory for the bfd is released. */ result = FALSE; continue; } @@ -12577,13 +12696,31 @@ _bfd_elf_copy_special_section_fields (const bfd * ibfd ATTRIBUTE_UNUSED, } /* Find the output section that corresponds to the isection's sh_info link. */ - BFD_ASSERT (isection->sh_info > 0 - && isection->sh_info < elf_numsections (ibfd)); + if (isection->sh_info == 0 + || isection->sh_info >= elf_numsections (ibfd)) + { + _bfd_error_handler + /* xgettext:c-format */ + (_("%pB(%pA): info section index is invalid"), + obfd, osec); + bfd_set_error (bfd_error_bad_value); + return FALSE; + } + isection = elf_elfsections (ibfd)[isection->sh_info]; - BFD_ASSERT (isection != NULL); - BFD_ASSERT (isection->bfd_section != NULL); - BFD_ASSERT (isection->bfd_section->output_section != NULL); + if (isection == NULL + || isection->bfd_section == NULL + || isection->bfd_section->output_section == NULL) + { + _bfd_error_handler + /* xgettext:c-format */ + (_("%pB(%pA): info section index cannot be set because the section is not in the output"), + obfd, osec); + bfd_set_error (bfd_error_bad_value); + return FALSE; + } + osection->sh_info = elf_section_data (isection->bfd_section->output_section)->this_idx; @@ -12604,6 +12741,10 @@ _bfd_elf_write_secondary_reloc_section (bfd *abfd, asection *sec) bfd_vma addr_offset; asection * relsec; bfd_vma (*r_info) (bfd_vma, bfd_vma); + bfd_boolean result = TRUE; + + if (sec == NULL) + return FALSE; #if BFD_DEFAULT_TARGET_SIZE > 32 if (bfd_arch_bits_per_address (abfd) != 32) @@ -12612,9 +12753,6 @@ _bfd_elf_write_secondary_reloc_section (bfd *abfd, asection *sec) #endif r_info = elf32_r_info; - if (sec == NULL) - return FALSE; - /* The address of an ELF reloc is section relative for an object file, and absolute for an executable file or shared library. The address of a BFD reloc is always section relative. */ @@ -12639,10 +12777,28 @@ _bfd_elf_write_secondary_reloc_section (bfd *abfd, asection *sec) arelent * src_irel; bfd_byte * dst_rela; - BFD_ASSERT (hdr->contents == NULL); + if (hdr->contents != NULL) + { + _bfd_error_handler + /* xgettext:c-format */ + (_("%pB(%pA): error: secondary reloc section processed twice"), + abfd, relsec); + bfd_set_error (bfd_error_bad_value); + result = FALSE; + continue; + } reloc_count = hdr->sh_size / hdr->sh_entsize; - BFD_ASSERT (reloc_count > 0); + if (reloc_count <= 0) + { + _bfd_error_handler + /* xgettext:c-format */ + (_("%pB(%pA): error: secondary reloc section is empty!"), + abfd, relsec); + bfd_set_error (bfd_error_bad_value); + result = FALSE; + continue; + } hdr->contents = bfd_alloc (abfd, hdr->sh_size); if (hdr->contents == NULL) @@ -12656,7 +12812,16 @@ _bfd_elf_write_secondary_reloc_section (bfd *abfd, asection *sec) last_sym_idx = 0; dst_rela = hdr->contents; src_irel = (arelent *) esd->sec_info; - BFD_ASSERT (src_irel != NULL); + if (src_irel == NULL) + { + _bfd_error_handler + /* xgettext:c-format */ + (_("%pB(%pA): error: internal relocs missing for secondary reloc section"), + abfd, relsec); + bfd_set_error (bfd_error_bad_value); + result = FALSE; + continue; + } for (idx = 0; idx < reloc_count; idx++, dst_rela += hdr->sh_entsize) { @@ -12666,55 +12831,78 @@ _bfd_elf_write_secondary_reloc_section (bfd *abfd, asection *sec) int n; ptr = src_irel + idx; - sym = *ptr->sym_ptr_ptr; + if (ptr == NULL) + { + _bfd_error_handler + /* xgettext:c-format */ + (_("%pB(%pA): error: reloc table entry %u is empty"), + abfd, relsec, idx); + bfd_set_error (bfd_error_bad_value); + result = FALSE; + break; + } - if (sym == last_sym) - n = last_sym_idx; + if (ptr->sym_ptr_ptr == NULL) + { + /* FIXME: Is this an error ? */ + n = 0; + } else { - last_sym = sym; - n = _bfd_elf_symbol_from_bfd_symbol (abfd, & sym); - if (n < 0) + sym = *ptr->sym_ptr_ptr; + + if (sym == last_sym) + n = last_sym_idx; + else { -#if DEBUG_SECONDARY_RELOCS - fprintf (stderr, "failed to find symbol %s whilst rewriting relocs\n", - sym->name); -#endif - /* FIXME: Signal failure somehow. */ - n = 0; + n = _bfd_elf_symbol_from_bfd_symbol (abfd, & sym); + if (n < 0) + { + _bfd_error_handler + /* xgettext:c-format */ + (_("%pB(%pA): error: secondary reloc %u references a missing symbol"), + abfd, relsec, idx); + bfd_set_error (bfd_error_bad_value); + result = FALSE; + n = 0; + } + + last_sym = sym; + last_sym_idx = n; } - last_sym_idx = n; - } - if ((*ptr->sym_ptr_ptr)->the_bfd != NULL - && (*ptr->sym_ptr_ptr)->the_bfd->xvec != abfd->xvec - && ! _bfd_elf_validate_reloc (abfd, ptr)) - { -#if DEBUG_SECONDARY_RELOCS - fprintf (stderr, "symbol %s is not in the output bfd\n", - sym->name); -#endif - /* FIXME: Signal failure somehow. */ - n = 0; + if (sym->the_bfd != NULL + && sym->the_bfd->xvec != abfd->xvec + && ! _bfd_elf_validate_reloc (abfd, ptr)) + { + _bfd_error_handler + /* xgettext:c-format */ + (_("%pB(%pA): error: secondary reloc %u references a deleted symbol"), + abfd, relsec, idx); + bfd_set_error (bfd_error_bad_value); + result = FALSE; + n = 0; + } } + src_rela.r_offset = ptr->address + addr_offset; if (ptr->howto == NULL) { -#if DEBUG_SECONDARY_RELOCS - fprintf (stderr, "reloc for symbol %s does not have a howto associated with it\n", - sym->name); -#endif - /* FIXME: Signal failure somehow. */ - n = 0; + _bfd_error_handler + /* xgettext:c-format */ + (_("%pB(%pA): error: secondary reloc %u is of an unknown type"), + abfd, relsec, idx); + bfd_set_error (bfd_error_bad_value); + result = FALSE; + src_rela.r_info = r_info (0, 0); } - - src_rela.r_offset = ptr->address + addr_offset; - src_rela.r_info = r_info (n, ptr->howto->type); + else + src_rela.r_info = r_info (n, ptr->howto->type); src_rela.r_addend = ptr->addend; ebd->s->swap_reloca_out (abfd, &src_rela, dst_rela); } } } - return TRUE; + return result; }