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.
This commit is contained in:
H.J. Lu 2020-02-02 17:07:51 -08:00
parent 0f8b5e560e
commit a8c4d40b57
34 changed files with 551 additions and 64 deletions

View File

@ -1,3 +1,12 @@
2020-02-02 H.J. Lu <hongjiu.lu@intel.com>
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 <nickc@redhat.com>
* config.bfd: Move the c30-aout and tic30-aout targets onto the

View File

@ -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, \

View File

@ -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, */

View File

@ -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, \

View File

@ -1,3 +1,9 @@
2020-02-02 H.J. Lu <hongjiu.lu@intel.com>
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 <nickc@redhat.com>
* README-how-to-make-a-release: Update with more details on the

View File

@ -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

View File

@ -1,3 +1,41 @@
2020-02-02 H.J. Lu <hongjiu.lu@intel.com>
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 <hongjiu.lu@intel.com>
* testsuite/gas/elf/section13.s: Replace @nobits with %nobits.

View File

@ -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)
{

View File

@ -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);

View File

@ -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. */

View File

@ -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);

View File

@ -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);

View File

@ -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)

View File

@ -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);

View File

@ -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);

View File

@ -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. */

View File

@ -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

View File

@ -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

View File

@ -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
#...

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -0,0 +1,2 @@
#name: incorrect section ID
#error_output: section17.l

View File

@ -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 `,'

View File

@ -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

View File

@ -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"

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -1,3 +1,11 @@
2020-02-02 H.J. Lu <hongjiu.lu@intel.com>
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 <jbeulich@suse.com>
* ld.texi: Remove space between @option and brace.

View File

@ -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

View File

@ -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

View File

@ -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