aboutsummaryrefslogtreecommitdiff
path: root/bfd/elf32-i386.c
diff options
context:
space:
mode:
Diffstat (limited to 'bfd/elf32-i386.c')
-rw-r--r--bfd/elf32-i386.c84
1 files changed, 78 insertions, 6 deletions
diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c
index 4179572..a90937b 100644
--- a/bfd/elf32-i386.c
+++ b/bfd/elf32-i386.c
@@ -887,6 +887,9 @@ struct elf_i386_link_hash_table
/* TRUE if there are dynamic relocs against IFUNC symbols that apply
to read-only sections. */
bfd_boolean readonly_dynrelocs_against_ifunc;
+
+ asection *sdynsharablebss;
+ asection *srelsharablebss;
};
/* Get the i386 ELF linker hash table from a link_info structure. */
@@ -1090,10 +1093,10 @@ elf_i386_create_dynamic_sections (bfd *dynobj, struct bfd_link_info *info)
if (bfd_link_executable (info))
{
/* Always allow copy relocs for building executables. */
+ const struct elf_backend_data *bed = get_elf_backend_data (dynobj);
asection *s = bfd_get_linker_section (dynobj, ".rel.bss");
if (s == NULL)
{
- const struct elf_backend_data *bed = get_elf_backend_data (dynobj);
s = bfd_make_section_anyway_with_flags (dynobj,
".rel.bss",
(bed->dynamic_sec_flags
@@ -1104,6 +1107,32 @@ elf_i386_create_dynamic_sections (bfd *dynobj, struct bfd_link_info *info)
return FALSE;
}
htab->srelbss = s;
+
+ s = bfd_get_linker_section (dynobj, ".dynsharablebss");
+ if (s == NULL)
+ {
+ s = bfd_make_section_anyway_with_flags (dynobj,
+ ".dynsharablebss",
+ (SEC_ALLOC
+ | SEC_LINKER_CREATED));
+ if (s == NULL)
+ return FALSE;
+ }
+ htab->sdynsharablebss = s;
+
+ s = bfd_get_linker_section (dynobj, ".rel.sharable_bss");
+ if (s == NULL)
+ {
+ s = bfd_make_section_anyway_with_flags (dynobj,
+ ".rel.sharable_bss",
+ (bed->dynamic_sec_flags
+ | SEC_READONLY));
+ if (s == NULL
+ || ! bfd_set_section_alignment (dynobj, s,
+ bed->s->log_file_align))
+ return FALSE;
+ }
+ htab->srelsharablebss = s;
}
if (get_elf_i386_backend_data (dynobj)->is_vxworks
@@ -2586,17 +2615,23 @@ elf_i386_adjust_dynamic_symbol (struct bfd_link_info *info,
both the dynamic object and the regular object will refer to the
same memory location for the variable. */
+ s = htab->sdynbss;
+
/* We must generate a R_386_COPY reloc to tell the dynamic linker to
copy the initial value out of the dynamic object and into the
runtime process image. */
if ((h->root.u.def.section->flags & SEC_ALLOC) != 0 && h->size != 0)
{
- htab->srelbss->size += sizeof (Elf32_External_Rel);
+ if (elf_section_flags (h->root.u.def.section) & SHF_GNU_SHARABLE)
+ {
+ htab->srelsharablebss->size += sizeof (Elf32_External_Rel);
+ s = htab->sdynsharablebss;
+ }
+ else
+ htab->srelbss->size += sizeof (Elf32_External_Rel);
h->needs_copy = 1;
}
- s = htab->sdynbss;
-
return _bfd_elf_adjust_dynamic_copy (info, h, s);
}
@@ -3408,6 +3443,7 @@ elf_i386_size_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info)
|| s == htab->elf.igotplt
|| s == htab->plt_got
|| s == htab->plt_eh_frame
+ || s == htab->sdynsharablebss
|| s == htab->sdynbss)
{
/* Strip these too. */
@@ -5560,20 +5596,26 @@ do_glob_dat:
if (h->needs_copy)
{
Elf_Internal_Rela rel;
+ asection *s;
+
+ if (h->root.u.def.section == htab->sdynsharablebss)
+ s = htab->srelsharablebss;
+ else
+ s = htab->srelbss;
/* This symbol needs a copy reloc. Set it up. */
if (h->dynindx == -1
|| (h->root.type != bfd_link_hash_defined
&& h->root.type != bfd_link_hash_defweak)
- || htab->srelbss == NULL)
+ || s == NULL)
abort ();
rel.r_offset = (h->root.u.def.value
+ h->root.u.def.section->output_section->vma
+ h->root.u.def.section->output_offset);
rel.r_info = ELF32_R_INFO (h->dynindx, R_386_COPY);
- elf_append_rel (output_bfd, htab->srelbss, &rel);
+ elf_append_rel (output_bfd, s, &rel);
}
return TRUE;
@@ -6032,6 +6074,22 @@ elf_i386_hash_symbol (struct elf_link_hash_entry *h)
return _bfd_elf_hash_symbol (h);
}
+/* Hook called by the linker routine which adds symbols from an object
+ file. */
+
+static bfd_boolean
+elf_i386_add_symbol_hook (bfd * abfd,
+ struct bfd_link_info * info,
+ Elf_Internal_Sym * sym,
+ const char ** namep,
+ flagword * flagsp,
+ asection ** secp,
+ bfd_vma * valp)
+{
+ return _bfd_elf_add_sharable_symbol (abfd, info, sym, namep, flagsp,
+ secp, valp);
+}
+
#define TARGET_LITTLE_SYM i386_elf32_vec
#define TARGET_LITTLE_NAME "elf32-i386"
#define ELF_ARCH bfd_arch_i386
@@ -6080,8 +6138,22 @@ elf_i386_hash_symbol (struct elf_link_hash_entry *h)
#define elf_backend_omit_section_dynsym \
((bfd_boolean (*) (bfd *, struct bfd_link_info *, asection *)) bfd_true)
#define elf_backend_hash_symbol elf_i386_hash_symbol
+#define elf_backend_add_symbol_hook elf_i386_add_symbol_hook
#define elf_backend_fixup_symbol elf_i386_fixup_symbol
+#define elf_backend_section_from_bfd_section \
+ _bfd_elf_sharable_section_from_bfd_section
+#define elf_backend_symbol_processing \
+ _bfd_elf_sharable_symbol_processing
+#define elf_backend_common_section_index \
+ _bfd_elf_sharable_common_section_index
+#define elf_backend_common_section \
+ _bfd_elf_sharable_common_section
+#define elf_backend_common_definition \
+ _bfd_elf_sharable_common_definition
+#define elf_backend_merge_symbol \
+ _bfd_elf_sharable_merge_symbol
+
#include "elf32-target.h"
/* FreeBSD support. */