diff options
-rw-r--r-- | bfd/ChangeLog | 14 | ||||
-rw-r--r-- | bfd/elf.c | 35 | ||||
-rw-r--r-- | bfd/elflink.c | 6 | ||||
-rw-r--r-- | include/ChangeLog | 5 | ||||
-rw-r--r-- | include/bfdlink.h | 3 | ||||
-rw-r--r-- | ld/ChangeLog | 21 | ||||
-rw-r--r-- | ld/NEWS | 5 | ||||
-rw-r--r-- | ld/ld.h | 5 | ||||
-rw-r--r-- | ld/ld.texinfo | 23 | ||||
-rw-r--r-- | ld/ldgram.y | 4 | ||||
-rw-r--r-- | ld/ldlang.c | 18 | ||||
-rw-r--r-- | ld/ldlex.h | 1 | ||||
-rw-r--r-- | ld/ldlex.l | 1 | ||||
-rw-r--r-- | ld/ldmain.c | 6 | ||||
-rw-r--r-- | ld/lexsup.c | 6 | ||||
-rw-r--r-- | ld/testsuite/ld-elf/group11.d | 6 | ||||
-rw-r--r-- | ld/testsuite/ld-elf/group12.d | 6 | ||||
-rw-r--r-- | ld/testsuite/ld-elf/group12.ld | 14 |
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 @@ -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 @@ -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 @@ -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) @@ -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. */ @@ -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) } +} |