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:
parent
0f8b5e560e
commit
a8c4d40b57
|
@ -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>
|
2020-02-01 Nick Clifton <nickc@redhat.com>
|
||||||
|
|
||||||
* config.bfd: Move the c30-aout and tic30-aout targets onto the
|
* config.bfd: Move the c30-aout and tic30-aout targets onto the
|
||||||
|
|
|
@ -795,6 +795,10 @@ typedef struct bfd_section
|
||||||
/* A unique sequence number. */
|
/* A unique sequence number. */
|
||||||
unsigned int id;
|
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. */
|
/* Which section in the bfd; 0..n-1 as sections are created in a bfd. */
|
||||||
unsigned int index;
|
unsigned int index;
|
||||||
|
|
||||||
|
@ -928,6 +932,10 @@ typedef struct bfd_section
|
||||||
else up the line will take care of it later. */
|
else up the line will take care of it later. */
|
||||||
#define SEC_LINKER_CREATED 0x100000
|
#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.
|
/* This section should not be subject to garbage collection.
|
||||||
Also set to inform the linker that this section should not be
|
Also set to inform the linker that this section should not be
|
||||||
listed in the link map as discarded. */
|
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) \
|
#define BFD_FAKE_SECTION(SEC, SYM, NAME, IDX, FLAGS) \
|
||||||
/* name, id, index, next, prev, flags, user_set_vma, */ \
|
/* name, id, section_id, index, next, prev, flags, user_set_vma, */ \
|
||||||
{ NAME, IDX, 0, NULL, NULL, FLAGS, 0, \
|
{ NAME, IDX, 0, 0, NULL, NULL, FLAGS, 0, \
|
||||||
\
|
\
|
||||||
/* linker_mark, linker_has_input, gc_mark, decompress_status, */ \
|
/* linker_mark, linker_has_input, gc_mark, decompress_status, */ \
|
||||||
0, 0, 1, 0, \
|
0, 0, 1, 0, \
|
||||||
|
|
|
@ -52,8 +52,10 @@
|
||||||
/* This stuff is somewhat copied from coffcode.h. */
|
/* This stuff is somewhat copied from coffcode.h. */
|
||||||
static asection bfd_debug_section =
|
static asection bfd_debug_section =
|
||||||
{
|
{
|
||||||
/* name, id, index, next, prev, flags, user_set_vma, */
|
/* name, id, section_id, index, next, prev, flags, */
|
||||||
"*DEBUG*", 0, 0, NULL, NULL, 0, 0,
|
"*DEBUG*", 0, 0, 0, NULL, NULL, 0,
|
||||||
|
/* user_set_vma, */
|
||||||
|
0,
|
||||||
/* linker_mark, linker_has_input, gc_mark, compress_status, */
|
/* linker_mark, linker_has_input, gc_mark, compress_status, */
|
||||||
0, 0, 1, 0,
|
0, 0, 1, 0,
|
||||||
/* segment_mark, sec_info_type, use_rela_p, */
|
/* segment_mark, sec_info_type, use_rela_p, */
|
||||||
|
|
|
@ -154,6 +154,10 @@ CODE_FRAGMENT
|
||||||
. {* A unique sequence number. *}
|
. {* A unique sequence number. *}
|
||||||
. unsigned int id;
|
. 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. *}
|
. {* Which section in the bfd; 0..n-1 as sections are created in a bfd. *}
|
||||||
. unsigned int index;
|
. unsigned int index;
|
||||||
.
|
.
|
||||||
|
@ -287,6 +291,10 @@ CODE_FRAGMENT
|
||||||
. else up the line will take care of it later. *}
|
. else up the line will take care of it later. *}
|
||||||
.#define SEC_LINKER_CREATED 0x100000
|
.#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.
|
. {* This section should not be subject to garbage collection.
|
||||||
. Also set to inform the linker that this section should not be
|
. Also set to inform the linker that this section should not be
|
||||||
. listed in the link map as discarded. *}
|
. listed in the link map as discarded. *}
|
||||||
|
@ -688,8 +696,8 @@ CODE_FRAGMENT
|
||||||
.}
|
.}
|
||||||
.
|
.
|
||||||
.#define BFD_FAKE_SECTION(SEC, SYM, NAME, IDX, FLAGS) \
|
.#define BFD_FAKE_SECTION(SEC, SYM, NAME, IDX, FLAGS) \
|
||||||
. {* name, id, index, next, prev, flags, user_set_vma, *} \
|
. {* name, id, section_id, index, next, prev, flags, user_set_vma, *} \
|
||||||
. { NAME, IDX, 0, NULL, NULL, FLAGS, 0, \
|
. { NAME, IDX, 0, 0, NULL, NULL, FLAGS, 0, \
|
||||||
. \
|
. \
|
||||||
. {* linker_mark, linker_has_input, gc_mark, decompress_status, *} \
|
. {* linker_mark, linker_has_input, gc_mark, decompress_status, *} \
|
||||||
. 0, 0, 1, 0, \
|
. 0, 0, 1, 0, \
|
||||||
|
|
|
@ -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>
|
2020-02-01 Nick Clifton <nickc@redhat.com>
|
||||||
|
|
||||||
* README-how-to-make-a-release: Update with more details on the
|
* README-how-to-make-a-release: Update with more details on the
|
||||||
|
|
|
@ -1065,6 +1065,13 @@ sym_ok (bfd_boolean want_section,
|
||||||
{
|
{
|
||||||
if (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
|
/* Note - we cannot just compare section pointers because they could
|
||||||
be different, but the same... Ie the symbol that we are trying to
|
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
|
find could have come from a separate debug info file. Under such
|
||||||
|
|
|
@ -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>
|
2020-02-02 H.J. Lu <hongjiu.lu@intel.com>
|
||||||
|
|
||||||
* testsuite/gas/elf/section13.s: Replace @nobits with %nobits.
|
* testsuite/gas/elf/section13.s: Replace @nobits with %nobits.
|
||||||
|
|
|
@ -518,22 +518,18 @@ struct section_stack
|
||||||
|
|
||||||
static struct section_stack *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
|
static bfd_boolean
|
||||||
get_section (bfd *abfd ATTRIBUTE_UNUSED, asection *sec, void *inf)
|
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 *gname = match->group_name;
|
||||||
const char *group_name = elf_group_name (sec);
|
const char *group_name = elf_group_name (sec);
|
||||||
unsigned int info = elf_section_data (sec)->this_hdr.sh_info;
|
unsigned int info = elf_section_data (sec)->this_hdr.sh_info;
|
||||||
|
|
||||||
return (info == match->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 == gname
|
||||||
|| (group_name != NULL
|
|| (group_name != NULL
|
||||||
&& gname != NULL
|
&& gname != NULL
|
||||||
|
@ -561,10 +557,9 @@ get_section (bfd *abfd ATTRIBUTE_UNUSED, asection *sec, void *inf)
|
||||||
void
|
void
|
||||||
obj_elf_change_section (const char *name,
|
obj_elf_change_section (const char *name,
|
||||||
unsigned int type,
|
unsigned int type,
|
||||||
unsigned int info,
|
|
||||||
bfd_vma attr,
|
bfd_vma attr,
|
||||||
int entsize,
|
int entsize,
|
||||||
const char *group_name,
|
struct elf_section_match *match_p,
|
||||||
int linkonce,
|
int linkonce,
|
||||||
int push)
|
int push)
|
||||||
{
|
{
|
||||||
|
@ -573,7 +568,12 @@ obj_elf_change_section (const char *name,
|
||||||
flagword flags;
|
flagword flags;
|
||||||
const struct elf_backend_data *bed;
|
const struct elf_backend_data *bed;
|
||||||
const struct bfd_elf_special_section *ssect;
|
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
|
#ifdef md_flush_pending_output
|
||||||
md_flush_pending_output ();
|
md_flush_pending_output ();
|
||||||
|
@ -594,10 +594,8 @@ obj_elf_change_section (const char *name,
|
||||||
previous_section = now_seg;
|
previous_section = now_seg;
|
||||||
previous_subsection = now_subseg;
|
previous_subsection = now_subseg;
|
||||||
|
|
||||||
match.group_name = group_name;
|
|
||||||
match.info = info;
|
|
||||||
old_sec = bfd_get_section_by_name_if (stdoutput, name, get_section,
|
old_sec = bfd_get_section_by_name_if (stdoutput, name, get_section,
|
||||||
(void *) &match);
|
(void *) match_p);
|
||||||
if (old_sec)
|
if (old_sec)
|
||||||
{
|
{
|
||||||
sec = old_sec;
|
sec = old_sec;
|
||||||
|
@ -696,7 +694,7 @@ obj_elf_change_section (const char *name,
|
||||||
#endif
|
#endif
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (group_name == NULL)
|
if (match_p->group_name == NULL)
|
||||||
as_warn (_("setting incorrect section attributes for %s"),
|
as_warn (_("setting incorrect section attributes for %s"),
|
||||||
name);
|
name);
|
||||||
override = TRUE;
|
override = TRUE;
|
||||||
|
@ -732,16 +730,20 @@ obj_elf_change_section (const char *name,
|
||||||
type = bfd_elf_get_default_section_type (flags);
|
type = bfd_elf_get_default_section_type (flags);
|
||||||
elf_section_type (sec) = type;
|
elf_section_type (sec) = type;
|
||||||
elf_section_flags (sec) = attr;
|
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. */
|
/* Prevent SEC_HAS_CONTENTS from being inadvertently set. */
|
||||||
if (type == SHT_NOBITS)
|
if (type == SHT_NOBITS)
|
||||||
seg_info (sec)->bss = 1;
|
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);
|
bfd_set_section_flags (sec, flags);
|
||||||
if (flags & SEC_MERGE)
|
if (flags & SEC_MERGE)
|
||||||
sec->entsize = entsize;
|
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. */
|
/* Add a symbol for this section to the symbol table. */
|
||||||
secsym = symbol_find (name);
|
secsym = symbol_find (name);
|
||||||
|
@ -1006,7 +1008,7 @@ obj_elf_section_name (void)
|
||||||
void
|
void
|
||||||
obj_elf_section (int push)
|
obj_elf_section (int push)
|
||||||
{
|
{
|
||||||
const char *name, *group_name;
|
const char *name;
|
||||||
char *beg;
|
char *beg;
|
||||||
int type, dummy;
|
int type, dummy;
|
||||||
bfd_vma attr;
|
bfd_vma attr;
|
||||||
|
@ -1014,7 +1016,7 @@ obj_elf_section (int push)
|
||||||
int entsize;
|
int entsize;
|
||||||
int linkonce;
|
int linkonce;
|
||||||
subsegT new_subsection = -1;
|
subsegT new_subsection = -1;
|
||||||
unsigned int info = 0;
|
struct elf_section_match match;
|
||||||
|
|
||||||
if (flag_mri)
|
if (flag_mri)
|
||||||
{
|
{
|
||||||
|
@ -1040,6 +1042,8 @@ obj_elf_section (int push)
|
||||||
if (name == NULL)
|
if (name == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
memset (&match, 0, sizeof (match));
|
||||||
|
|
||||||
symbolS * sym;
|
symbolS * sym;
|
||||||
if ((sym = symbol_find (name)) != NULL
|
if ((sym = symbol_find (name)) != NULL
|
||||||
&& ! symbol_section_p (sym)
|
&& ! symbol_section_p (sym)
|
||||||
|
@ -1054,7 +1058,6 @@ obj_elf_section (int push)
|
||||||
type = SHT_NULL;
|
type = SHT_NULL;
|
||||||
attr = 0;
|
attr = 0;
|
||||||
gnu_attr = 0;
|
gnu_attr = 0;
|
||||||
group_name = NULL;
|
|
||||||
entsize = 0;
|
entsize = 0;
|
||||||
linkonce = 0;
|
linkonce = 0;
|
||||||
|
|
||||||
|
@ -1159,8 +1162,8 @@ obj_elf_section (int push)
|
||||||
if ((attr & SHF_GROUP) != 0 && *input_line_pointer == ',')
|
if ((attr & SHF_GROUP) != 0 && *input_line_pointer == ',')
|
||||||
{
|
{
|
||||||
++input_line_pointer;
|
++input_line_pointer;
|
||||||
group_name = obj_elf_section_name ();
|
match.group_name = obj_elf_section_name ();
|
||||||
if (group_name == NULL)
|
if (match.group_name == NULL)
|
||||||
attr &= ~SHF_GROUP;
|
attr &= ~SHF_GROUP;
|
||||||
else if (*input_line_pointer == ',')
|
else if (*input_line_pointer == ',')
|
||||||
{
|
{
|
||||||
|
@ -1186,26 +1189,86 @@ obj_elf_section (int push)
|
||||||
const char *now_group = elf_group_name (now_seg);
|
const char *now_group = elf_group_name (now_seg);
|
||||||
if (now_group != NULL)
|
if (now_group != NULL)
|
||||||
{
|
{
|
||||||
group_name = xstrdup (now_group);
|
match.group_name = xstrdup (now_group);
|
||||||
linkonce = (now_seg->flags & SEC_LINK_ONCE) != 0;
|
linkonce = (now_seg->flags & SEC_LINK_ONCE) != 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((gnu_attr & SHF_GNU_MBIND) != 0 && *input_line_pointer == ',')
|
if ((gnu_attr & SHF_GNU_MBIND) != 0 && *input_line_pointer == ',')
|
||||||
{
|
{
|
||||||
|
char *save = input_line_pointer;
|
||||||
++input_line_pointer;
|
++input_line_pointer;
|
||||||
SKIP_WHITESPACE ();
|
SKIP_WHITESPACE ();
|
||||||
if (ISDIGIT (* input_line_pointer))
|
if (ISDIGIT (* input_line_pointer))
|
||||||
{
|
{
|
||||||
char *t = input_line_pointer;
|
char *t = input_line_pointer;
|
||||||
info = strtoul (input_line_pointer,
|
match.info = strtoul (input_line_pointer,
|
||||||
&input_line_pointer, 0);
|
&input_line_pointer, 0);
|
||||||
if (info == (unsigned int) -1)
|
if (match.info == (unsigned int) -1)
|
||||||
{
|
{
|
||||||
as_warn (_("unsupported mbind section info: %s"), t);
|
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
|
else
|
||||||
|
@ -1238,8 +1301,8 @@ obj_elf_section (int push)
|
||||||
done:
|
done:
|
||||||
demand_empty_rest_of_line ();
|
demand_empty_rest_of_line ();
|
||||||
|
|
||||||
obj_elf_change_section (name, type, info, attr, entsize, group_name,
|
obj_elf_change_section (name, type, attr, entsize, &match, linkonce,
|
||||||
linkonce, push);
|
push);
|
||||||
|
|
||||||
if ((gnu_attr & SHF_GNU_MBIND) != 0)
|
if ((gnu_attr & SHF_GNU_MBIND) != 0)
|
||||||
{
|
{
|
||||||
|
|
|
@ -77,6 +77,16 @@ struct elf_obj_sy
|
||||||
#endif
|
#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
|
#define OBJ_SYMFIELD_TYPE struct elf_obj_sy
|
||||||
|
|
||||||
#ifndef FALSE
|
#ifndef FALSE
|
||||||
|
@ -162,7 +172,7 @@ extern void obj_elf_common (int);
|
||||||
extern void obj_elf_data (int);
|
extern void obj_elf_data (int);
|
||||||
extern void obj_elf_text (int);
|
extern void obj_elf_text (int);
|
||||||
extern void obj_elf_change_section
|
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);
|
int, int);
|
||||||
extern void obj_elf_vtable_inherit (int);
|
extern void obj_elf_vtable_inherit (int);
|
||||||
extern void obj_elf_vtable_entry (int);
|
extern void obj_elf_vtable_entry (int);
|
||||||
|
|
|
@ -27011,7 +27011,7 @@ start_unwind_section (const segT text_seg, int idx)
|
||||||
const char * text_name;
|
const char * text_name;
|
||||||
const char * prefix;
|
const char * prefix;
|
||||||
const char * prefix_once;
|
const char * prefix_once;
|
||||||
const char * group_name;
|
struct elf_section_match match;
|
||||||
char * sec_name;
|
char * sec_name;
|
||||||
int type;
|
int type;
|
||||||
int flags;
|
int flags;
|
||||||
|
@ -27045,13 +27045,13 @@ start_unwind_section (const segT text_seg, int idx)
|
||||||
|
|
||||||
flags = SHF_ALLOC;
|
flags = SHF_ALLOC;
|
||||||
linkonce = 0;
|
linkonce = 0;
|
||||||
group_name = 0;
|
memset (&match, 0, sizeof (match));
|
||||||
|
|
||||||
/* Handle COMDAT group. */
|
/* Handle COMDAT group. */
|
||||||
if (prefix != prefix_once && (text_seg->flags & SEC_LINK_ONCE) != 0)
|
if (prefix != prefix_once && (text_seg->flags & SEC_LINK_ONCE) != 0)
|
||||||
{
|
{
|
||||||
group_name = elf_group_name (text_seg);
|
match.group_name = elf_group_name (text_seg);
|
||||||
if (group_name == NULL)
|
if (match.group_name == NULL)
|
||||||
{
|
{
|
||||||
as_bad (_("Group section `%s' has no group signature"),
|
as_bad (_("Group section `%s' has no group signature"),
|
||||||
segment_name (text_seg));
|
segment_name (text_seg));
|
||||||
|
@ -27062,7 +27062,7 @@ start_unwind_section (const segT text_seg, int idx)
|
||||||
linkonce = 1;
|
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);
|
linkonce, 0);
|
||||||
|
|
||||||
/* Set the section link for index tables. */
|
/* Set the section link for index tables. */
|
||||||
|
|
|
@ -1139,7 +1139,7 @@ obj_elf_vms_common (int ignore ATTRIBUTE_UNUSED)
|
||||||
demand_empty_rest_of_line ();
|
demand_empty_rest_of_line ();
|
||||||
|
|
||||||
obj_elf_change_section
|
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,
|
SHF_ALLOC | SHF_WRITE | SHF_IA_64_VMS_OVERLAID | SHF_IA_64_VMS_GLOBAL,
|
||||||
0, NULL, 1, 0);
|
0, NULL, 1, 0);
|
||||||
|
|
||||||
|
|
|
@ -149,7 +149,7 @@ static void
|
||||||
microblaze_s_data (int ignore ATTRIBUTE_UNUSED)
|
microblaze_s_data (int ignore ATTRIBUTE_UNUSED)
|
||||||
{
|
{
|
||||||
#ifdef OBJ_ELF
|
#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);
|
0, 0, 0, 0);
|
||||||
#else
|
#else
|
||||||
s_data (ignore);
|
s_data (ignore);
|
||||||
|
@ -162,7 +162,7 @@ static void
|
||||||
microblaze_s_sdata (int ignore ATTRIBUTE_UNUSED)
|
microblaze_s_sdata (int ignore ATTRIBUTE_UNUSED)
|
||||||
{
|
{
|
||||||
#ifdef OBJ_ELF
|
#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);
|
0, 0, 0, 0);
|
||||||
#else
|
#else
|
||||||
s_data (ignore);
|
s_data (ignore);
|
||||||
|
@ -281,7 +281,7 @@ microblaze_s_rdata (int localvar)
|
||||||
if (localvar == 0)
|
if (localvar == 0)
|
||||||
{
|
{
|
||||||
/* rodata. */
|
/* rodata. */
|
||||||
obj_elf_change_section (".rodata", SHT_PROGBITS, 0, SHF_ALLOC,
|
obj_elf_change_section (".rodata", SHT_PROGBITS, SHF_ALLOC,
|
||||||
0, 0, 0, 0);
|
0, 0, 0, 0);
|
||||||
if (rodata_segment == 0)
|
if (rodata_segment == 0)
|
||||||
rodata_segment = subseg_new (".rodata", 0);
|
rodata_segment = subseg_new (".rodata", 0);
|
||||||
|
@ -289,7 +289,7 @@ microblaze_s_rdata (int localvar)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* 1 .sdata2. */
|
/* 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);
|
0, 0, 0, 0);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
@ -302,12 +302,12 @@ microblaze_s_bss (int localvar)
|
||||||
{
|
{
|
||||||
#ifdef OBJ_ELF
|
#ifdef OBJ_ELF
|
||||||
if (localvar == 0) /* bss. */
|
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);
|
0, 0, 0, 0);
|
||||||
else if (localvar == 1)
|
else if (localvar == 1)
|
||||||
{
|
{
|
||||||
/* sbss. */
|
/* 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);
|
0, 0, 0, 0);
|
||||||
if (sbss_segment == 0)
|
if (sbss_segment == 0)
|
||||||
sbss_segment = subseg_new (".sbss", 0);
|
sbss_segment = subseg_new (".sbss", 0);
|
||||||
|
|
|
@ -16418,7 +16418,7 @@ s_change_section (int ignore ATTRIBUTE_UNUSED)
|
||||||
if (section_type == SHT_MIPS_DWARF)
|
if (section_type == SHT_MIPS_DWARF)
|
||||||
section_type = SHT_PROGBITS;
|
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);
|
section_entry_size, 0, 0, 0);
|
||||||
|
|
||||||
if (now_seg->name != section_name)
|
if (now_seg->name != section_name)
|
||||||
|
|
|
@ -620,7 +620,7 @@ msp430_profiler (int dummy ATTRIBUTE_UNUSED)
|
||||||
subseg = now_subseg;
|
subseg = now_subseg;
|
||||||
|
|
||||||
/* Now go to .profiler section. */
|
/* 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. */
|
/* Save flags. */
|
||||||
emit_expr (& exp, 2);
|
emit_expr (& exp, 2);
|
||||||
|
|
|
@ -491,7 +491,7 @@ parse_rx_section (char * name)
|
||||||
else
|
else
|
||||||
type = SHT_NOBITS;
|
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. */
|
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_STRINGS) ? SHF_STRINGS : 0)
|
||||||
| ((flags & SEC_THREAD_LOCAL) ? SHF_TLS : 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);
|
bfd_set_section_alignment (now_seg, align);
|
||||||
|
|
|
@ -4606,7 +4606,7 @@ tic6x_start_unwind_section (const segT text_seg, int idx)
|
||||||
const char * text_name;
|
const char * text_name;
|
||||||
const char * prefix;
|
const char * prefix;
|
||||||
const char * prefix_once;
|
const char * prefix_once;
|
||||||
const char * group_name;
|
struct elf_section_match match;
|
||||||
size_t prefix_len;
|
size_t prefix_len;
|
||||||
size_t text_len;
|
size_t text_len;
|
||||||
char * sec_name;
|
char * sec_name;
|
||||||
|
@ -4649,13 +4649,13 @@ tic6x_start_unwind_section (const segT text_seg, int idx)
|
||||||
|
|
||||||
flags = SHF_ALLOC;
|
flags = SHF_ALLOC;
|
||||||
linkonce = 0;
|
linkonce = 0;
|
||||||
group_name = 0;
|
memset (&match, 0, sizeof (match));
|
||||||
|
|
||||||
/* Handle COMDAT group. */
|
/* Handle COMDAT group. */
|
||||||
if (prefix != prefix_once && (text_seg->flags & SEC_LINK_ONCE) != 0)
|
if (prefix != prefix_once && (text_seg->flags & SEC_LINK_ONCE) != 0)
|
||||||
{
|
{
|
||||||
group_name = elf_group_name (text_seg);
|
match.group_name = elf_group_name (text_seg);
|
||||||
if (group_name == NULL)
|
if (match.group_name == NULL)
|
||||||
{
|
{
|
||||||
as_bad (_("group section `%s' has no group signature"),
|
as_bad (_("group section `%s' has no group signature"),
|
||||||
segment_name (text_seg));
|
segment_name (text_seg));
|
||||||
|
@ -4666,7 +4666,7 @@ tic6x_start_unwind_section (const segT text_seg, int idx)
|
||||||
linkonce = 1;
|
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);
|
linkonce, 0);
|
||||||
|
|
||||||
/* Set the section link for index tables. */
|
/* Set the section link for index tables. */
|
||||||
|
|
|
@ -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.
|
@code{G} with those same @var{GroupName} and @var{linkage} fields implicitly.
|
||||||
If not, then the @code{?} symbol has no effect.
|
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
|
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
|
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
|
none of the above flags: it will not be allocated in memory, nor writable, nor
|
||||||
|
|
|
@ -245,6 +245,10 @@ if { [is_elf_format] } then {
|
||||||
run_dump_test "section12b"
|
run_dump_test "section12b"
|
||||||
run_dump_test "section13"
|
run_dump_test "section13"
|
||||||
run_dump_test "section14"
|
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-1" $dump_opts
|
||||||
run_dump_test "dwarf2-2" $dump_opts
|
run_dump_test "dwarf2-2" $dump_opts
|
||||||
run_dump_test "dwarf2-3" $dump_opts
|
run_dump_test "dwarf2-3" $dump_opts
|
||||||
|
|
|
@ -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
|
||||||
|
#...
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -0,0 +1,2 @@
|
||||||
|
#name: incorrect section ID
|
||||||
|
#error_output: 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 `,'
|
|
@ -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
|
|
@ -491,6 +491,7 @@ if [expr ([istarget "i*86-*-*"] || [istarget "x86_64-*-*"]) && [gas_32_check]]
|
||||||
run_list_test "inval-pseudo" "-al"
|
run_list_test "inval-pseudo" "-al"
|
||||||
run_dump_test "nop-1"
|
run_dump_test "nop-1"
|
||||||
run_dump_test "nop-2"
|
run_dump_test "nop-2"
|
||||||
|
run_dump_test "unique"
|
||||||
run_dump_test "optimize-1"
|
run_dump_test "optimize-1"
|
||||||
run_dump_test "optimize-1a"
|
run_dump_test "optimize-1a"
|
||||||
run_dump_test "optimize-2"
|
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-movd-intel"
|
||||||
run_dump_test "x86-64-nop-1"
|
run_dump_test "x86-64-nop-1"
|
||||||
run_dump_test "x86-64-nop-2"
|
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"
|
||||||
run_dump_test "x86-64-movsxd-intel"
|
run_dump_test "x86-64-movsxd-intel"
|
||||||
run_list_test "x86-64-movsxd-inval" "-al"
|
run_list_test "x86-64-movsxd-inval" "-al"
|
||||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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>
|
2020-01-30 Jan Beulich <jbeulich@suse.com>
|
||||||
|
|
||||||
* ld.texi: Remove space between @option and brace.
|
* ld.texi: Remove space between @option and brace.
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
.section .rodata.str1.1,"aMS",@progbits,1
|
.section .rodata.str1.1,"aMS",@progbits,1
|
||||||
.LC0:
|
.LC0:
|
||||||
.string "PASS"
|
.string "PASS"
|
||||||
.section .text.startup,"ax",@progbits
|
.section .text,"ax",@progbits,unique,1
|
||||||
.p2align 4,,15
|
.p2align 4,,15
|
||||||
.globl main
|
.globl main
|
||||||
.type main, @function
|
.type main, @function
|
||||||
|
@ -41,7 +41,7 @@ main:
|
||||||
addl $16, %esp
|
addl $16, %esp
|
||||||
jmp .L3
|
jmp .L3
|
||||||
.size main, .-main
|
.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
|
.globl __x86.get_pc_thunk.bx
|
||||||
.hidden __x86.get_pc_thunk.bx
|
.hidden __x86.get_pc_thunk.bx
|
||||||
.type __x86.get_pc_thunk.bx, @function
|
.type __x86.get_pc_thunk.bx, @function
|
||||||
|
|
|
@ -47,15 +47,14 @@ test_gd:
|
||||||
movzbl %al, %eax
|
movzbl %al, %eax
|
||||||
ret
|
ret
|
||||||
.size test_gd, .-test_gd
|
.size test_gd, .-test_gd
|
||||||
.section .text.unlikely
|
.section .text,"axG",@progbits,__x86.get_pc_thunk.bx,comdat,unique,1
|
||||||
.section .text.__x86.get_pc_thunk.bx,"axG",@progbits,__x86.get_pc_thunk.bx,comdat
|
|
||||||
.globl __x86.get_pc_thunk.bx
|
.globl __x86.get_pc_thunk.bx
|
||||||
.hidden __x86.get_pc_thunk.bx
|
.hidden __x86.get_pc_thunk.bx
|
||||||
.type __x86.get_pc_thunk.bx, @function
|
.type __x86.get_pc_thunk.bx, @function
|
||||||
__x86.get_pc_thunk.bx:
|
__x86.get_pc_thunk.bx:
|
||||||
movl (%esp), %ebx
|
movl (%esp), %ebx
|
||||||
ret
|
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
|
.globl __x86.get_pc_thunk.cx
|
||||||
.hidden __x86.get_pc_thunk.cx
|
.hidden __x86.get_pc_thunk.cx
|
||||||
.type __x86.get_pc_thunk.cx, @function
|
.type __x86.get_pc_thunk.cx, @function
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
.section .rodata.str1.1,"aMS",@progbits,1
|
.section .rodata.foo,"aMS",@progbits,1,unique,1
|
||||||
.LC0:
|
.LC0:
|
||||||
.string "PASS"
|
.string "PASS"
|
||||||
.text
|
.text
|
||||||
|
@ -40,7 +40,7 @@ call_func1:
|
||||||
jmp *func1@GOTPCREL(%rip)
|
jmp *func1@GOTPCREL(%rip)
|
||||||
.size call_func1, .-call_func1
|
.size call_func1, .-call_func1
|
||||||
.globl func1_p
|
.globl func1_p
|
||||||
.section .rodata,"a",@progbits
|
.section .rodata.foo,"a",@progbits,unique,2
|
||||||
.align 8
|
.align 8
|
||||||
.size func1_p, 8
|
.size func1_p, 8
|
||||||
.type func1_p, @object
|
.type func1_p, @object
|
||||||
|
|
Loading…
Reference in New Issue