From b71702f1c01052b70b4fd8157982eadc2132fc24 Mon Sep 17 00:00:00 2001 From: Nick Clifton Date: Mon, 5 Oct 2020 10:40:07 +0100 Subject: [PATCH] GAS: Update the .section directive so that a numeric section index can be provided when the "o" flag is used. PR 26253 gas * config/obj-elf.c (obj_elf_section): Accept a numeric value for the "o" section flag. Interpret it as a section index. Allow an index of zero. * doc/as.texi: Document the new behaviour. * NEWS: Mention the new feature. Tidy entries. * testsuite/gas/elf/sh-link-zero.s: New test. * testsuite/gas/elf/sh-link-zero.d: New test driver. * testsuite/gas/elf/elf.exp: Run the new test. * testsuite/gas/elf/section21.l: Updated expected assembler output. bfd * elf.c (_bfd_elf_setup_sections): Do not complain about an sh_link value of zero when the SLF_LINK_ORDER flag is set. (assign_section_numbers): Likewise. --- bfd/ChangeLog | 7 +++++ bfd/elf.c | 32 +++++++---------------- gas/ChangeLog | 14 ++++++++++ gas/NEWS | 21 +++++---------- gas/config/obj-elf.c | 39 +++++++++++++++++++++------- gas/config/obj-elf.h | 10 +++---- gas/doc/as.texi | 7 +++-- gas/testsuite/gas/elf/elf.exp | 4 ++- gas/testsuite/gas/elf/section21.l | 2 +- gas/testsuite/gas/elf/sh-link-zero.d | 9 +++++++ gas/testsuite/gas/elf/sh-link-zero.s | 13 ++++++++++ 11 files changed, 103 insertions(+), 55 deletions(-) create mode 100644 gas/testsuite/gas/elf/sh-link-zero.d create mode 100644 gas/testsuite/gas/elf/sh-link-zero.s diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 623cb8a188b..659d8d4bd62 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,10 @@ +2020-10-05 Nick Clifton + + PR 26253 + * elf.c (_bfd_elf_setup_sections): Do not complain about an + sh_link value of zero when the SLF_LINK_ORDER flag is set. + (assign_section_numbers): Likewise. + 2020-10-02 H.J. Lu PR 26681 diff --git a/bfd/elf.c b/bfd/elf.c index 00594020c93..9d7cbd52e02 100644 --- a/bfd/elf.c +++ b/bfd/elf.c @@ -848,16 +848,14 @@ _bfd_elf_setup_sections (bfd *abfd) if ((this_hdr->sh_flags & SHF_LINK_ORDER) != 0) { unsigned int elfsec = this_hdr->sh_link; - /* FIXME: The old Intel compiler and old strip/objcopy may - not set the sh_link or sh_info fields. Hence we could - get the situation where elfsec is 0. */ + /* An sh_link value of 0 is now allowed. It indicates that linked + to section has already been discarded, but that the current + section has been retained for some other reason. This linking + section is still a candidate for later garbage collection + however. */ if (elfsec == 0) { - const struct elf_backend_data *bed = get_elf_backend_data (abfd); - bed->link_order_error_handler - /* xgettext:c-format */ - (_("%pB: warning: sh_link not set for section `%pA'"), - abfd, s); + elf_linked_to_section (s) = NULL; } else { @@ -3888,6 +3886,10 @@ assign_section_numbers (bfd *abfd, struct bfd_link_info *link_info) if ((d->this_hdr.sh_flags & SHF_LINK_ORDER) != 0) { s = elf_linked_to_section (sec); + /* We can now have a NULL linked section pointer. + This happens when the sh_link field is 0, which is done + when a linked to section is discarded but the linking + section has been retained for some reason. */ if (s) { /* Check discarded linkonce section. */ @@ -3923,20 +3925,6 @@ assign_section_numbers (bfd *abfd, struct bfd_link_info *link_info) s = s->output_section; d->this_hdr.sh_link = elf_section_data (s)->this_idx; } - else - { - /* PR 290: - The Intel C compiler generates SHT_IA_64_UNWIND with - SHF_LINK_ORDER. But it doesn't set the sh_link or - sh_info fields. Hence we could get the situation - where s is NULL. */ - const struct elf_backend_data *bed - = get_elf_backend_data (abfd); - bed->link_order_error_handler - /* xgettext:c-format */ - (_("%pB: warning: sh_link not set for section `%pA'"), - abfd, sec); - } } switch (d->this_hdr.sh_type) diff --git a/gas/ChangeLog b/gas/ChangeLog index 866a8b46baf..56796ff9485 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,17 @@ +2020-10-05 Nick Clifton + + PR 26253 + * config/obj-elf.c (obj_elf_section): Accept a numeric value for + the "o" section flag. Interpret it as a section index. Allow an + index of zero. + * doc/as.texi: Document the new behaviour. + * NEWS: Mention the new feature. Tidy entries. + * testsuite/gas/elf/sh-link-zero.s: New test. + * testsuite/gas/elf/sh-link-zero.d: New test driver. + * testsuite/gas/elf/elf.exp: Run the new test. + * testsuite/gas/elf/section21.l: Updated expected assembler + output. + 2020-10-03 H.J. Lu PR gas/26685 diff --git a/gas/NEWS b/gas/NEWS index 8394f7466ca..8f83beb15b2 100644 --- a/gas/NEWS +++ b/gas/NEWS @@ -1,21 +1,12 @@ -*- text -*- -* Add support for Cortex-A78 and Cortex-A78AE for ARM. +* When setting the link order attribute of ELF sections, it is now possible to + use a numeric section index instead of symbol name. -* Add support for Cortex-A78 and Cortex-A78AE for AArch64. +* Add support for Cortex-A78, Cortex-A78AE and Cortex-X1 for AArch64 and ARM. + Add support for Cortex-R82, Neoverse V1, and Neoverse N2 for ARM. -* Add support for ETMv4 (Embedded Trace Macrocell) system registers for - AArch64. - -* Add support for ETE (Embedded Trace Extension) system registers for AArch64. - -* Add support for TRBE (Trace Buffer Extension) system registers for AArch64. - -* Add support for Cortex-X1 for AArch64. - -* Add support for Cortex-X1 for ARM. - -* Add support for Arm's Cortex-R82, Neoverse V1, and Neoverse N2 - processors. +* Add support for ETMv4 (Embedded Trace Macrocell), ETE (Embedded Trace + Extension) and TRBE (Trace Buffer Extension) system registers for AArch64. * Add support for Armv8-R AArch64. diff --git a/gas/config/obj-elf.c b/gas/config/obj-elf.c index 45de821495e..f061ea61f3e 100644 --- a/gas/config/obj-elf.c +++ b/gas/config/obj-elf.c @@ -519,8 +519,10 @@ struct section_stack static struct section_stack *section_stack; +/* Return TRUE iff SEC matches the section info INF. */ + static bfd_boolean -get_section (bfd *abfd ATTRIBUTE_UNUSED, asection *sec, void *inf) +get_section_by_match (bfd *abfd ATTRIBUTE_UNUSED, asection *sec, void *inf) { struct elf_section_match *match = (struct elf_section_match *) inf; const char *gname = match->group_name; @@ -602,7 +604,7 @@ obj_elf_change_section (const char *name, previous_section = now_seg; previous_subsection = now_subseg; - old_sec = bfd_get_section_by_name_if (stdoutput, name, get_section, + old_sec = bfd_get_section_by_name_if (stdoutput, name, get_section_by_match, (void *) match_p); if (old_sec) { @@ -1076,6 +1078,7 @@ obj_elf_section (int push) int linkonce; subsegT new_subsection = -1; struct elf_section_match match; + unsigned long linked_to_section_index = -1UL; if (flag_mri) { @@ -1215,15 +1218,24 @@ obj_elf_section (int push) if ((attr & SHF_LINK_ORDER) != 0 && *input_line_pointer == ',') { - char c; - unsigned int length; ++input_line_pointer; SKIP_WHITESPACE (); - c = get_symbol_name (& beg); - (void) restore_line_pointer (c); - length = input_line_pointer - beg; - if (length) - match.linked_to_symbol_name = xmemdup0 (beg, length); + /* Check for a numeric section index, rather than a symbol name. */ + if (ISDIGIT (* input_line_pointer)) + { + linked_to_section_index = strtoul (input_line_pointer, & input_line_pointer, 0); + } + else + { + char c; + unsigned int length; + + c = get_symbol_name (& beg); + (void) restore_line_pointer (c); + length = input_line_pointer - beg; + if (length) + match.linked_to_symbol_name = xmemdup0 (beg, length); + } } if ((attr & SHF_GROUP) != 0 && is_clone) @@ -1231,6 +1243,7 @@ obj_elf_section (int push) as_warn (_("? section flag ignored with G present")); is_clone = FALSE; } + if ((attr & SHF_GROUP) != 0 && *input_line_pointer == ',') { ++input_line_pointer; @@ -1289,6 +1302,7 @@ obj_elf_section (int push) if (*input_line_pointer == ',') { char *save = input_line_pointer; + ++input_line_pointer; SKIP_WHITESPACE (); if (strncmp (input_line_pointer, "unique", 6) == 0) @@ -1394,6 +1408,13 @@ obj_elf_section (int push) } elf_section_flags (now_seg) |= gnu_attr; + if (linked_to_section_index != -1UL) + { + elf_section_flags (now_seg) |= SHF_LINK_ORDER; + elf_section_data (now_seg)->this_hdr.sh_link = linked_to_section_index; + /* FIXME: Should we perform some sanity checking on the section index ? */ + } + if (push && new_subsection != -1) subseg_set (now_seg, new_subsection); } diff --git a/gas/config/obj-elf.h b/gas/config/obj-elf.h index b39a1a1ab63..4f29572eef7 100644 --- a/gas/config/obj-elf.h +++ b/gas/config/obj-elf.h @@ -104,11 +104,11 @@ struct elf_obj_sy field. */ struct elf_section_match { - const char *group_name; - const char *linked_to_symbol_name; - unsigned int info; - unsigned int section_id; - flagword flags; + const char * group_name; + const char * linked_to_symbol_name; + unsigned int info; + unsigned int section_id; + flagword flags; }; #define OBJ_SYMFIELD_TYPE struct elf_obj_sy diff --git a/gas/doc/as.texi b/gas/doc/as.texi index c0baa945360..2ba101ce8d6 100644 --- a/gas/doc/as.texi +++ b/gas/doc/as.texi @@ -6728,11 +6728,14 @@ If @var{flags} contains the @code{o} flag, then the @var{type} argument must be present along with an additional field like this: @smallexample -.section @var{name},"@var{flags}"o,@@@var{type},@var{SymbolName} +.section @var{name},"@var{flags}"o,@@@var{type},@var{SymbolName}|@var{SectionIndex} @end smallexample The @var{SymbolName} field specifies the symbol name which the section -references. +references. Alternatively a numeric @var{SectionIndex} can be provided. This +is not generally a good idea as section indicies are rarely known at assembly +time, but the facility is provided for testing purposes. An index of zero is +allowed. It indicates that the linked-to section has already been discarded. Note: If both the @var{M} and @var{o} flags are present, then the fields for the Merge flag should come first, like this: diff --git a/gas/testsuite/gas/elf/elf.exp b/gas/testsuite/gas/elf/elf.exp index 5ce9691b389..9d751544830 100644 --- a/gas/testsuite/gas/elf/elf.exp +++ b/gas/testsuite/gas/elf/elf.exp @@ -142,7 +142,7 @@ if { [is_elf_format] } then { run_dump_test "attach-1" run_dump_test "attach-err" - + switch -glob $target_triplet { hppa64*-*-hpux* { } riscv*-*-* { } @@ -261,6 +261,8 @@ if { [is_elf_format] } then { run_dump_test "section19" run_dump_test "section20" run_dump_test "section21" + run_dump_test "sh-link-zero" + run_dump_test "dwarf2-1" $dump_opts run_dump_test "dwarf2-2" $dump_opts run_dump_test "dwarf2-3" $dump_opts diff --git a/gas/testsuite/gas/elf/section21.l b/gas/testsuite/gas/elf/section21.l index 50342ec659a..53f04151d33 100644 --- a/gas/testsuite/gas/elf/section21.l +++ b/gas/testsuite/gas/elf/section21.l @@ -1,5 +1,5 @@ [^:]*: Assembler messages: -[^:]*:11: Error: junk at end of line, first unrecognized character is `1' +[^:]*:11: Error: junk at end of line, first unrecognized character is `f' #... [^:]*: Error: undefined linked-to symbol `bar' on section `__patchable_function_entries' [^:]*: Error: undefined linked-to symbol `foo' on section `__patchable_function_entries' diff --git a/gas/testsuite/gas/elf/sh-link-zero.d b/gas/testsuite/gas/elf/sh-link-zero.d new file mode 100644 index 00000000000..243d50c613b --- /dev/null +++ b/gas/testsuite/gas/elf/sh-link-zero.d @@ -0,0 +1,9 @@ +#readelf: --wide --sections +#name: Setting the sh_link field to 0 +#source: sh-link-zero.s + +#... +.*\.meta1.*WAL[ ]+0.* +#... +.*\.meta2.*WAL[ ]+[1-9].* +#pass diff --git a/gas/testsuite/gas/elf/sh-link-zero.s b/gas/testsuite/gas/elf/sh-link-zero.s new file mode 100644 index 00000000000..9e907928d85 --- /dev/null +++ b/gas/testsuite/gas/elf/sh-link-zero.s @@ -0,0 +1,13 @@ +.section .meta1,"awo",%progbits,0 +1: + .dc.b 0 + +.section .meta2,"awo",%progbits,foo +2: + .dc.b 1 + +.section foo, "aw" + .dc.b 2 + +.section .gc_root,"a",%progbits + .dc.a 1b -- 2.30.2