aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bfd/ChangeLog11
-rw-r--r--bfd/elf.c46
-rw-r--r--gas/ChangeLog17
-rw-r--r--gas/config/obj-elf.c65
-rw-r--r--gas/testsuite/gas/arc/jli-1.d1
-rw-r--r--gas/testsuite/gas/elf/groupautob.d2
-rw-r--r--gas/testsuite/gas/mips/compact-eh-eb-2.d2
-rw-r--r--gas/testsuite/gas/mips/compact-eh-eb-5.d2
-rw-r--r--gas/testsuite/gas/mips/compact-eh-el-2.d2
-rw-r--r--gas/testsuite/gas/mips/compact-eh-el-5.d2
-rw-r--r--ld/ChangeLog5
-rw-r--r--ld/testsuite/ld-elf/group9b.d9
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
diff --git a/bfd/elf.c b/bfd/elf.c
index 38dba48..fd7f773 100644
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -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