(root)/
gcc-13.2.0/
gcc/
asan.h
       1  /* AddressSanitizer, a fast memory error detector.
       2     Copyright (C) 2011-2023 Free Software Foundation, Inc.
       3     Contributed by Kostya Serebryany <kcc@google.com>
       4  
       5  This file is part of GCC.
       6  
       7  GCC is free software; you can redistribute it and/or modify it under
       8  the terms of the GNU General Public License as published by the Free
       9  Software Foundation; either version 3, or (at your option) any later
      10  version.
      11  
      12  GCC is distributed in the hope that it will be useful, but WITHOUT ANY
      13  WARRANTY; without even the implied warranty of MERCHANTABILITY or
      14  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
      15  for more details.
      16  
      17  You should have received a copy of the GNU General Public License
      18  along with GCC; see the file COPYING3.  If not see
      19  <http://www.gnu.org/licenses/>.  */
      20  
      21  #ifndef TREE_ASAN
      22  #define TREE_ASAN
      23  
      24  extern void asan_function_start (void);
      25  extern void asan_finish_file (void);
      26  extern rtx_insn *asan_emit_stack_protection (rtx, rtx, unsigned int,
      27  					     HOST_WIDE_INT *, tree *, int);
      28  extern rtx_insn *asan_emit_allocas_unpoison (rtx, rtx, rtx_insn *);
      29  extern bool asan_protect_global (tree, bool ignore_decl_rtl_set_p = false);
      30  extern void initialize_sanitizer_builtins (void);
      31  extern tree asan_dynamic_init_call (bool);
      32  extern bool asan_expand_check_ifn (gimple_stmt_iterator *, bool);
      33  extern bool asan_expand_mark_ifn (gimple_stmt_iterator *);
      34  extern bool asan_expand_poison_ifn (gimple_stmt_iterator *, bool *,
      35  				    hash_map<tree, tree> &);
      36  extern rtx asan_memfn_rtl (tree);
      37  
      38  extern void hwasan_record_frame_init ();
      39  extern void hwasan_record_stack_var (rtx, rtx, poly_int64, poly_int64);
      40  extern void hwasan_emit_prologue ();
      41  extern rtx_insn *hwasan_emit_untag_frame (rtx, rtx);
      42  extern rtx hwasan_get_frame_extent ();
      43  extern rtx hwasan_frame_base ();
      44  extern void hwasan_maybe_emit_frame_base_init (void);
      45  extern bool stack_vars_base_reg_p (rtx);
      46  extern uint8_t hwasan_current_frame_tag ();
      47  extern void hwasan_increment_frame_tag ();
      48  extern rtx hwasan_truncate_to_tag_size (rtx, rtx);
      49  extern void hwasan_finish_file (void);
      50  extern bool hwasan_sanitize_p (void);
      51  extern bool hwasan_sanitize_stack_p (void);
      52  extern bool hwasan_sanitize_allocas_p (void);
      53  extern bool hwasan_expand_check_ifn (gimple_stmt_iterator *, bool);
      54  extern bool hwasan_expand_mark_ifn (gimple_stmt_iterator *);
      55  extern bool gate_hwasan (void);
      56  
      57  extern gimple_stmt_iterator create_cond_insert_point
      58       (gimple_stmt_iterator *, bool, bool, bool, basic_block *, basic_block *);
      59  
      60  /* Alias set for accessing the shadow memory.  */
      61  extern alias_set_type asan_shadow_set;
      62  
      63  /* Hash set of labels that are either used in a goto, or their address
      64     has been taken.  */
      65  extern hash_set <tree> *asan_used_labels;
      66  
      67  /* Shadow memory is found at
      68     (address >> ASAN_SHADOW_SHIFT) + asan_shadow_offset ().  */
      69  #define ASAN_SHADOW_SHIFT	3
      70  #define ASAN_SHADOW_GRANULARITY (1UL << ASAN_SHADOW_SHIFT)
      71  
      72  /* Red zone size, stack and global variables are padded by ASAN_RED_ZONE_SIZE
      73     up to 2 * ASAN_RED_ZONE_SIZE - 1 bytes.  */
      74  #define ASAN_RED_ZONE_SIZE	32
      75  
      76  /* Stack variable use more compact red zones.  The size includes also
      77     size of variable itself.  */
      78  
      79  #define ASAN_MIN_RED_ZONE_SIZE	16
      80  
      81  /* Shadow memory values for stack protection.  Left is below protected vars,
      82     the first pointer in stack corresponding to that offset contains
      83     ASAN_STACK_FRAME_MAGIC word, the second pointer to a string describing
      84     the frame.  Middle is for padding in between variables, right is
      85     above the last protected variable and partial immediately after variables
      86     up to ASAN_RED_ZONE_SIZE alignment.  */
      87  #define ASAN_STACK_MAGIC_LEFT		  0xf1
      88  #define ASAN_STACK_MAGIC_MIDDLE		  0xf2
      89  #define ASAN_STACK_MAGIC_RIGHT		  0xf3
      90  #define ASAN_STACK_MAGIC_USE_AFTER_RET	  0xf5
      91  #define ASAN_STACK_MAGIC_USE_AFTER_SCOPE  0xf8
      92  
      93  #define ASAN_STACK_FRAME_MAGIC		0x41b58ab3
      94  #define ASAN_STACK_RETIRED_MAGIC	0x45e0360e
      95  
      96  #define ASAN_USE_AFTER_SCOPE_ATTRIBUTE	"use after scope memory"
      97  
      98  /* NOTE: The values below and the hooks under targetm.memtag define an ABI and
      99     are hard-coded to these values in libhwasan, hence they can't be changed
     100     independently here.  */
     101  /* How many bits are used to store a tag in a pointer.
     102     The default version uses the entire top byte of a pointer (i.e. 8 bits).  */
     103  #define HWASAN_TAG_SIZE targetm.memtag.tag_size ()
     104  /* Tag Granule of HWASAN shadow stack.
     105     This is the size in real memory that each byte in the shadow memory refers
     106     to.  I.e. if a variable is X bytes long in memory then its tag in shadow
     107     memory will span X / HWASAN_TAG_GRANULE_SIZE bytes.
     108     Most variables will need to be aligned to this amount since two variables
     109     that are neighbors in memory and share a tag granule would need to share the
     110     same tag (the shared tag granule can only store one tag).  */
     111  #define HWASAN_TAG_GRANULE_SIZE targetm.memtag.granule_size ()
     112  /* Define the tag for the stack background.
     113     This defines what tag the stack pointer will be and hence what tag all
     114     variables that are not given special tags are (e.g. spilled registers,
     115     and parameters passed on the stack).  */
     116  #define HWASAN_STACK_BACKGROUND gen_int_mode (0, QImode)
     117  
     118  /* Various flags for Asan builtins.  */
     119  enum asan_check_flags
     120  {
     121    ASAN_CHECK_STORE = 1 << 0,
     122    ASAN_CHECK_SCALAR_ACCESS = 1 << 1,
     123    ASAN_CHECK_NON_ZERO_LEN = 1 << 2,
     124    ASAN_CHECK_LAST = 1 << 3
     125  };
     126  
     127  /* Flags for Asan check builtins.  */
     128  #define IFN_ASAN_MARK_FLAGS DEF(POISON), DEF(UNPOISON)
     129  
     130  enum asan_mark_flags
     131  {
     132  #define DEF(X) ASAN_MARK_##X
     133    IFN_ASAN_MARK_FLAGS
     134  #undef DEF
     135  };
     136  
     137  /* Return true if STMT is ASAN_MARK with FLAG as first argument.  */
     138  extern bool asan_mark_p (gimple *stmt, enum asan_mark_flags flag);
     139  
     140  /* Return the size of padding needed to insert after a protected
     141     decl of SIZE.  */
     142  
     143  inline unsigned int
     144  asan_red_zone_size (unsigned int size)
     145  {
     146    unsigned int c = size & (ASAN_RED_ZONE_SIZE - 1);
     147    return c ? 2 * ASAN_RED_ZONE_SIZE - c : ASAN_RED_ZONE_SIZE;
     148  }
     149  
     150  /* Return how much a stack variable occupis on a stack
     151     including a space for red zone.  */
     152  
     153  inline unsigned HOST_WIDE_INT
     154  asan_var_and_redzone_size (unsigned HOST_WIDE_INT size)
     155  {
     156    if (size <= 4)
     157      return 16;
     158    else if (size <= 16)
     159      return 32;
     160    else if (size <= 128)
     161      return size + 32;
     162    else if (size <= 512)
     163      return size + 64;
     164    else if (size <= 4096)
     165      return size + 128;
     166    else
     167      return size + 256;
     168  }
     169  
     170  extern bool set_asan_shadow_offset (const char *);
     171  
     172  extern bool asan_shadow_offset_set_p ();
     173  
     174  extern void set_sanitized_sections (const char *);
     175  
     176  extern bool asan_sanitize_stack_p (void);
     177  
     178  extern bool asan_sanitize_allocas_p (void);
     179  
     180  extern hash_set<tree> *asan_handled_variables;
     181  
     182  /* Return TRUE if builtin with given FCODE will be intercepted by
     183     libasan.  */
     184  
     185  inline bool
     186  asan_intercepted_p (enum built_in_function fcode)
     187  {
     188    if (hwasan_sanitize_p ())
     189      return false;
     190  
     191    return fcode == BUILT_IN_INDEX
     192  	 || fcode == BUILT_IN_MEMCHR
     193  	 || fcode == BUILT_IN_MEMCMP
     194  	 || fcode == BUILT_IN_MEMCPY
     195  	 || fcode == BUILT_IN_MEMMOVE
     196  	 || fcode == BUILT_IN_MEMSET
     197  	 || fcode == BUILT_IN_STRCASECMP
     198  	 || fcode == BUILT_IN_STRCAT
     199  	 || fcode == BUILT_IN_STRCHR
     200  	 || fcode == BUILT_IN_STRCMP
     201  	 || fcode == BUILT_IN_STRCPY
     202  	 || fcode == BUILT_IN_STRDUP
     203  	 || fcode == BUILT_IN_STRLEN
     204  	 || fcode == BUILT_IN_STRNCASECMP
     205  	 || fcode == BUILT_IN_STRNCAT
     206  	 || fcode == BUILT_IN_STRNCMP
     207  	 || fcode == BUILT_IN_STRCSPN
     208  	 || fcode == BUILT_IN_STRPBRK
     209  	 || fcode == BUILT_IN_STRSPN
     210  	 || fcode == BUILT_IN_STRSTR
     211  	 || fcode == BUILT_IN_STRNCPY;
     212  }
     213  
     214  /* Return TRUE if we should instrument for use-after-scope sanity checking.  */
     215  
     216  inline bool
     217  asan_sanitize_use_after_scope (void)
     218  {
     219    return (flag_sanitize_address_use_after_scope
     220  	  && (asan_sanitize_stack_p () || hwasan_sanitize_stack_p ()));
     221  }
     222  
     223  /* Return true if DECL should be guarded on the stack.  */
     224  
     225  inline bool
     226  asan_protect_stack_decl (tree decl)
     227  {
     228    return DECL_P (decl)
     229      && (!DECL_ARTIFICIAL (decl)
     230  	|| (asan_sanitize_use_after_scope () && TREE_ADDRESSABLE (decl)));
     231  }
     232  
     233  /* Return true when flag_sanitize & FLAG is non-zero.  If FN is non-null,
     234     remove all flags mentioned in "no_sanitize" of DECL_ATTRIBUTES.  */
     235  
     236  inline bool
     237  sanitize_flags_p (unsigned int flag, const_tree fn = current_function_decl)
     238  {
     239    unsigned int result_flags = flag_sanitize & flag;
     240    if (result_flags == 0)
     241      return false;
     242  
     243    if (fn != NULL_TREE)
     244      {
     245        tree value = lookup_attribute ("no_sanitize", DECL_ATTRIBUTES (fn));
     246        if (value)
     247  	result_flags &= ~tree_to_uhwi (TREE_VALUE (value));
     248      }
     249  
     250    return result_flags;
     251  }
     252  
     253  /* Return true when coverage sanitization should happend for FN function.  */
     254  
     255  inline bool
     256  sanitize_coverage_p (const_tree fn = current_function_decl)
     257  {
     258    return (flag_sanitize_coverage
     259  	  && (fn == NULL_TREE
     260  	      || lookup_attribute ("no_sanitize_coverage",
     261  				   DECL_ATTRIBUTES (fn)) == NULL_TREE));
     262  }
     263  
     264  #endif /* TREE_ASAN */