if (keep_memory)
esdo->relocs = internal_relocs;
- if (alloc1 != NULL)
- free (alloc1);
+ free (alloc1);
/* Don't free alloc2, since if it was allocated we are passing it
back (under the name of internal_relocs). */
return internal_relocs;
error_return:
- if (alloc1 != NULL)
- free (alloc1);
+ free (alloc1);
if (alloc2 != NULL)
{
if (keep_memory)
}
}
- if (extversym != NULL)
- {
- free (extversym);
- extversym = NULL;
- }
-
- if (isymbuf != NULL)
- {
- free (isymbuf);
- isymbuf = NULL;
- }
+ free (extversym);
+ extversym = NULL;
+ free (isymbuf);
+ isymbuf = NULL;
if ((elf_dyn_lib_class (abfd) & DYN_AS_NEEDED) != 0)
{
free (old_tab);
objalloc_free_block ((struct objalloc *) htab->root.table.memory,
alloc_mark);
- if (nondeflt_vers != NULL)
- free (nondeflt_vers);
+ free (nondeflt_vers);
return TRUE;
}
return TRUE;
error_free_vers:
- if (old_tab != NULL)
- free (old_tab);
- if (old_strtab != NULL)
- free (old_strtab);
- if (nondeflt_vers != NULL)
- free (nondeflt_vers);
- if (extversym != NULL)
- free (extversym);
+ free (old_tab);
+ free (old_strtab);
+ free (nondeflt_vers);
+ free (extversym);
error_free_sym:
- if (isymbuf != NULL)
- free (isymbuf);
+ free (isymbuf);
error_return:
return FALSE;
}
while (loop);
free (included);
-
return TRUE;
error_return:
- if (included != NULL)
- free (included);
+ free (included);
return FALSE;
}
later. */
h->u.elf_hash_value = ha;
- if (alc != NULL)
- free (alc);
-
+ free (alc);
return TRUE;
}
if (s->min_dynindx < 0 || s->min_dynindx > h->dynindx)
s->min_dynindx = h->dynindx;
- if (alc != NULL)
- free (alc);
-
+ free (alc);
return TRUE;
}
{
struct elf_link_hash_table *htab;
+ if (ind->dyn_relocs != NULL)
+ {
+ if (dir->dyn_relocs != NULL)
+ {
+ struct elf_dyn_relocs **pp;
+ struct elf_dyn_relocs *p;
+
+ /* Add reloc counts against the indirect sym to the direct sym
+ list. Merge any entries against the same section. */
+ for (pp = &ind->dyn_relocs; (p = *pp) != NULL; )
+ {
+ struct elf_dyn_relocs *q;
+
+ for (q = dir->dyn_relocs; q != NULL; q = q->next)
+ if (q->sec == p->sec)
+ {
+ q->pc_count += p->pc_count;
+ q->count += p->count;
+ *pp = p->next;
+ break;
+ }
+ if (q == NULL)
+ pp = &p->next;
+ }
+ *pp = dir->dyn_relocs;
+ }
+
+ dir->dyn_relocs = ind->dyn_relocs;
+ ind->dyn_relocs = NULL;
+ }
+
/* Copy down any references that we may have already seen to the
symbol which just became indirect. */
return TRUE;
error_return:
- if (dynbuf != NULL)
- free (dynbuf);
+ free (dynbuf);
return FALSE;
}
result = TRUE;
done:
- if (symtable1)
- free (symtable1);
- if (symtable2)
- free (symtable2);
- if (isymbuf1)
- free (isymbuf1);
- if (isymbuf2)
- free (isymbuf2);
+ free (symtable1);
+ free (symtable2);
+ free (isymbuf1);
+ free (isymbuf2);
return result;
}
if (flinfo->symstrtab != NULL)
_bfd_elf_strtab_free (flinfo->symstrtab);
- if (flinfo->contents != NULL)
- free (flinfo->contents);
- if (flinfo->external_relocs != NULL)
- free (flinfo->external_relocs);
- if (flinfo->internal_relocs != NULL)
- free (flinfo->internal_relocs);
- if (flinfo->external_syms != NULL)
- free (flinfo->external_syms);
- if (flinfo->locsym_shndx != NULL)
- free (flinfo->locsym_shndx);
- if (flinfo->internal_syms != NULL)
- free (flinfo->internal_syms);
- if (flinfo->indices != NULL)
- free (flinfo->indices);
- if (flinfo->sections != NULL)
- free (flinfo->sections);
- if (flinfo->symshndxbuf != NULL
- && flinfo->symshndxbuf != (Elf_External_Sym_Shndx *) -1)
+ free (flinfo->contents);
+ free (flinfo->external_relocs);
+ free (flinfo->internal_relocs);
+ free (flinfo->external_syms);
+ free (flinfo->locsym_shndx);
+ free (flinfo->internal_syms);
+ free (flinfo->indices);
+ free (flinfo->sections);
+ if (flinfo->symshndxbuf != (Elf_External_Sym_Shndx *) -1)
free (flinfo->symshndxbuf);
for (o = obfd->sections; o != NULL; o = o->next)
{
struct bfd_elf_section_data *esdo = elf_section_data (o);
- if ((o->flags & SEC_RELOC) != 0 && esdo->rel.hashes != NULL)
- free (esdo->rel.hashes);
- if ((o->flags & SEC_RELOC) != 0 && esdo->rela.hashes != NULL)
- free (esdo->rela.hashes);
+ free (esdo->rel.hashes);
+ free (esdo->rela.hashes);
}
}
if (!info->reduce_memory_overheads)
{
for (sub = info->input_bfds; sub != NULL; sub = sub->link.next)
- if (bfd_get_flavour (sub) == bfd_target_elf_flavour
- && elf_tdata (sub)->symbuf)
+ if (bfd_get_flavour (sub) == bfd_target_elf_flavour)
{
free (elf_tdata (sub)->symbuf);
elf_tdata (sub)->symbuf = NULL;
goto error_return;
/* Check for DT_TEXTREL (late, in case the backend removes it). */
- if (((info->warn_shared_textrel && bfd_link_pic (info))
- || info->error_textrel)
+ if (bfd_link_textrel_check (info)
&& (o = bfd_get_linker_section (dynobj, ".dynamic")) != NULL)
{
bfd_byte *dyncon, *dynconend;
if (dyn.d_tag == DT_TEXTREL)
{
- if (info->error_textrel)
+ if (info->textrel_check == textrel_check_error)
info->callbacks->einfo
(_("%P%X: read-only segment has dynamic relocations\n"));
+ else if (bfd_link_dll (info))
+ info->callbacks->einfo
+ (_("%P: warning: creating DT_TEXTREL in a shared object\n"));
else
info->callbacks->einfo
- (_("%P: warning: creating a DT_TEXTREL in a shared object\n"));
+ (_("%P: warning: creating DT_TEXTREL in a PIE\n"));
break;
}
}
Elf_Internal_Shdr *symtab_hdr;
symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
- if (cookie->locsyms != NULL
- && symtab_hdr->contents != (unsigned char *) cookie->locsyms)
+ if (symtab_hdr->contents != (unsigned char *) cookie->locsyms)
free (cookie->locsyms);
}
fini_reloc_cookie_rels (struct elf_reloc_cookie *cookie,
asection *sec)
{
- if (cookie->rels && elf_section_data (sec)->relocs != cookie->rels)
+ if (elf_section_data (sec)->relocs != cookie->rels)
free (cookie->rels);
}
}
return NULL;
}
+
+/* Find dynamic relocs for H that apply to read-only sections. */
+
+asection *
+_bfd_elf_readonly_dynrelocs (struct elf_link_hash_entry *h)
+{
+ struct elf_dyn_relocs *p;
+
+ for (p = h->dyn_relocs; p != NULL; p = p->next)
+ {
+ asection *s = p->sec->output_section;
+
+ if (s != NULL && (s->flags & SEC_READONLY) != 0)
+ return p->sec;
+ }
+ return NULL;
+}
+
+/* Set DF_TEXTREL if we find any dynamic relocs that apply to
+ read-only sections. */
+
+bfd_boolean
+_bfd_elf_maybe_set_textrel (struct elf_link_hash_entry *h, void *inf)
+{
+ asection *sec;
+
+ if (h->root.type == bfd_link_hash_indirect)
+ return TRUE;
+
+ sec = _bfd_elf_readonly_dynrelocs (h);
+ if (sec != NULL)
+ {
+ struct bfd_link_info *info = (struct bfd_link_info *) inf;
+
+ info->flags |= DF_TEXTREL;
+ /* xgettext:c-format */
+ info->callbacks->minfo (_("%pB: dynamic relocation against `%pT' "
+ "in read-only section `%pA'\n"),
+ sec->owner, h->root.root.string, sec);
+
+ if (bfd_link_textrel_check (info))
+ /* xgettext:c-format */
+ info->callbacks->einfo (_("%P: %pB: warning: relocation against `%s' "
+ "in read-only section `%pA'\n"),
+ sec->owner, h->root.root.string, sec);
+
+ /* Not an error, just cut short the traversal. */
+ return FALSE;
+ }
+ return TRUE;
+}