aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIlya Leoshkevich <iii@linux.ibm.com>2023-12-07 13:08:27 +0100
committerIlya Leoshkevich <iii@linux.ibm.com>2024-01-05 12:24:01 +0100
commite66dc37b299cac4171b1c5b90cf6b54388bd5bc5 (patch)
treeff5a38a90075021d3262b0b4a536ba23b7665b33
parentc659dd8bfb55e02a1b97407c1c28f7a0e8f7f09b (diff)
downloadgcc-e66dc37b299cac4171b1c5b90cf6b54388bd5bc5.zip
gcc-e66dc37b299cac4171b1c5b90cf6b54388bd5bc5.tar.gz
gcc-e66dc37b299cac4171b1c5b90cf6b54388bd5bc5.tar.bz2
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.
-rw-r--r--gcc/asan.cc6
-rw-r--r--gcc/config/i386/i386.cc2
-rw-r--r--gcc/config/s390/s390.cc2
-rw-r--r--gcc/defaults.h2
-rw-r--r--gcc/final.cc3
-rw-r--r--gcc/output.h4
-rw-r--r--gcc/varasm.cc14
7 files changed, 23 insertions, 10 deletions
diff --git a/gcc/asan.cc b/gcc/asan.cc
index 307d2fc..0fd7dd1 100644
--- a/gcc/asan.cc
+++ b/gcc/asan.cc
@@ -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),
diff --git a/gcc/config/i386/i386.cc b/gcc/config/i386/i386.cc
index e3636e1..8010532 100644
--- a/gcc/config/i386/i386.cc
+++ b/gcc/config/i386/i386.cc
@@ -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)
diff --git a/gcc/config/s390/s390.cc b/gcc/config/s390/s390.cc
index 116fdc6..748ad9c 100644
--- a/gcc/config/s390/s390.cc
+++ b/gcc/config/s390/s390.cc
@@ -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",
diff --git a/gcc/defaults.h b/gcc/defaults.h
index 71c6a69..92f3e07 100644
--- a/gcc/defaults.h
+++ b/gcc/defaults.h
@@ -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. */
diff --git a/gcc/final.cc b/gcc/final.cc
index 638e5c1..eb9e065 100644
--- a/gcc/final.cc
+++ b/gcc/final.cc
@@ -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))
{
diff --git a/gcc/output.h b/gcc/output.h
index bb28f19..c8fe1d2 100644
--- a/gcc/output.h
+++ b/gcc/output.h
@@ -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
diff --git a/gcc/varasm.cc b/gcc/varasm.cc
index 29ac8b1..25c1e05 100644
--- a/gcc/varasm.cc
+++ b/gcc/varasm.cc
@@ -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