* [PATCH] ELF: Add support for unique section ID to assembler @ 2020-02-02 17:51 H.J. Lu 2020-02-03 0:22 ` Alan Modra 0 siblings, 1 reply; 5+ messages in thread From: H.J. Lu @ 2020-02-02 17:51 UTC (permalink / raw) To: binutils 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. --- bfd/bfd-in2.h | 12 ++- bfd/ecoff.c | 6 +- bfd/section.c | 12 ++- binutils/objdump.c | 7 ++ gas/config/obj-elf.c | 121 +++++++++++++++++++------ gas/config/obj-elf.h | 12 ++- gas/config/tc-arm.c | 10 +- gas/config/tc-ia64.c | 2 +- gas/config/tc-microblaze.c | 12 +-- gas/config/tc-mips.c | 2 +- gas/config/tc-msp430.c | 2 +- gas/config/tc-rx.c | 4 +- gas/config/tc-tic6x.c | 10 +- gas/doc/as.texi | 5 + gas/testsuite/gas/elf/elf.exp | 4 + gas/testsuite/gas/elf/section15.d | 24 +++++ gas/testsuite/gas/elf/section15.s | 38 ++++++++ gas/testsuite/gas/elf/section16.s | 33 +++++++ gas/testsuite/gas/elf/section16a.d | 36 ++++++++ gas/testsuite/gas/elf/section16b.d | 36 ++++++++ gas/testsuite/gas/elf/section17.d | 2 + gas/testsuite/gas/elf/section17.l | 4 + gas/testsuite/gas/elf/section17.s | 6 ++ gas/testsuite/gas/i386/i386.exp | 2 + gas/testsuite/gas/i386/unique.d | 48 ++++++++++ gas/testsuite/gas/i386/unique.s | 36 ++++++++ gas/testsuite/gas/i386/x86-64-unique.d | 48 ++++++++++ ld/testsuite/ld-i386/pr22001-1c.S | 4 +- ld/testsuite/ld-i386/tls-gd1.S | 5 +- ld/testsuite/ld-x86-64/pr21481b.S | 4 +- 30 files changed, 483 insertions(+), 64 deletions(-) create mode 100644 gas/testsuite/gas/elf/section15.d create mode 100644 gas/testsuite/gas/elf/section15.s create mode 100644 gas/testsuite/gas/elf/section16.s create mode 100644 gas/testsuite/gas/elf/section16a.d create mode 100644 gas/testsuite/gas/elf/section16b.d create mode 100644 gas/testsuite/gas/elf/section17.d create mode 100644 gas/testsuite/gas/elf/section17.l create mode 100644 gas/testsuite/gas/elf/section17.s create mode 100644 gas/testsuite/gas/i386/unique.d create mode 100644 gas/testsuite/gas/i386/unique.s create mode 100644 gas/testsuite/gas/i386/x86-64-unique.d 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/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/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..c86c38c1f03 100644 --- a/gas/doc/as.texi +++ b/gas/doc/as.texi @@ -6693,6 +6693,11 @@ particular section belongs. The optional linkage field can contain: indicates that only one copy of this section should be retained @item .gnu.linkonce an alias for comdat + +@item unique,@code{<number>} +assigns @code{<number>} as a unique section ID to distinguish different +sections with the same section name. The valid values of @code{<number>} +are between 0 and 4294967295. @end table Note: if both the @var{M} and @var{G} flags are present then the fields for 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+ <foo>: + +[a-f0-9]+: 89 c3 mov %eax,%ebx + +[a-f0-9]+: c3 ret + +Disassembly of section .text: + +0+ <bar>: + +[a-f0-9]+: 31 c3 xor %eax,%ebx + +[a-f0-9]+: c3 ret + +Disassembly of section .text: + +0+ <foo1>: + +[a-f0-9]+: 89 c3 mov %eax,%ebx + +[a-f0-9]+: c3 ret + +Disassembly of section .text: + +0+ <bar1>: + +[a-f0-9]+: 01 c3 add %eax,%ebx + +[a-f0-9]+: 90 nop + +[a-f0-9]+: c3 ret + +Disassembly of section .text: + +0+ <bar2>: + +[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+ <foo2>: + +[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+ <foo>: + +[a-f0-9]+: 89 c3 mov %eax,%ebx + +[a-f0-9]+: c3 retq + +Disassembly of section .text: + +0+ <bar>: + +[a-f0-9]+: 31 c3 xor %eax,%ebx + +[a-f0-9]+: c3 retq + +Disassembly of section .text: + +0+ <foo1>: + +[a-f0-9]+: 89 c3 mov %eax,%ebx + +[a-f0-9]+: c3 retq + +Disassembly of section .text: + +0+ <bar1>: + +[a-f0-9]+: 01 c3 add %eax,%ebx + +[a-f0-9]+: 90 nop + +[a-f0-9]+: c3 retq + +Disassembly of section .text: + +0+ <bar2>: + +[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+ <foo2>: + +[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/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 -- 2.24.1 ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] ELF: Add support for unique section ID to assembler 2020-02-02 17:51 [PATCH] ELF: Add support for unique section ID to assembler H.J. Lu @ 2020-02-03 0:22 ` Alan Modra 2020-02-03 1:05 ` H.J. Lu 0 siblings, 1 reply; 5+ messages in thread From: Alan Modra @ 2020-02-03 0:22 UTC (permalink / raw) To: H.J. Lu; +Cc: binutils On Sun, Feb 02, 2020 at 09:50:54AM -0800, H.J. Lu wrote: > 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. Looks OK to me. -- Alan Modra Australia Development Lab, IBM ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] ELF: Add support for unique section ID to assembler 2020-02-03 0:22 ` Alan Modra @ 2020-02-03 1:05 ` H.J. Lu 2020-02-03 1:10 ` Fangrui Song 0 siblings, 1 reply; 5+ messages in thread From: H.J. Lu @ 2020-02-03 1:05 UTC (permalink / raw) To: Alan Modra; +Cc: Binutils [-- Attachment #1: Type: text/plain, Size: 2451 bytes --] On Sun, Feb 2, 2020 at 4:22 PM Alan Modra <amodra@gmail.com> wrote: > > On Sun, Feb 02, 2020 at 09:50:54AM -0800, H.J. Lu wrote: > > 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. > > Looks OK to me. > This is the patch I am checking in. I updated documentation with iff --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{<number>}} argument must come last. It +assigns @var{@code{<number>}} 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{<number>}} +.section @var{name},"@var{flags}"G,@@@var{type},@var{GroupName},[@var{linkage}] ,@var{unique,@code{<number>}} +.section @var{name},"@var{flags}"MG,@@@var{type},@var{entsize},@var{GroupName}[ ,@var{linkage}],@var{unique,@code{<number>}} +@end smallexample + +The valid values of @var{@code{<number>}} 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 -- H.J. [-- Attachment #2: 0001-ELF-Add-support-for-unique-section-ID-to-assembler.patch --] [-- Type: text/x-patch, Size: 40141 bytes --] From fd0834347c57605bac20ffd800700211e4bb3d38 Mon Sep 17 00:00:00 2001 From: "H.J. Lu" <hjl.tools@gmail.com> Date: Sat, 1 Feb 2020 12:22:09 -0800 Subject: [PATCH] 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. --- bfd/bfd-in2.h | 12 ++- bfd/ecoff.c | 6 +- bfd/section.c | 12 ++- binutils/objdump.c | 7 ++ gas/config/obj-elf.c | 121 +++++++++++++++++++------ gas/config/obj-elf.h | 12 ++- gas/config/tc-arm.c | 10 +- gas/config/tc-ia64.c | 2 +- gas/config/tc-microblaze.c | 12 +-- gas/config/tc-mips.c | 2 +- gas/config/tc-msp430.c | 2 +- gas/config/tc-rx.c | 4 +- gas/config/tc-tic6x.c | 10 +- gas/doc/as.texi | 12 +++ gas/testsuite/gas/elf/elf.exp | 4 + gas/testsuite/gas/elf/section15.d | 24 +++++ gas/testsuite/gas/elf/section15.s | 38 ++++++++ gas/testsuite/gas/elf/section16.s | 33 +++++++ gas/testsuite/gas/elf/section16a.d | 36 ++++++++ gas/testsuite/gas/elf/section16b.d | 36 ++++++++ gas/testsuite/gas/elf/section17.d | 2 + gas/testsuite/gas/elf/section17.l | 4 + gas/testsuite/gas/elf/section17.s | 6 ++ gas/testsuite/gas/i386/i386.exp | 2 + gas/testsuite/gas/i386/unique.d | 48 ++++++++++ gas/testsuite/gas/i386/unique.s | 36 ++++++++ gas/testsuite/gas/i386/x86-64-unique.d | 48 ++++++++++ ld/testsuite/ld-i386/pr22001-1c.S | 4 +- ld/testsuite/ld-i386/tls-gd1.S | 5 +- ld/testsuite/ld-x86-64/pr21481b.S | 4 +- 30 files changed, 490 insertions(+), 64 deletions(-) create mode 100644 gas/testsuite/gas/elf/section15.d create mode 100644 gas/testsuite/gas/elf/section15.s create mode 100644 gas/testsuite/gas/elf/section16.s create mode 100644 gas/testsuite/gas/elf/section16a.d create mode 100644 gas/testsuite/gas/elf/section16b.d create mode 100644 gas/testsuite/gas/elf/section17.d create mode 100644 gas/testsuite/gas/elf/section17.l create mode 100644 gas/testsuite/gas/elf/section17.s create mode 100644 gas/testsuite/gas/i386/unique.d create mode 100644 gas/testsuite/gas/i386/unique.s create mode 100644 gas/testsuite/gas/i386/x86-64-unique.d 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/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/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{<number>}} argument must come last. It +assigns @var{@code{<number>}} 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{<number>}} +.section @var{name},"@var{flags}"G,@@@var{type},@var{GroupName},[@var{linkage}],@var{unique,@code{<number>}} +.section @var{name},"@var{flags}"MG,@@@var{type},@var{entsize},@var{GroupName}[,@var{linkage}],@var{unique,@code{<number>}} +@end smallexample + +The valid values of @var{@code{<number>}} 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+ <foo>: + +[a-f0-9]+: 89 c3 mov %eax,%ebx + +[a-f0-9]+: c3 ret + +Disassembly of section .text: + +0+ <bar>: + +[a-f0-9]+: 31 c3 xor %eax,%ebx + +[a-f0-9]+: c3 ret + +Disassembly of section .text: + +0+ <foo1>: + +[a-f0-9]+: 89 c3 mov %eax,%ebx + +[a-f0-9]+: c3 ret + +Disassembly of section .text: + +0+ <bar1>: + +[a-f0-9]+: 01 c3 add %eax,%ebx + +[a-f0-9]+: 90 nop + +[a-f0-9]+: c3 ret + +Disassembly of section .text: + +0+ <bar2>: + +[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+ <foo2>: + +[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+ <foo>: + +[a-f0-9]+: 89 c3 mov %eax,%ebx + +[a-f0-9]+: c3 retq + +Disassembly of section .text: + +0+ <bar>: + +[a-f0-9]+: 31 c3 xor %eax,%ebx + +[a-f0-9]+: c3 retq + +Disassembly of section .text: + +0+ <foo1>: + +[a-f0-9]+: 89 c3 mov %eax,%ebx + +[a-f0-9]+: c3 retq + +Disassembly of section .text: + +0+ <bar1>: + +[a-f0-9]+: 01 c3 add %eax,%ebx + +[a-f0-9]+: 90 nop + +[a-f0-9]+: c3 retq + +Disassembly of section .text: + +0+ <bar2>: + +[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+ <foo2>: + +[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/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 -- 2.24.1 ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] ELF: Add support for unique section ID to assembler 2020-02-03 1:05 ` H.J. Lu @ 2020-02-03 1:10 ` Fangrui Song 2020-02-03 1:16 ` H.J. Lu 0 siblings, 1 reply; 5+ messages in thread From: Fangrui Song @ 2020-02-03 1:10 UTC (permalink / raw) To: H.J. Lu; +Cc: Alan Modra, Binutils On 2020-02-02, H.J. Lu wrote: >On Sun, Feb 2, 2020@4:22 PM Alan Modra <amodra@gmail.com> wrote: >> >> On Sun, Feb 02, 2020@09:50:54AM -0800, H.J. Lu wrote: >> > 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. >> >> Looks OK to me. >> > >This is the patch I am checking in. I updated documentation with > >iff --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{<number>}} argument must come last. It >+assigns @var{@code{<number>}} 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{<number>}} >+.section @var{name},"@var{flags}"G,@@@var{type},@var{GroupName},[@var{linkage}] >,@var{unique,@code{<number>}} >+.section @var{name},"@var{flags}"MG,@@@var{type},@var{entsize},@var{GroupName}[ >,@var{linkage}],@var{unique,@code{<number>}} >+@end smallexample >+ >+The valid values of @var{@code{<number>}} 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 > > >-- >H.J. Thanks for the patch! Looks good. + sections withe the same section name. */ Typo. withe -> with ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] ELF: Add support for unique section ID to assembler 2020-02-03 1:10 ` Fangrui Song @ 2020-02-03 1:16 ` H.J. Lu 0 siblings, 0 replies; 5+ messages in thread From: H.J. Lu @ 2020-02-03 1:16 UTC (permalink / raw) To: Fangrui Song; +Cc: Alan Modra, Binutils [-- Attachment #1: Type: text/plain, Size: 2884 bytes --] On Sun, Feb 2, 2020 at 5:10 PM Fangrui Song <i@maskray.me> wrote: > > > On 2020-02-02, H.J. Lu wrote: > >On Sun, Feb 2, 2020@4:22 PM Alan Modra <amodra@gmail.com> wrote: > >> > >> On Sun, Feb 02, 2020@09:50:54AM -0800, H.J. Lu wrote: > >> > 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. > >> > >> Looks OK to me. > >> > > > >This is the patch I am checking in. I updated documentation with > > > >iff --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{<number>}} argument must come last. It > >+assigns @var{@code{<number>}} 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{<number>}} > >+.section @var{name},"@var{flags}"G,@@@var{type},@var{GroupName},[@var{linkage}] > >,@var{unique,@code{<number>}} > >+.section @var{name},"@var{flags}"MG,@@@var{type},@var{entsize},@var{GroupName}[ > >,@var{linkage}],@var{unique,@code{<number>}} > >+@end smallexample > >+ > >+The valid values of @var{@code{<number>}} 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 > > > > > >-- > >H.J. > > Thanks for the patch! Looks good. > > + sections withe the same section name. */ > > Typo. withe -> with Oops. Fixed with this. Thanks. -- H.J. [-- Attachment #2: 0001-section.c-Fix-typo-in-comments-withe-with.patch --] [-- Type: text/x-patch, Size: 1753 bytes --] From ef4627fabaebd4f4a2bc2c5e92c95d747f388d78 Mon Sep 17 00:00:00 2001 From: "H.J. Lu" <hjl.tools@gmail.com> Date: Sun, 2 Feb 2020 17:14:12 -0800 Subject: [PATCH] section.c: Fix typo in comments (withe -> with) * bfd-in2.h: Regenerated. * section.c (SEC_ASSEMBLER_SECTION_ID): Fix a typo in comments. --- bfd/ChangeLog | 5 +++++ bfd/bfd-in2.h | 2 +- bfd/section.c | 2 +- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index f8e7dfaf94..f758f65034 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,8 @@ +2020-02-02 H.J. Lu <hongjiu.lu@intel.com> + + * bfd-in2.h: Regenerated. + * section.c (SEC_ASSEMBLER_SECTION_ID): Fix a typo in comments. + 2020-02-02 H.J. Lu <hongjiu.lu@intel.com> PR gas/25380 diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h index c890520ccb..09a5a39ff5 100644 --- a/bfd/bfd-in2.h +++ b/bfd/bfd-in2.h @@ -933,7 +933,7 @@ typedef struct bfd_section #define SEC_LINKER_CREATED 0x100000 /* This section contains a section ID to distinguish different - sections withe the same section name. */ + sections with the same section name. */ #define SEC_ASSEMBLER_SECTION_ID 0x100000 /* This section should not be subject to garbage collection. diff --git a/bfd/section.c b/bfd/section.c index 161ed33edc..0c15a0d646 100644 --- a/bfd/section.c +++ b/bfd/section.c @@ -292,7 +292,7 @@ CODE_FRAGMENT .#define SEC_LINKER_CREATED 0x100000 . . {* This section contains a section ID to distinguish different -. sections withe the same section name. *} +. sections with the same section name. *} .#define SEC_ASSEMBLER_SECTION_ID 0x100000 . . {* This section should not be subject to garbage collection. -- 2.24.1 ^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2020-02-03 1:16 UTC | newest] Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2020-02-02 17:51 [PATCH] ELF: Add support for unique section ID to assembler H.J. Lu 2020-02-03 0:22 ` Alan Modra 2020-02-03 1:05 ` H.J. Lu 2020-02-03 1:10 ` Fangrui Song 2020-02-03 1:16 ` H.J. Lu
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).