aboutsummaryrefslogtreecommitdiff
path: root/bfd/elflink.c
diff options
context:
space:
mode:
Diffstat (limited to 'bfd/elflink.c')
-rw-r--r--bfd/elflink.c116
1 files changed, 67 insertions, 49 deletions
diff --git a/bfd/elflink.c b/bfd/elflink.c
index df6eb25..666399b 100644
--- a/bfd/elflink.c
+++ b/bfd/elflink.c
@@ -3384,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);
@@ -3609,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;
}
@@ -4362,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. */
@@ -4430,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
@@ -4968,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;
@@ -5144,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))
{
@@ -5262,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;
@@ -5712,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);
+ }
}
}
}
@@ -6276,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)
{
@@ -12209,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;
@@ -12613,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;
@@ -12661,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)
@@ -12681,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;
}
@@ -13122,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.
@@ -13801,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;
@@ -14041,7 +14058,7 @@ _bfd_elf_gc_mark_rsec (struct bfd_link_info *info, asection *sec,
h = get_ext_sym_hash_from_cookie (cookie, r_symndx);
if (h == NULL)
{
- /* A corrup tinput file can lead to a situation where the index
+ /* 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;
@@ -14292,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);
@@ -14393,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)
@@ -15469,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;
}