/* We also need to define an indirection from the nondefault version
of the symbol. */
-nondefault:
+ nondefault:
len = strlen (name);
shortname = (char *) bfd_hash_allocate (&info->hash->table, len);
if (shortname == NULL)
return TRUE;
}
-/* Add a DT_NEEDED entry for this dynamic object if DO_IT is true,
- otherwise just check whether one already exists. Returns -1 on error,
+/* Add a DT_NEEDED entry for this dynamic object. Returns -1 on error,
1 if a DT_NEEDED tag already exists, and 0 on success. */
-static int
-elf_add_dt_needed_tag (bfd *abfd,
- struct bfd_link_info *info,
- const char *soname,
- bfd_boolean do_it)
+int
+bfd_elf_add_dt_needed_tag (bfd *abfd, struct bfd_link_info *info)
{
struct elf_link_hash_table *hash_table;
size_t strindex;
+ const char *soname;
if (!_bfd_elf_link_create_dynstrtab (abfd, info))
return -1;
hash_table = elf_hash_table (info);
+ soname = elf_dt_name (abfd);
strindex = _bfd_elf_strtab_add (hash_table->dynstr, soname, FALSE);
if (strindex == (size_t) -1)
return -1;
}
}
- if (do_it)
- {
- if (!_bfd_elf_link_create_dynamic_sections (hash_table->dynobj, info))
- return -1;
+ if (!_bfd_elf_link_create_dynamic_sections (hash_table->dynobj, info))
+ return -1;
- if (!_bfd_elf_add_dynamic_entry (info, DT_NEEDED, strindex))
- return -1;
- }
- else
- /* We were just checking for existence of the tag. */
- _bfd_elf_strtab_delref (hash_table->dynstr, strindex);
+ if (!_bfd_elf_add_dynamic_entry (info, DT_NEEDED, strindex))
+ return -1;
return 0;
}
char *audit = NULL;
struct bfd_link_needed_list *rpath = NULL, *runpath = NULL;
const Elf_Internal_Phdr *phdr;
- int ret;
+ struct elf_link_loaded_list *loaded_lib;
/* ld --just-symbols and dynamic objects don't mix very well.
ld shouldn't allow it. */
if (!bfd_malloc_and_get_section (abfd, s, &dynbuf))
{
-error_free_dyn:
+ error_free_dyn:
free (dynbuf);
goto error_return;
}
will need to know it. */
elf_dt_name (abfd) = soname;
- ret = elf_add_dt_needed_tag (abfd, info, soname, add_needed);
- if (ret < 0)
- goto error_return;
-
/* If we have already included this dynamic object in the
link, just ignore it. There is no reason to include a
particular dynamic object more than once. */
- if (ret > 0)
- return TRUE;
+ for (loaded_lib = htab->dyn_loaded;
+ loaded_lib != NULL;
+ loaded_lib = loaded_lib->next)
+ {
+ if (strcmp (elf_dt_name (loaded_lib->abfd), soname) == 0)
+ return TRUE;
+ }
+
+ /* Create dynamic sections for backends that require that be done
+ before setup_gnu_properties. */
+ if (add_needed
+ && !_bfd_elf_link_create_dynamic_sections (abfd, info))
+ return FALSE;
/* Save the DT_AUDIT entry for the linker emulation code. */
elf_dt_audit (abfd) = audit;
Elf_Internal_Shdr *versymhdr = &elf_tdata (abfd)->dynversym_hdr;
bfd_size_type amt = versymhdr->sh_size;
- extversym = (Elf_External_Versym *) bfd_malloc (amt);
+ if (bfd_seek (abfd, versymhdr->sh_offset, SEEK_SET) != 0)
+ goto error_free_sym;
+ extversym = (Elf_External_Versym *)
+ _bfd_malloc_and_read (abfd, amt, amt);
if (extversym == NULL)
goto error_free_sym;
- if (bfd_seek (abfd, versymhdr->sh_offset, SEEK_SET) != 0
- || bfd_bread (extversym, amt, abfd) != amt)
- goto error_free_vers;
extversym_end = extversym + amt / sizeof (*extversym);
}
}
old_table = htab->root.table.table;
old_size = htab->root.table.size;
old_count = htab->root.table.count;
- old_strtab = _bfd_elf_strtab_save (htab->dynstr);
- if (old_strtab == NULL)
- goto error_free_vers;
+ old_strtab = NULL;
+ if (htab->dynstr != NULL)
+ {
+ old_strtab = _bfd_elf_strtab_save (htab->dynstr);
+ if (old_strtab == NULL)
+ goto error_free_vers;
+ }
for (i = 0; i < htab->root.table.size; i++)
{
&& !on_needed_list (elf_dt_name (abfd),
htab->needed, NULL))))
{
- int ret;
const char *soname = elf_dt_name (abfd);
info->callbacks->minfo ("%!", soname, old_bfd,
elf_dyn_lib_class (abfd) = (enum dynamic_lib_link_class)
(elf_dyn_lib_class (abfd) & ~DYN_AS_NEEDED);
+ /* Create dynamic sections for backends that require
+ that be done before setup_gnu_properties. */
+ if (!_bfd_elf_link_create_dynamic_sections (abfd, info))
+ return FALSE;
add_needed = TRUE;
- ret = elf_add_dt_needed_tag (abfd, info, soname, add_needed);
- if (ret < 0)
- goto error_free_vers;
-
- BFD_ASSERT (ret == 0);
}
}
}
memcpy (htab->root.table.table, old_tab, tabsize);
htab->root.undefs = old_undefs;
htab->root.undefs_tail = old_undefs_tail;
- _bfd_elf_strtab_restore (htab->dynstr, old_strtab);
+ if (htab->dynstr != NULL)
+ _bfd_elf_strtab_restore (htab->dynstr, old_strtab);
free (old_strtab);
old_strtab = NULL;
for (i = 0; i < htab->root.table.size; i++)
}
}
- if (is_elf_hash_table (htab) && add_needed)
+ if (dynamic && add_needed)
{
/* Add this bfd to the loaded list. */
struct elf_link_loaded_list *n;
if (n == NULL)
goto error_return;
n->abfd = abfd;
- n->next = htab->loaded;
- htab->loaded = n;
+ n->next = htab->dyn_loaded;
+ htab->dyn_loaded = n;
}
+ if (dynamic && !add_needed
+ && (elf_dyn_lib_class (abfd) & DYN_DT_NEEDED) != 0)
+ elf_dyn_lib_class (abfd) |= DYN_NO_NEEDED;
return TRUE;
Elf_Internal_Sym **ind, **indbufend, **indbuf;
struct elf_symbuf_symbol *ssym;
struct elf_symbuf_head *ssymbuf, *ssymhead;
- size_t i, shndx_count, total_size;
+ size_t i, shndx_count, total_size, amt;
- indbuf = (Elf_Internal_Sym **) bfd_malloc2 (symcount, sizeof (*indbuf));
+ amt = symcount * sizeof (*indbuf);
+ indbuf = (Elf_Internal_Sym **) bfd_malloc (amt);
if (indbuf == NULL)
return NULL;
result = TRUE;
-done:
+ done:
if (symtable1)
free (symtable1);
if (symtable2)
}
BFD_ASSERT (abfd != NULL);
- for (loaded = elf_hash_table (info)->loaded;
+ for (loaded = elf_hash_table (info)->dyn_loaded;
loaded != NULL;
loaded = loaded->next)
{
/* We check each DSO for a possible hidden versioned definition. */
if (input == abfd
- || (input->flags & DYNAMIC) == 0
|| elf_dynversym (input) == 0)
continue;
/* Read in any version definitions. */
versymhdr = &elf_tdata (input)->dynversym_hdr;
- extversym = (Elf_External_Versym *) bfd_malloc (versymhdr->sh_size);
- if (extversym == NULL)
- goto error_ret;
-
if (bfd_seek (input, versymhdr->sh_offset, SEEK_SET) != 0
- || (bfd_bread (extversym, versymhdr->sh_size, input)
- != versymhdr->sh_size))
+ || (extversym = (Elf_External_Versym *)
+ _bfd_malloc_and_read (input, versymhdr->sh_size,
+ versymhdr->sh_size)) == NULL)
{
- free (extversym);
- error_ret:
free (isymbuf);
return FALSE;
}
long symcount;
long src_count;
elf_symbol_type *osymbuf;
+ size_t amt;
implib_bfd = info->out_implib_bfd;
bed = get_elf_backend_data (abfd);
/* Make symbols absolute. */
- osymbuf = (elf_symbol_type *) bfd_alloc2 (implib_bfd, symcount,
- sizeof (*osymbuf));
+ amt = symcount * sizeof (*osymbuf);
+ osymbuf = (elf_symbol_type *) bfd_alloc (implib_bfd, amt);
if (osymbuf == NULL)
goto free_sym_buf;
ret = TRUE;
-free_sym_buf:
+ free_sym_buf:
free (sympp);
return ret;
}