diff options
Diffstat (limited to 'bfd/elf32-s390.c')
-rw-r--r-- | bfd/elf32-s390.c | 29 |
1 files changed, 22 insertions, 7 deletions
diff --git a/bfd/elf32-s390.c b/bfd/elf32-s390.c index 79c4050..b52144a 100644 --- a/bfd/elf32-s390.c +++ b/bfd/elf32-s390.c @@ -1607,7 +1607,7 @@ elf_s390_adjust_dynamic_symbol (struct bfd_link_info *info, struct elf_link_hash_entry *h) { struct elf_s390_link_hash_table *htab; - asection *s; + asection *s, *srel; /* STT_GNU_IFUNC symbol must go through PLT. */ if (s390_is_ifunc_symbol_p (h)) @@ -1757,14 +1757,22 @@ elf_s390_adjust_dynamic_symbol (struct bfd_link_info *info, /* We must generate a R_390_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_READONLY) != 0) + { + s = htab->elf.sdynrelro; + srel = htab->elf.sreldynrelro; + } + else + { + s = htab->elf.sdynbss; + srel = htab->elf.srelbss; + } if ((h->root.u.def.section->flags & SEC_ALLOC) != 0 && h->size != 0) { - htab->elf.srelbss->size += sizeof (Elf32_External_Rela); + srel->size += sizeof (Elf32_External_Rela); h->needs_copy = 1; } - s = htab->elf.sdynbss; - return _bfd_elf_adjust_dynamic_copy (info, h, s); } @@ -2157,6 +2165,7 @@ elf_s390_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED, || s == htab->elf.sgot || s == htab->elf.sgotplt || s == htab->elf.sdynbss + || s == htab->elf.sdynrelro || s == htab->elf.iplt || s == htab->elf.igotplt || s == htab->irelifunc) @@ -3800,6 +3809,7 @@ elf_s390_finish_dynamic_symbol (bfd *output_bfd, if (h->needs_copy) { Elf_Internal_Rela rela; + asection *s; bfd_byte *loc; /* This symbols needs a copy reloc. Set it up. */ @@ -3807,7 +3817,8 @@ elf_s390_finish_dynamic_symbol (bfd *output_bfd, if (h->dynindx == -1 || (h->root.type != bfd_link_hash_defined && h->root.type != bfd_link_hash_defweak) - || htab->elf.srelbss == NULL) + || htab->elf.srelbss == NULL + || htab->elf.sreldynrelro == NULL) abort (); rela.r_offset = (h->root.u.def.value @@ -3815,8 +3826,11 @@ elf_s390_finish_dynamic_symbol (bfd *output_bfd, + h->root.u.def.section->output_offset); rela.r_info = ELF32_R_INFO (h->dynindx, R_390_COPY); rela.r_addend = 0; - loc = htab->elf.srelbss->contents; - loc += htab->elf.srelbss->reloc_count++ * sizeof (Elf32_External_Rela); + if ((h->root.u.def.section->flags & SEC_READONLY) != 0) + s = htab->elf.sreldynrelro; + else + s = htab->elf.srelbss; + loc = s->contents + s->reloc_count++ * sizeof (Elf32_External_Rela); bfd_elf32_swap_reloca_out (output_bfd, &rela, loc); } @@ -4154,6 +4168,7 @@ elf32_s390_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info) #define elf_backend_plt_readonly 1 #define elf_backend_want_plt_sym 0 #define elf_backend_got_header_size 12 +#define elf_backend_want_dynrelro 1 #define elf_backend_rela_normal 1 #define elf_info_to_howto elf_s390_info_to_howto |