diff options
Diffstat (limited to 'bfd/elf32-i386.c')
-rw-r--r-- | bfd/elf32-i386.c | 84 |
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. */ |