Use the section flag 'o' for __patchable_function_entries
This commit in GNU binutils 2.35: https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;a=commit;h=b7d072167715829eed0622616f6ae0182900de3e added the section flag 'o' to .section directive: .section __patchable_function_entries,"awo",@progbits,foo which specifies the symbol name which the section references. Assembler creates a unique __patchable_function_entries section with the section, where foo is defined, as its linked-to section. Linker keeps a section if its linked-to section is kept during garbage collection. This patch checks assembler support for the section flag 'o' and uses it to implement __patchable_function_entries section. Since Solaris may use GNU assembler with Solairs ld. Even if GNU assembler supports the section flag 'o', it doesn't mean that Solairs ld supports it. This feature is disabled for Solairs targets. gcc/ PR middle-end/93195 PR middle-end/93197 * configure.ac (HAVE_GAS_SECTION_LINK_ORDER): New. Define 1 if the assembler supports the section flag 'o' for specifying section with link-order. * output.h (SECTION_LINK_ORDER): New. Defined to 0x8000000. (SECTION_MACH_DEP): Changed from 0x8000000 to 0x10000000. * targhooks.c (default_print_patchable_function_entry): Pass SECTION_LINK_ORDER to switch_to_section if the section flag 'o' works. Pass current_function_decl to switch_to_section. * varasm.c (default_elf_asm_named_section): Use 'o' flag for SECTION_LINK_ORDER if assembler supports it. * config.in: Regenerated. * configure: Likewise. * doc/sourcebuild.texi: Document o_flag_in_section. gcc/testsuite/ PR middle-end/93195 * g++.dg/pr93195a.C: New test. * g++.dg/pr93195b.C: Likewise. * lib/target-supports.exp (check_effective_target_o_flag_in_section): New proc.
This commit is contained in:
parent
a1ebd4f9f7
commit
694d4a6d0c
@ -1386,6 +1386,12 @@
|
||||
#endif
|
||||
|
||||
|
||||
/* Define 0/1 if your assembler supports 'o' flag in .section directive. */
|
||||
#ifndef USED_FOR_TARGET
|
||||
#undef HAVE_GAS_SECTION_LINK_ORDER
|
||||
#endif
|
||||
|
||||
|
||||
/* Define 0/1 if your assembler supports marking sections with SHF_GNU_RETAIN
|
||||
flag. */
|
||||
#ifndef USED_FOR_TARGET
|
||||
|
52
gcc/configure
vendored
52
gcc/configure
vendored
@ -24481,6 +24481,58 @@ cat >>confdefs.h <<_ACEOF
|
||||
_ACEOF
|
||||
|
||||
|
||||
# Test if the assembler supports the section flag 'o' for specifying
|
||||
# section with link-order.
|
||||
case "${target}" in
|
||||
# Solaris may use GNU assembler with Solairs ld. Even if GNU
|
||||
# assembler supports the section flag 'o', it doesn't mean that
|
||||
# Solairs ld supports it.
|
||||
*-*-solaris2*)
|
||||
gcc_cv_as_section_link_order=no
|
||||
;;
|
||||
*)
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for section 'o' flag" >&5
|
||||
$as_echo_n "checking assembler for section 'o' flag... " >&6; }
|
||||
if ${gcc_cv_as_section_link_order+:} false; then :
|
||||
$as_echo_n "(cached) " >&6
|
||||
else
|
||||
gcc_cv_as_section_link_order=no
|
||||
if test $in_tree_gas = yes; then
|
||||
if test $gcc_cv_gas_vers -ge `expr \( \( 2 \* 1000 \) + 35 \) \* 1000 + 0`
|
||||
then gcc_cv_as_section_link_order=yes
|
||||
fi
|
||||
elif test x$gcc_cv_as != x; then
|
||||
$as_echo '.section .foo,"a"
|
||||
.byte 0
|
||||
.section __patchable_function_entries,"awo",%progbits,.foo
|
||||
.byte 0' > conftest.s
|
||||
if { ac_try='$gcc_cv_as $gcc_cv_as_flags --fatal-warnings -o conftest.o conftest.s >&5'
|
||||
{ { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
|
||||
(eval $ac_try) 2>&5
|
||||
ac_status=$?
|
||||
$as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
|
||||
test $ac_status = 0; }; }
|
||||
then
|
||||
gcc_cv_as_section_link_order=yes
|
||||
else
|
||||
echo "configure: failed program was" >&5
|
||||
cat conftest.s >&5
|
||||
fi
|
||||
rm -f conftest.o conftest.s
|
||||
fi
|
||||
fi
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_as_section_link_order" >&5
|
||||
$as_echo "$gcc_cv_as_section_link_order" >&6; }
|
||||
|
||||
|
||||
;;
|
||||
esac
|
||||
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
#define HAVE_GAS_SECTION_LINK_ORDER `if test $gcc_cv_as_section_link_order = yes; then echo 1; else echo 0; fi`
|
||||
_ACEOF
|
||||
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for section merging support" >&5
|
||||
$as_echo_n "checking assembler for section merging support... " >&6; }
|
||||
if ${gcc_cv_as_shf_merge+:} false; then :
|
||||
|
@ -3350,6 +3350,28 @@ AC_DEFINE_UNQUOTED(HAVE_GAS_SHF_GNU_RETAIN,
|
||||
[`if test $gcc_cv_as_shf_gnu_retain = yes; then echo 1; else echo 0; fi`],
|
||||
[Define 0/1 if your assembler supports marking sections with SHF_GNU_RETAIN flag.])
|
||||
|
||||
# Test if the assembler supports the section flag 'o' for specifying
|
||||
# section with link-order.
|
||||
case "${target}" in
|
||||
# Solaris may use GNU assembler with Solairs ld. Even if GNU
|
||||
# assembler supports the section flag 'o', it doesn't mean that
|
||||
# Solairs ld supports it.
|
||||
*-*-solaris2*)
|
||||
gcc_cv_as_section_link_order=no
|
||||
;;
|
||||
*)
|
||||
gcc_GAS_CHECK_FEATURE([section 'o' flag], gcc_cv_as_section_link_order,
|
||||
[2,35,0], [--fatal-warnings],
|
||||
[.section .foo,"a"
|
||||
.byte 0
|
||||
.section __patchable_function_entries,"awo",%progbits,.foo
|
||||
.byte 0])
|
||||
;;
|
||||
esac
|
||||
AC_DEFINE_UNQUOTED(HAVE_GAS_SECTION_LINK_ORDER,
|
||||
[`if test $gcc_cv_as_section_link_order = yes; then echo 1; else echo 0; fi`],
|
||||
[Define 0/1 if your assembler supports 'o' flag in .section directive.])
|
||||
|
||||
gcc_GAS_CHECK_FEATURE(section merging support, gcc_cv_as_shf_merge,
|
||||
[elf,2,12,0], [--fatal-warnings],
|
||||
[.section .rodata.str, "aMS", @progbits, 1])
|
||||
|
@ -2548,6 +2548,9 @@ Target supports the @code{noinit} variable attribute.
|
||||
@item nonpic
|
||||
Target does not generate PIC by default.
|
||||
|
||||
@item o_flag_in_section
|
||||
Target supports the 'o' flag in .section directive in assembly inputs.
|
||||
|
||||
@item offload_gcn
|
||||
Target has been configured for OpenACC/OpenMP offloading on AMD GCN.
|
||||
|
||||
|
@ -382,10 +382,11 @@ extern void no_asm_to_stream (FILE *);
|
||||
#define SECTION_RELRO 0x1000000 /* data is readonly after relocation processing */
|
||||
#define SECTION_EXCLUDE 0x2000000 /* discarded by the linker */
|
||||
#define SECTION_RETAIN 0x4000000 /* retained by the linker. */
|
||||
#define SECTION_LINK_ORDER 0x8000000 /* section needs link-order. */
|
||||
|
||||
/* NB: The maximum SECTION_MACH_DEP is 0x10000000 since AVR needs 4 bits
|
||||
in SECTION_MACH_DEP. */
|
||||
#define SECTION_MACH_DEP 0x8000000 /* subsequent bits reserved for target */
|
||||
#define SECTION_MACH_DEP 0x10000000 /* subsequent bits reserved for target */
|
||||
|
||||
/* This SECTION_STYLE is used for unnamed sections that we can switch
|
||||
to using a special assembler directive. */
|
||||
|
@ -1864,8 +1864,11 @@ default_print_patchable_function_entry (FILE *file,
|
||||
patch_area_number++;
|
||||
ASM_GENERATE_INTERNAL_LABEL (buf, "LPFE", patch_area_number);
|
||||
|
||||
unsigned int flags = SECTION_WRITE | SECTION_RELRO;
|
||||
if (HAVE_GAS_SECTION_LINK_ORDER)
|
||||
flags |= SECTION_LINK_ORDER;
|
||||
switch_to_section (get_section ("__patchable_function_entries",
|
||||
SECTION_WRITE | SECTION_RELRO, NULL));
|
||||
flags, current_function_decl));
|
||||
assemble_align (POINTER_SIZE);
|
||||
fputs (asm_op, file);
|
||||
assemble_name_raw (file, buf);
|
||||
|
27
gcc/testsuite/g++.dg/pr93195a.C
Normal file
27
gcc/testsuite/g++.dg/pr93195a.C
Normal file
@ -0,0 +1,27 @@
|
||||
/* { dg-do link { target { ! { nvptx*-*-* visium-*-* } } } } */
|
||||
// { dg-require-effective-target o_flag_in_section }
|
||||
/* { dg-options "-O0 -fpatchable-function-entry=1" } */
|
||||
/* { dg-additional-options "-fno-pie" { target sparc*-*-* } } */
|
||||
/* { dg-additional-sources pr93195b.C } */
|
||||
|
||||
extern void bar1 (void);
|
||||
|
||||
inline void
|
||||
foo (void)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
bar (void)
|
||||
{
|
||||
foo ();
|
||||
bar1 ();
|
||||
}
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
bar ();
|
||||
return 0;
|
||||
}
|
||||
|
14
gcc/testsuite/g++.dg/pr93195b.C
Normal file
14
gcc/testsuite/g++.dg/pr93195b.C
Normal file
@ -0,0 +1,14 @@
|
||||
/* { dg-do compile { target { ! { nvptx*-*-* visium-*-* } } } } */
|
||||
/* { dg-options "-O0 -fpatchable-function-entry=1" } */
|
||||
/* { dg-additional-options "-fno-pie" { target sparc*-*-* } } */
|
||||
|
||||
inline void
|
||||
foo (void)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
bar1 (void)
|
||||
{
|
||||
foo ();
|
||||
}
|
@ -10702,3 +10702,43 @@ proc check_effective_target_R_flag_in_section { } {
|
||||
}
|
||||
}]
|
||||
}
|
||||
|
||||
# Return 1 if this target supports 'o' flag in .section directive, 0
|
||||
# otherwise. Cache the result.
|
||||
|
||||
proc check_effective_target_o_flag_in_section { } {
|
||||
global tool
|
||||
global GCC_UNDER_TEST
|
||||
|
||||
# Need auto-host.h to check linker support.
|
||||
if { ![file exists ../../auto-host.h ] } {
|
||||
return 0
|
||||
}
|
||||
|
||||
return [check_cached_effective_target o_flag_in_section {
|
||||
|
||||
set src pie[pid].c
|
||||
set obj pie[pid].o
|
||||
|
||||
set f [open $src "w"]
|
||||
puts $f "#include \"../../auto-host.h\""
|
||||
puts $f "#if HAVE_GAS_SECTION_LINK_ORDER == 0"
|
||||
puts $f "# error Assembler does not support 'o' flag in .section directive."
|
||||
puts $f "#endif"
|
||||
close $f
|
||||
|
||||
verbose "check_effective_target_o_flag_in_section compiling testfile $src" 2
|
||||
set lines [${tool}_target_compile $src $obj object ""]
|
||||
|
||||
file delete $src
|
||||
file delete $obj
|
||||
|
||||
if [string match "" $lines] then {
|
||||
verbose "check_effective_target_o_flag_in_section testfile compilation passed" 2
|
||||
return 1
|
||||
} else {
|
||||
verbose "check_effective_target_o_flag_in_section testfile compilation failed" 2
|
||||
return 0
|
||||
}
|
||||
}]
|
||||
}
|
||||
|
10
gcc/varasm.c
10
gcc/varasm.c
@ -6789,6 +6789,8 @@ default_elf_asm_named_section (const char *name, unsigned int flags,
|
||||
*f++ = 'G';
|
||||
if (flags & SECTION_RETAIN)
|
||||
*f++ = 'R';
|
||||
if (flags & SECTION_LINK_ORDER)
|
||||
*f++ = 'o';
|
||||
#ifdef MACH_DEP_SECTION_ASM_FLAG
|
||||
if (flags & SECTION_MACH_DEP)
|
||||
*f++ = MACH_DEP_SECTION_ASM_FLAG;
|
||||
@ -6821,6 +6823,14 @@ default_elf_asm_named_section (const char *name, unsigned int flags,
|
||||
|
||||
if (flags & SECTION_ENTSIZE)
|
||||
fprintf (asm_out_file, ",%d", flags & SECTION_ENTSIZE);
|
||||
if (flags & SECTION_LINK_ORDER)
|
||||
{
|
||||
tree id = DECL_ASSEMBLER_NAME (decl);
|
||||
ultimate_transparent_alias_target (&id);
|
||||
const char *name = IDENTIFIER_POINTER (id);
|
||||
name = targetm.strip_name_encoding (name);
|
||||
fprintf (asm_out_file, ",%s", name);
|
||||
}
|
||||
if (HAVE_COMDAT_GROUP && (flags & SECTION_LINKONCE))
|
||||
{
|
||||
if (TREE_CODE (decl) == IDENTIFIER_NODE)
|
||||
|
Loading…
Reference in New Issue
Block a user