From 28e07a0510ca896311014cddf125aedfd7a8cd52 Mon Sep 17 00:00:00 2001 From: Alan Modra Date: Mon, 20 Nov 2017 21:35:09 +1030 Subject: [PATCH] PR22451, strip no longer works on older object files Setting SHF_GROUP unconditionally on rel/rela sections associated with SHF_GROUP sections fails badly with objcopy/strip and ld -r if the input file SHT_GROUP section didn't specify the rel/rela sections. This patch rearranges where SHF_GROUP is set for rel/rela sections. PR 22451 PR 22460 * elf.c (_bfd_elf_init_reloc_shdr): Delete "sec_hdr" parameter and leave rel_hdr->sh_flags zero. Update calls. (bfd_elf_set_group_contents): Check input rel/rela SHF_GROUP flag when !gas before adding rel/rela section to group. Set output rel/rela SHF_GROUP flags. --- bfd/ChangeLog | 10 ++++++++++ bfd/elf.c | 22 +++++++++++++++------- 2 files changed, 25 insertions(+), 7 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 485371a..6e148b0 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,13 @@ +2017-11-20 Alan Modra + + PR 22451 + PR 22460 + * elf.c (_bfd_elf_init_reloc_shdr): Delete "sec_hdr" parameter + and leave rel_hdr->sh_flags zero. Update calls. + (bfd_elf_set_group_contents): Check input rel/rela SHF_GROUP + flag when !gas before adding rel/rela section to group. Set + output rel/rela SHF_GROUP flags. + 2017-11-18 Jim Wilson * elfnn-riscv.c (_bfd_riscv_relax_align): Add space between alignment diff --git a/bfd/elf.c b/bfd/elf.c index 93ed443..8cd67ad 100644 --- a/bfd/elf.c +++ b/bfd/elf.c @@ -3061,7 +3061,6 @@ _bfd_elf_set_reloc_sh_name (bfd *abfd, static bfd_boolean _bfd_elf_init_reloc_shdr (bfd *abfd, struct bfd_elf_section_reloc_data *reldata, - const Elf_Internal_Shdr *sec_hdr, const char *sec_name, bfd_boolean use_rela_p, bfd_boolean delay_st_name_p) @@ -3083,7 +3082,7 @@ _bfd_elf_init_reloc_shdr (bfd *abfd, ? bed->s->sizeof_rela : bed->s->sizeof_rel); rel_hdr->sh_addralign = (bfd_vma) 1 << bed->s->log_file_align; - rel_hdr->sh_flags = sec_hdr->sh_flags & SHF_GROUP; + rel_hdr->sh_flags = 0; rel_hdr->sh_addr = 0; rel_hdr->sh_size = 0; rel_hdr->sh_offset = 0; @@ -3374,14 +3373,14 @@ elf_fake_sections (bfd *abfd, asection *asect, void *fsarg) || arg->link_info->emitrelocations)) { if (esd->rel.count && esd->rel.hdr == NULL - && !_bfd_elf_init_reloc_shdr (abfd, &esd->rel, this_hdr, name, + && !_bfd_elf_init_reloc_shdr (abfd, &esd->rel, name, FALSE, delay_st_name_p)) { arg->failed = TRUE; return; } if (esd->rela.count && esd->rela.hdr == NULL - && !_bfd_elf_init_reloc_shdr (abfd, &esd->rela, this_hdr, name, + && !_bfd_elf_init_reloc_shdr (abfd, &esd->rela, name, TRUE, delay_st_name_p)) { arg->failed = TRUE; @@ -3391,7 +3390,6 @@ elf_fake_sections (bfd *abfd, asection *asect, void *fsarg) else if (!_bfd_elf_init_reloc_shdr (abfd, (asect->use_rela_p ? &esd->rela : &esd->rel), - this_hdr, name, asect->use_rela_p, delay_st_name_p)) @@ -3526,13 +3524,23 @@ bfd_elf_set_group_contents (bfd *abfd, asection *sec, void *failedptrarg) && !bfd_is_abs_section (s)) { struct bfd_elf_section_data *elf_sec = elf_section_data (s); - if (elf_sec->rel.hdr != NULL) + struct bfd_elf_section_data *input_elf_sec = elf_section_data (elt); + + if (elf_sec->rel.hdr != NULL + && (gas + || (input_elf_sec->rel.hdr != NULL + && input_elf_sec->rel.hdr->sh_flags & SHF_GROUP) != 0)) { + elf_sec->rel.hdr->sh_flags |= SHF_GROUP; loc -= 4; H_PUT_32 (abfd, elf_sec->rel.idx, loc); } - if (elf_sec->rela.hdr != NULL) + if (elf_sec->rela.hdr != NULL + && (gas + || (input_elf_sec->rela.hdr != NULL + && input_elf_sec->rela.hdr->sh_flags & SHF_GROUP) != 0)) { + elf_sec->rela.hdr->sh_flags |= SHF_GROUP; loc -= 4; H_PUT_32 (abfd, elf_sec->rela.idx, loc); } -- 2.7.4