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
{
}
/* 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
{
/* 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);
}
}
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;
&& (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;
/* If we have version information, print it. */
version_string = _bfd_elf_get_symbol_version_string (abfd,
symbol,
+ TRUE,
&hidden);
if (version_string)
{
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])
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;
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;
}
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;
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);
}
}
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;
asection *first_mbind = NULL;
asection *dynsec, *eh_frame_hdr;
size_t amt;
- bfd_vma addr_mask, wrap_to = 0;
- bfd_size_type phdr_size;
+ bfd_vma addr_mask, wrap_to = 0; /* Bytes. */
+ bfd_size_type phdr_size; /* Octets/bytes. */
unsigned int opb = bfd_octets_per_byte (abfd, NULL);
/* Select the allocated sections, and sort them. */
sections[i] = s;
++i;
/* A wrapping section potentially clashes with header. */
- if (((s->lma + s->size) & addr_mask) < (s->lma & addr_mask))
- wrap_to = (s->lma + s->size) & addr_mask;
+ if (((s->lma + s->size / opb) & addr_mask) < (s->lma & addr_mask))
+ wrap_to = (s->lma + s->size / opb) & addr_mask;
}
}
BFD_ASSERT (i <= bfd_count_sections (abfd));
program headers we will need. */
if (phdr_in_segment && count > 0)
{
- bfd_vma phdr_lma;
+ bfd_vma phdr_lma; /* Bytes. */
bfd_boolean separate_phdr = FALSE;
phdr_lma = (sections[0]->lma - phdr_size) & addr_mask & -maxpagesize;
m = make_mapping (abfd, sections, 0, 0, phdr_in_segment);
if (m == NULL)
goto error_return;
- m->p_paddr = phdr_lma;
+ m->p_paddr = phdr_lma * opb;
m->p_vaddr_offset
= (sections[0]->vma - phdr_size) & addr_mask & -maxpagesize;
m->p_paddr_valid = 1;
if (s2->next->alignment_power == alignment_power
&& (s2->next->flags & SEC_LOAD) != 0
&& elf_section_type (s2->next) == SHT_NOTE
- && align_power (s2->lma + s2->size,
+ && align_power (s2->lma + s2->size / opb,
alignment_power)
== s2->next->lma)
count++;
{
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;
return m1->no_sort_lma ? -1 : 1;
if (m1->p_type == PT_LOAD && !m1->no_sort_lma)
{
- bfd_vma lma1, lma2;
+ bfd_vma lma1, lma2; /* Octets. */
lma1 = 0;
if (m1->p_paddr_valid)
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;
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;
}
if (p->p_type == PT_LOAD
&& m->count > 0)
{
- bfd_size_type align;
+ bfd_size_type align; /* Bytes. */
unsigned int align_power = 0;
if (m->p_align_valid)
break;
}
- off_adjust = vma_page_aligned_bias (p->p_vaddr, off, align);
+ off_adjust = vma_page_aligned_bias (p->p_vaddr, off, align * opb);
/* Broken hardware and/or kernel require that files do not
map the same page with different permissions on some hppa
}
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.
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)
|| hash->root.type == bfd_link_hash_common))
{
asection *s = NULL;
- bfd_vma filehdr_vaddr = phdrs[phdr_load_seg->idx].p_vaddr;
+ bfd_vma filehdr_vaddr = phdrs[phdr_load_seg->idx].p_vaddr / opb;
if (phdr_load_seg->count != 0)
/* The segment contains sections, so use the first one. */
Elf_Internal_Phdr *p;
struct elf_segment_map *m;
file_ptr off;
+ unsigned int opb = bfd_octets_per_byte (abfd, NULL);
i_shdrpp = elf_elfsections (abfd);
end_hdrpp = i_shdrpp + elf_numsections (abfd);
{
if (p->p_type == PT_GNU_RELRO)
{
- bfd_vma start, end;
+ bfd_vma start, end; /* Bytes. */
bfd_boolean ok;
if (link_info != NULL)
if (!m->p_size_valid)
abort ();
start = m->sections[0]->vma;
- end = start + m->p_size;
+ end = start + m->p_size / opb;
}
else
{
&& lm->count != 0
&& (lm->sections[lm->count - 1]->vma
+ (!IS_TBSS (lm->sections[lm->count - 1])
- ? lm->sections[lm->count - 1]->size
+ ? lm->sections[lm->count - 1]->size / opb
: 0)) > start
&& lm->sections[0]->vma < end)
break;
if (i < lm->count)
{
- unsigned int opb = bfd_octets_per_byte (abfd,
- lm->sections[i]);
-
p->p_vaddr = lm->sections[i]->vma * opb;
p->p_paddr = lm->sections[i]->lma * opb;
p->p_offset = lm->sections[i]->filepos;
- p->p_memsz = end - p->p_vaddr;
+ p->p_memsz = end * opb - p->p_vaddr;
p->p_filesz = p->p_memsz;
/* The RELRO segment typically ends a few bytes
+ (map->includes_phdrs
? iehdr->e_phnum * iehdr->e_phentsize
: 0),
- output_section->alignment_power)
- == output_section->vma))
+ output_section->alignment_power * opb)
+ == (output_section->vma * opb)))
map->p_paddr = segment->p_vaddr;
/* Match up the physical address of the segment with the
if (matching_lma == NULL)
matching_lma = suggested_lma;
- map->p_paddr = matching_lma->lma;
+ map->p_paddr = matching_lma->lma * opb;
/* Offset the segment physical address from the lma
to allow for space taken up by elf headers. */
the same alignment. */
if (segment->p_align != 0 && segment->p_align < align)
align = segment->p_align;
- map->p_paddr &= -align;
+ map->p_paddr &= -(align * opb);
}
}
+ (map->includes_phdrs
? iehdr->e_phnum * iehdr->e_phentsize
: 0),
- output_section->alignment_power)
- != output_section->lma)
+ output_section->alignment_power * opb)
+ != output_section->lma * opb)
goto sorry;
}
else
map->p_type = segment->p_type;
map->p_flags = segment->p_flags;
map->p_flags_valid = 1;
- map->p_paddr = suggested_lma->lma;
+ map->p_paddr = suggested_lma->lma * opb;
map->p_paddr_valid = p_paddr_valid;
map->includes_filehdr = 0;
map->includes_phdrs = 0;
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)
}
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 *))
{
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)
}
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 *))
{
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 *);
}
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 */
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)
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. */
/* 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)
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,
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;
}
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;
!= 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;
}
}
/* 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;
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)
#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. */
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)
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)
{
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;
}