aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bfd/ChangeLog14
-rw-r--r--bfd/elf.c35
-rw-r--r--bfd/elflink.c6
-rw-r--r--include/ChangeLog5
-rw-r--r--include/bfdlink.h3
-rw-r--r--ld/ChangeLog21
-rw-r--r--ld/NEWS5
-rw-r--r--ld/ld.h5
-rw-r--r--ld/ld.texinfo23
-rw-r--r--ld/ldgram.y4
-rw-r--r--ld/ldlang.c18
-rw-r--r--ld/ldlex.h1
-rw-r--r--ld/ldlex.l1
-rw-r--r--ld/ldmain.c6
-rw-r--r--ld/lexsup.c6
-rw-r--r--ld/testsuite/ld-elf/group11.d6
-rw-r--r--ld/testsuite/ld-elf/group12.d6
-rw-r--r--ld/testsuite/ld-elf/group12.ld14
18 files changed, 155 insertions, 24 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 7dfc62f..99329c8 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,17 @@
+2017-06-06 Andrew Burgess <andrew.burgess@embecosm.com>
+
+ * elf.c (_bfd_elf_make_section_from_shdr): Don't initially mark
+ SEC_GROUP sections as SEC_EXCLUDE.
+ (bfd_elf_set_group_contents): Replace use of abort with an assert.
+ (assign_section_numbers): Use resolve_section_groups flag instead
+ of relocatable link type.
+ (_bfd_elf_init_private_section_data): Use resolve_section_groups
+ flag instead of checking the final_link flag for part of the
+ checks in here. Fix white space as a result.
+ * elflink.c (elf_link_input_bfd): Use resolve_section_groups flag
+ instead of relocatable link type.
+ (bfd_elf_final_link): Likewise.
+
2017-06-06 Jose E. Marchesi <jose.marchesi@oracle.com>
* elfxx-mips.c (_bfd_mips_elf_relocate_section): Remove unused
diff --git a/bfd/elf.c b/bfd/elf.c
index b0da500..bab1e16 100644
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -983,7 +983,7 @@ _bfd_elf_make_section_from_shdr (bfd *abfd,
if (hdr->sh_type != SHT_NOBITS)
flags |= SEC_HAS_CONTENTS;
if (hdr->sh_type == SHT_GROUP)
- flags |= SEC_GROUP | SEC_EXCLUDE;
+ flags |= SEC_GROUP;
if ((hdr->sh_flags & SHF_ALLOC) != 0)
{
flags |= SEC_ALLOC;
@@ -3533,8 +3533,8 @@ bfd_elf_set_group_contents (bfd *abfd, asection *sec, void *failedptrarg)
break;
}
- if ((loc -= 4) != sec->contents)
- abort ();
+ loc -= 4;
+ BFD_ASSERT (loc == sec->contents);
H_PUT_32 (abfd, sec->flags & SEC_LINK_ONCE ? GRP_COMDAT : 0, loc);
}
@@ -3609,7 +3609,7 @@ assign_section_numbers (bfd *abfd, struct bfd_link_info *link_info)
_bfd_elf_strtab_clear_all_refs (elf_shstrtab (abfd));
/* SHT_GROUP sections are in relocatable files only. */
- if (link_info == NULL || bfd_link_relocatable (link_info))
+ if (link_info == NULL || !link_info->resolve_section_groups)
{
size_t reloc_count = 0;
@@ -7445,23 +7445,22 @@ _bfd_elf_init_private_section_data (bfd *ibfd,
SHT_GROUP section will have its elf_next_in_group pointing back
to the input group members. Ignore linker created group section.
See elfNN_ia64_object_p in elfxx-ia64.c. */
- if (!final_link)
+ if ((link_info == NULL
+ || !link_info->resolve_section_groups)
+ && (elf_sec_group (isec) == NULL
+ || (elf_sec_group (isec)->flags & SEC_LINKER_CREATED) == 0))
{
- if (elf_sec_group (isec) == NULL
- || (elf_sec_group (isec)->flags & SEC_LINKER_CREATED) == 0)
- {
- if (elf_section_flags (isec) & SHF_GROUP)
- elf_section_flags (osec) |= SHF_GROUP;
- elf_next_in_group (osec) = elf_next_in_group (isec);
- elf_section_data (osec)->group = elf_section_data (isec)->group;
- }
-
- /* If not decompress, preserve SHF_COMPRESSED. */
- if ((ibfd->flags & BFD_DECOMPRESS) == 0)
- elf_section_flags (osec) |= (elf_section_flags (isec)
- & SHF_COMPRESSED);
+ if (elf_section_flags (isec) & SHF_GROUP)
+ elf_section_flags (osec) |= SHF_GROUP;
+ elf_next_in_group (osec) = elf_next_in_group (isec);
+ elf_section_data (osec)->group = elf_section_data (isec)->group;
}
+ /* If not decompress, preserve SHF_COMPRESSED. */
+ if (!final_link && (ibfd->flags & BFD_DECOMPRESS) == 0)
+ elf_section_flags (osec) |= (elf_section_flags (isec)
+ & SHF_COMPRESSED);
+
ihdr = &elf_section_data (isec)->this_hdr;
/* We need to handle elf_linked_to_section for SHF_LINK_ORDER. We
diff --git a/bfd/elflink.c b/bfd/elflink.c
index 7b001b7..1b447bb 100644
--- a/bfd/elflink.c
+++ b/bfd/elflink.c
@@ -10277,7 +10277,7 @@ elf_link_input_bfd (struct elf_final_link_info *flinfo, bfd *input_bfd)
continue;
}
- if (bfd_link_relocatable (flinfo->info)
+ if (!flinfo->info->resolve_section_groups
&& (o->flags & (SEC_LINKER_CREATED | SEC_GROUP)) == SEC_GROUP)
{
/* Deal with the group signature symbol. */
@@ -10285,6 +10285,7 @@ elf_link_input_bfd (struct elf_final_link_info *flinfo, bfd *input_bfd)
unsigned long symndx = sec_data->this_hdr.sh_info;
asection *osec = o->output_section;
+ BFD_ASSERT (bfd_link_relocatable (flinfo->info));
if (symndx >= locsymcount
|| (elf_bad_symtab (input_bfd)
&& flinfo->sections[symndx] == NULL))
@@ -12463,10 +12464,11 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info)
}
}
- if (bfd_link_relocatable (info))
+ if (!info->resolve_section_groups)
{
bfd_boolean failed = FALSE;
+ BFD_ASSERT (bfd_link_relocatable (info));
bfd_map_over_sections (abfd, bfd_elf_set_group_contents, &failed);
if (failed)
goto error_return;
diff --git a/include/ChangeLog b/include/ChangeLog
index d034b2b..3818610 100644
--- a/include/ChangeLog
+++ b/include/ChangeLog
@@ -1,3 +1,8 @@
+2017-06-06 Andrew Burgess <andrew.burgess@embecosm.com>
+
+ * bfdlink.h (struct bfd_link_info): Add new resolve_section_groups
+ flag.
+
2017-06-01 Alan Modra <amodra@gmail.com>
* elf/ppc64.h (PPC64_OPT_LOCALENTRY): Define.
diff --git a/include/bfdlink.h b/include/bfdlink.h
index 371822c..2e3f0b1 100644
--- a/include/bfdlink.h
+++ b/include/bfdlink.h
@@ -348,6 +348,9 @@ struct bfd_link_info
/* TRUE if all data symbols should be dynamic. */
unsigned int dynamic_data: 1;
+ /* TRUE if section groups should be resolved. */
+ unsigned int resolve_section_groups: 1;
+
/* Which symbols to strip. */
ENUM_BITFIELD (bfd_link_strip) strip : 2;
diff --git a/ld/ChangeLog b/ld/ChangeLog
index 0e52c27..e80477f 100644
--- a/ld/ChangeLog
+++ b/ld/ChangeLog
@@ -1,3 +1,24 @@
+2017-06-06 Andrew Burgess <andrew.burgess@embecosm.com>
+
+ * ld.h (struct args_type): Add force_group_allocation field.
+ * ldgram.y: Add support for FORCE_GROUP_ALLOCATION.
+ * ldlex.h: Likewise.
+ * ldlex.l: Likewise.
+ * lexsup.c: Likewise.
+ * ldlang.c (unique_section_p): Check resolve_section_groups flag
+ not the relaxable link flag.
+ (lang_add_section): Discard section groups when we're resolving
+ groups. Clear the SEC_LINK_ONCE flag if we're resolving section
+ groups.
+ * ldmain.c (main): Initialise resolve_section_groups flag in
+ link_info based on command line flags.
+ * testsuite/ld-elf/group11.d: New file.
+ * testsuite/ld-elf/group12.d: New file.
+ * testsuite/ld-elf/group12.ld: New file.
+ * NEWS: Mention new features.
+ * ld.texinfo (Options): Document --force-group-allocation.
+ (Miscellaneous Commands): Document FORCE_GROUP_ALLOCATION.
+
2017-06-05 H.J. Lu <hongjiu.lu@intel.com>
PR ld/21529
diff --git a/ld/NEWS b/ld/NEWS
index 52daa6b..98055b5 100644
--- a/ld/NEWS
+++ b/ld/NEWS
@@ -15,6 +15,11 @@
* Orphan sections placed after an empty section that has an AT(LMA) will now
take an load memory address starting from LMA.
+* Section groups can now be resolved (the group deleted and the group members
+ placed like normal sections) at partial link time either using the new linker
+ option --force-group-allocation or by placing FORCE_GROUP_ALLOCATION into the
+ linker script.
+
Changes in 2.28:
* The EXCLUDE_FILE linker script construct can now be applied outside of the
diff --git a/ld/ld.h b/ld/ld.h
index 104bb8e..d9bb653 100644
--- a/ld/ld.h
+++ b/ld/ld.h
@@ -172,6 +172,11 @@ typedef struct
/* If set, display the target memory usage (per memory region). */
bfd_boolean print_memory_usage;
+ /* Shold we force section groups to be resolved? Controlled with
+ --force-group-allocation on the command line or FORCE_GROUP_ALLOCATION
+ in the linker script. */
+ bfd_boolean force_group_allocation;
+
/* Big or little endian as set on command line. */
enum endian_enum endian;
diff --git a/ld/ld.texinfo b/ld/ld.texinfo
index edf1e31..790b52f 100644
--- a/ld/ld.texinfo
+++ b/ld/ld.texinfo
@@ -1484,6 +1484,18 @@ and also prevents any possible confusion over resolving to the wrong
duplicate when there are many dynamic modules with specialized search
paths for runtime symbol resolution.
+@cindex group allocation in linker script
+@cindex section groups
+@cindex COMDAT
+@kindex --force-group-allocation
+@item --force-group-allocation
+This option causes the linker to place section group members like
+normal input sections, and to delete the section groups. This is the
+default behaviour for a final link but this option can be used to
+change the behaviour of a relocatable link (@samp{-r}). The script
+command @code{FORCE_GROUP_ALLOCATION} has the same
+effect. @xref{Miscellaneous Commands}.
+
@cindex symbols, from command line
@kindex --defsym=@var{symbol}=@var{exp}
@item --defsym=@var{symbol}=@var{expression}
@@ -3726,6 +3738,17 @@ This command has the same effect as the @samp{--no-define-common}
command-line option: to make @code{ld} omit the assignment of addresses
to common symbols even for a non-relocatable output file.
+@item FORCE_GROUP_ALLOCATION
+@kindex FORCE_GROUP_ALLOCATION
+@cindex group allocation in linker script
+@cindex section groups
+@cindex COMDAT
+This command has the same effect as the
+@samp{--force-group-allocation} command-line option: to make
+@command{ld} place section group members like normal input sections,
+and to delete the section groups even if a relocatable output file is
+specified (@samp{-r}).
+
@item INSERT [ AFTER | BEFORE ] @var{output_section}
@kindex INSERT
@cindex insert user script into default script
diff --git a/ld/ldgram.y b/ld/ldgram.y
index 849f272..4c1efdc 100644
--- a/ld/ldgram.y
+++ b/ld/ldgram.y
@@ -131,7 +131,7 @@ static int error_index;
%token SORT_BY_INIT_PRIORITY
%token '{' '}'
%token SIZEOF_HEADERS OUTPUT_FORMAT FORCE_COMMON_ALLOCATION OUTPUT_ARCH
-%token INHIBIT_COMMON_ALLOCATION
+%token INHIBIT_COMMON_ALLOCATION FORCE_GROUP_ALLOCATION
%token SEGMENT_START
%token INCLUDE
%token MEMORY
@@ -336,6 +336,8 @@ ifile_p1:
{ ldfile_set_output_arch ($3, bfd_arch_unknown); }
| FORCE_COMMON_ALLOCATION
{ command_line.force_common_definition = TRUE ; }
+ | FORCE_GROUP_ALLOCATION
+ { command_line.force_group_allocation = TRUE ; }
| INHIBIT_COMMON_ALLOCATION
{ command_line.inhibit_common_definition = TRUE ; }
| INPUT '(' input_list ')'
diff --git a/ld/ldlang.c b/ld/ldlang.c
index ed7e552..252400b 100644
--- a/ld/ldlang.c
+++ b/ld/ldlang.c
@@ -207,7 +207,7 @@ unique_section_p (const asection *sec,
struct unique_sections *unam;
const char *secnam;
- if (bfd_link_relocatable (&link_info)
+ if (!link_info.resolve_section_groups
&& sec->owner != NULL
&& bfd_is_group_section (sec->owner, sec))
return !(os != NULL
@@ -2349,6 +2349,12 @@ lang_add_section (lang_statement_list_type *ptr,
if (strcmp (output->name, DISCARD_SECTION_NAME) == 0)
discard = TRUE;
+ /* Discard the group descriptor sections when we're finally placing the
+ sections from within the group. */
+ if ((section->flags & SEC_GROUP) == SEC_GROUP
+ && link_info.resolve_section_groups)
+ discard = TRUE;
+
/* Discard debugging sections if we are stripping debugging
information. */
if ((link_info.strip == strip_debugger || link_info.strip == strip_all)
@@ -2389,8 +2395,14 @@ lang_add_section (lang_statement_list_type *ptr,
already been processed. One reason to do this is that on pe
format targets, .text$foo sections go into .text and it's odd
to see .text with SEC_LINK_ONCE set. */
-
- if (!bfd_link_relocatable (&link_info))
+ if ((flags & (SEC_LINK_ONCE | SEC_GROUP)) == (SEC_LINK_ONCE | SEC_GROUP))
+ {
+ if (link_info.resolve_section_groups)
+ flags &= ~(SEC_LINK_ONCE | SEC_LINK_DUPLICATES | SEC_RELOC);
+ else
+ flags &= ~(SEC_LINK_DUPLICATES | SEC_RELOC);
+ }
+ else if (!bfd_link_relocatable (&link_info))
flags &= ~(SEC_LINK_ONCE | SEC_LINK_DUPLICATES | SEC_RELOC);
switch (output->sectype)
diff --git a/ld/ldlex.h b/ld/ldlex.h
index dac152b..5aa7f6b 100644
--- a/ld/ldlex.h
+++ b/ld/ldlex.h
@@ -146,6 +146,7 @@ enum option_values
OPTION_PRINT_MEMORY_USAGE,
OPTION_REQUIRE_DEFINED_SYMBOL,
OPTION_ORPHAN_HANDLING,
+ OPTION_FORCE_GROUP_ALLOCATION,
};
/* The initial parser states. */
diff --git a/ld/ldlex.l b/ld/ldlex.l
index acba1a2..ba618ec 100644
--- a/ld/ldlex.l
+++ b/ld/ldlex.l
@@ -274,6 +274,7 @@ V_IDENTIFIER [*?.$_a-zA-Z\[\]\-\!\^\\]([*?.$_a-zA-Z0-9\[\]\-\!\^\\]|::)*
<BOTH,SCRIPT>"CREATE_OBJECT_SYMBOLS" { RTOKEN(CREATE_OBJECT_SYMBOLS);}
<BOTH,SCRIPT>"CONSTRUCTORS" { RTOKEN( CONSTRUCTORS);}
<BOTH,SCRIPT>"FORCE_COMMON_ALLOCATION" { RTOKEN(FORCE_COMMON_ALLOCATION);}
+<BOTH,SCRIPT>"FORCE_GROUP_ALLOCATION" { RTOKEN(FORCE_GROUP_ALLOCATION);}
<BOTH,SCRIPT>"INHIBIT_COMMON_ALLOCATION" { RTOKEN(INHIBIT_COMMON_ALLOCATION);}
<BOTH,SCRIPT>"SECTIONS" { RTOKEN(SECTIONS);}
<BOTH,SCRIPT>"INSERT" { RTOKEN(INSERT_K);}
diff --git a/ld/ldmain.c b/ld/ldmain.c
index 2b3a591..ee5ab11 100644
--- a/ld/ldmain.c
+++ b/ld/ldmain.c
@@ -386,6 +386,12 @@ main (int argc, char **argv)
info_msg ("\n==================================================\n");
}
+ if (command_line.force_group_allocation
+ || !bfd_link_relocatable (&link_info))
+ link_info.resolve_section_groups = TRUE;
+ else
+ link_info.resolve_section_groups = FALSE;
+
if (command_line.print_output_format)
info_msg ("%s\n", lang_get_output_target ());
diff --git a/ld/lexsup.c b/ld/lexsup.c
index 0b7d497..95c7e59 100644
--- a/ld/lexsup.c
+++ b/ld/lexsup.c
@@ -112,6 +112,9 @@ static const struct ld_option ld_options[] =
'd', NULL, N_("Force common symbols to be defined"), ONE_DASH },
{ {"dp", no_argument, NULL, 'd'},
'\0', NULL, NULL, ONE_DASH },
+ { {"force-group-allocation", no_argument, NULL,
+ OPTION_FORCE_GROUP_ALLOCATION},
+ '\0', NULL, N_("Force group members out of groups"), TWO_DASHES },
{ {"entry", required_argument, NULL, 'e'},
'e', N_("ADDRESS"), N_("Set start address"), TWO_DASHES },
{ {"export-dynamic", no_argument, NULL, OPTION_EXPORT_DYNAMIC},
@@ -767,6 +770,9 @@ parse_args (unsigned argc, char **argv)
case 'd':
command_line.force_common_definition = TRUE;
break;
+ case OPTION_FORCE_GROUP_ALLOCATION:
+ command_line.force_group_allocation = TRUE;
+ break;
case OPTION_DEFSYM:
lex_string = optarg;
lex_redirect (optarg, "--defsym", ++defsym_count);
diff --git a/ld/testsuite/ld-elf/group11.d b/ld/testsuite/ld-elf/group11.d
new file mode 100644
index 0000000..245cf440
--- /dev/null
+++ b/ld/testsuite/ld-elf/group11.d
@@ -0,0 +1,6 @@
+#source: group1a.s
+#source: group1b.s
+#ld: -r --force-group-allocation
+#readelf: -g
+
+There are no section groups in this file.
diff --git a/ld/testsuite/ld-elf/group12.d b/ld/testsuite/ld-elf/group12.d
new file mode 100644
index 0000000..3fa7be8
--- /dev/null
+++ b/ld/testsuite/ld-elf/group12.d
@@ -0,0 +1,6 @@
+#source: group1a.s
+#source: group1b.s
+#ld: -r -T group12.ld
+#readelf: -g
+
+There are no section groups in this file.
diff --git a/ld/testsuite/ld-elf/group12.ld b/ld/testsuite/ld-elf/group12.ld
new file mode 100644
index 0000000..4a36ee5
--- /dev/null
+++ b/ld/testsuite/ld-elf/group12.ld
@@ -0,0 +1,14 @@
+FORCE_GROUP_ALLOCATION
+
+PHDRS
+{
+ header PT_PHDR PHDRS ;
+ image PT_LOAD PHDRS;
+}
+
+SECTIONS
+{
+ . = 0x1000;
+ .text : { *(.text) *(.rodata.brlt) } :image :header
+ /DISCARD/ : { *(.dropme) *(.reginfo) *(.MIPS.abiflags) }
+}