aboutsummaryrefslogtreecommitdiff
path: root/bfd/elflink.c
diff options
context:
space:
mode:
Diffstat (limited to 'bfd/elflink.c')
-rw-r--r--bfd/elflink.c47
1 files changed, 47 insertions, 0 deletions
diff --git a/bfd/elflink.c b/bfd/elflink.c
index f27db39..9f0efa5 100644
--- a/bfd/elflink.c
+++ b/bfd/elflink.c
@@ -9266,6 +9266,9 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info)
size_t relativecount = 0;
asection *reldyn = 0;
bfd_size_type amt;
+ asection *attr_section = NULL;
+ bfd_vma attr_size = 0;
+ const char *std_attrs_section;
if (! is_elf_hash_table (info->hash))
return FALSE;
@@ -9313,6 +9316,40 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info)
finfo.symbuf_count = 0;
finfo.shndxbuf_size = 0;
+ /* The object attributes have been merged. Remove the input
+ sections from the link, and set the contents of the output
+ secton. */
+ std_attrs_section = get_elf_backend_data (abfd)->obj_attrs_section;
+ for (o = abfd->sections; o != NULL; o = o->next)
+ {
+ if ((std_attrs_section && strcmp (o->name, std_attrs_section) == 0)
+ || strcmp (o->name, ".gnu.attributes") == 0)
+ {
+ for (p = o->map_head.link_order; p != NULL; p = p->next)
+ {
+ asection *input_section;
+
+ if (p->type != bfd_indirect_link_order)
+ continue;
+ input_section = p->u.indirect.section;
+ /* Hack: reset the SEC_HAS_CONTENTS flag so that
+ elf_link_input_bfd ignores this section. */
+ input_section->flags &= ~SEC_HAS_CONTENTS;
+ }
+
+ attr_size = bfd_elf_obj_attr_size (abfd);
+ if (attr_size)
+ {
+ bfd_set_section_size (abfd, o, attr_size);
+ attr_section = o;
+ /* Skip this section later on. */
+ o->map_head.link_order = NULL;
+ }
+ else
+ o->flags |= SEC_EXCLUDE;
+ }
+ }
+
/* Count up the number of relocations we will output for each output
section, so that we know the sizes of the reloc sections. We
also figure out some maximum sizes. */
@@ -10257,6 +10294,16 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info)
elf_tdata (abfd)->linker = TRUE;
+ if (attr_section)
+ {
+ bfd_byte *contents = bfd_malloc (attr_size);
+ if (contents == NULL)
+ goto error_return;
+ bfd_elf_set_obj_attr_contents (abfd, contents, attr_size);
+ bfd_set_section_contents (abfd, attr_section, contents, 0, attr_size);
+ free (contents);
+ }
+
return TRUE;
error_return: