asan: Align .LASANPC on function boundary

GCC can emit code between the function label and the .LASANPC label,
making the latter unaligned.  Some architectures cannot load unaligned
labels directly and require literal pool entries, which is inefficient.

Move the invocation of asan_function_start to
ASM_OUTPUT_FUNCTION_LABEL, which guarantees that no additional code is
emitted.  This allows setting the .LASANPC label alignment to the
respective function alignment.

Link: https://inbox.sourceware.org/gcc-patches/20240102194511.3171559-3-iii@linux.ibm.com/
Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>

gcc/ChangeLog:

	* asan.cc (asan_function_start): Drop switch_to_section ().
	(asan_emit_stack_protection): Set .LASANPC alignment.
	* config/i386/i386.cc: Use assemble_function_label_raw ()
	instead of ASM_OUTPUT_LABEL ().
	* config/s390/s390.cc (s390_asm_output_function_label):
	Likewise.
	* defaults.h (ASM_OUTPUT_FUNCTION_LABEL): Likewise.
	* final.cc (final_start_function_1): Drop
	asan_function_start ().
	* output.h (assemble_function_label_raw): New function.
	* varasm.cc (assemble_function_label_raw): Likewise.
This commit is contained in:
Ilya Leoshkevich 2023-12-07 13:08:27 +01:00
parent c659dd8bfb
commit e66dc37b29
7 changed files with 23 additions and 10 deletions

View file

@ -1481,10 +1481,7 @@ asan_clear_shadow (rtx shadow_mem, HOST_WIDE_INT len)
void
asan_function_start (void)
{
section *fnsec = function_section (current_function_decl);
switch_to_section (fnsec);
ASM_OUTPUT_DEBUG_LABEL (asm_out_file, "LASANPC",
current_function_funcdef_no);
ASM_OUTPUT_DEBUG_LABEL (asm_out_file, "LASANPC", current_function_funcdef_no);
}
/* Return number of shadow bytes that are occupied by a local variable
@ -2006,6 +2003,7 @@ asan_emit_stack_protection (rtx base, rtx pbase, unsigned int alignb,
DECL_INITIAL (decl) = decl;
TREE_ASM_WRITTEN (decl) = 1;
TREE_ASM_WRITTEN (id) = 1;
DECL_ALIGN_RAW (decl) = DECL_ALIGN_RAW (current_function_decl);
emit_move_insn (mem, expand_normal (build_fold_addr_expr (decl)));
shadow_base = expand_binop (Pmode, lshr_optab, base,
gen_int_shift_amount (Pmode, ASAN_SHADOW_SHIFT),

View file

@ -1640,7 +1640,7 @@ ix86_asm_output_function_label (FILE *out_file, const char *fname,
SUBTARGET_ASM_UNWIND_INIT (out_file);
#endif
ASM_OUTPUT_LABEL (out_file, fname);
assemble_function_label_raw (out_file, fname);
/* Output magic byte marker, if hot-patch attribute is set. */
if (is_ms_hook)

View file

@ -8323,7 +8323,7 @@ s390_asm_output_function_label (FILE *out_file, const char *fname,
asm_fprintf (out_file, "\t# fn:%s wd%d\n", fname,
s390_warn_dynamicstack_p);
}
ASM_OUTPUT_LABEL (out_file, fname);
assemble_function_label_raw (out_file, fname);
if (hw_after > 0)
asm_fprintf (out_file,
"\t# post-label NOPs for hotpatch (%d halfwords)\n",

View file

@ -150,7 +150,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
#ifndef ASM_OUTPUT_FUNCTION_LABEL
#define ASM_OUTPUT_FUNCTION_LABEL(FILE, NAME, DECL) \
ASM_OUTPUT_LABEL ((FILE), (NAME))
assemble_function_label_raw ((FILE), (NAME))
#endif
/* Output the definition of a compiler-generated label named NAME. */

View file

@ -1686,9 +1686,6 @@ final_start_function_1 (rtx_insn **firstp, FILE *file, int *seen,
high_block_linenum = high_function_linenum = last_linenum;
if (flag_sanitize & SANITIZE_ADDRESS)
asan_function_start ();
rtx_insn *first = *firstp;
if (in_initial_view_p (first))
{

View file

@ -178,6 +178,10 @@ extern void assemble_asm (tree);
/* Get the function's name from a decl, as described by its RTL. */
extern const char *get_fnname_from_decl (tree);
/* Output function label, possibly with accompanying metadata. No additional
code or data is output after the label. */
extern void assemble_function_label_raw (FILE *, const char *);
/* Output assembler code for the constant pool of a function and associated
with defining the name of the function. DECL describes the function.
NAME is the function's name. For the constant pool, we use the current

View file

@ -61,6 +61,7 @@ along with GCC; see the file COPYING3. If not see
#include "alloc-pool.h"
#include "toplev.h"
#include "opts.h"
#include "asan.h"
/* The (assembler) name of the first globally-visible object output. */
extern GTY(()) const char *first_global_object_name;
@ -1835,6 +1836,19 @@ get_fnname_from_decl (tree decl)
return XSTR (x, 0);
}
/* Output function label, possibly with accompanying metadata. No additional
code or data is output after the label. */
void
assemble_function_label_raw (FILE *file, const char *name)
{
ASM_OUTPUT_LABEL (file, name);
if ((flag_sanitize & SANITIZE_ADDRESS)
/* Notify ASAN only about the first function label. */
&& (in_cold_section_p == first_function_block_is_cold))
asan_function_start ();
}
/* Output assembler code for the constant pool of a function and associated
with defining the name of the function. DECL describes the function.
NAME is the function's name. For the constant pool, we use the current