]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
asan: Align .LASANPC on function boundary
authorIlya Leoshkevich <iii@linux.ibm.com>
Thu, 7 Dec 2023 12:08:27 +0000 (13:08 +0100)
committerIlya Leoshkevich <iii@linux.ibm.com>
Fri, 5 Jan 2024 11:24:01 +0000 (12:24 +0100)
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.

gcc/asan.cc
gcc/config/i386/i386.cc
gcc/config/s390/s390.cc
gcc/defaults.h
gcc/final.cc
gcc/output.h
gcc/varasm.cc

index 307d2fc12a59e1790fd07752aa86aab85bc34115..0fd7dd1f3ed4c598559534657f9d794315374002 100644 (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),
index e3636e115def3ed89754b90f11cea3ce1a58a41c..80105322fa522e926385a64d53cc1eb7641baca2 100644 (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)
index 116fdc600b5ceac9b30d594d55c9b74adac5dbf0..748ad9cd932ea1cb217c87ad160491d3a8f6c67b 100644 (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",
index 71c6a69a251114f2c91b7ef2971c005246599f0a..92f3e07f742f641a4711ed9d0f16dba531450042 100644 (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.  */
index 638e5c14eff5d7b56a9d7b0221b7c5a3a1191fbc..eb9e065d9f0a35121ec22395e467c29049070657 100644 (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))
     {
index bb28f19e29ccf16879ae4d9938219f2c58e6dd43..c8fe1d2643d9067656b2638acbd147fd01dbaa57 100644 (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
index 29ac8b143b40d3cc141f438d485d9471a3f44ac1..25c1e05628d9108b221a41d27a03505a08e7e87d 100644 (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