From: H.J. Lu Date: Mon, 3 Feb 2020 01:07:51 +0000 (-0800) Subject: ELF: Add support for unique section ID to assembler X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=a8c4d40b578378be3b12575d127d4c7bd9972f32;p=binutils-gdb.git ELF: Add support for unique section ID to assembler Clang's integrated assembler supports multiple section with the same name: .section .text,"ax",@progbits,unique,1 nop .section .text,"ax",@progbits,unique,2 nop "unique,N" assigns the number, N, as the section ID, to a section. The valid values of the section ID are between 0 and 4294967295. It can be used to distinguish different sections with the same section name. This is useful with -fno-unique-section-names -ffunction-sections. -ffunction-sections by default generates .text.foo, .text.bar, etc. Using the same string can save lots of space in .strtab. This patch adds section_id to bfd_section and reuses the linker internal bit in BFD section flags, SEC_LINKER_CREATED, for assmebler internal use to mark valid section_id. It also updates objdump to compare section pointers if 2 sections comes from the same file since 2 different sections can have the same section name. bfd/ PR gas/25380 * bfd-in2.h: Regenerated. * ecoff.c (bfd_debug_section): Add section_id. * section.c (bfd_section): Add section_id. (SEC_ASSEMBLER_SECTION_ID): New. (BFD_FAKE_SECTION): Add section_id. binutils/ PR gas/25380 * objdump.c (sym_ok): Return FALSE if 2 sections are in the same file with different section pointers. gas/ PR gas/25380 * config/obj-elf.c (section_match): Removed. (get_section): Also match SEC_ASSEMBLER_SECTION_ID and section_id. (obj_elf_change_section): Replace info and group_name arguments with match_p. Also update the section ID and flags from match_p. (obj_elf_section): Handle "unique,N". Update call to obj_elf_change_section. * config/obj-elf.h (elf_section_match): New. (obj_elf_change_section): Updated. * config/tc-arm.c (start_unwind_section): Update call to obj_elf_change_section. * config/tc-ia64.c (obj_elf_vms_common): Likewise. * config/tc-microblaze.c (microblaze_s_data): Likewise. (microblaze_s_sdata): Likewise. (microblaze_s_rdata): Likewise. (microblaze_s_bss): Likewise. * config/tc-mips.c (s_change_section): Likewise. * config/tc-msp430.c (msp430_profiler): Likewise. * config/tc-rx.c (parse_rx_section): Likewise. * config/tc-tic6x.c (tic6x_start_unwind_section): Likewise. * doc/as.texi: Document "unique,N" in .section directive. * testsuite/gas/elf/elf.exp: Run "unique,N" tests. * testsuite/gas/elf/section15.d: New file. * testsuite/gas/elf/section15.s: Likewise. * testsuite/gas/elf/section16.s: Likewise. * testsuite/gas/elf/section16a.d: Likewise. * testsuite/gas/elf/section16b.d: Likewise. * testsuite/gas/elf/section17.d: Likewise. * testsuite/gas/elf/section17.l: Likewise. * testsuite/gas/elf/section17.s: Likewise. * testsuite/gas/i386/unique.d: Likewise. * testsuite/gas/i386/unique.s: Likewise. * testsuite/gas/i386/x86-64-unique.d: Likewise. * testsuite/gas/i386/i386.exp: Run unique and x86-64-unique. ld/ PR gas/25380 * testsuite/ld-i386/pr22001-1c.S: Use "unique,N" in .section directives. * testsuite/ld-i386/tls-gd1.S: Likewise. * testsuite/ld-x86-64/pr21481b.S: Likewise. --- diff --git a/bfd/ChangeLog b/bfd/ChangeLog index f252905dc0e..f8e7dfaf94f 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,12 @@ +2020-02-02 H.J. Lu + + PR gas/25380 + * bfd-in2.h: Regenerated. + * ecoff.c (bfd_debug_section): Add section_id. + * section.c (bfd_section): Add section_id. + (SEC_ASSEMBLER_SECTION_ID): New. + (BFD_FAKE_SECTION): Add section_id. + 2020-02-01 Nick Clifton * config.bfd: Move the c30-aout and tic30-aout targets onto the diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h index 8144b167e04..c890520ccb1 100644 --- a/bfd/bfd-in2.h +++ b/bfd/bfd-in2.h @@ -795,6 +795,10 @@ typedef struct bfd_section /* A unique sequence number. */ unsigned int id; + /* A unique section number which can be used by assembler to + distinguish different sections with the same section name. */ + unsigned int section_id; + /* Which section in the bfd; 0..n-1 as sections are created in a bfd. */ unsigned int index; @@ -928,6 +932,10 @@ typedef struct bfd_section else up the line will take care of it later. */ #define SEC_LINKER_CREATED 0x100000 + /* This section contains a section ID to distinguish different + sections withe the same section name. */ +#define SEC_ASSEMBLER_SECTION_ID 0x100000 + /* This section should not be subject to garbage collection. Also set to inform the linker that this section should not be listed in the link map as discarded. */ @@ -1329,8 +1337,8 @@ discarded_section (const asection *sec) } #define BFD_FAKE_SECTION(SEC, SYM, NAME, IDX, FLAGS) \ - /* name, id, index, next, prev, flags, user_set_vma, */ \ - { NAME, IDX, 0, NULL, NULL, FLAGS, 0, \ + /* name, id, section_id, index, next, prev, flags, user_set_vma, */ \ + { NAME, IDX, 0, 0, NULL, NULL, FLAGS, 0, \ \ /* linker_mark, linker_has_input, gc_mark, decompress_status, */ \ 0, 0, 1, 0, \ diff --git a/bfd/ecoff.c b/bfd/ecoff.c index f2713626d60..050fd7b5081 100644 --- a/bfd/ecoff.c +++ b/bfd/ecoff.c @@ -52,8 +52,10 @@ /* This stuff is somewhat copied from coffcode.h. */ static asection bfd_debug_section = { - /* name, id, index, next, prev, flags, user_set_vma, */ - "*DEBUG*", 0, 0, NULL, NULL, 0, 0, + /* name, id, section_id, index, next, prev, flags, */ + "*DEBUG*", 0, 0, 0, NULL, NULL, 0, + /* user_set_vma, */ + 0, /* linker_mark, linker_has_input, gc_mark, compress_status, */ 0, 0, 1, 0, /* segment_mark, sec_info_type, use_rela_p, */ diff --git a/bfd/section.c b/bfd/section.c index d42c2b4287e..161ed33edc4 100644 --- a/bfd/section.c +++ b/bfd/section.c @@ -154,6 +154,10 @@ CODE_FRAGMENT . {* A unique sequence number. *} . unsigned int id; . +. {* A unique section number which can be used by assembler to +. distinguish different sections with the same section name. *} +. unsigned int section_id; +. . {* Which section in the bfd; 0..n-1 as sections are created in a bfd. *} . unsigned int index; . @@ -287,6 +291,10 @@ CODE_FRAGMENT . else up the line will take care of it later. *} .#define SEC_LINKER_CREATED 0x100000 . +. {* This section contains a section ID to distinguish different +. sections withe the same section name. *} +.#define SEC_ASSEMBLER_SECTION_ID 0x100000 +. . {* This section should not be subject to garbage collection. . Also set to inform the linker that this section should not be . listed in the link map as discarded. *} @@ -688,8 +696,8 @@ CODE_FRAGMENT .} . .#define BFD_FAKE_SECTION(SEC, SYM, NAME, IDX, FLAGS) \ -. {* name, id, index, next, prev, flags, user_set_vma, *} \ -. { NAME, IDX, 0, NULL, NULL, FLAGS, 0, \ +. {* name, id, section_id, index, next, prev, flags, user_set_vma, *} \ +. { NAME, IDX, 0, 0, NULL, NULL, FLAGS, 0, \ . \ . {* linker_mark, linker_has_input, gc_mark, decompress_status, *} \ . 0, 0, 1, 0, \ diff --git a/binutils/ChangeLog b/binutils/ChangeLog index 222ea7af4b7..a7fd43176b5 100644 --- a/binutils/ChangeLog +++ b/binutils/ChangeLog @@ -1,3 +1,9 @@ +2020-02-02 H.J. Lu + + PR gas/25380 + * objdump.c (sym_ok): Return FALSE if 2 sections are in the + same file with different section pointers. + 2020-02-01 Nick Clifton * README-how-to-make-a-release: Update with more details on the diff --git a/binutils/objdump.c b/binutils/objdump.c index 60a39671292..17c0637b350 100644 --- a/binutils/objdump.c +++ b/binutils/objdump.c @@ -1065,6 +1065,13 @@ sym_ok (bfd_boolean want_section, { if (want_section) { + /* NB: An object file can have different sections with the same + section name. Compare compare section pointers if they have + the same owner. */ + if (sorted_syms[place]->section->owner == sec->owner + && sorted_syms[place]->section != sec) + return FALSE; + /* Note - we cannot just compare section pointers because they could be different, but the same... Ie the symbol that we are trying to find could have come from a separate debug info file. Under such diff --git a/gas/ChangeLog b/gas/ChangeLog index 518e9468152..b8c886421e8 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,41 @@ +2020-02-02 H.J. Lu + + PR gas/25380 + * config/obj-elf.c (section_match): Removed. + (get_section): Also match SEC_ASSEMBLER_SECTION_ID and + section_id. + (obj_elf_change_section): Replace info and group_name arguments + with match_p. Also update the section ID and flags from match_p. + (obj_elf_section): Handle "unique,N". Update call to + obj_elf_change_section. + * config/obj-elf.h (elf_section_match): New. + (obj_elf_change_section): Updated. + * config/tc-arm.c (start_unwind_section): Update call to + obj_elf_change_section. + * config/tc-ia64.c (obj_elf_vms_common): Likewise. + * config/tc-microblaze.c (microblaze_s_data): Likewise. + (microblaze_s_sdata): Likewise. + (microblaze_s_rdata): Likewise. + (microblaze_s_bss): Likewise. + * config/tc-mips.c (s_change_section): Likewise. + * config/tc-msp430.c (msp430_profiler): Likewise. + * config/tc-rx.c (parse_rx_section): Likewise. + * config/tc-tic6x.c (tic6x_start_unwind_section): Likewise. + * doc/as.texi: Document "unique,N" in .section directive. + * testsuite/gas/elf/elf.exp: Run "unique,N" tests. + * testsuite/gas/elf/section15.d: New file. + * testsuite/gas/elf/section15.s: Likewise. + * testsuite/gas/elf/section16.s: Likewise. + * testsuite/gas/elf/section16a.d: Likewise. + * testsuite/gas/elf/section16b.d: Likewise. + * testsuite/gas/elf/section17.d: Likewise. + * testsuite/gas/elf/section17.l: Likewise. + * testsuite/gas/elf/section17.s: Likewise. + * testsuite/gas/i386/unique.d: Likewise. + * testsuite/gas/i386/unique.s: Likewise. + * testsuite/gas/i386/x86-64-unique.d: Likewise. + * testsuite/gas/i386/i386.exp: Run unique and x86-64-unique. + 2020-02-02 H.J. Lu * testsuite/gas/elf/section13.s: Replace @nobits with %nobits. diff --git a/gas/config/obj-elf.c b/gas/config/obj-elf.c index 7cf921c051f..2958490c323 100644 --- a/gas/config/obj-elf.c +++ b/gas/config/obj-elf.c @@ -518,22 +518,18 @@ struct section_stack static struct section_stack *section_stack; -/* Match both section group name and the sh_info field. */ -struct section_match -{ - const char *group_name; - unsigned int info; -}; - static bfd_boolean get_section (bfd *abfd ATTRIBUTE_UNUSED, asection *sec, void *inf) { - struct section_match *match = (struct section_match *) inf; + struct elf_section_match *match = (struct elf_section_match *) inf; const char *gname = match->group_name; const char *group_name = elf_group_name (sec); unsigned int info = elf_section_data (sec)->this_hdr.sh_info; return (info == match->info + && ((bfd_section_flags (sec) & SEC_ASSEMBLER_SECTION_ID) + == (match->flags & SEC_ASSEMBLER_SECTION_ID)) + && sec->section_id == match->section_id && (group_name == gname || (group_name != NULL && gname != NULL @@ -561,10 +557,9 @@ get_section (bfd *abfd ATTRIBUTE_UNUSED, asection *sec, void *inf) void obj_elf_change_section (const char *name, unsigned int type, - unsigned int info, bfd_vma attr, int entsize, - const char *group_name, + struct elf_section_match *match_p, int linkonce, int push) { @@ -573,7 +568,12 @@ obj_elf_change_section (const char *name, flagword flags; const struct elf_backend_data *bed; const struct bfd_elf_special_section *ssect; - struct section_match match; + + if (match_p == NULL) + { + static struct elf_section_match unused_match; + match_p = &unused_match; + } #ifdef md_flush_pending_output md_flush_pending_output (); @@ -594,10 +594,8 @@ obj_elf_change_section (const char *name, previous_section = now_seg; previous_subsection = now_subseg; - match.group_name = group_name; - match.info = info; old_sec = bfd_get_section_by_name_if (stdoutput, name, get_section, - (void *) &match); + (void *) match_p); if (old_sec) { sec = old_sec; @@ -696,7 +694,7 @@ obj_elf_change_section (const char *name, #endif else { - if (group_name == NULL) + if (match_p->group_name == NULL) as_warn (_("setting incorrect section attributes for %s"), name); override = TRUE; @@ -732,16 +730,20 @@ obj_elf_change_section (const char *name, type = bfd_elf_get_default_section_type (flags); elf_section_type (sec) = type; elf_section_flags (sec) = attr; - elf_section_data (sec)->this_hdr.sh_info = info; + elf_section_data (sec)->this_hdr.sh_info = match_p->info; /* Prevent SEC_HAS_CONTENTS from being inadvertently set. */ if (type == SHT_NOBITS) seg_info (sec)->bss = 1; + /* Set the section ID and flags. */ + sec->section_id = match_p->section_id; + flags |= match_p->flags; + bfd_set_section_flags (sec, flags); if (flags & SEC_MERGE) sec->entsize = entsize; - elf_group_name (sec) = group_name; + elf_group_name (sec) = match_p->group_name; /* Add a symbol for this section to the symbol table. */ secsym = symbol_find (name); @@ -1006,7 +1008,7 @@ obj_elf_section_name (void) void obj_elf_section (int push) { - const char *name, *group_name; + const char *name; char *beg; int type, dummy; bfd_vma attr; @@ -1014,7 +1016,7 @@ obj_elf_section (int push) int entsize; int linkonce; subsegT new_subsection = -1; - unsigned int info = 0; + struct elf_section_match match; if (flag_mri) { @@ -1040,6 +1042,8 @@ obj_elf_section (int push) if (name == NULL) return; + memset (&match, 0, sizeof (match)); + symbolS * sym; if ((sym = symbol_find (name)) != NULL && ! symbol_section_p (sym) @@ -1054,7 +1058,6 @@ obj_elf_section (int push) type = SHT_NULL; attr = 0; gnu_attr = 0; - group_name = NULL; entsize = 0; linkonce = 0; @@ -1159,8 +1162,8 @@ obj_elf_section (int push) if ((attr & SHF_GROUP) != 0 && *input_line_pointer == ',') { ++input_line_pointer; - group_name = obj_elf_section_name (); - if (group_name == NULL) + match.group_name = obj_elf_section_name (); + if (match.group_name == NULL) attr &= ~SHF_GROUP; else if (*input_line_pointer == ',') { @@ -1186,26 +1189,86 @@ obj_elf_section (int push) const char *now_group = elf_group_name (now_seg); if (now_group != NULL) { - group_name = xstrdup (now_group); + match.group_name = xstrdup (now_group); linkonce = (now_seg->flags & SEC_LINK_ONCE) != 0; } } if ((gnu_attr & SHF_GNU_MBIND) != 0 && *input_line_pointer == ',') { + char *save = input_line_pointer; ++input_line_pointer; SKIP_WHITESPACE (); if (ISDIGIT (* input_line_pointer)) { char *t = input_line_pointer; - info = strtoul (input_line_pointer, - &input_line_pointer, 0); - if (info == (unsigned int) -1) + match.info = strtoul (input_line_pointer, + &input_line_pointer, 0); + if (match.info == (unsigned int) -1) { as_warn (_("unsupported mbind section info: %s"), t); - info = 0; + match.info = 0; } } + else + input_line_pointer = save; + } + + if (*input_line_pointer == ',') + { + char *save = input_line_pointer; + ++input_line_pointer; + SKIP_WHITESPACE (); + if (strncmp (input_line_pointer, "unique", 6) == 0) + { + input_line_pointer += 6; + SKIP_WHITESPACE (); + if (*input_line_pointer == ',') + { + ++input_line_pointer; + SKIP_WHITESPACE (); + if (ISDIGIT (* input_line_pointer)) + { + bfd_vma id; + bfd_boolean overflow; + char *t = input_line_pointer; + if (sizeof (bfd_vma) <= sizeof (unsigned long)) + { + errno = 0; + id = strtoul (input_line_pointer, + &input_line_pointer, 0); + overflow = (id == (unsigned long) -1 + && errno == ERANGE); + } + else + { + id = bfd_scan_vma + (input_line_pointer, + (const char **) &input_line_pointer, 0); + overflow = id == ~(bfd_vma) 0; + } + if (overflow || id > (unsigned int) -1) + { + char *linefeed, saved_char = 0; + if ((linefeed = strchr (t, '\n')) != NULL) + { + saved_char = *linefeed; + *linefeed = '\0'; + } + as_bad (_("unsupported section id: %s"), t); + if (saved_char) + *linefeed = saved_char; + } + else + { + match.section_id = id; + match.flags |= SEC_ASSEMBLER_SECTION_ID; + } + } + } + } + else + input_line_pointer = save; } } else @@ -1238,8 +1301,8 @@ obj_elf_section (int push) done: demand_empty_rest_of_line (); - obj_elf_change_section (name, type, info, attr, entsize, group_name, - linkonce, push); + obj_elf_change_section (name, type, attr, entsize, &match, linkonce, + push); if ((gnu_attr & SHF_GNU_MBIND) != 0) { diff --git a/gas/config/obj-elf.h b/gas/config/obj-elf.h index b0a5a2d7b82..7cfcc254823 100644 --- a/gas/config/obj-elf.h +++ b/gas/config/obj-elf.h @@ -77,6 +77,16 @@ struct elf_obj_sy #endif }; +/* Match section group name, the sh_info field and the section_id + field. */ +struct elf_section_match +{ + const char *group_name; + unsigned int info; + unsigned int section_id; + flagword flags; +}; + #define OBJ_SYMFIELD_TYPE struct elf_obj_sy #ifndef FALSE @@ -162,7 +172,7 @@ extern void obj_elf_common (int); extern void obj_elf_data (int); extern void obj_elf_text (int); extern void obj_elf_change_section - (const char *, unsigned int, unsigned int, bfd_vma, int, const char *, + (const char *, unsigned int, bfd_vma, int, struct elf_section_match *, int, int); extern void obj_elf_vtable_inherit (int); extern void obj_elf_vtable_entry (int); diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c index bb0b03e35ea..26a76f3fe12 100644 --- a/gas/config/tc-arm.c +++ b/gas/config/tc-arm.c @@ -27011,7 +27011,7 @@ start_unwind_section (const segT text_seg, int idx) const char * text_name; const char * prefix; const char * prefix_once; - const char * group_name; + struct elf_section_match match; char * sec_name; int type; int flags; @@ -27045,13 +27045,13 @@ start_unwind_section (const segT text_seg, int idx) flags = SHF_ALLOC; linkonce = 0; - group_name = 0; + memset (&match, 0, sizeof (match)); /* Handle COMDAT group. */ if (prefix != prefix_once && (text_seg->flags & SEC_LINK_ONCE) != 0) { - group_name = elf_group_name (text_seg); - if (group_name == NULL) + match.group_name = elf_group_name (text_seg); + if (match.group_name == NULL) { as_bad (_("Group section `%s' has no group signature"), segment_name (text_seg)); @@ -27062,7 +27062,7 @@ start_unwind_section (const segT text_seg, int idx) linkonce = 1; } - obj_elf_change_section (sec_name, type, 0, flags, 0, group_name, + obj_elf_change_section (sec_name, type, flags, 0, &match, linkonce, 0); /* Set the section link for index tables. */ diff --git a/gas/config/tc-ia64.c b/gas/config/tc-ia64.c index fbddd54120a..f908ba51fa3 100644 --- a/gas/config/tc-ia64.c +++ b/gas/config/tc-ia64.c @@ -1139,7 +1139,7 @@ obj_elf_vms_common (int ignore ATTRIBUTE_UNUSED) demand_empty_rest_of_line (); obj_elf_change_section - (sec_name, SHT_NOBITS, 0, + (sec_name, SHT_NOBITS, SHF_ALLOC | SHF_WRITE | SHF_IA_64_VMS_OVERLAID | SHF_IA_64_VMS_GLOBAL, 0, NULL, 1, 0); diff --git a/gas/config/tc-microblaze.c b/gas/config/tc-microblaze.c index f4ae298b5b8..24ea3582447 100644 --- a/gas/config/tc-microblaze.c +++ b/gas/config/tc-microblaze.c @@ -149,7 +149,7 @@ static void microblaze_s_data (int ignore ATTRIBUTE_UNUSED) { #ifdef OBJ_ELF - obj_elf_change_section (".data", SHT_PROGBITS, 0, SHF_ALLOC+SHF_WRITE, + obj_elf_change_section (".data", SHT_PROGBITS, SHF_ALLOC+SHF_WRITE, 0, 0, 0, 0); #else s_data (ignore); @@ -162,7 +162,7 @@ static void microblaze_s_sdata (int ignore ATTRIBUTE_UNUSED) { #ifdef OBJ_ELF - obj_elf_change_section (".sdata", SHT_PROGBITS, 0, SHF_ALLOC+SHF_WRITE, + obj_elf_change_section (".sdata", SHT_PROGBITS, SHF_ALLOC+SHF_WRITE, 0, 0, 0, 0); #else s_data (ignore); @@ -281,7 +281,7 @@ microblaze_s_rdata (int localvar) if (localvar == 0) { /* rodata. */ - obj_elf_change_section (".rodata", SHT_PROGBITS, 0, SHF_ALLOC, + obj_elf_change_section (".rodata", SHT_PROGBITS, SHF_ALLOC, 0, 0, 0, 0); if (rodata_segment == 0) rodata_segment = subseg_new (".rodata", 0); @@ -289,7 +289,7 @@ microblaze_s_rdata (int localvar) else { /* 1 .sdata2. */ - obj_elf_change_section (".sdata2", SHT_PROGBITS, 0, SHF_ALLOC, + obj_elf_change_section (".sdata2", SHT_PROGBITS, SHF_ALLOC, 0, 0, 0, 0); } #else @@ -302,12 +302,12 @@ microblaze_s_bss (int localvar) { #ifdef OBJ_ELF if (localvar == 0) /* bss. */ - obj_elf_change_section (".bss", SHT_NOBITS, 0, SHF_ALLOC+SHF_WRITE, + obj_elf_change_section (".bss", SHT_NOBITS, SHF_ALLOC+SHF_WRITE, 0, 0, 0, 0); else if (localvar == 1) { /* sbss. */ - obj_elf_change_section (".sbss", SHT_NOBITS, 0, SHF_ALLOC+SHF_WRITE, + obj_elf_change_section (".sbss", SHT_NOBITS, SHF_ALLOC+SHF_WRITE, 0, 0, 0, 0); if (sbss_segment == 0) sbss_segment = subseg_new (".sbss", 0); diff --git a/gas/config/tc-mips.c b/gas/config/tc-mips.c index fc6898834e7..6244d8ac091 100644 --- a/gas/config/tc-mips.c +++ b/gas/config/tc-mips.c @@ -16418,7 +16418,7 @@ s_change_section (int ignore ATTRIBUTE_UNUSED) if (section_type == SHT_MIPS_DWARF) section_type = SHT_PROGBITS; - obj_elf_change_section (section_name, section_type, 0, section_flag, + obj_elf_change_section (section_name, section_type, section_flag, section_entry_size, 0, 0, 0); if (now_seg->name != section_name) diff --git a/gas/config/tc-msp430.c b/gas/config/tc-msp430.c index 57538824e92..840e5137ae7 100644 --- a/gas/config/tc-msp430.c +++ b/gas/config/tc-msp430.c @@ -620,7 +620,7 @@ msp430_profiler (int dummy ATTRIBUTE_UNUSED) subseg = now_subseg; /* Now go to .profiler section. */ - obj_elf_change_section (".profiler", SHT_PROGBITS, 0, 0, 0, 0, 0, 0); + obj_elf_change_section (".profiler", SHT_PROGBITS, 0, 0, 0, 0, 0); /* Save flags. */ emit_expr (& exp, 2); diff --git a/gas/config/tc-rx.c b/gas/config/tc-rx.c index b406e03b079..febdb5ab956 100644 --- a/gas/config/tc-rx.c +++ b/gas/config/tc-rx.c @@ -491,7 +491,7 @@ parse_rx_section (char * name) else type = SHT_NOBITS; - obj_elf_change_section (name, type, 0, attr, 0, NULL, FALSE, FALSE); + obj_elf_change_section (name, type, attr, 0, NULL, FALSE, FALSE); } else /* Try not to redefine a section, especially B_1. */ { @@ -506,7 +506,7 @@ parse_rx_section (char * name) | ((flags & SEC_STRINGS) ? SHF_STRINGS : 0) | ((flags & SEC_THREAD_LOCAL) ? SHF_TLS : 0); - obj_elf_change_section (name, type, 0, attr, 0, NULL, FALSE, FALSE); + obj_elf_change_section (name, type, attr, 0, NULL, FALSE, FALSE); } bfd_set_section_alignment (now_seg, align); diff --git a/gas/config/tc-tic6x.c b/gas/config/tc-tic6x.c index 9a506ed1e55..9f5b24e648d 100644 --- a/gas/config/tc-tic6x.c +++ b/gas/config/tc-tic6x.c @@ -4606,7 +4606,7 @@ tic6x_start_unwind_section (const segT text_seg, int idx) const char * text_name; const char * prefix; const char * prefix_once; - const char * group_name; + struct elf_section_match match; size_t prefix_len; size_t text_len; char * sec_name; @@ -4649,13 +4649,13 @@ tic6x_start_unwind_section (const segT text_seg, int idx) flags = SHF_ALLOC; linkonce = 0; - group_name = 0; + memset (&match, 0, sizeof (match)); /* Handle COMDAT group. */ if (prefix != prefix_once && (text_seg->flags & SEC_LINK_ONCE) != 0) { - group_name = elf_group_name (text_seg); - if (group_name == NULL) + match.group_name = elf_group_name (text_seg); + if (match.group_name == NULL) { as_bad (_("group section `%s' has no group signature"), segment_name (text_seg)); @@ -4666,7 +4666,7 @@ tic6x_start_unwind_section (const segT text_seg, int idx) linkonce = 1; } - obj_elf_change_section (sec_name, type, 0, flags, 0, group_name, + obj_elf_change_section (sec_name, type, flags, 0, &match, linkonce, 0); /* Set the section link for index tables. */ diff --git a/gas/doc/as.texi b/gas/doc/as.texi index fa155096159..152bbfdd009 100644 --- a/gas/doc/as.texi +++ b/gas/doc/as.texi @@ -6709,6 +6709,18 @@ this directive. If that section used @code{G}, then the new section will use @code{G} with those same @var{GroupName} and @var{linkage} fields implicitly. If not, then the @code{?} symbol has no effect. +The optional @var{unique,@code{}} argument must come last. It +assigns @var{@code{}} as a unique section ID to distinguish +different sections with the same section name like these: + +@smallexample +.section @var{name},"@var{flags}",@@@var{type},@var{unique,@code{}} +.section @var{name},"@var{flags}"G,@@@var{type},@var{GroupName},[@var{linkage}],@var{unique,@code{}} +.section @var{name},"@var{flags}"MG,@@@var{type},@var{entsize},@var{GroupName}[,@var{linkage}],@var{unique,@code{}} +@end smallexample + +The valid values of @var{@code{}} are between 0 and 4294967295. + If no flags are specified, the default flags depend upon the section name. If the section name is not recognized, the default will be for the section to have none of the above flags: it will not be allocated in memory, nor writable, nor diff --git a/gas/testsuite/gas/elf/elf.exp b/gas/testsuite/gas/elf/elf.exp index 5a298fe5832..08c6830e0db 100644 --- a/gas/testsuite/gas/elf/elf.exp +++ b/gas/testsuite/gas/elf/elf.exp @@ -245,6 +245,10 @@ if { [is_elf_format] } then { run_dump_test "section12b" run_dump_test "section13" run_dump_test "section14" + run_dump_test "section15" + run_dump_test "section16a" + run_dump_test "section16b" + run_dump_test "section17" 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/section15.d b/gas/testsuite/gas/elf/section15.d new file mode 100644 index 00000000000..a7cda1394f4 --- /dev/null +++ b/gas/testsuite/gas/elf/section15.d @@ -0,0 +1,24 @@ +#objdump: -s +#name: elf section15 +# .pushsection always creates the named section, but the +# test harness translates ".text" into "P" for the RX... +#notarget: rx-* + +.*: +file format .* + +# The MIPS includes a 'section .reginfo' and such here. +#... +Contents of section .bar: + 0000 00000000 00000000 0000 .* +Contents of section .bar: + 0000 0102 .* +Contents of section .bar: + 0000 0102 .* +Contents of section .bar: + 0000 0103 .* +Contents of section .bar: + 0000 04 .* +Contents of section .text: + 0000 feff .* +# Arm includes a .ARM.attributes section here +#... diff --git a/gas/testsuite/gas/elf/section15.s b/gas/testsuite/gas/elf/section15.s new file mode 100644 index 00000000000..949cd84f89d --- /dev/null +++ b/gas/testsuite/gas/elf/section15.s @@ -0,0 +1,38 @@ + .section .bar,"a",unique,0 + .byte 0 + .pushsection .bar,2,"a",unique,1 + .byte 2 + .popsection + .byte 0 + .pushsection .bar,3,"a",unique,2 + .byte 2 + .popsection + .byte 0 + .pushsection .bar,2,"a", %progbits,unique,3 + .byte 3 + .popsection + .byte 0 + .pushsection .bar,"",unique,4 + .byte 4 + .popsection + .byte 0 + .pushsection .text,1,"axG",%progbits,foo,comdat,unique,0xffffffff + .byte -1 + .popsection + .byte 0 + .pushsection .text,"axG",%progbits,foo,comdat,unique,0xffffffff + .byte -2 + .popsection + .byte 0 + .pushsection .bar,"a",unique,1 + .byte 1 + .popsection + .byte 0 + .pushsection .bar,"a", %progbits,unique,3 + .byte 1 + .popsection + .byte 0 + .pushsection .bar,"a",unique,2 + .byte 1 + .popsection + .byte 0 diff --git a/gas/testsuite/gas/elf/section16.s b/gas/testsuite/gas/elf/section16.s new file mode 100644 index 00000000000..77e20a368f7 --- /dev/null +++ b/gas/testsuite/gas/elf/section16.s @@ -0,0 +1,33 @@ + .section .mbind.data,"adw",%progbits,unique,0 + .byte 1 + + .section .mbind.data,"adw",%progbits,0x3,unique,1 + .byte 2 + + .section .mbind.text,"adx",%progbits,unique,2 + .byte 3 + + .section .mbind.text,"adx",%progbits,0x3,unique,3 + .byte 4 + + .section .mbind.bss,"adw",%nobits,unique,4 + .zero 5 + + .section .mbind.bss,"adw",%nobits,0x3,unique,5 + .zero 6 + + .section .mbind.rodata,"adG",%progbits,.foo_group,comdat,0x2,unique,6 + .byte 7 + + .section .mbind.data,"adGw",%progbits,.foo_group,comdat,unique,7 + .byte 8 + + .section .mbind.data,"adGw",%progbits,.foo_group,comdat,0x3,unique,8 + .byte 9 + + # Check that .pushsection works as well. + .pushsection .mbind.text,"adGx",%progbits,.foo_group,comdat,0x3,unique,9 + .byte 10 + + .popsection + .byte 11 diff --git a/gas/testsuite/gas/elf/section16a.d b/gas/testsuite/gas/elf/section16a.d new file mode 100644 index 00000000000..d1abf570c61 --- /dev/null +++ b/gas/testsuite/gas/elf/section16a.d @@ -0,0 +1,36 @@ +#source: section16.s +#as: --no-pad-sections +#readelf: -Sg --wide +#name: mbind sections +# A number of targets do not support SHF_GNU_MBIND +#xfail: arm*-*-netbsdelf* arm*-*-nto* msp430-*-* visium-*-* +#xfail: *-*-hpux* *-*-cloudabi + +#... + \[[ 0-9]+\] \.mbind\.data[ ]+PROGBITS[ ]+0+0 0+[0-9a-f]+ 0+1 00 WAD 0 0 1 +#... + \[[ 0-9]+\] \.mbind\.data[ ]+PROGBITS[ ]+0+0 0+[0-9a-f]+ 0+1 00 WAD 0 3 1 +#... + \[[ 0-9]+\] \.mbind\.text[ ]+PROGBITS[ ]+0+0 0+[0-9a-f]+ 0+1 00 AXD 0 0 . +#... + \[[ 0-9]+\] \.mbind\.text[ ]+PROGBITS[ ]+0+0 0+[0-9a-f]+ 0+1 00 AXD 0 3 . +#... + \[[ 0-9]+\] \.mbind\.bss[ ]+NOBITS[ ]+0+0 0+[0-9a-f]+ 0+5 00 WAD 0 0 1 +#... + \[[ 0-9]+\] \.mbind\.bss[ ]+NOBITS[ ]+0+0 0+[0-9a-f]+ 0+6 00 WAD 0 3 1 +#... + \[[ 0-9]+\] \.mbind\.rodata[ ]+PROGBITS[ ]+0+0 0+[0-9a-f]+ 0+1 00 AGD 0 2 1 +#... + \[[ 0-9]+\] \.mbind\.data[ ]+PROGBITS[ ]+0+0 0+[0-9a-f]+ 0+1 00 WAGD 0 0 1 +#... + \[[ 0-9]+\] \.mbind\.data[ ]+PROGBITS[ ]+0+0 0+[0-9a-f]+ 0+2 00 WAGD 0 3 1 +#... + \[[ 0-9]+\] \.mbind\.text[ ]+PROGBITS[ ]+0+0 0+[0-9a-f]+ 0+1 00 AXGD 0 3 1 +#... +COMDAT group section \[ 1\] `\.group' \[\.foo_group\] contains . sections: +[ ]+\[Index\][ ]+Name +[ ]+\[[ 0-9]+][ ]+\.mbind\.rodata +[ ]+\[[ 0-9]+][ ]+\.mbind\.data +[ ]+\[[ 0-9]+][ ]+\.mbind\.data +[ ]+\[[ 0-9]+][ ]+\.mbind\.text +#pass diff --git a/gas/testsuite/gas/elf/section16b.d b/gas/testsuite/gas/elf/section16b.d new file mode 100644 index 00000000000..a146c0de7e1 --- /dev/null +++ b/gas/testsuite/gas/elf/section16b.d @@ -0,0 +1,36 @@ +#source: section16.s +#as: --no-pad-sections +#objdump: -s +#name: mbind section contents +# RX annoyingly reorders the sections so that they do not match the sequence +# expected below. +#xfail: rx-*-* +# A number of targets do not support SHF_GNU_MBIND +#xfail: arm*-*-netbsdelf* arm*-*-nto* msp430-*-* visium-*-* +#xfail: *-*-hpux* *-*-cloudabi + +#... +Contents of section .mbind.data: + 0000 01 . +#... +Contents of section .mbind.data: + 0000 02 . +#... +Contents of section .mbind.text: + 0000 03 . +#... +Contents of section .mbind.text: + 0000 04 . +#... +Contents of section .mbind.rodata: + 0000 07 . +#... +Contents of section .mbind.data: + 0000 08 . +#... +Contents of section .mbind.data: + 0000 090b .. +#... +Contents of section .mbind.text: + 0000 0a . +#pass diff --git a/gas/testsuite/gas/elf/section17.d b/gas/testsuite/gas/elf/section17.d new file mode 100644 index 00000000000..3efdc22abfe --- /dev/null +++ b/gas/testsuite/gas/elf/section17.d @@ -0,0 +1,2 @@ +#name: incorrect section ID +#error_output: section17.l diff --git a/gas/testsuite/gas/elf/section17.l b/gas/testsuite/gas/elf/section17.l new file mode 100644 index 00000000000..5b3e2b6d340 --- /dev/null +++ b/gas/testsuite/gas/elf/section17.l @@ -0,0 +1,4 @@ +[^:]*: Assembler messages: +[^:]*:1: Error: unsupported section id: 0x100000000 +[^:]*:3: Error: junk at end of line, first unrecognized character is `f' +[^:]*:5: Error: junk at end of line, first unrecognized character is `,' diff --git a/gas/testsuite/gas/elf/section17.s b/gas/testsuite/gas/elf/section17.s new file mode 100644 index 00000000000..43de1d7f2b6 --- /dev/null +++ b/gas/testsuite/gas/elf/section17.s @@ -0,0 +1,6 @@ + .section .data,"aw",%progbits,unique,0x100000000 + .byte 0 + .section .bss,"aw",%nobits,unique,foo + .byte 0 + .section .text,"ax",%progbits,unique,1,foo + .byte 0 diff --git a/gas/testsuite/gas/i386/i386.exp b/gas/testsuite/gas/i386/i386.exp index feab8c2be95..ffeff0c101a 100644 --- a/gas/testsuite/gas/i386/i386.exp +++ b/gas/testsuite/gas/i386/i386.exp @@ -491,6 +491,7 @@ if [expr ([istarget "i*86-*-*"] || [istarget "x86_64-*-*"]) && [gas_32_check]] run_list_test "inval-pseudo" "-al" run_dump_test "nop-1" run_dump_test "nop-2" + run_dump_test "unique" run_dump_test "optimize-1" run_dump_test "optimize-1a" run_dump_test "optimize-2" @@ -1050,6 +1051,7 @@ if [expr ([istarget "i*86-*-*"] || [istarget "x86_64-*-*"]) && [gas_64_check]] t run_dump_test "x86-64-movd-intel" run_dump_test "x86-64-nop-1" run_dump_test "x86-64-nop-2" + run_dump_test "x86-64-unique" run_dump_test "x86-64-movsxd" run_dump_test "x86-64-movsxd-intel" run_list_test "x86-64-movsxd-inval" "-al" diff --git a/gas/testsuite/gas/i386/unique.d b/gas/testsuite/gas/i386/unique.d new file mode 100644 index 00000000000..0337733d992 --- /dev/null +++ b/gas/testsuite/gas/i386/unique.d @@ -0,0 +1,48 @@ +#objdump: -dw +#name: i386 unique sections + +.*: +file format .* + + +Disassembly of section .text: + +0+ : + +[a-f0-9]+: 89 c3 mov %eax,%ebx + +[a-f0-9]+: c3 ret + +Disassembly of section .text: + +0+ : + +[a-f0-9]+: 31 c3 xor %eax,%ebx + +[a-f0-9]+: c3 ret + +Disassembly of section .text: + +0+ : + +[a-f0-9]+: 89 c3 mov %eax,%ebx + +[a-f0-9]+: c3 ret + +Disassembly of section .text: + +0+ : + +[a-f0-9]+: 01 c3 add %eax,%ebx + +[a-f0-9]+: 90 nop + +[a-f0-9]+: c3 ret + +Disassembly of section .text: + +0+ : + +[a-f0-9]+: 29 c3 sub %eax,%ebx + +[a-f0-9]+: 90 nop + +[a-f0-9]+: 90 nop + +[a-f0-9]+: 90 nop + +[a-f0-9]+: c3 ret + +Disassembly of section .text: + +0+ : + +[a-f0-9]+: 31 c3 xor %eax,%ebx + +[a-f0-9]+: 90 nop + +[a-f0-9]+: 90 nop + +[a-f0-9]+: c3 ret +#pass diff --git a/gas/testsuite/gas/i386/unique.s b/gas/testsuite/gas/i386/unique.s new file mode 100644 index 00000000000..89b23b0fc66 --- /dev/null +++ b/gas/testsuite/gas/i386/unique.s @@ -0,0 +1,36 @@ + .section .text,"ax",@progbits,unique,1 +foo: + mov %eax, %ebx + .section .text,"ax",@progbits,unique,2 +bar: + xor %eax, %ebx + .section .text,"ax",@progbits,unique,1 + ret + .section .text,"ax",@progbits,unique,2 + ret + .section .text,"axG",@progbits,foo,comdat,unique,1 +foo1: + mov %eax, %ebx + .section .text,"axG",@progbits,bar,comdat,unique,1 +bar1: + add %eax, %ebx + .section .text,"axG",@progbits,bar,comdat,unique,2 +bar2: + sub %eax, %ebx + .section .text,"axG",@progbits,foo,comdat,unique,2 +foo2: + xor %eax, %ebx + .section .text,"axG",@progbits,bar,comdat,unique,1 + nop + ret + .section .text,"axG",@progbits,foo,comdat,unique,1 + ret + .section .text,"axG",@progbits,bar,comdat,unique,2 + nop + nop + nop + ret + .section .text,"axG",@progbits,foo,comdat,unique,2 + nop + nop + ret diff --git a/gas/testsuite/gas/i386/x86-64-unique.d b/gas/testsuite/gas/i386/x86-64-unique.d new file mode 100644 index 00000000000..4cfd30d5e9d --- /dev/null +++ b/gas/testsuite/gas/i386/x86-64-unique.d @@ -0,0 +1,48 @@ +#source: unique.s +#objdump: -dw +#name: 64bit unique sections + +.*: +file format .* + +Disassembly of section .text: + +0+ : + +[a-f0-9]+: 89 c3 mov %eax,%ebx + +[a-f0-9]+: c3 retq + +Disassembly of section .text: + +0+ : + +[a-f0-9]+: 31 c3 xor %eax,%ebx + +[a-f0-9]+: c3 retq + +Disassembly of section .text: + +0+ : + +[a-f0-9]+: 89 c3 mov %eax,%ebx + +[a-f0-9]+: c3 retq + +Disassembly of section .text: + +0+ : + +[a-f0-9]+: 01 c3 add %eax,%ebx + +[a-f0-9]+: 90 nop + +[a-f0-9]+: c3 retq + +Disassembly of section .text: + +0+ : + +[a-f0-9]+: 29 c3 sub %eax,%ebx + +[a-f0-9]+: 90 nop + +[a-f0-9]+: 90 nop + +[a-f0-9]+: 90 nop + +[a-f0-9]+: c3 retq + +Disassembly of section .text: + +0+ : + +[a-f0-9]+: 31 c3 xor %eax,%ebx + +[a-f0-9]+: 90 nop + +[a-f0-9]+: 90 nop + +[a-f0-9]+: c3 retq +#pass diff --git a/ld/ChangeLog b/ld/ChangeLog index d97c6356bf1..2b885b5fb3e 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,11 @@ +2020-02-02 H.J. Lu + + PR gas/25380 + * testsuite/ld-i386/pr22001-1c.S: Use "unique,N" in .section + directives. + * testsuite/ld-i386/tls-gd1.S: Likewise. + * testsuite/ld-x86-64/pr21481b.S: Likewise. + 2020-01-30 Jan Beulich * ld.texi: Remove space between @option and brace. diff --git a/ld/testsuite/ld-i386/pr22001-1c.S b/ld/testsuite/ld-i386/pr22001-1c.S index 2c1041dba77..51094efce35 100644 --- a/ld/testsuite/ld-i386/pr22001-1c.S +++ b/ld/testsuite/ld-i386/pr22001-1c.S @@ -1,7 +1,7 @@ .section .rodata.str1.1,"aMS",@progbits,1 .LC0: .string "PASS" - .section .text.startup,"ax",@progbits + .section .text,"ax",@progbits,unique,1 .p2align 4,,15 .globl main .type main, @function @@ -41,7 +41,7 @@ main: addl $16, %esp jmp .L3 .size main, .-main - .section .text.__x86.get_pc_thunk.bx,"axG",@progbits,__x86.get_pc_thunk.bx,comdat + .section .text,"axG",@progbits,__x86.get_pc_thunk.bx,comdat,unique,2 .globl __x86.get_pc_thunk.bx .hidden __x86.get_pc_thunk.bx .type __x86.get_pc_thunk.bx, @function diff --git a/ld/testsuite/ld-i386/tls-gd1.S b/ld/testsuite/ld-i386/tls-gd1.S index 3b16eab6aa2..cf5c913560c 100644 --- a/ld/testsuite/ld-i386/tls-gd1.S +++ b/ld/testsuite/ld-i386/tls-gd1.S @@ -47,15 +47,14 @@ test_gd: movzbl %al, %eax ret .size test_gd, .-test_gd - .section .text.unlikely - .section .text.__x86.get_pc_thunk.bx,"axG",@progbits,__x86.get_pc_thunk.bx,comdat + .section .text,"axG",@progbits,__x86.get_pc_thunk.bx,comdat,unique,1 .globl __x86.get_pc_thunk.bx .hidden __x86.get_pc_thunk.bx .type __x86.get_pc_thunk.bx, @function __x86.get_pc_thunk.bx: movl (%esp), %ebx ret - .section .text.__x86.get_pc_thunk.cx,"axG",@progbits,__x86.get_pc_thunk.cx,comdat + .section .text,"axG",@progbits,__x86.get_pc_thunk.cx,comdat,unique,2 .globl __x86.get_pc_thunk.cx .hidden __x86.get_pc_thunk.cx .type __x86.get_pc_thunk.cx, @function diff --git a/ld/testsuite/ld-x86-64/pr21481b.S b/ld/testsuite/ld-x86-64/pr21481b.S index 583ec77d121..d66c86f2286 100644 --- a/ld/testsuite/ld-x86-64/pr21481b.S +++ b/ld/testsuite/ld-x86-64/pr21481b.S @@ -1,4 +1,4 @@ - .section .rodata.str1.1,"aMS",@progbits,1 + .section .rodata.foo,"aMS",@progbits,1,unique,1 .LC0: .string "PASS" .text @@ -40,7 +40,7 @@ call_func1: jmp *func1@GOTPCREL(%rip) .size call_func1, .-call_func1 .globl func1_p - .section .rodata,"a",@progbits + .section .rodata.foo,"a",@progbits,unique,2 .align 8 .size func1_p, 8 .type func1_p, @object