diff options
-rw-r--r-- | bfd/ChangeLog | 11 | ||||
-rw-r--r-- | bfd/elf.c | 46 | ||||
-rw-r--r-- | gas/ChangeLog | 17 | ||||
-rw-r--r-- | gas/config/obj-elf.c | 65 | ||||
-rw-r--r-- | gas/testsuite/gas/arc/jli-1.d | 1 | ||||
-rw-r--r-- | gas/testsuite/gas/elf/groupautob.d | 2 | ||||
-rw-r--r-- | gas/testsuite/gas/mips/compact-eh-eb-2.d | 2 | ||||
-rw-r--r-- | gas/testsuite/gas/mips/compact-eh-eb-5.d | 2 | ||||
-rw-r--r-- | gas/testsuite/gas/mips/compact-eh-el-2.d | 2 | ||||
-rw-r--r-- | gas/testsuite/gas/mips/compact-eh-el-5.d | 2 | ||||
-rw-r--r-- | ld/ChangeLog | 5 | ||||
-rw-r--r-- | ld/testsuite/ld-elf/group9b.d | 9 |
12 files changed, 111 insertions, 53 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index cffa777..9b377f5 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,14 @@ +2017-10-05 Alan Modra <amodra@gmail.com> + + PR 21167 + * elf.c (_bfd_elf_setup_sections): Don't trim reloc sections from + groups. + (_bfd_elf_init_reloc_shdr): Pass sec_hdr, use it to copy SHF_GROUP + flag from section. + (elf_fake_sections): Adjust calls. Exit immediately on failure. + (bfd_elf_set_group_contents): Add associated reloc section indices + to group contents. + 2017-10-04 Alan Modra <amodra@gmail.com> * elf64-ppc.c (ppc64_elf_get_synthetic_symtab): Don't sort or @@ -913,15 +913,8 @@ _bfd_elf_setup_sections (bfd *abfd) continue; else if (idx->shdr->bfd_section) elf_sec_group (idx->shdr->bfd_section) = shdr->bfd_section; - else if (idx->shdr->sh_type == SHT_RELA - || idx->shdr->sh_type == SHT_REL) - /* We won't include relocation sections in section groups in - output object files. We adjust the group section size here - so that relocatable link will work correctly when - relocation sections are in section group in input object - files. */ - shdr->bfd_section->size -= 4; - else + else if (idx->shdr->sh_type != SHT_RELA + && idx->shdr->sh_type != SHT_REL) { /* There are some unknown sections in the group. */ _bfd_error_handler @@ -3068,6 +3061,7 @@ _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) @@ -3089,7 +3083,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 = 0; + rel_hdr->sh_flags = sec_hdr->sh_flags & SHF_GROUP; rel_hdr->sh_addr = 0; rel_hdr->sh_size = 0; rel_hdr->sh_offset = 0; @@ -3380,15 +3374,15 @@ 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, name, FALSE, - delay_st_name_p)) + && !_bfd_elf_init_reloc_shdr (abfd, &esd->rel, this_hdr, 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, name, TRUE, - delay_st_name_p)) + && !_bfd_elf_init_reloc_shdr (abfd, &esd->rela, this_hdr, name, + TRUE, delay_st_name_p)) { arg->failed = TRUE; return; @@ -3397,17 +3391,24 @@ 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)) + { arg->failed = TRUE; + return; + } } /* Check for processor-specific section types. */ sh_type = this_hdr->sh_type; if (bed->elf_backend_fake_sections && !(*bed->elf_backend_fake_sections) (abfd, this_hdr, asect)) - arg->failed = TRUE; + { + arg->failed = TRUE; + return; + } if (sh_type == SHT_NOBITS && asect->size != 0) { @@ -3524,10 +3525,19 @@ bfd_elf_set_group_contents (bfd *abfd, asection *sec, void *failedptrarg) if (s != NULL && !bfd_is_abs_section (s)) { - unsigned int idx = elf_section_data (s)->this_idx; - + struct bfd_elf_section_data *elf_sec = elf_section_data (s); + if (elf_sec->rel.hdr != NULL) + { + loc -= 4; + H_PUT_32 (abfd, elf_sec->rel.idx, loc); + } + if (elf_sec->rela.hdr != NULL) + { + loc -= 4; + H_PUT_32 (abfd, elf_sec->rela.idx, loc); + } loc -= 4; - H_PUT_32 (abfd, idx, loc); + H_PUT_32 (abfd, elf_sec->this_idx, loc); } elt = elf_next_in_group (elt); if (elt == first) diff --git a/gas/ChangeLog b/gas/ChangeLog index 05e06c6..c112d86 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,20 @@ +2017-10-05 Alan Modra <amodra@gmail.com> + + PR 21167 + * config/obj-elf.c (struct group_list): Delete elt_count. + (groups): New static. + (build_group_lists): Don't count elements. + (elf_adjust_symtab): Use "groups" rather than auto "list". Set up + pointer from group member to SHT_GROUP section. Don't size + SHT_GROUP section or clean up here.. + (elf_frob_file_after_relocs): ..do so here instead. + * testsuite/gas/arc/jli-1.d, + * testsuite/gas/elf/groupautob.d, + * testsuite/gas/mips/compact-eh-eb-2.d, + * testsuite/gas/mips/compact-eh-eb-5.d, + * testsuite/gas/mips/compact-eh-el-2.d, + * testsuite/gas/mips/compact-eh-el-5.d: Adjust. + 2017-10-01 Alexander Fedotov <alfedotov@gmail.com> * testsuite/gas/ppc/vle-mult-ld-st-insns.s: New file: Tests the diff --git a/gas/config/obj-elf.c b/gas/config/obj-elf.c index 49d99a4..3f641f4 100644 --- a/gas/config/obj-elf.c +++ b/gas/config/obj-elf.c @@ -2346,11 +2346,12 @@ elf_frob_symbol (symbolS *symp, int *puntp) struct group_list { asection **head; /* Section lists. */ - unsigned int *elt_count; /* Number of sections in each list. */ unsigned int num_group; /* Number of lists. */ struct hash_control *indexes; /* Maps group name to index in head array. */ }; +static struct group_list groups; + /* Called via bfd_map_over_sections. If SEC is a member of a group, add it to a list of sections belonging to the group. INF is a pointer to a struct group_list, which is where we store the head of @@ -2375,7 +2376,6 @@ build_group_lists (bfd *abfd ATTRIBUTE_UNUSED, asection *sec, void *inf) { elf_next_in_group (sec) = list->head[*elem_idx]; list->head[*elem_idx] = sec; - list->elt_count[*elem_idx] += 1; return; } @@ -2386,10 +2386,8 @@ build_group_lists (bfd *abfd ATTRIBUTE_UNUSED, asection *sec, void *inf) { unsigned int newsize = i + 128; list->head = XRESIZEVEC (asection *, list->head, newsize); - list->elt_count = XRESIZEVEC (unsigned int, list->elt_count, newsize); } list->head[i] = sec; - list->elt_count[i] = 1; list->num_group += 1; /* Add index to hash. */ @@ -2403,38 +2401,37 @@ static void free_section_idx (const char *key ATTRIBUTE_UNUSED, void *val) free ((unsigned int *) val); } +/* Create symbols for group signature. */ + void elf_adjust_symtab (void) { - struct group_list list; unsigned int i; /* Go find section groups. */ - list.num_group = 0; - list.head = NULL; - list.elt_count = NULL; - list.indexes = hash_new (); - bfd_map_over_sections (stdoutput, build_group_lists, &list); + groups.num_group = 0; + groups.head = NULL; + groups.indexes = hash_new (); + bfd_map_over_sections (stdoutput, build_group_lists, &groups); /* Make the SHT_GROUP sections that describe each section group. We can't set up the section contents here yet, because elf section indices have yet to be calculated. elf.c:set_group_contents does the rest of the work. */ - for (i = 0; i < list.num_group; i++) + for (i = 0; i < groups.num_group; i++) { - const char *group_name = elf_group_name (list.head[i]); + const char *group_name = elf_group_name (groups.head[i]); const char *sec_name; asection *s; flagword flags; struct symbol *sy; - bfd_size_type size; flags = SEC_READONLY | SEC_HAS_CONTENTS | SEC_IN_MEMORY | SEC_GROUP; - for (s = list.head[i]; s != NULL; s = elf_next_in_group (s)) + for (s = groups.head[i]; s != NULL; s = elf_next_in_group (s)) if ((s->flags ^ flags) & SEC_LINK_ONCE) { flags |= SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD; - if (s != list.head[i]) + if (s != groups.head[i]) { as_warn (_("assuming all members of group `%s' are COMDAT"), group_name); @@ -2454,7 +2451,8 @@ elf_adjust_symtab (void) elf_section_type (s) = SHT_GROUP; /* Pass a pointer to the first section in this group. */ - elf_next_in_group (s) = list.head[i]; + elf_next_in_group (s) = groups.head[i]; + elf_sec_group (groups.head[i]) = s; /* Make sure that the signature symbol for the group has the name of the group. */ sy = symbol_find_exact (group_name); @@ -2476,17 +2474,7 @@ elf_adjust_symtab (void) symbol_table_insert (sy); } elf_group_id (s) = symbol_get_bfdsym (sy); - - size = 4 * (list.elt_count[i] + 1); - bfd_set_section_size (stdoutput, s, size); - s->contents = (unsigned char *) frag_more (size); - frag_now->fr_fix = frag_now_fix_octets (); - frag_wane (frag_now); } - - /* Cleanup hash. */ - hash_traverse (list.indexes, free_section_idx); - hash_die (list.indexes); } void @@ -2550,6 +2538,31 @@ elf_frob_file_before_adjust (void) void elf_frob_file_after_relocs (void) { + unsigned int i; + + /* Set SHT_GROUP section size. */ + for (i = 0; i < groups.num_group; i++) + { + asection *s, *head, *group; + bfd_size_type size; + + head = groups.head[i]; + size = 4; + for (s = head; s != NULL; s = elf_next_in_group (s)) + size += (s->flags & SEC_RELOC) != 0 ? 8 : 4; + + group = elf_sec_group (head); + subseg_set (group, 0); + bfd_set_section_size (stdoutput, group, size); + group->contents = (unsigned char *) frag_more (size); + frag_now->fr_fix = frag_now_fix_octets (); + frag_wane (frag_now); + } + + /* Cleanup hash. */ + hash_traverse (groups.indexes, free_section_idx); + hash_die (groups.indexes); + #ifdef NEED_ECOFF_DEBUG if (ECOFF_DEBUGGING) /* Generate the ECOFF debugging information. */ diff --git a/gas/testsuite/gas/arc/jli-1.d b/gas/testsuite/gas/arc/jli-1.d index 10550a2..46587be 100644 --- a/gas/testsuite/gas/arc/jli-1.d +++ b/gas/testsuite/gas/arc/jli-1.d @@ -9,6 +9,7 @@ Disassembly of section .group: 00000000 <jlitab.foo>: 0: 0[10] 00 00 0[01] .word 0x00000001 4: 0[60] 00 00 0[06] .word 0x00000006 + 8: 0[70] 00 00 0[07] .word 0x00000007 Disassembly of section .text: diff --git a/gas/testsuite/gas/elf/groupautob.d b/gas/testsuite/gas/elf/groupautob.d index 76c60b4..5f6081f 100644 --- a/gas/testsuite/gas/elf/groupautob.d +++ b/gas/testsuite/gas/elf/groupautob.d @@ -3,7 +3,7 @@ #source: groupauto.s #... -COMDAT group section \[ 1\] `\.group' \[some_group\] contains 2 sections: +COMDAT group section \[ 1\] `\.group' \[some_group\] contains [23] sections: [ ]+\[Index\][ ]+Name [ ]+\[.*\][ ]+.text [ ]+\[.*\][ ]+.note.bar diff --git a/gas/testsuite/gas/mips/compact-eh-eb-2.d b/gas/testsuite/gas/mips/compact-eh-eb-2.d index 226a5ff..feefafa 100644 --- a/gas/testsuite/gas/mips/compact-eh-eb-2.d +++ b/gas/testsuite/gas/mips/compact-eh-eb-2.d @@ -23,7 +23,7 @@ OFFSET TYPE VALUE Contents of section .group: - 0000 00000001 00000007 .* + 0000 00000001 00000007 00000008 .* Contents of section .text: 0000 00000000.* Contents of section .reginfo: diff --git a/gas/testsuite/gas/mips/compact-eh-eb-5.d b/gas/testsuite/gas/mips/compact-eh-eb-5.d index fd278a1..79a65bb 100644 --- a/gas/testsuite/gas/mips/compact-eh-eb-5.d +++ b/gas/testsuite/gas/mips/compact-eh-eb-5.d @@ -23,7 +23,7 @@ OFFSET TYPE VALUE Contents of section .group: - 0000 00000001 00000007 .* + 0000 00000001 00000007 00000008 .* Contents of section .text: 0000 00000000 00000000 00000000 00000000 .* 0010 00000000.* diff --git a/gas/testsuite/gas/mips/compact-eh-el-2.d b/gas/testsuite/gas/mips/compact-eh-el-2.d index 80627eb..f5fe968 100644 --- a/gas/testsuite/gas/mips/compact-eh-el-2.d +++ b/gas/testsuite/gas/mips/compact-eh-el-2.d @@ -23,7 +23,7 @@ OFFSET TYPE VALUE Contents of section .group: - 0000 01000000 07000000 .* + 0000 01000000 07000000 08000000 .* Contents of section .text: 0000 00000000.* Contents of section .reginfo: diff --git a/gas/testsuite/gas/mips/compact-eh-el-5.d b/gas/testsuite/gas/mips/compact-eh-el-5.d index 7f07622..aa84332 100644 --- a/gas/testsuite/gas/mips/compact-eh-el-5.d +++ b/gas/testsuite/gas/mips/compact-eh-el-5.d @@ -22,7 +22,7 @@ OFFSET TYPE VALUE Contents of section .group: - 0000 01000000 07000000 .* + 0000 01000000 07000000 08000000 .* Contents of section .text: 0000 00000000 00000000 00000000 00000000 .* 0010 00000000.* diff --git a/ld/ChangeLog b/ld/ChangeLog index 18a95f1..7c266e6 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,8 @@ +2017-10-05 Alan Modra <amodra@gmail.com> + + PR 21167 + * testsuite/ld-elf/group9b.d: Adjust for relocs included in group. + 2017-10-03 Alan Modra <amodra@gmail.com> PR 21294 diff --git a/ld/testsuite/ld-elf/group9b.d b/ld/testsuite/ld-elf/group9b.d index 3005f8f..c237f54 100644 --- a/ld/testsuite/ld-elf/group9b.d +++ b/ld/testsuite/ld-elf/group9b.d @@ -10,9 +10,10 @@ COMDAT group section \[[ 0-9]+\] `.group' \[foo\] contains 2 sections: \[Index\] Name - \[[ 0-9]+\] .text.foo - \[[ 0-9]+\] .data.foo + \[[ 0-9]+\] \.text\.foo + \[[ 0-9]+\] \.data\.foo -COMDAT group section \[[ 0-9]+\] `.group' \[bar\] contains 1 sections: +COMDAT group section \[[ 0-9]+\] `.group' \[bar\] contains 2 sections: \[Index\] Name - \[[ 0-9]+\] .text.bar + \[[ 0-9]+\] \.text\.bar + \[[ 0-9]+\] \.rela?\.text\.bar |