[PATCH v2] gas: Add --unique-pushsection
H.J. Lu
hjl.tools@gmail.com
Fri May 16 21:15:26 GMT 2025
Linker kernel uses .pushsection directive extensively. But when
-ffunction-sections is used to build kernel, for
__attribute__((always_inline))
static void inline
test_section(void)
{
asm goto("jmp 1f\n"
"\t.pushsection .alt_section, \"ax\"\n"
"1:\n"
"\tjmp %l[t_label]\n"
"\t.popsection\n"
: :
: : t_label);
t_label:
return;
}
void
foo(void)
{
test_section();
}
void
bar(void)
{
test_section();
}
we get
.text
.section .text.foo,"ax",@progbits
.p2align 4
.globl foo
.type foo, @function
foo:
.LFB1:
.cfi_startproc
jmp 1f
.pushsection .alt_section, "ax"
1:
jmp .L2
.popsection
.L2:
ret
.L3:
.cfi_endproc
.LFE1:
.size foo, .-foo
.section .text.bar,"ax",@progbits
.p2align 4
.globl bar
.type bar, @function
bar:
.LFB2:
.cfi_startproc
jmp 1f
.pushsection .alt_section, "ax"
1:
jmp .L6
.popsection
.L6:
ret
.L7:
.cfi_endproc
.LFE2:
.size bar, .-bar
Functions foo and bar are placed in the different sections. But since
".pushsection .alt_section" always generates the same .alt_section
section for foo and bar, --gc-sections doesn't remove foo when bar is
referenced while foo isn't. To help linker to remove the unreferenced
functions with .pushsection directive:
Add --unique-pushsection option to ELF assembler to append the current
section name to the new section name for .pushsection.
Another option is to replace ".pushsection .alt_section" with
".pushsection .alt_section%S" and compile with -Wa,--sectname-subst.
Tested with small test cases and kernel build, all working fine. Below
are the details:
OS: Ubuntu 24.04
GCC: 14.2.0 in Ubuntu default
Binutils: 2.44.50, built with this patch
Test cases:
1. compile test.c with assembler new parameter "--unique-pushsection"
2. modify test.c to use ".pushsection .alt_section%S" and compile with
-Wa,--sectname-subst
3. try (2) with "--unique-pushsection" parameter
4. build Linux kernel 6.12 with the new parameter for some specific files
All can see that unused functions were removed as expected and kernel
works correctly.
gas/
PR gas/32961
* NEWS: Mention --unique-pushsection.
* as.c (flag_unique_pushsection): New.
(show_usage): Also show --unique-pushsection.
(parse_args): Support --unique-pushsection.
* as.h (flag_unique_pushsection): New.
* config/obj-elf.c (change_section): Append the previous section
name to the new section name for .pushsection with
--unique-pushsection.
* doc/as.texi: Document --unique-pushsection.
* testsuite/gas/elf/elf.exp: Run PR gas/32961 tests.
* testsuite/gas/elf/pushsection-1.d: New file.
* testsuite/gas/elf/pushsection-1.s: Likewise.
* testsuite/gas/elf/pushsection-2.s: Likewise.
* testsuite/gas/elf/pushsection-2a.d: Likewise.
* testsuite/gas/elf/pushsection-2b.d: Likewise.
ld/
PR gas/32961
* testsuite/ld-elf/pushsection-1.d: New file.
* testsuite/ld-elf/pushsection-1.s: Likewise.
* testsuite/ld-elf/pushsection-2.s: Likewise.
* testsuite/ld-elf/pushsection-2a.d: Likewise.
* testsuite/ld-elf/pushsection-2b.d: Likewise.
* testsuite/ld-elf/pushsection-3.d: Likewise.
* testsuite/ld-elf/pushsection-3.s: Likewise.
* testsuite/ld-elf/pushsection-4.s: Likewise.
* testsuite/ld-elf/pushsection-4a.d: Likewise.
* testsuite/ld-elf/pushsection-4b.d: Likewise.
Signed-off-by: H.J. Lu <hjl.tools@gmail.com>
Tested-by: Zhiyuan Lv <zhiyuan.lv@linux.intel.com>
---
gas/NEWS | 3 +
gas/as.c | 12 +++-
gas/as.h | 3 +
gas/config/obj-elf.c | 5 ++
gas/doc/as.texi | 6 ++
gas/testsuite/gas/elf/elf.exp | 4 ++
gas/testsuite/gas/elf/pushsection-1.d | 25 +++++++
gas/testsuite/gas/elf/pushsection-1.s | 60 +++++++++++++++++
gas/testsuite/gas/elf/pushsection-2.s | 60 +++++++++++++++++
gas/testsuite/gas/elf/pushsection-2a.d | 26 ++++++++
gas/testsuite/gas/elf/pushsection-2b.d | 26 ++++++++
ld/testsuite/ld-elf/pushsection-1.d | 13 ++++
ld/testsuite/ld-elf/pushsection-1.s | 60 +++++++++++++++++
ld/testsuite/ld-elf/pushsection-2.s | 60 +++++++++++++++++
ld/testsuite/ld-elf/pushsection-2a.d | 14 ++++
ld/testsuite/ld-elf/pushsection-2b.d | 14 ++++
ld/testsuite/ld-elf/pushsection-3.d | 13 ++++
ld/testsuite/ld-elf/pushsection-3.s | 90 ++++++++++++++++++++++++++
ld/testsuite/ld-elf/pushsection-4.s | 90 ++++++++++++++++++++++++++
ld/testsuite/ld-elf/pushsection-4a.d | 14 ++++
ld/testsuite/ld-elf/pushsection-4b.d | 14 ++++
21 files changed, 611 insertions(+), 1 deletion(-)
create mode 100644 gas/testsuite/gas/elf/pushsection-1.d
create mode 100644 gas/testsuite/gas/elf/pushsection-1.s
create mode 100644 gas/testsuite/gas/elf/pushsection-2.s
create mode 100644 gas/testsuite/gas/elf/pushsection-2a.d
create mode 100644 gas/testsuite/gas/elf/pushsection-2b.d
create mode 100644 ld/testsuite/ld-elf/pushsection-1.d
create mode 100644 ld/testsuite/ld-elf/pushsection-1.s
create mode 100644 ld/testsuite/ld-elf/pushsection-2.s
create mode 100644 ld/testsuite/ld-elf/pushsection-2a.d
create mode 100644 ld/testsuite/ld-elf/pushsection-2b.d
create mode 100644 ld/testsuite/ld-elf/pushsection-3.d
create mode 100644 ld/testsuite/ld-elf/pushsection-3.s
create mode 100644 ld/testsuite/ld-elf/pushsection-4.s
create mode 100644 ld/testsuite/ld-elf/pushsection-4a.d
create mode 100644 ld/testsuite/ld-elf/pushsection-4b.d
diff --git a/gas/NEWS b/gas/NEWS
index 42c3329d83e..9d4e9c1b84d 100644
--- a/gas/NEWS
+++ b/gas/NEWS
@@ -1,5 +1,8 @@
-*- text -*-
+* Add --unique-pushsection option to ELF assembler to append the current
+ section name to the new section name for .pushsection.
+
* Support for x86 AVX10.2 256 bit rounding has been dropped, as all the
hardware would directly support 512 bit vecotr width.
diff --git a/gas/as.c b/gas/as.c
index 7edac577d16..66a8b21d555 100644
--- a/gas/as.c
+++ b/gas/as.c
@@ -111,6 +111,7 @@ unsigned int dwarf_level = 3;
#if defined OBJ_ELF || defined OBJ_MAYBE_ELF
int flag_use_elf_stt_common = DEFAULT_GENERATE_ELF_STT_COMMON;
bool flag_generate_build_notes = DEFAULT_GENERATE_BUILD_NOTES;
+bool flag_unique_pushsection = false;
#endif
segT reg_section;
@@ -311,6 +312,8 @@ Options:\n\
fprintf (stream, _("\
generate GNU Build notes if none are present in the input\n"));
fprintf (stream, _("\
+ --unique-pushsection Create a unique section for .pushsection\n"));
+ fprintf (stream, _("\
--gsframe generate SFrame stack trace information\n"));
# if defined (TARGET_USE_SCFI) && defined (TARGET_USE_GINSN)
fprintf (stream, _("\
@@ -507,7 +510,8 @@ parse_args (int * pargc, char *** pargv)
OPTION_SFRAME,
OPTION_SCFI,
OPTION_INFO,
- OPTION_NOINFO
+ OPTION_NOINFO,
+ OPTION_UNIQUE_PUSHSECTION
/* When you add options here, check that they do
not collide with OPTION_MD_BASE. See as.h. */
};
@@ -538,6 +542,8 @@ parse_args (int * pargc, char *** pargv)
,{"elf-stt-common", required_argument, NULL, OPTION_ELF_STT_COMMON}
,{"sectname-subst", no_argument, NULL, OPTION_SECTNAME_SUBST}
,{"generate-missing-build-notes", required_argument, NULL, OPTION_ELF_BUILD_NOTES}
+ ,{"unique-pushsection", no_argument, NULL,
+ OPTION_UNIQUE_PUSHSECTION}
,{"gsframe", no_argument, NULL, OPTION_SFRAME}
# if defined (TARGET_USE_SCFI) && defined (TARGET_USE_GINSN)
,{"scfi", required_argument, NULL, OPTION_SCFI}
@@ -1035,6 +1041,10 @@ This program has absolutely no warranty.\n"));
flag_gen_sframe = 1;
break;
+ case OPTION_UNIQUE_PUSHSECTION:
+ flag_unique_pushsection = true;
+ break;
+
#endif /* OBJ_ELF */
case 'Z':
diff --git a/gas/as.h b/gas/as.h
index 826d88db013..c58fcf492aa 100644
--- a/gas/as.h
+++ b/gas/as.h
@@ -628,6 +628,9 @@ extern int flag_use_elf_stt_common;
be generated if none are in the input files. */
extern bool flag_generate_build_notes;
+/* TRUE if each .pushsection should create a unique section. */
+extern bool flag_unique_pushsection;
+
/* If section name substitution sequences should be honored */
COMMON int flag_sectname_subst;
#endif
diff --git a/gas/config/obj-elf.c b/gas/config/obj-elf.c
index bc981f05dd5..6b02c6e2756 100644
--- a/gas/config/obj-elf.c
+++ b/gas/config/obj-elf.c
@@ -622,6 +622,11 @@ change_section (const char *name,
obj_elf_section_change_hook ();
+ if (push
+ && previous_section
+ && flag_unique_pushsection)
+ name = concat (name, previous_section->name, NULL);
+
unsigned int *group_idx = NULL;
if (match_p->group_name)
old_sec = group_section_find (match_p, name, &group_idx);
diff --git a/gas/doc/as.texi b/gas/doc/as.texi
index 40d45f75d18..26db3530acb 100644
--- a/gas/doc/as.texi
+++ b/gas/doc/as.texi
@@ -240,6 +240,7 @@ gcc(1), ld(1), and the Info entries for @file{binutils} and @file{ld}.
[@b{--gdwarf-<N>}] [@b{--gdwarf-sections}]
[@b{--gdwarf-cie-version}=@var{VERSION}]
[@b{--generate-missing-build-notes=[no|yes]}]
+ [@b{--unique-pushsection}]
[@b{--gsframe}]
[@b{--hash-size}=@var{N}]
[@b{--help}] [@b{--target-help}]
@@ -853,6 +854,11 @@ attribute notes if none are present in the input sources.
The default can be controlled by the @option{--enable-generate-build-notes}
configure option.
+@item --unique-pushsection
+@itemx --unique-pushsection
+Append the current section name to the new section name for
+@code{.pushsection} directive.
+
@item --gsframe
@itemx --gsframe
Create @var{.sframe} section from CFI directives.
diff --git a/gas/testsuite/gas/elf/elf.exp b/gas/testsuite/gas/elf/elf.exp
index 1f42c3f3723..9702f531a9e 100644
--- a/gas/testsuite/gas/elf/elf.exp
+++ b/gas/testsuite/gas/elf/elf.exp
@@ -388,4 +388,8 @@ if { [is_elf_format] } then {
run_dump_test "bignums" $dump_opts
run_dump_test "section-symbol-redef"
run_dump_test "pr27228"
+
+ run_dump_test "pushsection-1"
+ run_dump_test "pushsection-2a"
+ run_dump_test "pushsection-2b"
}
diff --git a/gas/testsuite/gas/elf/pushsection-1.d b/gas/testsuite/gas/elf/pushsection-1.d
new file mode 100644
index 00000000000..c716ae1d377
--- /dev/null
+++ b/gas/testsuite/gas/elf/pushsection-1.d
@@ -0,0 +1,25 @@
+#as: --unique-pushsection
+#readelf: -SW
+# .pushsection always creates the named section, but the
+# test harness translates ".text" into "P" for the RX...
+#xfail: rx-*
+
+#...
+ \[..\] \.text\.foo0 +PROGBITS +[0-9a-f]+ [0-9a-f]+ [0-9a-f]+ 00 AX 0 0 +[1-9][0-9]*
+#...
+ \[..\] \.alt_section\.text\.foo0 +PROGBITS +[0-9a-f]+ [0-9a-f]+ [0-9a-f]+ 00 AX 0 0 +[1-9][0-9]*
+#...
+ \[..\] \.text\.foo1 +PROGBITS +[0-9a-f]+ [0-9a-f]+ [0-9a-f]+ 00 AX 0 0 +[1-9][0-9]*
+#...
+ \[..\] \.text\.foo2 +PROGBITS +[0-9a-f]+ [0-9a-f]+ [0-9a-f]+ 00 AX 0 0 +[1-9][0-9]*
+#...
+ \[..\] \.alt_section\.text\.foo2 +PROGBITS +[0-9a-f]+ [0-9a-f]+ [0-9a-f]+ 00 AX 0 0 +[1-9][0-9]*
+#...
+ \[..\] \.text\.foo3 +PROGBITS +[0-9a-f]+ [0-9a-f]+ [0-9a-f]+ 00 AX 0 0 +[1-9][0-9]*
+#...
+ \[..\] \.alt_section\.text\.foo3 +PROGBITS +[0-9a-f]+ [0-9a-f]+ [0-9a-f]+ 00 AX 0 0 +[1-9][0-9]*
+#...
+ \[..\] \.text\.entry_func +PROGBITS +[0-9a-f]+ [0-9a-f]+ [0-9a-f]+ 00 AX 0 0 +[1-9][0-9]*
+#...
+ \[..\] \.alt_section\.text\.entry_func +PROGBITS +[0-9a-f]+ [0-9a-f]+ [0-9a-f]+ 00 AX 0 0 +[1-9][0-9]*
+#pass
diff --git a/gas/testsuite/gas/elf/pushsection-1.s b/gas/testsuite/gas/elf/pushsection-1.s
new file mode 100644
index 00000000000..d0196ab7b1a
--- /dev/null
+++ b/gas/testsuite/gas/elf/pushsection-1.s
@@ -0,0 +1,60 @@
+ .section .text.foo0,"ax",%progbits
+ .p2align 4
+ .globl foo0
+ .type foo0, %function
+foo0:
+ .dc.a 1f
+ .pushsection .alt_section, "ax"
+1:
+ .dc.a .L0
+ .popsection
+.L0:
+ .dc.a 0
+ .size foo0, .-foo0
+ .section .text.foo1,"ax",%progbits
+ .p2align 4
+ .globl foo1
+ .type foo1, %function
+foo1:
+ .dc.a 0
+ .size foo1, .-foo1
+ .section .text.foo2,"ax",%progbits
+ .p2align 4
+ .globl foo2
+ .type foo2, %function
+foo2:
+ .dc.a 1f
+ .pushsection .alt_section, "ax"
+1:
+ .dc.a .L4
+ .popsection
+.L4:
+ .dc.a 0
+ .size foo2, .-foo2
+ .section .text.foo3,"ax",%progbits
+ .p2align 4
+ .globl foo3
+ .type foo3, %function
+foo3:
+ .dc.a 1f
+ .pushsection .alt_section, "ax"
+1:
+ .dc.a .L7
+ .popsection
+.L7:
+ .dc.a 0
+ .size foo3, .-foo3
+ .section .text.entry_func,"ax",%progbits
+ .p2align 4
+ .globl entry_func
+ .type entry_func, %function
+entry_func:
+ .dc.a 1f
+ .pushsection .alt_section, "ax"
+1:
+ .dc.a .L10
+ .popsection
+.L10:
+ .dc.a foo0
+ .size entry_func, .-entry_func
+ .section .note.GNU-stack,"",%progbits
diff --git a/gas/testsuite/gas/elf/pushsection-2.s b/gas/testsuite/gas/elf/pushsection-2.s
new file mode 100644
index 00000000000..d78d603e3d0
--- /dev/null
+++ b/gas/testsuite/gas/elf/pushsection-2.s
@@ -0,0 +1,60 @@
+ .section .text.foo0,"ax",%progbits
+ .p2align 4
+ .globl foo0
+ .type foo0, %function
+foo0:
+ .dc.a 1f
+ .pushsection .alt_section%S, "ax"
+1:
+ .dc.a .L0
+ .popsection
+.L0:
+ .dc.a 0
+ .size foo0, .-foo0
+ .section .text.foo1,"ax",%progbits
+ .p2align 4
+ .globl foo1
+ .type foo1, %function
+foo1:
+ .dc.a 0
+ .size foo1, .-foo1
+ .section .text.foo2,"ax",%progbits
+ .p2align 4
+ .globl foo2
+ .type foo2, %function
+foo2:
+ .dc.a 1f
+ .pushsection .alt_section%S, "ax"
+1:
+ .dc.a .L4
+ .popsection
+.L4:
+ .dc.a 0
+ .size foo2, .-foo2
+ .section .text.foo3,"ax",%progbits
+ .p2align 4
+ .globl foo3
+ .type foo3, %function
+foo3:
+ .dc.a 1f
+ .pushsection .alt_section%S, "ax"
+1:
+ .dc.a .L7
+ .popsection
+.L7:
+ .dc.a 0
+ .size foo3, .-foo3
+ .section .text.entry_func,"ax",%progbits
+ .p2align 4
+ .globl entry_func
+ .type entry_func, %function
+entry_func:
+ .dc.a 1f
+ .pushsection .alt_section%S, "ax"
+1:
+ .dc.a .L10
+ .popsection
+.L10:
+ .dc.a foo0
+ .size entry_func, .-entry_func
+ .section .note.GNU-stack,"",%progbits
diff --git a/gas/testsuite/gas/elf/pushsection-2a.d b/gas/testsuite/gas/elf/pushsection-2a.d
new file mode 100644
index 00000000000..c70eae05116
--- /dev/null
+++ b/gas/testsuite/gas/elf/pushsection-2a.d
@@ -0,0 +1,26 @@
+#source: pushsection-2.s
+#as: --sectname-subst
+#readelf: -SW
+# .pushsection always creates the named section, but the
+# test harness translates ".text" into "P" for the RX...
+#xfail: rx-*
+
+#...
+ \[..\] \.text\.foo0 +PROGBITS +[0-9a-f]+ [0-9a-f]+ [0-9a-f]+ 00 AX 0 0 +[1-9][0-9]*
+#...
+ \[..\] \.alt_section\.text\.foo0 +PROGBITS +[0-9a-f]+ [0-9a-f]+ [0-9a-f]+ 00 AX 0 0 +[1-9][0-9]*
+#...
+ \[..\] \.text\.foo1 +PROGBITS +[0-9a-f]+ [0-9a-f]+ [0-9a-f]+ 00 AX 0 0 +[1-9][0-9]*
+#...
+ \[..\] \.text\.foo2 +PROGBITS +[0-9a-f]+ [0-9a-f]+ [0-9a-f]+ 00 AX 0 0 +[1-9][0-9]*
+#...
+ \[..\] \.alt_section\.text\.foo2 +PROGBITS +[0-9a-f]+ [0-9a-f]+ [0-9a-f]+ 00 AX 0 0 +[1-9][0-9]*
+#...
+ \[..\] \.text\.foo3 +PROGBITS +[0-9a-f]+ [0-9a-f]+ [0-9a-f]+ 00 AX 0 0 +[1-9][0-9]*
+#...
+ \[..\] \.alt_section\.text\.foo3 +PROGBITS +[0-9a-f]+ [0-9a-f]+ [0-9a-f]+ 00 AX 0 0 +[1-9][0-9]*
+#...
+ \[..\] \.text\.entry_func +PROGBITS +[0-9a-f]+ [0-9a-f]+ [0-9a-f]+ 00 AX 0 0 +[1-9][0-9]*
+#...
+ \[..\] \.alt_section\.text\.entry_func +PROGBITS +[0-9a-f]+ [0-9a-f]+ [0-9a-f]+ 00 AX 0 0 +[1-9][0-9]*
+#pass
diff --git a/gas/testsuite/gas/elf/pushsection-2b.d b/gas/testsuite/gas/elf/pushsection-2b.d
new file mode 100644
index 00000000000..e95a09f67ba
--- /dev/null
+++ b/gas/testsuite/gas/elf/pushsection-2b.d
@@ -0,0 +1,26 @@
+#source: pushsection-2.s
+#as: --sectname-subst --unique-pushsection
+#readelf: -SW
+# .pushsection always creates the named section, but the
+# test harness translates ".text" into "P" for the RX...
+#xfail: rx-*
+
+#...
+ \[..\] \.text\.foo0 +PROGBITS +[0-9a-f]+ [0-9a-f]+ [0-9a-f]+ 00 AX 0 0 +[1-9][0-9]*
+#...
+ \[..\] \.alt_section\.text\.foo0\.text\.foo0 +PROGBITS +[0-9a-f]+ [0-9a-f]+ [0-9a-f]+ 00 AX 0 0 +[1-9][0-9]*
+#...
+ \[..\] \.text\.foo1 +PROGBITS +[0-9a-f]+ [0-9a-f]+ [0-9a-f]+ 00 AX 0 0 +[1-9][0-9]*
+#...
+ \[..\] \.text\.foo2 +PROGBITS +[0-9a-f]+ [0-9a-f]+ [0-9a-f]+ 00 AX 0 0 +[1-9][0-9]*
+#...
+ \[..\] \.alt_section\.text\.foo2\.text\.foo2 +PROGBITS +[0-9a-f]+ [0-9a-f]+ [0-9a-f]+ 00 AX 0 0 +[1-9][0-9]*
+#...
+ \[..\] \.text\.foo3 +PROGBITS +[0-9a-f]+ [0-9a-f]+ [0-9a-f]+ 00 AX 0 0 +[1-9][0-9]*
+#...
+ \[..\] \.alt_section\.text\.foo3\.text\.foo3 +PROGBITS +[0-9a-f]+ [0-9a-f]+ [0-9a-f]+ 00 AX 0 0 +[1-9][0-9]*
+#...
+ \[..\] \.text\.entry_func +PROGBITS +[0-9a-f]+ [0-9a-f]+ [0-9a-f]+ 00 AX 0 0 +[1-9][0-9]*
+#...
+ \[..\] \.alt_section\.text\.entry_func\.text\.entry_func +PROGBITS +[0-9a-f]+ [0-9a-f]+ [0-9a-f]+ 00 AX 0 0 +[1-9][0-9]*
+#pass
diff --git a/ld/testsuite/ld-elf/pushsection-1.d b/ld/testsuite/ld-elf/pushsection-1.d
new file mode 100644
index 00000000000..49c47282f6a
--- /dev/null
+++ b/ld/testsuite/ld-elf/pushsection-1.d
@@ -0,0 +1,13 @@
+#as: --unique-pushsection
+#ld: --gc-sections -e entry_func
+#nm: -n
+#xfail: [is_generic] fr30-*-* frv-*-elf ft32-*-* iq2000-*-* mn10200-*-*
+#xfail: msp430-* mt-*-* z80-*-*
+# Generic linker targets don't comply with all orhpan section merging
+# rules. z80 fails since a, b, c, d are registers for z80.
+
+#failif
+#...
+.* T foo2
+.* T foo3
+#...
diff --git a/ld/testsuite/ld-elf/pushsection-1.s b/ld/testsuite/ld-elf/pushsection-1.s
new file mode 100644
index 00000000000..d0196ab7b1a
--- /dev/null
+++ b/ld/testsuite/ld-elf/pushsection-1.s
@@ -0,0 +1,60 @@
+ .section .text.foo0,"ax",%progbits
+ .p2align 4
+ .globl foo0
+ .type foo0, %function
+foo0:
+ .dc.a 1f
+ .pushsection .alt_section, "ax"
+1:
+ .dc.a .L0
+ .popsection
+.L0:
+ .dc.a 0
+ .size foo0, .-foo0
+ .section .text.foo1,"ax",%progbits
+ .p2align 4
+ .globl foo1
+ .type foo1, %function
+foo1:
+ .dc.a 0
+ .size foo1, .-foo1
+ .section .text.foo2,"ax",%progbits
+ .p2align 4
+ .globl foo2
+ .type foo2, %function
+foo2:
+ .dc.a 1f
+ .pushsection .alt_section, "ax"
+1:
+ .dc.a .L4
+ .popsection
+.L4:
+ .dc.a 0
+ .size foo2, .-foo2
+ .section .text.foo3,"ax",%progbits
+ .p2align 4
+ .globl foo3
+ .type foo3, %function
+foo3:
+ .dc.a 1f
+ .pushsection .alt_section, "ax"
+1:
+ .dc.a .L7
+ .popsection
+.L7:
+ .dc.a 0
+ .size foo3, .-foo3
+ .section .text.entry_func,"ax",%progbits
+ .p2align 4
+ .globl entry_func
+ .type entry_func, %function
+entry_func:
+ .dc.a 1f
+ .pushsection .alt_section, "ax"
+1:
+ .dc.a .L10
+ .popsection
+.L10:
+ .dc.a foo0
+ .size entry_func, .-entry_func
+ .section .note.GNU-stack,"",%progbits
diff --git a/ld/testsuite/ld-elf/pushsection-2.s b/ld/testsuite/ld-elf/pushsection-2.s
new file mode 100644
index 00000000000..d78d603e3d0
--- /dev/null
+++ b/ld/testsuite/ld-elf/pushsection-2.s
@@ -0,0 +1,60 @@
+ .section .text.foo0,"ax",%progbits
+ .p2align 4
+ .globl foo0
+ .type foo0, %function
+foo0:
+ .dc.a 1f
+ .pushsection .alt_section%S, "ax"
+1:
+ .dc.a .L0
+ .popsection
+.L0:
+ .dc.a 0
+ .size foo0, .-foo0
+ .section .text.foo1,"ax",%progbits
+ .p2align 4
+ .globl foo1
+ .type foo1, %function
+foo1:
+ .dc.a 0
+ .size foo1, .-foo1
+ .section .text.foo2,"ax",%progbits
+ .p2align 4
+ .globl foo2
+ .type foo2, %function
+foo2:
+ .dc.a 1f
+ .pushsection .alt_section%S, "ax"
+1:
+ .dc.a .L4
+ .popsection
+.L4:
+ .dc.a 0
+ .size foo2, .-foo2
+ .section .text.foo3,"ax",%progbits
+ .p2align 4
+ .globl foo3
+ .type foo3, %function
+foo3:
+ .dc.a 1f
+ .pushsection .alt_section%S, "ax"
+1:
+ .dc.a .L7
+ .popsection
+.L7:
+ .dc.a 0
+ .size foo3, .-foo3
+ .section .text.entry_func,"ax",%progbits
+ .p2align 4
+ .globl entry_func
+ .type entry_func, %function
+entry_func:
+ .dc.a 1f
+ .pushsection .alt_section%S, "ax"
+1:
+ .dc.a .L10
+ .popsection
+.L10:
+ .dc.a foo0
+ .size entry_func, .-entry_func
+ .section .note.GNU-stack,"",%progbits
diff --git a/ld/testsuite/ld-elf/pushsection-2a.d b/ld/testsuite/ld-elf/pushsection-2a.d
new file mode 100644
index 00000000000..efedc35aeb4
--- /dev/null
+++ b/ld/testsuite/ld-elf/pushsection-2a.d
@@ -0,0 +1,14 @@
+#source: pushsection-2.s
+#as: --sectname-subst
+#ld: --gc-sections -e entry_func
+#nm: -n
+#xfail: [is_generic] fr30-*-* frv-*-elf ft32-*-* iq2000-*-* mn10200-*-*
+#xfail: msp430-* mt-*-* z80-*-*
+# Generic linker targets don't comply with all orhpan section merging
+# rules. z80 fails since a, b, c, d are registers for z80.
+
+#failif
+#...
+.* T foo2
+.* T foo3
+#...
diff --git a/ld/testsuite/ld-elf/pushsection-2b.d b/ld/testsuite/ld-elf/pushsection-2b.d
new file mode 100644
index 00000000000..dd475f90b2e
--- /dev/null
+++ b/ld/testsuite/ld-elf/pushsection-2b.d
@@ -0,0 +1,14 @@
+#source: pushsection-2.s
+#as: --sectname-subst --unique-pushsection
+#ld: --gc-sections -e entry_func
+#nm: -n
+#xfail: [is_generic] fr30-*-* frv-*-elf ft32-*-* iq2000-*-* mn10200-*-*
+#xfail: msp430-* mt-*-* z80-*-*
+# Generic linker targets don't comply with all orhpan section merging
+# rules. z80 fails since a, b, c, d are registers for z80.
+
+#failif
+#...
+.* T foo2
+.* T foo3
+#...
diff --git a/ld/testsuite/ld-elf/pushsection-3.d b/ld/testsuite/ld-elf/pushsection-3.d
new file mode 100644
index 00000000000..49c47282f6a
--- /dev/null
+++ b/ld/testsuite/ld-elf/pushsection-3.d
@@ -0,0 +1,13 @@
+#as: --unique-pushsection
+#ld: --gc-sections -e entry_func
+#nm: -n
+#xfail: [is_generic] fr30-*-* frv-*-elf ft32-*-* iq2000-*-* mn10200-*-*
+#xfail: msp430-* mt-*-* z80-*-*
+# Generic linker targets don't comply with all orhpan section merging
+# rules. z80 fails since a, b, c, d are registers for z80.
+
+#failif
+#...
+.* T foo2
+.* T foo3
+#...
diff --git a/ld/testsuite/ld-elf/pushsection-3.s b/ld/testsuite/ld-elf/pushsection-3.s
new file mode 100644
index 00000000000..7909714dbd4
--- /dev/null
+++ b/ld/testsuite/ld-elf/pushsection-3.s
@@ -0,0 +1,90 @@
+ .section .text.foo0,"ax",%progbits
+ .p2align 4
+ .globl foo0
+ .section __patchable_function_entries,"awo",%progbits,.LPFE1
+ .p2align 3
+ .dc.a .LPFE0
+ .section .text.foo0
+.LPFE0:
+ .dc.a 0
+ .type foo0, %function
+foo0:
+ .dc.a 1f
+ .pushsection .alt_section, "ax"
+1:
+ .dc.a .L0
+ .popsection
+.L0:
+ .dc.a 0
+ .size foo0, .-foo0
+ .section .text.foo1,"ax",%progbits
+ .p2align 4
+ .globl foo1
+ .section __patchable_function_entries,"awo",%progbits,.LPFE1
+ .p2align 3
+ .dc.a .LPFE1
+ .section .text.foo1
+.LPFE1:
+ .dc.a 0
+ .type foo1, %function
+foo1:
+ .dc.a 0
+ .size foo1, .-foo1
+ .section .text.foo2,"ax",%progbits
+ .p2align 4
+ .globl foo2
+ .section __patchable_function_entries,"awo",%progbits,.LPFE2
+ .p2align 3
+ .dc.a .LPFE2
+ .section .text.foo2
+.LPFE2:
+ .dc.a 0
+ .type foo2, %function
+foo2:
+ .dc.a 1f
+ .pushsection .alt_section, "ax"
+1:
+ .dc.a .L4
+ .popsection
+.L4:
+ .dc.a 0
+ .size foo2, .-foo2
+ .section .text.foo3,"ax",%progbits
+ .p2align 4
+ .globl foo3
+ .section __patchable_function_entries,"awo",%progbits,.LPFE3
+ .p2align 3
+ .dc.a .LPFE3
+ .section .text.foo3
+.LPFE3:
+ .dc.a 0
+ .type foo3, %function
+foo3:
+ .dc.a 1f
+ .pushsection .alt_section, "ax"
+1:
+ .dc.a .L7
+ .popsection
+.L7:
+ .dc.a 0
+ .size foo3, .-foo3
+ .section .text.entry_func,"ax",%progbits
+ .p2align 4
+ .globl entry_func
+ .section __patchable_function_entries,"awo",%progbits,.LPFE4
+ .p2align 3
+ .dc.a .LPFE4
+ .section .text.entry_func
+.LPFE4:
+ .dc.a 0
+ .type entry_func, %function
+entry_func:
+ .dc.a 1f
+ .pushsection .alt_section, "ax"
+1:
+ .dc.a .L10
+ .popsection
+.L10:
+ .dc.a foo0
+ .size entry_func, .-entry_func
+ .section .note.GNU-stack,"",%progbits
diff --git a/ld/testsuite/ld-elf/pushsection-4.s b/ld/testsuite/ld-elf/pushsection-4.s
new file mode 100644
index 00000000000..5ffe2983a9a
--- /dev/null
+++ b/ld/testsuite/ld-elf/pushsection-4.s
@@ -0,0 +1,90 @@
+ .section .text.foo0,"ax",%progbits
+ .p2align 4
+ .globl foo0
+ .section __patchable_function_entries,"awo",%progbits,.LPFE1
+ .p2align 3
+ .dc.a .LPFE0
+ .section .text.foo0
+.LPFE0:
+ .dc.a 0
+ .type foo0, %function
+foo0:
+ .dc.a 1f
+ .pushsection .alt_section%S, "ax"
+1:
+ .dc.a .L0
+ .popsection
+.L0:
+ .dc.a 0
+ .size foo0, .-foo0
+ .section .text.foo1,"ax",%progbits
+ .p2align 4
+ .globl foo1
+ .section __patchable_function_entries,"awo",%progbits,.LPFE1
+ .p2align 3
+ .dc.a .LPFE1
+ .section .text.foo1
+.LPFE1:
+ .dc.a 0
+ .type foo1, %function
+foo1:
+ .dc.a 0
+ .size foo1, .-foo1
+ .section .text.foo2,"ax",%progbits
+ .p2align 4
+ .globl foo2
+ .section __patchable_function_entries,"awo",%progbits,.LPFE2
+ .p2align 3
+ .dc.a .LPFE2
+ .section .text.foo2
+.LPFE2:
+ .dc.a 0
+ .type foo2, %function
+foo2:
+ .dc.a 1f
+ .pushsection .alt_section%S, "ax"
+1:
+ .dc.a .L4
+ .popsection
+.L4:
+ .dc.a 0
+ .size foo2, .-foo2
+ .section .text.foo3,"ax",%progbits
+ .p2align 4
+ .globl foo3
+ .section __patchable_function_entries,"awo",%progbits,.LPFE3
+ .p2align 3
+ .dc.a .LPFE3
+ .section .text.foo3
+.LPFE3:
+ .dc.a 0
+ .type foo3, %function
+foo3:
+ .dc.a 1f
+ .pushsection .alt_section%S, "ax"
+1:
+ .dc.a .L7
+ .popsection
+.L7:
+ .dc.a 0
+ .size foo3, .-foo3
+ .section .text.entry_func,"ax",%progbits
+ .p2align 4
+ .globl entry_func
+ .section __patchable_function_entries,"awo",%progbits,.LPFE4
+ .p2align 3
+ .dc.a .LPFE4
+ .section .text.entry_func
+.LPFE4:
+ .dc.a 0
+ .type entry_func, %function
+entry_func:
+ .dc.a 1f
+ .pushsection .alt_section%S, "ax"
+1:
+ .dc.a .L10
+ .popsection
+.L10:
+ .dc.a foo0
+ .size entry_func, .-entry_func
+ .section .note.GNU-stack,"",%progbits
diff --git a/ld/testsuite/ld-elf/pushsection-4a.d b/ld/testsuite/ld-elf/pushsection-4a.d
new file mode 100644
index 00000000000..9d3155369f7
--- /dev/null
+++ b/ld/testsuite/ld-elf/pushsection-4a.d
@@ -0,0 +1,14 @@
+#source: pushsection-4.s
+#as: --sectname-subst
+#ld: --gc-sections -e entry_func
+#nm: -n
+#xfail: [is_generic] fr30-*-* frv-*-elf ft32-*-* iq2000-*-* mn10200-*-*
+#xfail: msp430-* mt-*-* z80-*-*
+# Generic linker targets don't comply with all orhpan section merging
+# rules. z80 fails since a, b, c, d are registers for z80.
+
+#failif
+#...
+.* T foo2
+.* T foo3
+#...
diff --git a/ld/testsuite/ld-elf/pushsection-4b.d b/ld/testsuite/ld-elf/pushsection-4b.d
new file mode 100644
index 00000000000..a0f5ae93a9f
--- /dev/null
+++ b/ld/testsuite/ld-elf/pushsection-4b.d
@@ -0,0 +1,14 @@
+#source: pushsection-4.s
+#as: --sectname-subst --unique-pushsection
+#ld: --gc-sections -e entry_func
+#nm: -n
+#xfail: [is_generic] fr30-*-* frv-*-elf ft32-*-* iq2000-*-* mn10200-*-*
+#xfail: msp430-* mt-*-* z80-*-*
+# Generic linker targets don't comply with all orhpan section merging
+# rules. z80 fails since a, b, c, d are registers for z80.
+
+#failif
+#...
+.* T foo2
+.* T foo3
+#...
--
2.49.0
More information about the Binutils
mailing list