aboutsummaryrefslogtreecommitdiff
path: root/ld
diff options
context:
space:
mode:
Diffstat (limited to 'ld')
-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
13 files changed, 112 insertions, 4 deletions
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) }
+}