+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
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
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)
? 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;
|| 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;
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)
{
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)
+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
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
{
elf_next_in_group (sec) = list->head[*elem_idx];
list->head[*elem_idx] = sec;
- list->elt_count[*elem_idx] += 1;
return;
}
{
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. */
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);
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);
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
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. */
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:
#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
Contents of section .group:
- 0000 00000001 00000007 .*
+ 0000 00000001 00000007 00000008 .*
Contents of section .text:
0000 00000000.*
Contents of section .reginfo:
Contents of section .group:
- 0000 00000001 00000007 .*
+ 0000 00000001 00000007 00000008 .*
Contents of section .text:
0000 00000000 00000000 00000000 00000000 .*
0010 00000000.*
Contents of section .group:
- 0000 01000000 07000000 .*
+ 0000 01000000 07000000 08000000 .*
Contents of section .text:
0000 00000000.*
Contents of section .reginfo:
Contents of section .group:
- 0000 01000000 07000000 .*
+ 0000 01000000 07000000 08000000 .*
Contents of section .text:
0000 00000000 00000000 00000000 00000000 .*
0010 00000000.*
+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
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