aboutsummaryrefslogtreecommitdiff
path: root/bfd/elf.c
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2017-11-20 21:35:09 +1030
committerAlan Modra <amodra@gmail.com>2017-11-21 00:09:07 +1030
commit28e07a0510ca896311014cddf125aedfd7a8cd52 (patch)
tree3def5b5fa879960c313f57db5098fd989920455b /bfd/elf.c
parent578290ecafb83e93f0ac695df586b65dac5e8c5d (diff)
downloadbinutils-28e07a0510ca896311014cddf125aedfd7a8cd52.zip
binutils-28e07a0510ca896311014cddf125aedfd7a8cd52.tar.gz
binutils-28e07a0510ca896311014cddf125aedfd7a8cd52.tar.bz2
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.
Diffstat (limited to 'bfd/elf.c')
-rw-r--r--bfd/elf.c22
1 files changed, 15 insertions, 7 deletions
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);
}