/* AddressSanitizer, a fast memory error detector.
   Copyright (C) 2012-2022 Free Software Foundation, Inc.
   Contributed by Kostya Serebryany <kcc@google.com>

This file is part of GCC.

GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 3, or (at your option) any later
version.

GCC is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
for more details.

You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3.  If not see
<http://www.gnu.org/licenses/>.  */


#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "backend.h"
#include "target.h"
#include "rtl.h"
#include "tree.h"
#include "gimple.h"
#include "cfghooks.h"
#include "alloc-pool.h"
#include "tree-pass.h"
#include "memmodel.h"
#include "tm_p.h"
#include "ssa.h"
#include "stringpool.h"
#include "tree-ssanames.h"
#include "optabs.h"
#include "emit-rtl.h"
#include "cgraph.h"
#include "gimple-pretty-print.h"
#include "alias.h"
#include "fold-const.h"
#include "cfganal.h"
#include "gimplify.h"
#include "gimple-iterator.h"
#include "varasm.h"
#include "stor-layout.h"
#include "tree-iterator.h"
#include "stringpool.h"
#include "attribs.h"
#include "asan.h"
#include "dojump.h"
#include "explow.h"
#include "expr.h"
#include "output.h"
#include "langhooks.h"
#include "cfgloop.h"
#include "gimple-builder.h"
#include "gimple-fold.h"
#include "ubsan.h"
#include "builtins.h"
#include "fnmatch.h"
#include "tree-inline.h"
#include "tree-ssa.h"
#include "tree-eh.h"

/* AddressSanitizer finds out-of-bounds and use-after-free bugs
   with <2x slowdown on average.

   The tool consists of two parts:
   instrumentation module (this file) and a run-time library.
   The instrumentation module adds a run-time check before every memory insn.
     For a 8- or 16- byte load accessing address X:
       ShadowAddr = (X >> 3) + Offset
       ShadowValue = *(char*)ShadowAddr;  // *(short*) for 16-byte access.
       if (ShadowValue)
	 __asan_report_load8(X);
     For a load of N bytes (N=1, 2 or 4) from address X:
       ShadowAddr = (X >> 3) + Offset
       ShadowValue = *(char*)ShadowAddr;
       if (ShadowValue)
	 if ((X & 7) + N - 1 > ShadowValue)
	   __asan_report_loadN(X);
   Stores are instrumented similarly, but using __asan_report_storeN functions.
   A call too __asan_init_vN() is inserted to the list of module CTORs.
   N is the version number of the AddressSanitizer API. The changes between the
   API versions are listed in libsanitizer/asan/asan_interface_internal.h.

   The run-time library redefines malloc (so that redzone are inserted around
   the allocated memory) and free (so that reuse of free-ed memory is delayed),
   provides __asan_report* and __asan_init_vN functions.

   Read more:
   http://code.google.com/p/address-sanitizer/wiki/AddressSanitizerAlgorithm

   The current implementation supports detection of out-of-bounds and
   use-after-free in the heap, on the stack and for global variables.

   [Protection of stack variables]

   To understand how detection of out-of-bounds and use-after-free works
   for stack variables, lets look at this example on x86_64 where the
   stack grows downward:

     int
     foo ()
     {
       char a[24] = {0};
       int b[2] = {0};

       a[5] = 1;
       b[1] = 2;

       return a[5] + b[1];
     }

   For this function, the stack protected by asan will be organized as
   follows, from the top of the stack to the bottom:

   Slot 1/ [red zone of 32 bytes called 'RIGHT RedZone']

   Slot 2/ [8 bytes of red zone, that adds up to the space of 'a' to make
	   the next slot be 32 bytes aligned; this one is called Partial
	   Redzone; this 32 bytes alignment is an asan constraint]

   Slot 3/ [24 bytes for variable 'a']

   Slot 4/ [red zone of 32 bytes called 'Middle RedZone']

   Slot 5/ [24 bytes of Partial Red Zone (similar to slot 2]

   Slot 6/ [8 bytes for variable 'b']

   Slot 7/ [32 bytes of Red Zone at the bottom of the stack, called
	    'LEFT RedZone']

   The 32 bytes of LEFT red zone at the bottom of the stack can be
   decomposed as such:

     1/ The first 8 bytes contain a magical asan number that is always
     0x41B58AB3.

     2/ The following 8 bytes contains a pointer to a string (to be
     parsed at runtime by the runtime asan library), which format is
     the following:

      "<function-name> <space> <num-of-variables-on-the-stack>
      (<32-bytes-aligned-offset-in-bytes-of-variable> <space>
      <length-of-var-in-bytes> ){n} "

	where '(...){n}' means the content inside the parenthesis occurs 'n'
	times, with 'n' being the number of variables on the stack.

     3/ The following 8 bytes contain the PC of the current function which
     will be used by the run-time library to print an error message.

     4/ The following 8 bytes are reserved for internal use by the run-time.

   The shadow memory for that stack layout is going to look like this:

     - content of shadow memory 8 bytes for slot 7: 0xF1F1F1F1.
       The F1 byte pattern is a magic number called
       ASAN_STACK_MAGIC_LEFT and is a way for the runtime to know that
       the memory for that shadow byte is part of a the LEFT red zone
       intended to seat at the bottom of the variables on the stack.

     - content of shadow memory 8 bytes for slots 6 and 5:
       0xF4F4F400.  The F4 byte pattern is a magic number
       called ASAN_STACK_MAGIC_PARTIAL.  It flags the fact that the
       memory region for this shadow byte is a PARTIAL red zone
       intended to pad a variable A, so that the slot following
       {A,padding} is 32 bytes aligned.

       Note that the fact that the least significant byte of this
       shadow memory content is 00 means that 8 bytes of its
       corresponding memory (which corresponds to the memory of
       variable 'b') is addressable.

     - content of shadow memory 8 bytes for slot 4: 0xF2F2F2F2.
       The F2 byte pattern is a magic number called
       ASAN_STACK_MAGIC_MIDDLE.  It flags the fact that the memory
       region for this shadow byte is a MIDDLE red zone intended to
       seat between two 32 aligned slots of {variable,padding}.

     - content of shadow memory 8 bytes for slot 3 and 2:
       0xF4000000.  This represents is the concatenation of
       variable 'a' and the partial red zone following it, like what we
       had for variable 'b'.  The least significant 3 bytes being 00
       means that the 3 bytes of variable 'a' are addressable.

     - content of shadow memory 8 bytes for slot 1: 0xF3F3F3F3.
       The F3 byte pattern is a magic number called
       ASAN_STACK_MAGIC_RIGHT.  It flags the fact that the memory
       region for this shadow byte is a RIGHT red zone intended to seat
       at the top of the variables of the stack.

   Note that the real variable layout is done in expand_used_vars in
   cfgexpand.cc.  As far as Address Sanitizer is concerned, it lays out
   stack variables as well as the different red zones, emits some
   prologue code to populate the shadow memory as to poison (mark as
   non-accessible) the regions of the red zones and mark the regions of
   stack variables as accessible, and emit some epilogue code to
   un-poison (mark as accessible) the regions of red zones right before
   the function exits.

   [Protection of global variables]

   The basic idea is to insert a red zone between two global variables
   and install a constructor function that calls the asan runtime to do
   the populating of the relevant shadow memory regions at load time.

   So the global variables are laid out as to insert a red zone between
   them. The size of the red zones is so that each variable starts on a
   32 bytes boundary.

   Then a constructor function is installed so that, for each global
   variable, it calls the runtime asan library function
   __asan_register_globals_with an instance of this type:

     struct __asan_global
     {
       // Address of the beginning of the global variable.
       const void *__beg;

       // Initial size of the global variable.
       uptr __size;

       // Size of the global variable + size of the red zone.  This
       //   size is 32 bytes aligned.
       uptr __size_with_redzone;

       // Name of the global variable.
       const void *__name;

       // Name of the module where the global variable is declared.
       const void *__module_name;

       // 1 if it has dynamic initialization, 0 otherwise.
       uptr __has_dynamic_init;

       // A pointer to struct that contains source location, could be NULL.
       __asan_global_source_location *__location;
     }

   A destructor function that calls the runtime asan library function
   _asan_unregister_globals is also installed.  */

static unsigned HOST_WIDE_INT asan_shadow_offset_value;
static bool asan_shadow_offset_computed;
static vec<char *> sanitized_sections;
static tree last_alloca_addr;

/* Set of variable declarations that are going to be guarded by
   use-after-scope sanitizer.  */

hash_set<tree> *asan_handled_variables = NULL;

hash_set <tree> *asan_used_labels = NULL;

/* Global variables for HWASAN stack tagging.  */
/* hwasan_frame_tag_offset records the offset from the frame base tag that the
   next object should have.  */
static uint8_t hwasan_frame_tag_offset = 0;
/* hwasan_frame_base_ptr is a pointer with the same address as
   `virtual_stack_vars_rtx` for the current frame, and with the frame base tag
   stored in it.  N.b. this global RTX does not need to be marked GTY, but is
   done so anyway.  The need is not there since all uses are in just one pass
   (cfgexpand) and there are no calls to ggc_collect between the uses.  We mark
   it GTY(()) anyway to allow the use of the variable later on if needed by
   future features.  */
static GTY(()) rtx hwasan_frame_base_ptr = NULL_RTX;
/* hwasan_frame_base_init_seq is the sequence of RTL insns that will initialize
   the hwasan_frame_base_ptr.  When the hwasan_frame_base_ptr is requested, we
   generate this sequence but do not emit it.  If the sequence was created it
   is emitted once the function body has been expanded.

   This delay is because the frame base pointer may be needed anywhere in the
   function body, or needed by the expand_used_vars function.  Emitting once in
   a known place is simpler than requiring the emission of the instructions to
   be know where it should go depending on the first place the hwasan frame
   base is needed.  */
static GTY(()) rtx_insn *hwasan_frame_base_init_seq = NULL;

/* Structure defining the extent of one object on the stack that HWASAN needs
   to tag in the corresponding shadow stack space.

   The range this object spans on the stack is between `untagged_base +
   nearest_offset` and `untagged_base + farthest_offset`.
   `tagged_base` is an rtx containing the same value as `untagged_base` but
   with a random tag stored in the top byte.  We record both `untagged_base`
   and `tagged_base` so that `hwasan_emit_prologue` can use both without having
   to emit RTL into the instruction stream to re-calculate one from the other.
   (`hwasan_emit_prologue` needs to use both bases since the
   __hwasan_tag_memory call it emits uses an untagged value, and it calculates
   the tag to store in shadow memory based on the tag_offset plus the tag in
   tagged_base).  */
struct hwasan_stack_var
{
  rtx untagged_base;
  rtx tagged_base;
  poly_int64 nearest_offset;
  poly_int64 farthest_offset;
  uint8_t tag_offset;
};

/* Variable recording all stack variables that HWASAN needs to tag.
   Does not need to be marked as GTY(()) since every use is in the cfgexpand
   pass and gcc_collect is not called in the middle of that pass.  */
static vec<hwasan_stack_var> hwasan_tagged_stack_vars;


/* Sets shadow offset to value in string VAL.  */

bool
set_asan_shadow_offset (const char *val)
{
  char *endp;

  errno = 0;
#ifdef HAVE_LONG_LONG
  asan_shadow_offset_value = strtoull (val, &endp, 0);
#else
  asan_shadow_offset_value = strtoul (val, &endp, 0);
#endif
  if (!(*val != '\0' && *endp == '\0' && errno == 0))
    return false;

  asan_shadow_offset_computed = true;

  return true;
}

/* Set list of user-defined sections that need to be sanitized.  */

void
set_sanitized_sections (const char *sections)
{
  char *pat;
  unsigned i;
  FOR_EACH_VEC_ELT (sanitized_sections, i, pat)
    free (pat);
  sanitized_sections.truncate (0);

  for (const char *s = sections; *s; )
    {
      const char *end;
      for (end = s; *end && *end != ','; ++end);
      size_t len = end - s;
      sanitized_sections.safe_push (xstrndup (s, len));
      s = *end ? end + 1 : end;
    }
}

bool
asan_mark_p (gimple *stmt, enum asan_mark_flags flag)
{
  return (gimple_call_internal_p (stmt, IFN_ASAN_MARK)
	  && tree_to_uhwi (gimple_call_arg (stmt, 0)) == flag);
}

bool
asan_sanitize_stack_p (void)
{
  return (sanitize_flags_p (SANITIZE_ADDRESS) && param_asan_stack);
}

bool
asan_sanitize_allocas_p (void)
{
  return (asan_sanitize_stack_p () && param_asan_protect_allocas);
}

bool
asan_instrument_reads (void)
{
  return (sanitize_flags_p (SANITIZE_ADDRESS) && param_asan_instrument_reads);
}

bool
asan_instrument_writes (void)
{
  return (sanitize_flags_p (SANITIZE_ADDRESS) && param_asan_instrument_writes);
}

bool
asan_memintrin (void)
{
  return (sanitize_flags_p (SANITIZE_ADDRESS) && param_asan_memintrin);
}


/* Checks whether section SEC should be sanitized.  */

static bool
section_sanitized_p (const char *sec)
{
  char *pat;
  unsigned i;
  FOR_EACH_VEC_ELT (sanitized_sections, i, pat)
    if (fnmatch (pat, sec, FNM_PERIOD) == 0)
      return true;
  return false;
}

/* Returns Asan shadow offset.  */

static unsigned HOST_WIDE_INT
asan_shadow_offset ()
{
  if (!asan_shadow_offset_computed)
    {
      asan_shadow_offset_computed = true;
      asan_shadow_offset_value = targetm.asan_shadow_offset ();
    }
  return asan_shadow_offset_value;
}

/* Returns Asan shadow offset has been set.  */
bool
asan_shadow_offset_set_p ()
{
  return asan_shadow_offset_computed;
}

alias_set_type asan_shadow_set = -1;

/* Pointer types to 1, 2 or 4 byte integers in shadow memory.  A separate
   alias set is used for all shadow memory accesses.  */
static GTY(()) tree shadow_ptr_types[3];

/* Decl for __asan_option_detect_stack_use_after_return.  */
static GTY(()) tree asan_detect_stack_use_after_return;

/* Hashtable support for memory references used by gimple
   statements.  */

/* This type represents a reference to a memory region.  */
struct asan_mem_ref
{
  /* The expression of the beginning of the memory region.  */
  tree start;

  /* The size of the access.  */
  HOST_WIDE_INT access_size;
};

object_allocator <asan_mem_ref> asan_mem_ref_pool ("asan_mem_ref");

/* Initializes an instance of asan_mem_ref.  */

static void
asan_mem_ref_init (asan_mem_ref *ref, tree start, HOST_WIDE_INT access_size)
{
  ref->start = start;
  ref->access_size = access_size;
}

/* Allocates memory for an instance of asan_mem_ref into the memory
   pool returned by asan_mem_ref_get_alloc_pool and initialize it.
   START is the address of (or the expression pointing to) the
   beginning of memory reference.  ACCESS_SIZE is the size of the
   access to the referenced memory.  */

static asan_mem_ref*
asan_mem_ref_new (tree start, HOST_WIDE_INT access_size)
{
  asan_mem_ref *ref = asan_mem_ref_pool.allocate ();

  asan_mem_ref_init (ref, start, access_size);
  return ref;
}

/* This builds and returns a pointer to the end of the memory region
   that starts at START and of length LEN.  */

tree
asan_mem_ref_get_end (tree start, tree len)
{
  if (len == NULL_TREE || integer_zerop (len))
    return start;

  if (!ptrofftype_p (len))
    len = convert_to_ptrofftype (len);

  return fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (start), start, len);
}

/*  Return a tree expression that represents the end of the referenced
    memory region.  Beware that this function can actually build a new
    tree expression.  */

tree
asan_mem_ref_get_end (const asan_mem_ref *ref, tree len)
{
  return asan_mem_ref_get_end (ref->start, len);
}

struct asan_mem_ref_hasher : nofree_ptr_hash <asan_mem_ref>
{
  static inline hashval_t hash (const asan_mem_ref *);
  static inline bool equal (const asan_mem_ref *, const asan_mem_ref *);
};

/* Hash a memory reference.  */

inline hashval_t
asan_mem_ref_hasher::hash (const asan_mem_ref *mem_ref)
{
  return iterative_hash_expr (mem_ref->start, 0);
}

/* Compare two memory references.  We accept the length of either
   memory references to be NULL_TREE.  */

inline bool
asan_mem_ref_hasher::equal (const asan_mem_ref *m1,
			    const asan_mem_ref *m2)
{
  return operand_equal_p (m1->start, m2->start, 0);
}

static hash_table<asan_mem_ref_hasher> *asan_mem_ref_ht;

/* Returns a reference to the hash table containing memory references.
   This function ensures that the hash table is created.  Note that
   this hash table is updated by the function
   update_mem_ref_hash_table.  */

static hash_table<asan_mem_ref_hasher> *
get_mem_ref_hash_table ()
{
  if (!asan_mem_ref_ht)
    asan_mem_ref_ht = new hash_table<asan_mem_ref_hasher> (10);

  return asan_mem_ref_ht;
}

/* Clear all entries from the memory references hash table.  */

static void
empty_mem_ref_hash_table ()
{
  if (asan_mem_ref_ht)
    asan_mem_ref_ht->empty ();
}

/* Free the memory references hash table.  */

static void
free_mem_ref_resources ()
{
  delete asan_mem_ref_ht;
  asan_mem_ref_ht = NULL;

  asan_mem_ref_pool.release ();
}

/* Return true iff the memory reference REF has been instrumented.  */

static bool
has_mem_ref_been_instrumented (tree ref, HOST_WIDE_INT access_size)
{
  asan_mem_ref r;
  asan_mem_ref_init (&r, ref, access_size);

  asan_mem_ref *saved_ref = get_mem_ref_hash_table ()->find (&r);
  return saved_ref && saved_ref->access_size >= access_size;
}

/* Return true iff the memory reference REF has been instrumented.  */

static bool
has_mem_ref_been_instrumented (const asan_mem_ref *ref)
{
  return has_mem_ref_been_instrumented (ref->start, ref->access_size);
}

/* Return true iff access to memory region starting at REF and of
   length LEN has been instrumented.  */

static bool
has_mem_ref_been_instrumented (const asan_mem_ref *ref, tree len)
{
  HOST_WIDE_INT size_in_bytes
    = tree_fits_shwi_p (len) ? tree_to_shwi (len) : -1;

  return size_in_bytes != -1
    && has_mem_ref_been_instrumented (ref->start, size_in_bytes);
}

/* Set REF to the memory reference present in a gimple assignment
   ASSIGNMENT.  Return true upon successful completion, false
   otherwise.  */

static bool
get_mem_ref_of_assignment (const gassign *assignment,
			   asan_mem_ref *ref,
			   bool *ref_is_store)
{
  gcc_assert (gimple_assign_single_p (assignment));

  if (gimple_store_p (assignment)
      && !gimple_clobber_p (assignment))
    {
      ref->start = gimple_assign_lhs (assignment);
      *ref_is_store = true;
    }
  else if (gimple_assign_load_p (assignment))
    {
      ref->start = gimple_assign_rhs1 (assignment);
      *ref_is_store = false;
    }
  else
    return false;

  ref->access_size = int_size_in_bytes (TREE_TYPE (ref->start));
  return true;
}

/* Return address of last allocated dynamic alloca.  */

static tree
get_last_alloca_addr ()
{
  if (last_alloca_addr)
    return last_alloca_addr;

  last_alloca_addr = create_tmp_reg (ptr_type_node, "last_alloca_addr");
  gassign *g = gimple_build_assign (last_alloca_addr, null_pointer_node);
  edge e = single_succ_edge (ENTRY_BLOCK_PTR_FOR_FN (cfun));
  gsi_insert_on_edge_immediate (e, g);
  return last_alloca_addr;
}

/* Insert __asan_allocas_unpoison (top, bottom) call before
   __builtin_stack_restore (new_sp) call.
   The pseudocode of this routine should look like this:
     top = last_alloca_addr;
     bot = new_sp;
     __asan_allocas_unpoison (top, bot);
     last_alloca_addr = new_sp;
     __builtin_stack_restore (new_sp);
   In general, we can't use new_sp as bot parameter because on some
   architectures SP has non zero offset from dynamic stack area.  Moreover, on
   some architectures this offset (STACK_DYNAMIC_OFFSET) becomes known for each
   particular function only after all callees were expanded to rtl.
   The most noticeable example is PowerPC{,64}, see
   http://refspecs.linuxfoundation.org/ELF/ppc64/PPC-elf64abi.html#DYNAM-STACK.
   To overcome the issue we use following trick: pass new_sp as a second
   parameter to __asan_allocas_unpoison and rewrite it during expansion with
   new_sp + (virtual_dynamic_stack_rtx - sp) later in
   expand_asan_emit_allocas_unpoison function.

   HWASAN needs to do very similar, the eventual pseudocode should be:
      __hwasan_tag_memory (virtual_stack_dynamic_rtx,
			   0,
			   new_sp - sp);
      __builtin_stack_restore (new_sp)

   Need to use the same trick to handle STACK_DYNAMIC_OFFSET as described
   above.  */

static void
handle_builtin_stack_restore (gcall *call, gimple_stmt_iterator *iter)
{
  if (!iter
      || !(asan_sanitize_allocas_p () || hwasan_sanitize_allocas_p ()))
    return;

  tree restored_stack = gimple_call_arg (call, 0);

  gimple *g;

  if (hwasan_sanitize_allocas_p ())
    {
      enum internal_fn fn = IFN_HWASAN_ALLOCA_UNPOISON;
      /* There is only one piece of information `expand_HWASAN_ALLOCA_UNPOISON`
	 needs to work.  This is the length of the area that we're
	 deallocating.  Since the stack pointer is known at expand time, the
	 position of the new stack pointer after deallocation is enough
	 information to calculate this length.  */
      g = gimple_build_call_internal (fn, 1, restored_stack);
    }
  else
    {
      tree last_alloca = get_last_alloca_addr ();
      tree fn = builtin_decl_implicit (BUILT_IN_ASAN_ALLOCAS_UNPOISON);
      g = gimple_build_call (fn, 2, last_alloca, restored_stack);
      gsi_insert_before (iter, g, GSI_SAME_STMT);
      g = gimple_build_assign (last_alloca, restored_stack);
    }

  gsi_insert_before (iter, g, GSI_SAME_STMT);
}

/* Deploy and poison redzones around __builtin_alloca call.  To do this, we
   should replace this call with another one with changed parameters and
   replace all its uses with new address, so
       addr = __builtin_alloca (old_size, align);
   is replaced by
       left_redzone_size = max (align, ASAN_RED_ZONE_SIZE);
   Following two statements are optimized out if we know that
   old_size & (ASAN_RED_ZONE_SIZE - 1) == 0, i.e. alloca doesn't need partial
   redzone.
       misalign = old_size & (ASAN_RED_ZONE_SIZE - 1);
       partial_redzone_size = ASAN_RED_ZONE_SIZE - misalign;
       right_redzone_size = ASAN_RED_ZONE_SIZE;
       additional_size = left_redzone_size + partial_redzone_size +
                         right_redzone_size;
       new_size = old_size + additional_size;
       new_alloca = __builtin_alloca (new_size, max (align, 32))
       __asan_alloca_poison (new_alloca, old_size)
       addr = new_alloca + max (align, ASAN_RED_ZONE_SIZE);
       last_alloca_addr = new_alloca;
   ADDITIONAL_SIZE is added to make new memory allocation contain not only
   requested memory, but also left, partial and right redzones as well as some
   additional space, required by alignment.  */

static void
handle_builtin_alloca (gcall *call, gimple_stmt_iterator *iter)
{
  if (!iter
      || !(asan_sanitize_allocas_p () || hwasan_sanitize_allocas_p ()))
    return;

  gassign *g;
  gcall *gg;
  tree callee = gimple_call_fndecl (call);
  tree lhs = gimple_call_lhs (call);
  tree old_size = gimple_call_arg (call, 0);
  tree ptr_type = lhs ? TREE_TYPE (lhs) : ptr_type_node;
  tree partial_size = NULL_TREE;
  unsigned int align
    = DECL_FUNCTION_CODE (callee) == BUILT_IN_ALLOCA
      ? 0 : tree_to_uhwi (gimple_call_arg (call, 1));

  bool throws = false;
  edge e = NULL;
  if (stmt_can_throw_internal (cfun, call))
    {
      if (!lhs)
	return;
      throws = true;
      e = find_fallthru_edge (gsi_bb (*iter)->succs);
    }

  if (hwasan_sanitize_allocas_p ())
    {
      gimple_seq stmts = NULL;
      location_t loc = gimple_location (gsi_stmt (*iter));
      /*
	 HWASAN needs a different expansion.

	 addr = __builtin_alloca (size, align);

	 should be replaced by

	 new_size = size rounded up to HWASAN_TAG_GRANULE_SIZE byte alignment;
	 untagged_addr = __builtin_alloca (new_size, align);
	 tag = __hwasan_choose_alloca_tag ();
	 addr = ifn_HWASAN_SET_TAG (untagged_addr, tag);
	 __hwasan_tag_memory (untagged_addr, tag, new_size);
	*/
      /* Ensure alignment at least HWASAN_TAG_GRANULE_SIZE bytes so we start on
	 a tag granule.  */
      align = align > HWASAN_TAG_GRANULE_SIZE ? align : HWASAN_TAG_GRANULE_SIZE;

      tree old_size = gimple_call_arg (call, 0);
      tree new_size = gimple_build_round_up (&stmts, loc, size_type_node,
					     old_size,
					     HWASAN_TAG_GRANULE_SIZE);

      /* Make the alloca call */
      tree untagged_addr
	= gimple_build (&stmts, loc,
			as_combined_fn (BUILT_IN_ALLOCA_WITH_ALIGN), ptr_type,
			new_size, build_int_cst (size_type_node, align));

      /* Choose the tag.
	 Here we use an internal function so we can choose the tag at expand
	 time.  We need the decision to be made after stack variables have been
	 assigned their tag (i.e. once the hwasan_frame_tag_offset variable has
	 been set to one after the last stack variables tag).  */
      tree tag = gimple_build (&stmts, loc, CFN_HWASAN_CHOOSE_TAG,
			       unsigned_char_type_node);

      /* Add tag to pointer.  */
      tree addr
	= gimple_build (&stmts, loc, CFN_HWASAN_SET_TAG, ptr_type,
			untagged_addr, tag);

      /* Tag shadow memory.
	 NOTE: require using `untagged_addr` here for libhwasan API.  */
      gimple_build (&stmts, loc, as_combined_fn (BUILT_IN_HWASAN_TAG_MEM),
		    void_type_node, untagged_addr, tag, new_size);

      /* Insert the built up code sequence into the original instruction stream
	 the iterator points to.  */
      gsi_insert_seq_before (iter, stmts, GSI_SAME_STMT);

      /* Finally, replace old alloca ptr with NEW_ALLOCA.  */
      replace_call_with_value (iter, addr);
      return;
    }

  tree last_alloca = get_last_alloca_addr ();
  const HOST_WIDE_INT redzone_mask = ASAN_RED_ZONE_SIZE - 1;

  /* If ALIGN > ASAN_RED_ZONE_SIZE, we embed left redzone into first ALIGN
     bytes of allocated space.  Otherwise, align alloca to ASAN_RED_ZONE_SIZE
     manually.  */
  align = MAX (align, ASAN_RED_ZONE_SIZE * BITS_PER_UNIT);

  tree alloca_rz_mask = build_int_cst (size_type_node, redzone_mask);
  tree redzone_size = build_int_cst (size_type_node, ASAN_RED_ZONE_SIZE);

  /* Extract lower bits from old_size.  */
  wide_int size_nonzero_bits = get_nonzero_bits (old_size);
  wide_int rz_mask
    = wi::uhwi (redzone_mask, wi::get_precision (size_nonzero_bits));
  wide_int old_size_lower_bits = wi::bit_and (size_nonzero_bits, rz_mask);

  /* If alloca size is aligned to ASAN_RED_ZONE_SIZE, we don't need partial
     redzone.  Otherwise, compute its size here.  */
  if (wi::ne_p (old_size_lower_bits, 0))
    {
      /* misalign = size & (ASAN_RED_ZONE_SIZE - 1)
         partial_size = ASAN_RED_ZONE_SIZE - misalign.  */
      g = gimple_build_assign (make_ssa_name (size_type_node, NULL),
			       BIT_AND_EXPR, old_size, alloca_rz_mask);
      gsi_insert_before (iter, g, GSI_SAME_STMT);
      tree misalign = gimple_assign_lhs (g);
      g = gimple_build_assign (make_ssa_name (size_type_node, NULL), MINUS_EXPR,
			       redzone_size, misalign);
      gsi_insert_before (iter, g, GSI_SAME_STMT);
      partial_size = gimple_assign_lhs (g);
    }

  /* additional_size = align + ASAN_RED_ZONE_SIZE.  */
  tree additional_size = build_int_cst (size_type_node, align / BITS_PER_UNIT
							+ ASAN_RED_ZONE_SIZE);
  /* If alloca has partial redzone, include it to additional_size too.  */
  if (partial_size)
    {
      /* additional_size += partial_size.  */
      g = gimple_build_assign (make_ssa_name (size_type_node), PLUS_EXPR,
			       partial_size, additional_size);
      gsi_insert_before (iter, g, GSI_SAME_STMT);
      additional_size = gimple_assign_lhs (g);
    }

  /* new_size = old_size + additional_size.  */
  g = gimple_build_assign (make_ssa_name (size_type_node), PLUS_EXPR, old_size,
			   additional_size);
  gsi_insert_before (iter, g, GSI_SAME_STMT);
  tree new_size = gimple_assign_lhs (g);

  /* Build new __builtin_alloca call:
       new_alloca_with_rz = __builtin_alloca (new_size, align).  */
  tree fn = builtin_decl_implicit (BUILT_IN_ALLOCA_WITH_ALIGN);
  gg = gimple_build_call (fn, 2, new_size,
			  build_int_cst (size_type_node, align));
  tree new_alloca_with_rz = make_ssa_name (ptr_type, gg);
  gimple_call_set_lhs (gg, new_alloca_with_rz);
  if (throws)
    {
      gimple_call_set_lhs (call, NULL);
      gsi_replace (iter, gg, true);
    }
  else
    gsi_insert_before (iter, gg, GSI_SAME_STMT);

  /* new_alloca = new_alloca_with_rz + align.  */
  g = gimple_build_assign (make_ssa_name (ptr_type), POINTER_PLUS_EXPR,
			   new_alloca_with_rz,
			   build_int_cst (size_type_node,
					  align / BITS_PER_UNIT));
  gimple_stmt_iterator gsi = gsi_none ();
  if (throws)
    {
      gsi_insert_on_edge_immediate (e, g);
      gsi = gsi_for_stmt (g);
    }
  else
    gsi_insert_before (iter, g, GSI_SAME_STMT);
  tree new_alloca = gimple_assign_lhs (g);

  /* Poison newly created alloca redzones:
      __asan_alloca_poison (new_alloca, old_size).  */
  fn = builtin_decl_implicit (BUILT_IN_ASAN_ALLOCA_POISON);
  gg = gimple_build_call (fn, 2, new_alloca, old_size);
  if (throws)
    gsi_insert_after (&gsi, gg, GSI_NEW_STMT);
  else
    gsi_insert_before (iter, gg, GSI_SAME_STMT);

  /* Save new_alloca_with_rz value into last_alloca to use it during
     allocas unpoisoning.  */
  g = gimple_build_assign (last_alloca, new_alloca_with_rz);
  if (throws)
    gsi_insert_after (&gsi, g, GSI_NEW_STMT);
  else
    gsi_insert_before (iter, g, GSI_SAME_STMT);

  /* Finally, replace old alloca ptr with NEW_ALLOCA.  */
  if (throws)
    {
      g = gimple_build_assign (lhs, new_alloca);
      gsi_insert_after (&gsi, g, GSI_NEW_STMT);
    }
  else
    replace_call_with_value (iter, new_alloca);
}

/* Return the memory references contained in a gimple statement
   representing a builtin call that has to do with memory access.  */

static bool
get_mem_refs_of_builtin_call (gcall *call,
			      asan_mem_ref *src0,
			      tree *src0_len,
			      bool *src0_is_store,
			      asan_mem_ref *src1,
			      tree *src1_len,
			      bool *src1_is_store,
			      asan_mem_ref *dst,
			      tree *dst_len,
			      bool *dst_is_store,
			      bool *dest_is_deref,
			      bool *intercepted_p,
			      gimple_stmt_iterator *iter = NULL)
{
  gcc_checking_assert (gimple_call_builtin_p (call, BUILT_IN_NORMAL));

  tree callee = gimple_call_fndecl (call);
  tree source0 = NULL_TREE, source1 = NULL_TREE,
    dest = NULL_TREE, len = NULL_TREE;
  bool is_store = true, got_reference_p = false;
  HOST_WIDE_INT access_size = 1;

  *intercepted_p = asan_intercepted_p ((DECL_FUNCTION_CODE (callee)));

  switch (DECL_FUNCTION_CODE (callee))
    {
      /* (s, s, n) style memops.  */
    case BUILT_IN_BCMP:
    case BUILT_IN_MEMCMP:
      source0 = gimple_call_arg (call, 0);
      source1 = gimple_call_arg (call, 1);
      len = gimple_call_arg (call, 2);
      break;

      /* (src, dest, n) style memops.  */
    case BUILT_IN_BCOPY:
      source0 = gimple_call_arg (call, 0);
      dest = gimple_call_arg (call, 1);
      len = gimple_call_arg (call, 2);
      break;

      /* (dest, src, n) style memops.  */
    case BUILT_IN_MEMCPY:
    case BUILT_IN_MEMCPY_CHK:
    case BUILT_IN_MEMMOVE:
    case BUILT_IN_MEMMOVE_CHK:
    case BUILT_IN_MEMPCPY:
    case BUILT_IN_MEMPCPY_CHK:
      dest = gimple_call_arg (call, 0);
      source0 = gimple_call_arg (call, 1);
      len = gimple_call_arg (call, 2);
      break;

      /* (dest, n) style memops.  */
    case BUILT_IN_BZERO:
      dest = gimple_call_arg (call, 0);
      len = gimple_call_arg (call, 1);
      break;

      /* (dest, x, n) style memops*/
    case BUILT_IN_MEMSET:
    case BUILT_IN_MEMSET_CHK:
      dest = gimple_call_arg (call, 0);
      len = gimple_call_arg (call, 2);
      break;

    case BUILT_IN_STRLEN:
      /* Special case strlen here since its length is taken from its return
	 value.

	 The approach taken by the sanitizers is to check a memory access
	 before it's taken.  For ASAN strlen is intercepted by libasan, so no
	 check is inserted by the compiler.

	 This function still returns `true` and provides a length to the rest
	 of the ASAN pass in order to record what areas have been checked,
	 avoiding superfluous checks later on.

	 HWASAN does not intercept any of these internal functions.
	 This means that checks for memory accesses must be inserted by the
	 compiler.
	 strlen is a special case, because we can tell the length from the
	 return of the function, but that is not known until after the function
	 has returned.

	 Hence we can't check the memory access before it happens.
	 We could check the memory access after it has already happened, but
	 for now we choose to just ignore `strlen` calls.
	 This decision was simply made because that means the special case is
	 limited to this one case of this one function.  */
      if (hwasan_sanitize_p ())
	return false;
      source0 = gimple_call_arg (call, 0);
      len = gimple_call_lhs (call);
      break;

    case BUILT_IN_STACK_RESTORE:
      handle_builtin_stack_restore (call, iter);
      break;

    CASE_BUILT_IN_ALLOCA:
      handle_builtin_alloca (call, iter);
      break;
    /* And now the __atomic* and __sync builtins.
       These are handled differently from the classical memory
       access builtins above.  */

    case BUILT_IN_ATOMIC_LOAD_1:
      is_store = false;
      /* FALLTHRU */
    case BUILT_IN_SYNC_FETCH_AND_ADD_1:
    case BUILT_IN_SYNC_FETCH_AND_SUB_1:
    case BUILT_IN_SYNC_FETCH_AND_OR_1:
    case BUILT_IN_SYNC_FETCH_AND_AND_1:
    case BUILT_IN_SYNC_FETCH_AND_XOR_1:
    case BUILT_IN_SYNC_FETCH_AND_NAND_1:
    case BUILT_IN_SYNC_ADD_AND_FETCH_1:
    case BUILT_IN_SYNC_SUB_AND_FETCH_1:
    case BUILT_IN_SYNC_OR_AND_FETCH_1:
    case BUILT_IN_SYNC_AND_AND_FETCH_1:
    case BUILT_IN_SYNC_XOR_AND_FETCH_1:
    case BUILT_IN_SYNC_NAND_AND_FETCH_1:
    case BUILT_IN_SYNC_BOOL_COMPARE_AND_SWAP_1:
    case BUILT_IN_SYNC_VAL_COMPARE_AND_SWAP_1:
    case BUILT_IN_SYNC_LOCK_TEST_AND_SET_1:
    case BUILT_IN_SYNC_LOCK_RELEASE_1:
    case BUILT_IN_ATOMIC_EXCHANGE_1:
    case BUILT_IN_ATOMIC_COMPARE_EXCHANGE_1:
    case BUILT_IN_ATOMIC_STORE_1:
    case BUILT_IN_ATOMIC_ADD_FETCH_1:
    case BUILT_IN_ATOMIC_SUB_FETCH_1:
    case BUILT_IN_ATOMIC_AND_FETCH_1:
    case BUILT_IN_ATOMIC_NAND_FETCH_1:
    case BUILT_IN_ATOMIC_XOR_FETCH_1:
    case BUILT_IN_ATOMIC_OR_FETCH_1:
    case BUILT_IN_ATOMIC_FETCH_ADD_1:
    case BUILT_IN_ATOMIC_FETCH_SUB_1:
    case BUILT_IN_ATOMIC_FETCH_AND_1:
    case BUILT_IN_ATOMIC_FETCH_NAND_1:
    case BUILT_IN_ATOMIC_FETCH_XOR_1:
    case BUILT_IN_ATOMIC_FETCH_OR_1:
      access_size = 1;
      goto do_atomic;

    case BUILT_IN_ATOMIC_LOAD_2:
      is_store = false;
      /* FALLTHRU */
    case BUILT_IN_SYNC_FETCH_AND_ADD_2:
    case BUILT_IN_SYNC_FETCH_AND_SUB_2:
    case BUILT_IN_SYNC_FETCH_AND_OR_2:
    case BUILT_IN_SYNC_FETCH_AND_AND_2:
    case BUILT_IN_SYNC_FETCH_AND_XOR_2:
    case BUILT_IN_SYNC_FETCH_AND_NAND_2:
    case BUILT_IN_SYNC_ADD_AND_FETCH_2:
    case BUILT_IN_SYNC_SUB_AND_FETCH_2:
    case BUILT_IN_SYNC_OR_AND_FETCH_2:
    case BUILT_IN_SYNC_AND_AND_FETCH_2:
    case BUILT_IN_SYNC_XOR_AND_FETCH_2:
    case BUILT_IN_SYNC_NAND_AND_FETCH_2:
    case BUILT_IN_SYNC_BOOL_COMPARE_AND_SWAP_2:
    case BUILT_IN_SYNC_VAL_COMPARE_AND_SWAP_2:
    case BUILT_IN_SYNC_LOCK_TEST_AND_SET_2:
    case BUILT_IN_SYNC_LOCK_RELEASE_2:
    case BUILT_IN_ATOMIC_EXCHANGE_2:
    case BUILT_IN_ATOMIC_COMPARE_EXCHANGE_2:
    case BUILT_IN_ATOMIC_STORE_2:
    case BUILT_IN_ATOMIC_ADD_FETCH_2:
    case BUILT_IN_ATOMIC_SUB_FETCH_2:
    case BUILT_IN_ATOMIC_AND_FETCH_2:
    case BUILT_IN_ATOMIC_NAND_FETCH_2:
    case BUILT_IN_ATOMIC_XOR_FETCH_2:
    case BUILT_IN_ATOMIC_OR_FETCH_2:
    case BUILT_IN_ATOMIC_FETCH_ADD_2:
    case BUILT_IN_ATOMIC_FETCH_SUB_2:
    case BUILT_IN_ATOMIC_FETCH_AND_2:
    case BUILT_IN_ATOMIC_FETCH_NAND_2:
    case BUILT_IN_ATOMIC_FETCH_XOR_2:
    case BUILT_IN_ATOMIC_FETCH_OR_2:
      access_size = 2;
      goto do_atomic;

    case BUILT_IN_ATOMIC_LOAD_4:
      is_store = false;
      /* FALLTHRU */
    case BUILT_IN_SYNC_FETCH_AND_ADD_4:
    case BUILT_IN_SYNC_FETCH_AND_SUB_4:
    case BUILT_IN_SYNC_FETCH_AND_OR_4:
    case BUILT_IN_SYNC_FETCH_AND_AND_4:
    case BUILT_IN_SYNC_FETCH_AND_XOR_4:
    case BUILT_IN_SYNC_FETCH_AND_NAND_4:
    case BUILT_IN_SYNC_ADD_AND_FETCH_4:
    case BUILT_IN_SYNC_SUB_AND_FETCH_4:
    case BUILT_IN_SYNC_OR_AND_FETCH_4:
    case BUILT_IN_SYNC_AND_AND_FETCH_4:
    case BUILT_IN_SYNC_XOR_AND_FETCH_4:
    case BUILT_IN_SYNC_NAND_AND_FETCH_4:
    case BUILT_IN_SYNC_BOOL_COMPARE_AND_SWAP_4:
    case BUILT_IN_SYNC_VAL_COMPARE_AND_SWAP_4:
    case BUILT_IN_SYNC_LOCK_TEST_AND_SET_4:
    case BUILT_IN_SYNC_LOCK_RELEASE_4:
    case BUILT_IN_ATOMIC_EXCHANGE_4:
    case BUILT_IN_ATOMIC_COMPARE_EXCHANGE_4:
    case BUILT_IN_ATOMIC_STORE_4:
    case BUILT_IN_ATOMIC_ADD_FETCH_4:
    case BUILT_IN_ATOMIC_SUB_FETCH_4:
    case BUILT_IN_ATOMIC_AND_FETCH_4:
    case BUILT_IN_ATOMIC_NAND_FETCH_4:
    case BUILT_IN_ATOMIC_XOR_FETCH_4:
    case BUILT_IN_ATOMIC_OR_FETCH_4:
    case BUILT_IN_ATOMIC_FETCH_ADD_4:
    case BUILT_IN_ATOMIC_FETCH_SUB_4:
    case BUILT_IN_ATOMIC_FETCH_AND_4:
    case BUILT_IN_ATOMIC_FETCH_NAND_4:
    case BUILT_IN_ATOMIC_FETCH_XOR_4:
    case BUILT_IN_ATOMIC_FETCH_OR_4:
      access_size = 4;
      goto do_atomic;

    case BUILT_IN_ATOMIC_LOAD_8:
      is_store = false;
      /* FALLTHRU */
    case BUILT_IN_SYNC_FETCH_AND_ADD_8:
    case BUILT_IN_SYNC_FETCH_AND_SUB_8:
    case BUILT_IN_SYNC_FETCH_AND_OR_8:
    case BUILT_IN_SYNC_FETCH_AND_AND_8:
    case BUILT_IN_SYNC_FETCH_AND_XOR_8:
    case BUILT_IN_SYNC_FETCH_AND_NAND_8:
    case BUILT_IN_SYNC_ADD_AND_FETCH_8:
    case BUILT_IN_SYNC_SUB_AND_FETCH_8:
    case BUILT_IN_SYNC_OR_AND_FETCH_8:
    case BUILT_IN_SYNC_AND_AND_FETCH_8:
    case BUILT_IN_SYNC_XOR_AND_FETCH_8:
    case BUILT_IN_SYNC_NAND_AND_FETCH_8:
    case BUILT_IN_SYNC_BOOL_COMPARE_AND_SWAP_8:
    case BUILT_IN_SYNC_VAL_COMPARE_AND_SWAP_8:
    case BUILT_IN_SYNC_LOCK_TEST_AND_SET_8:
    case BUILT_IN_SYNC_LOCK_RELEASE_8:
    case BUILT_IN_ATOMIC_EXCHANGE_8:
    case BUILT_IN_ATOMIC_COMPARE_EXCHANGE_8:
    case BUILT_IN_ATOMIC_STORE_8:
    case BUILT_IN_ATOMIC_ADD_FETCH_8:
    case BUILT_IN_ATOMIC_SUB_FETCH_8:
    case BUILT_IN_ATOMIC_AND_FETCH_8:
    case BUILT_IN_ATOMIC_NAND_FETCH_8:
    case BUILT_IN_ATOMIC_XOR_FETCH_8:
    case BUILT_IN_ATOMIC_OR_FETCH_8:
    case BUILT_IN_ATOMIC_FETCH_ADD_8:
    case BUILT_IN_ATOMIC_FETCH_SUB_8:
    case BUILT_IN_ATOMIC_FETCH_AND_8:
    case BUILT_IN_ATOMIC_FETCH_NAND_8:
    case BUILT_IN_ATOMIC_FETCH_XOR_8:
    case BUILT_IN_ATOMIC_FETCH_OR_8:
      access_size = 8;
      goto do_atomic;

    case BUILT_IN_ATOMIC_LOAD_16:
      is_store = false;
      /* FALLTHRU */
    case BUILT_IN_SYNC_FETCH_AND_ADD_16:
    case BUILT_IN_SYNC_FETCH_AND_SUB_16:
    case BUILT_IN_SYNC_FETCH_AND_OR_16:
    case BUILT_IN_SYNC_FETCH_AND_AND_16:
    case BUILT_IN_SYNC_FETCH_AND_XOR_16:
    case BUILT_IN_SYNC_FETCH_AND_NAND_16:
    case BUILT_IN_SYNC_ADD_AND_FETCH_16:
    case BUILT_IN_SYNC_SUB_AND_FETCH_16:
    case BUILT_IN_SYNC_OR_AND_FETCH_16:
    case BUILT_IN_SYNC_AND_AND_FETCH_16:
    case BUILT_IN_SYNC_XOR_AND_FETCH_16:
    case BUILT_IN_SYNC_NAND_AND_FETCH_16:
    case BUILT_IN_SYNC_BOOL_COMPARE_AND_SWAP_16:
    case BUILT_IN_SYNC_VAL_COMPARE_AND_SWAP_16:
    case BUILT_IN_SYNC_LOCK_TEST_AND_SET_16:
    case BUILT_IN_SYNC_LOCK_RELEASE_16:
    case BUILT_IN_ATOMIC_EXCHANGE_16:
    case BUILT_IN_ATOMIC_COMPARE_EXCHANGE_16:
    case BUILT_IN_ATOMIC_STORE_16:
    case BUILT_IN_ATOMIC_ADD_FETCH_16:
    case BUILT_IN_ATOMIC_SUB_FETCH_16:
    case BUILT_IN_ATOMIC_AND_FETCH_16:
    case BUILT_IN_ATOMIC_NAND_FETCH_16:
    case BUILT_IN_ATOMIC_XOR_FETCH_16:
    case BUILT_IN_ATOMIC_OR_FETCH_16:
    case BUILT_IN_ATOMIC_FETCH_ADD_16:
    case BUILT_IN_ATOMIC_FETCH_SUB_16:
    case BUILT_IN_ATOMIC_FETCH_AND_16:
    case BUILT_IN_ATOMIC_FETCH_NAND_16:
    case BUILT_IN_ATOMIC_FETCH_XOR_16:
    case BUILT_IN_ATOMIC_FETCH_OR_16:
      access_size = 16;
      /* FALLTHRU */
    do_atomic:
      {
	dest = gimple_call_arg (call, 0);
	/* DEST represents the address of a memory location.
	   instrument_derefs wants the memory location, so lets
	   dereference the address DEST before handing it to
	   instrument_derefs.  */
	tree type = build_nonstandard_integer_type (access_size
						    * BITS_PER_UNIT, 1);
	dest = build2 (MEM_REF, type, dest,
		       build_int_cst (build_pointer_type (char_type_node), 0));
	break;
      }

    default:
      /* The other builtins memory access are not instrumented in this
	 function because they either don't have any length parameter,
	 or their length parameter is just a limit.  */
      break;
    }

  if (len != NULL_TREE)
    {
      if (source0 != NULL_TREE)
	{
	  src0->start = source0;
	  src0->access_size = access_size;
	  *src0_len = len;
	  *src0_is_store = false;
	}

      if (source1 != NULL_TREE)
	{
	  src1->start = source1;
	  src1->access_size = access_size;
	  *src1_len = len;
	  *src1_is_store = false;
	}

      if (dest != NULL_TREE)
	{
	  dst->start = dest;
	  dst->access_size = access_size;
	  *dst_len = len;
	  *dst_is_store = true;
	}

      got_reference_p = true;
    }
  else if (dest)
    {
      dst->start = dest;
      dst->access_size = access_size;
      *dst_len = NULL_TREE;
      *dst_is_store = is_store;
      *dest_is_deref = true;
      got_reference_p = true;
    }

  return got_reference_p;
}

/* Return true iff a given gimple statement has been instrumented.
   Note that the statement is "defined" by the memory references it
   contains.  */

static bool
has_stmt_been_instrumented_p (gimple *stmt)
{
  if (gimple_assign_single_p (stmt))
    {
      bool r_is_store;
      asan_mem_ref r;
      asan_mem_ref_init (&r, NULL, 1);

      if (get_mem_ref_of_assignment (as_a <gassign *> (stmt), &r,
				     &r_is_store))
	return has_mem_ref_been_instrumented (&r);
    }
  else if (gimple_call_builtin_p (stmt, BUILT_IN_NORMAL))
    {
      asan_mem_ref src0, src1, dest;
      asan_mem_ref_init (&src0, NULL, 1);
      asan_mem_ref_init (&src1, NULL, 1);
      asan_mem_ref_init (&dest, NULL, 1);

      tree src0_len = NULL_TREE, src1_len = NULL_TREE, dest_len = NULL_TREE;
      bool src0_is_store = false, src1_is_store = false,
	dest_is_store = false, dest_is_deref = false, intercepted_p = true;
      if (get_mem_refs_of_builtin_call (as_a <gcall *> (stmt),
					&src0, &src0_len, &src0_is_store,
					&src1, &src1_len, &src1_is_store,
					&dest, &dest_len, &dest_is_store,
					&dest_is_deref, &intercepted_p))
	{
	  if (src0.start != NULL_TREE
	      && !has_mem_ref_been_instrumented (&src0, src0_len))
	    return false;

	  if (src1.start != NULL_TREE
	      && !has_mem_ref_been_instrumented (&src1, src1_len))
	    return false;

	  if (dest.start != NULL_TREE
	      && !has_mem_ref_been_instrumented (&dest, dest_len))
	    return false;

	  return true;
	}
    }
  else if (is_gimple_call (stmt) && gimple_store_p (stmt))
    {
      asan_mem_ref r;
      asan_mem_ref_init (&r, NULL, 1);

      r.start = gimple_call_lhs (stmt);
      r.access_size = int_size_in_bytes (TREE_TYPE (r.start));
      return has_mem_ref_been_instrumented (&r);
    }

  return false;
}

/*  Insert a memory reference into the hash table.  */

static void
update_mem_ref_hash_table (tree ref, HOST_WIDE_INT access_size)
{
  hash_table<asan_mem_ref_hasher> *ht = get_mem_ref_hash_table ();

  asan_mem_ref r;
  asan_mem_ref_init (&r, ref, access_size);

  asan_mem_ref **slot = ht->find_slot (&r, INSERT);
  if (*slot == NULL || (*slot)->access_size < access_size)
    *slot = asan_mem_ref_new (ref, access_size);
}

/* Initialize shadow_ptr_types array.  */

static void
asan_init_shadow_ptr_types (void)
{
  asan_shadow_set = new_alias_set ();
  tree types[3] = { signed_char_type_node, short_integer_type_node,
		    integer_type_node };

  for (unsigned i = 0; i < 3; i++)
    {
      shadow_ptr_types[i] = build_distinct_type_copy (types[i]);
      TYPE_ALIAS_SET (shadow_ptr_types[i]) = asan_shadow_set;
      shadow_ptr_types[i] = build_pointer_type (shadow_ptr_types[i]);
    }

  initialize_sanitizer_builtins ();
}

/* Create ADDR_EXPR of STRING_CST with the PP pretty printer text.  */

static tree
asan_pp_string (pretty_printer *pp)
{
  const char *buf = pp_formatted_text (pp);
  size_t len = strlen (buf);
  tree ret = build_string (len + 1, buf);
  TREE_TYPE (ret)
    = build_array_type (TREE_TYPE (shadow_ptr_types[0]),
			build_index_type (size_int (len)));
  TREE_READONLY (ret) = 1;
  TREE_STATIC (ret) = 1;
  return build1 (ADDR_EXPR, shadow_ptr_types[0], ret);
}

/* Clear shadow memory at SHADOW_MEM, LEN bytes.  Can't call a library call here
   though.  */

static void
asan_clear_shadow (rtx shadow_mem, HOST_WIDE_INT len)
{
  rtx_insn *insn, *insns, *jump;
  rtx_code_label *top_label;
  rtx end, addr, tmp;

  gcc_assert ((len & 3) == 0);
  start_sequence ();
  clear_storage (shadow_mem, GEN_INT (len), BLOCK_OP_NORMAL);
  insns = get_insns ();
  end_sequence ();
  for (insn = insns; insn; insn = NEXT_INSN (insn))
    if (CALL_P (insn))
      break;
  if (insn == NULL_RTX)
    {
      emit_insn (insns);
      return;
    }

  top_label = gen_label_rtx ();
  addr = copy_to_mode_reg (Pmode, XEXP (shadow_mem, 0));
  shadow_mem = adjust_automodify_address (shadow_mem, SImode, addr, 0);
  end = force_reg (Pmode, plus_constant (Pmode, addr, len));
  emit_label (top_label);

  emit_move_insn (shadow_mem, const0_rtx);
  tmp = expand_simple_binop (Pmode, PLUS, addr, gen_int_mode (4, Pmode), addr,
			     true, OPTAB_LIB_WIDEN);
  if (tmp != addr)
    emit_move_insn (addr, tmp);
  emit_cmp_and_jump_insns (addr, end, LT, NULL_RTX, Pmode, true, top_label);
  jump = get_last_insn ();
  gcc_assert (JUMP_P (jump));
  add_reg_br_prob_note (jump,
			profile_probability::guessed_always ()
			   .apply_scale (80, 100));
}

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);
}

/* Return number of shadow bytes that are occupied by a local variable
   of SIZE bytes.  */

static unsigned HOST_WIDE_INT
shadow_mem_size (unsigned HOST_WIDE_INT size)
{
  /* It must be possible to align stack variables to granularity
     of shadow memory.  */
  gcc_assert (BITS_PER_UNIT
	      * ASAN_SHADOW_GRANULARITY <= MAX_SUPPORTED_STACK_ALIGNMENT);

  return ROUND_UP (size, ASAN_SHADOW_GRANULARITY) / ASAN_SHADOW_GRANULARITY;
}

/* Always emit 4 bytes at a time.  */
#define RZ_BUFFER_SIZE 4

/* ASAN redzone buffer container that handles emission of shadow bytes.  */
class asan_redzone_buffer
{
public:
  /* Constructor.  */
  asan_redzone_buffer (rtx shadow_mem, HOST_WIDE_INT prev_offset):
    m_shadow_mem (shadow_mem), m_prev_offset (prev_offset),
    m_original_offset (prev_offset), m_shadow_bytes (RZ_BUFFER_SIZE)
  {}

  /* Emit VALUE shadow byte at a given OFFSET.  */
  void emit_redzone_byte (HOST_WIDE_INT offset, unsigned char value);

  /* Emit RTX emission of the content of the buffer.  */
  void flush_redzone_payload (void);

private:
  /* Flush if the content of the buffer is full
     (equal to RZ_BUFFER_SIZE).  */
  void flush_if_full (void);

  /* Memory where we last emitted a redzone payload.  */
  rtx m_shadow_mem;

  /* Relative offset where we last emitted a redzone payload.  */
  HOST_WIDE_INT m_prev_offset;

  /* Relative original offset.  Used for checking only.  */
  HOST_WIDE_INT m_original_offset;

public:
  /* Buffer with redzone payload.  */
  auto_vec<unsigned char> m_shadow_bytes;
};

/* Emit VALUE shadow byte at a given OFFSET.  */

void
asan_redzone_buffer::emit_redzone_byte (HOST_WIDE_INT offset,
					unsigned char value)
{
  gcc_assert ((offset & (ASAN_SHADOW_GRANULARITY - 1)) == 0);
  gcc_assert (offset >= m_prev_offset);

  HOST_WIDE_INT off
    = m_prev_offset + ASAN_SHADOW_GRANULARITY * m_shadow_bytes.length ();
  if (off == offset)
    /* Consecutive shadow memory byte.  */;
  else if (offset < m_prev_offset + (HOST_WIDE_INT) (ASAN_SHADOW_GRANULARITY
						     * RZ_BUFFER_SIZE)
	   && !m_shadow_bytes.is_empty ())
    {
      /* Shadow memory byte with a small gap.  */
      for (; off < offset; off += ASAN_SHADOW_GRANULARITY)
	m_shadow_bytes.safe_push (0);
    }
  else
    {
      if (!m_shadow_bytes.is_empty ())
	flush_redzone_payload ();

      /* Maybe start earlier in order to use aligned store.  */
      HOST_WIDE_INT align = (offset - m_prev_offset) % ASAN_RED_ZONE_SIZE;
      if (align)
	{
	  offset -= align;
	  for (unsigned i = 0; i < align / BITS_PER_UNIT; i++)
	    m_shadow_bytes.safe_push (0);
	}

      /* Adjust m_prev_offset and m_shadow_mem.  */
      HOST_WIDE_INT diff = offset - m_prev_offset;
      m_shadow_mem = adjust_address (m_shadow_mem, VOIDmode,
				     diff >> ASAN_SHADOW_SHIFT);
      m_prev_offset = offset;
    }
  m_shadow_bytes.safe_push (value);
  flush_if_full ();
}

/* Emit RTX emission of the content of the buffer.  */

void
asan_redzone_buffer::flush_redzone_payload (void)
{
  gcc_assert (WORDS_BIG_ENDIAN == BYTES_BIG_ENDIAN);

  if (m_shadow_bytes.is_empty ())
    return;

  /* Be sure we always emit to an aligned address.  */
  gcc_assert (((m_prev_offset - m_original_offset)
	      & (ASAN_RED_ZONE_SIZE - 1)) == 0);

  /* Fill it to RZ_BUFFER_SIZE bytes with zeros if needed.  */
  unsigned l = m_shadow_bytes.length ();
  for (unsigned i = 0; i <= RZ_BUFFER_SIZE - l; i++)
    m_shadow_bytes.safe_push (0);

  if (dump_file && (dump_flags & TDF_DETAILS))
    fprintf (dump_file,
	     "Flushing rzbuffer at offset %" PRId64 " with: ", m_prev_offset);

  unsigned HOST_WIDE_INT val = 0;
  for (unsigned i = 0; i < RZ_BUFFER_SIZE; i++)
    {
      unsigned char v
	= m_shadow_bytes[BYTES_BIG_ENDIAN ? RZ_BUFFER_SIZE - i - 1 : i];
      val |= (unsigned HOST_WIDE_INT)v << (BITS_PER_UNIT * i);
      if (dump_file && (dump_flags & TDF_DETAILS))
	fprintf (dump_file, "%02x ", v);
    }

  if (dump_file && (dump_flags & TDF_DETAILS))
    fprintf (dump_file, "\n");

  rtx c = gen_int_mode (val, SImode);
  m_shadow_mem = adjust_address (m_shadow_mem, SImode, 0);
  emit_move_insn (m_shadow_mem, c);
  m_shadow_bytes.truncate (0);
}

/* Flush if the content of the buffer is full
   (equal to RZ_BUFFER_SIZE).  */

void
asan_redzone_buffer::flush_if_full (void)
{
  if (m_shadow_bytes.length () == RZ_BUFFER_SIZE)
    flush_redzone_payload ();
}


/* HWAddressSanitizer (hwasan) is a probabilistic method for detecting
   out-of-bounds and use-after-free bugs.
   Read more:
   http://code.google.com/p/address-sanitizer/

   Similar to AddressSanitizer (asan) it consists of two parts: the
   instrumentation module in this file, and a run-time library.

   The instrumentation module adds a run-time check before every memory insn in
   the same manner as asan (see the block comment for AddressSanitizer above).
   Currently, hwasan only adds out-of-line instrumentation, where each check is
   implemented as a function call to the run-time library.  Hence a check for a
   load of N bytes from address X would be implemented with a function call to
   __hwasan_loadN(X), and checking a store of N bytes from address X would be
   implemented with a function call to __hwasan_storeN(X).

   The main difference between hwasan and asan is in the information stored to
   help this checking.  Both sanitizers use a shadow memory area which stores
   data recording the state of main memory at a corresponding address.

   For hwasan, each 16 byte granule in main memory has a corresponding 1 byte
   in shadow memory.  This shadow address can be calculated with equation:
     (addr >> log_2(HWASAN_TAG_GRANULE_SIZE))
	  + __hwasan_shadow_memory_dynamic_address;
   The conversion between real and shadow memory for asan is given in the block
   comment at the top of this file.
   The description of how this shadow memory is laid out for asan is in the
   block comment at the top of this file, here we describe how this shadow
   memory is used for hwasan.

   For hwasan, each variable is assigned a byte-sized 'tag'.  The extent of
   the shadow memory for that variable is filled with the assigned tag, and
   every pointer referencing that variable has its top byte set to the same
   tag.  The run-time library redefines malloc so that every allocation returns
   a tagged pointer and tags the corresponding shadow memory with the same tag.

   On each pointer dereference the tag found in the pointer is compared to the
   tag found in the shadow memory corresponding to the accessed memory address.
   If these tags are found to differ then this memory access is judged to be
   invalid and a report is generated.

   This method of bug detection is not perfect -- it can not catch every bad
   access -- but catches them probabilistically instead.  There is always the
   possibility that an invalid memory access will happen to access memory
   tagged with the same tag as the pointer that this access used.
   The chances of this are approx. 0.4% for any two uncorrelated objects.

   Random tag generation can mitigate this problem by decreasing the
   probability that an invalid access will be missed in the same manner over
   multiple runs.  i.e. if two objects are tagged the same in one run of the
   binary they are unlikely to be tagged the same in the next run.
   Both heap and stack allocated objects have random tags by default.

   [16 byte granule implications]
    Since the shadow memory only has a resolution on real memory of 16 bytes,
    invalid accesses that are within the same 16 byte granule as a valid
    address will not be caught.

    There is a "short-granule" feature in the runtime library which does catch
    such accesses, but this feature is not implemented for stack objects (since
    stack objects are allocated and tagged by compiler instrumentation, and
    this feature has not yet been implemented in GCC instrumentation).

    Another outcome of this 16 byte resolution is that each tagged object must
    be 16 byte aligned.  If two objects were to share any 16 byte granule in
    memory, then they both would have to be given the same tag, and invalid
    accesses to one using a pointer to the other would be undetectable.

   [Compiler instrumentation]
    Compiler instrumentation ensures that two adjacent buffers on the stack are
    given different tags, this means an access to one buffer using a pointer
    generated from the other (e.g. through buffer overrun) will have mismatched
    tags and be caught by hwasan.

    We don't randomly tag every object on the stack, since that would require
    keeping many registers to record each tag.  Instead we randomly generate a
    tag for each function frame, and each new stack object uses a tag offset
    from that frame tag.
    i.e. each object is tagged as RFT + offset, where RFT is the "random frame
    tag" generated for this frame.
    This means that randomisation does not peturb the difference between tags
    on tagged stack objects within a frame, but this is mitigated by the fact
    that objects with the same tag within a frame are very far apart
    (approx. 2^HWASAN_TAG_SIZE objects apart).

    As a demonstration, using the same example program as in the asan block
    comment above:

     int
     foo ()
     {
       char a[24] = {0};
       int b[2] = {0};

       a[5] = 1;
       b[1] = 2;

       return a[5] + b[1];
     }

    On AArch64 the stack will be ordered as follows for the above function:

    Slot 1/ [24 bytes for variable 'a']
    Slot 2/ [8 bytes padding for alignment]
    Slot 3/ [8 bytes for variable 'b']
    Slot 4/ [8 bytes padding for alignment]

    (The padding is there to ensure 16 byte alignment as described in the 16
     byte granule implications).

    While the shadow memory will be ordered as follows:

    - 2 bytes (representing 32 bytes in real memory) tagged with RFT + 1.
    - 1 byte (representing 16 bytes in real memory) tagged with RFT + 2.

    And any pointer to "a" will have the tag RFT + 1, and any pointer to "b"
    will have the tag RFT + 2.

   [Top Byte Ignore requirements]
    Hwasan requires the ability to store an 8 bit tag in every pointer.  There
    is no instrumentation done to remove this tag from pointers before
    dereferencing, which means the hardware must ignore this tag during memory
    accesses.

    Architectures where this feature is available should indicate this using
    the TARGET_MEMTAG_CAN_TAG_ADDRESSES hook.

   [Stack requires cleanup on unwinding]
    During normal operation of a hwasan sanitized program more space in the
    shadow memory becomes tagged as the stack grows.  As the stack shrinks this
    shadow memory space must become untagged.  If it is not untagged then when
    the stack grows again (during other function calls later on in the program)
    objects on the stack that are usually not tagged (e.g. parameters passed on
    the stack) can be placed in memory whose shadow space is tagged with
    something else, and accesses can cause false positive reports.

    Hence we place untagging code on every epilogue of functions which tag some
    stack objects.

    Moreover, the run-time library intercepts longjmp & setjmp to untag when
    the stack is unwound this way.

    C++ exceptions are not yet handled, which means this sanitizer can not
    handle C++ code that throws exceptions -- it will give false positives
    after an exception has been thrown.  The implementation that the hwasan
    library has for handling these relies on the frame pointer being after any
    local variables.  This is not generally the case for GCC.  */


/* Returns whether we are tagging pointers and checking those tags on memory
   access.  */
bool
hwasan_sanitize_p ()
{
  return sanitize_flags_p (SANITIZE_HWADDRESS);
}

/* Are we tagging the stack?  */
bool
hwasan_sanitize_stack_p ()
{
  return (hwasan_sanitize_p () && param_hwasan_instrument_stack);
}

/* Are we tagging alloca objects?  */
bool
hwasan_sanitize_allocas_p (void)
{
  return (hwasan_sanitize_stack_p () && param_hwasan_instrument_allocas);
}

/* Should we instrument reads?  */
bool
hwasan_instrument_reads (void)
{
  return (hwasan_sanitize_p () && param_hwasan_instrument_reads);
}

/* Should we instrument writes?  */
bool
hwasan_instrument_writes (void)
{
  return (hwasan_sanitize_p () && param_hwasan_instrument_writes);
}

/* Should we instrument builtin calls?  */
bool
hwasan_memintrin (void)
{
  return (hwasan_sanitize_p () && param_hwasan_instrument_mem_intrinsics);
}

/* Insert code to protect stack vars.  The prologue sequence should be emitted
   directly, epilogue sequence returned.  BASE is the register holding the
   stack base, against which OFFSETS array offsets are relative to, OFFSETS
   array contains pairs of offsets in reverse order, always the end offset
   of some gap that needs protection followed by starting offset,
   and DECLS is an array of representative decls for each var partition.
   LENGTH is the length of the OFFSETS array, DECLS array is LENGTH / 2 - 1
   elements long (OFFSETS include gap before the first variable as well
   as gaps after each stack variable).  PBASE is, if non-NULL, some pseudo
   register which stack vars DECL_RTLs are based on.  Either BASE should be
   assigned to PBASE, when not doing use after return protection, or
   corresponding address based on __asan_stack_malloc* return value.  */

rtx_insn *
asan_emit_stack_protection (rtx base, rtx pbase, unsigned int alignb,
			    HOST_WIDE_INT *offsets, tree *decls, int length)
{
  rtx shadow_base, shadow_mem, ret, mem, orig_base;
  rtx_code_label *lab;
  rtx_insn *insns;
  char buf[32];
  HOST_WIDE_INT base_offset = offsets[length - 1];
  HOST_WIDE_INT base_align_bias = 0, offset, prev_offset;
  HOST_WIDE_INT asan_frame_size = offsets[0] - base_offset;
  HOST_WIDE_INT last_offset, last_size, last_size_aligned;
  int l;
  unsigned char cur_shadow_byte = ASAN_STACK_MAGIC_LEFT;
  tree str_cst, decl, id;
  int use_after_return_class = -1;

  if (shadow_ptr_types[0] == NULL_TREE)
    asan_init_shadow_ptr_types ();

  expanded_location cfun_xloc
    = expand_location (DECL_SOURCE_LOCATION (current_function_decl));

  /* First of all, prepare the description string.  */
  pretty_printer asan_pp;

  pp_decimal_int (&asan_pp, length / 2 - 1);
  pp_space (&asan_pp);
  for (l = length - 2; l; l -= 2)
    {
      tree decl = decls[l / 2 - 1];
      pp_wide_integer (&asan_pp, offsets[l] - base_offset);
      pp_space (&asan_pp);
      pp_wide_integer (&asan_pp, offsets[l - 1] - offsets[l]);
      pp_space (&asan_pp);

      expanded_location xloc
	= expand_location (DECL_SOURCE_LOCATION (decl));
      char location[32];

      if (xloc.file == cfun_xloc.file)
	sprintf (location, ":%d", xloc.line);
      else
	location[0] = '\0';

      if (DECL_P (decl) && DECL_NAME (decl))
	{
	  unsigned idlen
	    = IDENTIFIER_LENGTH (DECL_NAME (decl)) + strlen (location);
	  pp_decimal_int (&asan_pp, idlen);
	  pp_space (&asan_pp);
	  pp_tree_identifier (&asan_pp, DECL_NAME (decl));
	  pp_string (&asan_pp, location);
	}
      else
	pp_string (&asan_pp, "9 <unknown>");

      if (l > 2)
	pp_space (&asan_pp);
    }
  str_cst = asan_pp_string (&asan_pp);

  /* Emit the prologue sequence.  */
  if (asan_frame_size > 32 && asan_frame_size <= 65536 && pbase
      && param_asan_use_after_return)
    {
      use_after_return_class = floor_log2 (asan_frame_size - 1) - 5;
      /* __asan_stack_malloc_N guarantees alignment
	 N < 6 ? (64 << N) : 4096 bytes.  */
      if (alignb > (use_after_return_class < 6
		    ? (64U << use_after_return_class) : 4096U))
	use_after_return_class = -1;
      else if (alignb > ASAN_RED_ZONE_SIZE && (asan_frame_size & (alignb - 1)))
	base_align_bias = ((asan_frame_size + alignb - 1)
			   & ~(alignb - HOST_WIDE_INT_1)) - asan_frame_size;
    }

  /* Align base if target is STRICT_ALIGNMENT.  */
  if (STRICT_ALIGNMENT)
    {
      const HOST_WIDE_INT align
	= (GET_MODE_ALIGNMENT (SImode) / BITS_PER_UNIT) << ASAN_SHADOW_SHIFT;
      base = expand_binop (Pmode, and_optab, base, gen_int_mode (-align, Pmode),
			   NULL_RTX, 1, OPTAB_DIRECT);
    }

  if (use_after_return_class == -1 && pbase)
    emit_move_insn (pbase, base);

  base = expand_binop (Pmode, add_optab, base,
		       gen_int_mode (base_offset - base_align_bias, Pmode),
		       NULL_RTX, 1, OPTAB_DIRECT);
  orig_base = NULL_RTX;
  if (use_after_return_class != -1)
    {
      if (asan_detect_stack_use_after_return == NULL_TREE)
	{
	  id = get_identifier ("__asan_option_detect_stack_use_after_return");
	  decl = build_decl (BUILTINS_LOCATION, VAR_DECL, id,
			     integer_type_node);
	  SET_DECL_ASSEMBLER_NAME (decl, id);
	  TREE_ADDRESSABLE (decl) = 1;
	  DECL_ARTIFICIAL (decl) = 1;
	  DECL_IGNORED_P (decl) = 1;
	  DECL_EXTERNAL (decl) = 1;
	  TREE_STATIC (decl) = 1;
	  TREE_PUBLIC (decl) = 1;
	  TREE_USED (decl) = 1;
	  asan_detect_stack_use_after_return = decl;
	}
      orig_base = gen_reg_rtx (Pmode);
      emit_move_insn (orig_base, base);
      ret = expand_normal (asan_detect_stack_use_after_return);
      lab = gen_label_rtx ();
      emit_cmp_and_jump_insns (ret, const0_rtx, EQ, NULL_RTX,
			       VOIDmode, 0, lab,
			       profile_probability::very_likely ());
      snprintf (buf, sizeof buf, "__asan_stack_malloc_%d",
		use_after_return_class);
      ret = init_one_libfunc (buf);
      ret = emit_library_call_value (ret, NULL_RTX, LCT_NORMAL, ptr_mode,
				     GEN_INT (asan_frame_size
					      + base_align_bias),
				     TYPE_MODE (pointer_sized_int_node));
      /* __asan_stack_malloc_[n] returns a pointer to fake stack if succeeded
	 and NULL otherwise.  Check RET value is NULL here and jump over the
	 BASE reassignment in this case.  Otherwise, reassign BASE to RET.  */
      emit_cmp_and_jump_insns (ret, const0_rtx, EQ, NULL_RTX,
			       VOIDmode, 0, lab,
			       profile_probability:: very_unlikely ());
      ret = convert_memory_address (Pmode, ret);
      emit_move_insn (base, ret);
      emit_label (lab);
      emit_move_insn (pbase, expand_binop (Pmode, add_optab, base,
					   gen_int_mode (base_align_bias
							 - base_offset, Pmode),
					   NULL_RTX, 1, OPTAB_DIRECT));
    }
  mem = gen_rtx_MEM (ptr_mode, base);
  mem = adjust_address (mem, VOIDmode, base_align_bias);
  emit_move_insn (mem, gen_int_mode (ASAN_STACK_FRAME_MAGIC, ptr_mode));
  mem = adjust_address (mem, VOIDmode, GET_MODE_SIZE (ptr_mode));
  emit_move_insn (mem, expand_normal (str_cst));
  mem = adjust_address (mem, VOIDmode, GET_MODE_SIZE (ptr_mode));
  ASM_GENERATE_INTERNAL_LABEL (buf, "LASANPC", current_function_funcdef_no);
  id = get_identifier (buf);
  decl = build_decl (DECL_SOURCE_LOCATION (current_function_decl),
		    VAR_DECL, id, char_type_node);
  SET_DECL_ASSEMBLER_NAME (decl, id);
  TREE_ADDRESSABLE (decl) = 1;
  TREE_READONLY (decl) = 1;
  DECL_ARTIFICIAL (decl) = 1;
  DECL_IGNORED_P (decl) = 1;
  TREE_STATIC (decl) = 1;
  TREE_PUBLIC (decl) = 0;
  TREE_USED (decl) = 1;
  DECL_INITIAL (decl) = decl;
  TREE_ASM_WRITTEN (decl) = 1;
  TREE_ASM_WRITTEN (id) = 1;
  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),
			      NULL_RTX, 1, OPTAB_DIRECT);
  shadow_base
    = plus_constant (Pmode, shadow_base,
		     asan_shadow_offset ()
		     + (base_align_bias >> ASAN_SHADOW_SHIFT));
  gcc_assert (asan_shadow_set != -1
	      && (ASAN_RED_ZONE_SIZE >> ASAN_SHADOW_SHIFT) == 4);
  shadow_mem = gen_rtx_MEM (SImode, shadow_base);
  set_mem_alias_set (shadow_mem, asan_shadow_set);
  if (STRICT_ALIGNMENT)
    set_mem_align (shadow_mem, (GET_MODE_ALIGNMENT (SImode)));
  prev_offset = base_offset;

  asan_redzone_buffer rz_buffer (shadow_mem, prev_offset);
  for (l = length; l; l -= 2)
    {
      if (l == 2)
	cur_shadow_byte = ASAN_STACK_MAGIC_RIGHT;
      offset = offsets[l - 1];

      bool extra_byte = (offset - base_offset) & (ASAN_SHADOW_GRANULARITY - 1);
      /* If a red-zone is not aligned to ASAN_SHADOW_GRANULARITY then
	 the previous stack variable has size % ASAN_SHADOW_GRANULARITY != 0.
	 In that case we have to emit one extra byte that will describe
	 how many bytes (our of ASAN_SHADOW_GRANULARITY) can be accessed.  */
      if (extra_byte)
	{
	  HOST_WIDE_INT aoff
	    = base_offset + ((offset - base_offset)
			     & ~(ASAN_SHADOW_GRANULARITY - HOST_WIDE_INT_1));
	  rz_buffer.emit_redzone_byte (aoff, offset - aoff);
	  offset = aoff + ASAN_SHADOW_GRANULARITY;
	}

      /* Calculate size of red zone payload.  */
      while (offset < offsets[l - 2])
	{
	  rz_buffer.emit_redzone_byte (offset, cur_shadow_byte);
	  offset += ASAN_SHADOW_GRANULARITY;
	}

      cur_shadow_byte = ASAN_STACK_MAGIC_MIDDLE;
    }

  /* As the automatic variables are aligned to
     ASAN_RED_ZONE_SIZE / ASAN_SHADOW_GRANULARITY, the buffer should be
     flushed here.  */
  gcc_assert (rz_buffer.m_shadow_bytes.is_empty ());

  do_pending_stack_adjust ();

  /* Construct epilogue sequence.  */
  start_sequence ();

  lab = NULL;
  if (use_after_return_class != -1)
    {
      rtx_code_label *lab2 = gen_label_rtx ();
      char c = (char) ASAN_STACK_MAGIC_USE_AFTER_RET;
      emit_cmp_and_jump_insns (orig_base, base, EQ, NULL_RTX,
			       VOIDmode, 0, lab2,
			       profile_probability::very_likely ());
      shadow_mem = gen_rtx_MEM (BLKmode, shadow_base);
      set_mem_alias_set (shadow_mem, asan_shadow_set);
      mem = gen_rtx_MEM (ptr_mode, base);
      mem = adjust_address (mem, VOIDmode, base_align_bias);
      emit_move_insn (mem, gen_int_mode (ASAN_STACK_RETIRED_MAGIC, ptr_mode));
      unsigned HOST_WIDE_INT sz = asan_frame_size >> ASAN_SHADOW_SHIFT;
      if (use_after_return_class < 5
	  && can_store_by_pieces (sz, builtin_memset_read_str, &c,
				  BITS_PER_UNIT, true))
	{
	  /* Emit:
	       memset(ShadowBase, kAsanStackAfterReturnMagic, ShadowSize);
	       **SavedFlagPtr(FakeStack, class_id) = 0
	  */
	  store_by_pieces (shadow_mem, sz, builtin_memset_read_str, &c,
			   BITS_PER_UNIT, true, RETURN_BEGIN);

	  unsigned HOST_WIDE_INT offset
	    = (1 << (use_after_return_class + 6));
	  offset -= GET_MODE_SIZE (ptr_mode);
	  mem = gen_rtx_MEM (ptr_mode, base);
	  mem = adjust_address (mem, ptr_mode, offset);
	  rtx addr = gen_reg_rtx (ptr_mode);
	  emit_move_insn (addr, mem);
	  addr = convert_memory_address (Pmode, addr);
	  mem = gen_rtx_MEM (QImode, addr);
	  emit_move_insn (mem, const0_rtx);
	}
      else if (use_after_return_class >= 5
	       || !set_storage_via_setmem (shadow_mem,
					   GEN_INT (sz),
					   gen_int_mode (c, QImode),
					   BITS_PER_UNIT, BITS_PER_UNIT,
					   -1, sz, sz, sz))
	{
	  snprintf (buf, sizeof buf, "__asan_stack_free_%d",
		    use_after_return_class);
	  ret = init_one_libfunc (buf);
	  rtx addr = convert_memory_address (ptr_mode, base);
	  rtx orig_addr = convert_memory_address (ptr_mode, orig_base);
	  emit_library_call (ret, LCT_NORMAL, ptr_mode, addr, ptr_mode,
			     GEN_INT (asan_frame_size + base_align_bias),
			     TYPE_MODE (pointer_sized_int_node),
			     orig_addr, ptr_mode);
	}
      lab = gen_label_rtx ();
      emit_jump (lab);
      emit_label (lab2);
    }

  shadow_mem = gen_rtx_MEM (BLKmode, shadow_base);
  set_mem_alias_set (shadow_mem, asan_shadow_set);

  if (STRICT_ALIGNMENT)
    set_mem_align (shadow_mem, (GET_MODE_ALIGNMENT (SImode)));

  prev_offset = base_offset;
  last_offset = base_offset;
  last_size = 0;
  last_size_aligned = 0;
  for (l = length; l; l -= 2)
    {
      offset = base_offset + ((offsets[l - 1] - base_offset)
			      & ~(ASAN_RED_ZONE_SIZE - HOST_WIDE_INT_1));
      if (last_offset + last_size_aligned < offset)
	{
	  shadow_mem = adjust_address (shadow_mem, VOIDmode,
				       (last_offset - prev_offset)
				       >> ASAN_SHADOW_SHIFT);
	  prev_offset = last_offset;
	  asan_clear_shadow (shadow_mem, last_size_aligned >> ASAN_SHADOW_SHIFT);
	  last_offset = offset;
	  last_size = 0;
	}
      else
	last_size = offset - last_offset;
      last_size += base_offset + ((offsets[l - 2] - base_offset)
				  & ~(ASAN_MIN_RED_ZONE_SIZE - HOST_WIDE_INT_1))
		   - offset;

      /* Unpoison shadow memory that corresponds to a variable that is 
	 is subject of use-after-return sanitization.  */
      if (l > 2)
	{
	  decl = decls[l / 2 - 2];
	  if (asan_handled_variables != NULL
	      && asan_handled_variables->contains (decl))
	    {
	      HOST_WIDE_INT size = offsets[l - 3] - offsets[l - 2];
	      if (dump_file && (dump_flags & TDF_DETAILS))
		{
		  const char *n = (DECL_NAME (decl)
				   ? IDENTIFIER_POINTER (DECL_NAME (decl))
				   : "<unknown>");
		  fprintf (dump_file, "Unpoisoning shadow stack for variable: "
			   "%s (%" PRId64 " B)\n", n, size);
		}

		last_size += size & ~(ASAN_MIN_RED_ZONE_SIZE - HOST_WIDE_INT_1);
	    }
	}
      last_size_aligned
	= ((last_size + (ASAN_RED_ZONE_SIZE - HOST_WIDE_INT_1))
	   & ~(ASAN_RED_ZONE_SIZE - HOST_WIDE_INT_1));
    }
  if (last_size_aligned)
    {
      shadow_mem = adjust_address (shadow_mem, VOIDmode,
				   (last_offset - prev_offset)
				   >> ASAN_SHADOW_SHIFT);
      asan_clear_shadow (shadow_mem, last_size_aligned >> ASAN_SHADOW_SHIFT);
    }

  /* Clean-up set with instrumented stack variables.  */
  delete asan_handled_variables;
  asan_handled_variables = NULL;
  delete asan_used_labels;
  asan_used_labels = NULL;

  do_pending_stack_adjust ();
  if (lab)
    emit_label (lab);

  insns = get_insns ();
  end_sequence ();
  return insns;
}

/* Emit __asan_allocas_unpoison (top, bot) call.  The BASE parameter corresponds
   to BOT argument, for TOP virtual_stack_dynamic_rtx is used.  NEW_SEQUENCE
   indicates whether we're emitting new instructions sequence or not.  */

rtx_insn *
asan_emit_allocas_unpoison (rtx top, rtx bot, rtx_insn *before)
{
  if (before)
    push_to_sequence (before);
  else
    start_sequence ();
  rtx ret = init_one_libfunc ("__asan_allocas_unpoison");
  top = convert_memory_address (ptr_mode, top);
  bot = convert_memory_address (ptr_mode, bot);
  emit_library_call (ret, LCT_NORMAL, ptr_mode,
		     top, ptr_mode, bot, ptr_mode);

  do_pending_stack_adjust ();
  rtx_insn *insns = get_insns ();
  end_sequence ();
  return insns;
}

/* Return true if DECL, a global var, might be overridden and needs
   therefore a local alias.  */

static bool
asan_needs_local_alias (tree decl)
{
  return DECL_WEAK (decl) || !targetm.binds_local_p (decl);
}

/* Return true if DECL, a global var, is an artificial ODR indicator symbol
   therefore doesn't need protection.  */

static bool
is_odr_indicator (tree decl)
{
  return (DECL_ARTIFICIAL (decl)
	  && lookup_attribute ("asan odr indicator", DECL_ATTRIBUTES (decl)));
}

/* Return true if DECL is a VAR_DECL that should be protected
   by Address Sanitizer, by appending a red zone with protected
   shadow memory after it and aligning it to at least
   ASAN_RED_ZONE_SIZE bytes.  */

bool
asan_protect_global (tree decl, bool ignore_decl_rtl_set_p)
{
  if (!param_asan_globals)
    return false;

  rtx rtl, symbol;

  if (TREE_CODE (decl) == STRING_CST)
    {
      /* Instrument all STRING_CSTs except those created
	 by asan_pp_string here.  */
      if (shadow_ptr_types[0] != NULL_TREE
	  && TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE
	  && TREE_TYPE (TREE_TYPE (decl)) == TREE_TYPE (shadow_ptr_types[0]))
	return false;
      return true;
    }
  if (!VAR_P (decl)
      /* TLS vars aren't statically protectable.  */
      || DECL_THREAD_LOCAL_P (decl)
      /* Externs will be protected elsewhere.  */
      || DECL_EXTERNAL (decl)
      /* PR sanitizer/81697: For architectures that use section anchors first
	 call to asan_protect_global may occur before DECL_RTL (decl) is set.
	 We should ignore DECL_RTL_SET_P then, because otherwise the first call
	 to asan_protect_global will return FALSE and the following calls on the
	 same decl after setting DECL_RTL (decl) will return TRUE and we'll end
	 up with inconsistency at runtime.  */
      || (!DECL_RTL_SET_P (decl) && !ignore_decl_rtl_set_p)
      /* Comdat vars pose an ABI problem, we can't know if
	 the var that is selected by the linker will have
	 padding or not.  */
      || DECL_ONE_ONLY (decl)
      /* Similarly for common vars.  People can use -fno-common.
	 Note: Linux kernel is built with -fno-common, so we do instrument
	 globals there even if it is C.  */
      || (DECL_COMMON (decl) && TREE_PUBLIC (decl))
      /* Don't protect if using user section, often vars placed
	 into user section from multiple TUs are then assumed
	 to be an array of such vars, putting padding in there
	 breaks this assumption.  */
      || (DECL_SECTION_NAME (decl) != NULL
	  && !symtab_node::get (decl)->implicit_section
	  && !section_sanitized_p (DECL_SECTION_NAME (decl)))
      || DECL_SIZE (decl) == 0
      || ASAN_RED_ZONE_SIZE * BITS_PER_UNIT > MAX_OFILE_ALIGNMENT
      || TREE_CODE (DECL_SIZE_UNIT (decl)) != INTEGER_CST
      || !valid_constant_size_p (DECL_SIZE_UNIT (decl))
      || DECL_ALIGN_UNIT (decl) > 2 * ASAN_RED_ZONE_SIZE
      || TREE_TYPE (decl) == ubsan_get_source_location_type ()
      || is_odr_indicator (decl))
    return false;

  if (!ignore_decl_rtl_set_p || DECL_RTL_SET_P (decl))
    {

      rtl = DECL_RTL (decl);
      if (!MEM_P (rtl) || GET_CODE (XEXP (rtl, 0)) != SYMBOL_REF)
	return false;
      symbol = XEXP (rtl, 0);

      if (CONSTANT_POOL_ADDRESS_P (symbol)
	  || TREE_CONSTANT_POOL_ADDRESS_P (symbol))
	return false;
    }

  if (lookup_attribute ("weakref", DECL_ATTRIBUTES (decl)))
    return false;

  if (!TARGET_SUPPORTS_ALIASES && asan_needs_local_alias (decl))
    return false;

  return true;
}

/* Construct a function tree for __asan_report_{load,store}{1,2,4,8,16,_n}.
   IS_STORE is either 1 (for a store) or 0 (for a load).  */

static tree
report_error_func (bool is_store, bool recover_p, HOST_WIDE_INT size_in_bytes,
		   int *nargs)
{
  gcc_assert (!hwasan_sanitize_p ());

  static enum built_in_function report[2][2][6]
    = { { { BUILT_IN_ASAN_REPORT_LOAD1, BUILT_IN_ASAN_REPORT_LOAD2,
	    BUILT_IN_ASAN_REPORT_LOAD4, BUILT_IN_ASAN_REPORT_LOAD8,
	    BUILT_IN_ASAN_REPORT_LOAD16, BUILT_IN_ASAN_REPORT_LOAD_N },
	  { BUILT_IN_ASAN_REPORT_STORE1, BUILT_IN_ASAN_REPORT_STORE2,
	    BUILT_IN_ASAN_REPORT_STORE4, BUILT_IN_ASAN_REPORT_STORE8,
	    BUILT_IN_ASAN_REPORT_STORE16, BUILT_IN_ASAN_REPORT_STORE_N } },
	{ { BUILT_IN_ASAN_REPORT_LOAD1_NOABORT,
	    BUILT_IN_ASAN_REPORT_LOAD2_NOABORT,
	    BUILT_IN_ASAN_REPORT_LOAD4_NOABORT,
	    BUILT_IN_ASAN_REPORT_LOAD8_NOABORT,
	    BUILT_IN_ASAN_REPORT_LOAD16_NOABORT,
	    BUILT_IN_ASAN_REPORT_LOAD_N_NOABORT },
	  { BUILT_IN_ASAN_REPORT_STORE1_NOABORT,
	    BUILT_IN_ASAN_REPORT_STORE2_NOABORT,
	    BUILT_IN_ASAN_REPORT_STORE4_NOABORT,
	    BUILT_IN_ASAN_REPORT_STORE8_NOABORT,
	    BUILT_IN_ASAN_REPORT_STORE16_NOABORT,
	    BUILT_IN_ASAN_REPORT_STORE_N_NOABORT } } };
  if (size_in_bytes == -1)
    {
      *nargs = 2;
      return builtin_decl_implicit (report[recover_p][is_store][5]);
    }
  *nargs = 1;
  int size_log2 = exact_log2 (size_in_bytes);
  return builtin_decl_implicit (report[recover_p][is_store][size_log2]);
}

/* Construct a function tree for __asan_{load,store}{1,2,4,8,16,_n}.
   IS_STORE is either 1 (for a store) or 0 (for a load).  */

static tree
check_func (bool is_store, bool recover_p, HOST_WIDE_INT size_in_bytes,
	    int *nargs)
{
  static enum built_in_function check[2][2][6]
    = { { { BUILT_IN_ASAN_LOAD1, BUILT_IN_ASAN_LOAD2,
	    BUILT_IN_ASAN_LOAD4, BUILT_IN_ASAN_LOAD8,
	    BUILT_IN_ASAN_LOAD16, BUILT_IN_ASAN_LOADN },
	  { BUILT_IN_ASAN_STORE1, BUILT_IN_ASAN_STORE2,
	    BUILT_IN_ASAN_STORE4, BUILT_IN_ASAN_STORE8,
	    BUILT_IN_ASAN_STORE16, BUILT_IN_ASAN_STOREN } },
	{ { BUILT_IN_ASAN_LOAD1_NOABORT,
	    BUILT_IN_ASAN_LOAD2_NOABORT,
	    BUILT_IN_ASAN_LOAD4_NOABORT,
	    BUILT_IN_ASAN_LOAD8_NOABORT,
	    BUILT_IN_ASAN_LOAD16_NOABORT,
	    BUILT_IN_ASAN_LOADN_NOABORT },
	  { BUILT_IN_ASAN_STORE1_NOABORT,
	    BUILT_IN_ASAN_STORE2_NOABORT,
	    BUILT_IN_ASAN_STORE4_NOABORT,
	    BUILT_IN_ASAN_STORE8_NOABORT,
	    BUILT_IN_ASAN_STORE16_NOABORT,
	    BUILT_IN_ASAN_STOREN_NOABORT } } };
  if (size_in_bytes == -1)
    {
      *nargs = 2;
      return builtin_decl_implicit (check[recover_p][is_store][5]);
    }
  *nargs = 1;
  int size_log2 = exact_log2 (size_in_bytes);
  return builtin_decl_implicit (check[recover_p][is_store][size_log2]);
}

/* Split the current basic block and create a condition statement
   insertion point right before or after the statement pointed to by
   ITER.  Return an iterator to the point at which the caller might
   safely insert the condition statement.

   THEN_BLOCK must be set to the address of an uninitialized instance
   of basic_block.  The function will then set *THEN_BLOCK to the
   'then block' of the condition statement to be inserted by the
   caller.

   If CREATE_THEN_FALLTHRU_EDGE is false, no edge will be created from
   *THEN_BLOCK to *FALLTHROUGH_BLOCK.

   Similarly, the function will set *FALLTRHOUGH_BLOCK to the 'else
   block' of the condition statement to be inserted by the caller.

   Note that *FALLTHROUGH_BLOCK is a new block that contains the
   statements starting from *ITER, and *THEN_BLOCK is a new empty
   block.

   *ITER is adjusted to point to always point to the first statement
    of the basic block * FALLTHROUGH_BLOCK.  That statement is the
    same as what ITER was pointing to prior to calling this function,
    if BEFORE_P is true; otherwise, it is its following statement.  */

gimple_stmt_iterator
create_cond_insert_point (gimple_stmt_iterator *iter,
			  bool before_p,
			  bool then_more_likely_p,
			  bool create_then_fallthru_edge,
			  basic_block *then_block,
			  basic_block *fallthrough_block)
{
  gimple_stmt_iterator gsi = *iter;

  if (!gsi_end_p (gsi) && before_p)
    gsi_prev (&gsi);

  basic_block cur_bb = gsi_bb (*iter);

  edge e = split_block (cur_bb, gsi_stmt (gsi));

  /* Get a hold on the 'condition block', the 'then block' and the
     'else block'.  */
  basic_block cond_bb = e->src;
  basic_block fallthru_bb = e->dest;
  basic_block then_bb = create_empty_bb (cond_bb);
  if (current_loops)
    {
      add_bb_to_loop (then_bb, cond_bb->loop_father);
      loops_state_set (LOOPS_NEED_FIXUP);
    }

  /* Set up the newly created 'then block'.  */
  e = make_edge (cond_bb, then_bb, EDGE_TRUE_VALUE);
  profile_probability fallthrough_probability
    = then_more_likely_p
    ? profile_probability::very_unlikely ()
    : profile_probability::very_likely ();
  e->probability = fallthrough_probability.invert ();
  then_bb->count = e->count ();
  if (create_then_fallthru_edge)
    make_single_succ_edge (then_bb, fallthru_bb, EDGE_FALLTHRU);

  /* Set up the fallthrough basic block.  */
  e = find_edge (cond_bb, fallthru_bb);
  e->flags = EDGE_FALSE_VALUE;
  e->probability = fallthrough_probability;

  /* Update dominance info for the newly created then_bb; note that
     fallthru_bb's dominance info has already been updated by
     split_bock.  */
  if (dom_info_available_p (CDI_DOMINATORS))
    set_immediate_dominator (CDI_DOMINATORS, then_bb, cond_bb);

  *then_block = then_bb;
  *fallthrough_block = fallthru_bb;
  *iter = gsi_start_bb (fallthru_bb);

  return gsi_last_bb (cond_bb);
}

/* Insert an if condition followed by a 'then block' right before the
   statement pointed to by ITER.  The fallthrough block -- which is the
   else block of the condition as well as the destination of the
   outcoming edge of the 'then block' -- starts with the statement
   pointed to by ITER.

   COND is the condition of the if.

   If THEN_MORE_LIKELY_P is true, the probability of the edge to the
   'then block' is higher than the probability of the edge to the
   fallthrough block.

   Upon completion of the function, *THEN_BB is set to the newly
   inserted 'then block' and similarly, *FALLTHROUGH_BB is set to the
   fallthrough block.

   *ITER is adjusted to still point to the same statement it was
   pointing to initially.  */

static void
insert_if_then_before_iter (gcond *cond,
			    gimple_stmt_iterator *iter,
			    bool then_more_likely_p,
			    basic_block *then_bb,
			    basic_block *fallthrough_bb)
{
  gimple_stmt_iterator cond_insert_point =
    create_cond_insert_point (iter,
			      /*before_p=*/true,
			      then_more_likely_p,
			      /*create_then_fallthru_edge=*/true,
			      then_bb,
			      fallthrough_bb);
  gsi_insert_after (&cond_insert_point, cond, GSI_NEW_STMT);
}

/* Build (base_addr >> ASAN_SHADOW_SHIFT) + asan_shadow_offset ().
   If RETURN_ADDRESS is set to true, return memory location instread
   of a value in the shadow memory.  */

static tree
build_shadow_mem_access (gimple_stmt_iterator *gsi, location_t location,
			 tree base_addr, tree shadow_ptr_type,
			 bool return_address = false)
{
  tree t, uintptr_type = TREE_TYPE (base_addr);
  tree shadow_type = TREE_TYPE (shadow_ptr_type);
  gimple *g;

  t = build_int_cst (uintptr_type, ASAN_SHADOW_SHIFT);
  g = gimple_build_assign (make_ssa_name (uintptr_type), RSHIFT_EXPR,
			   base_addr, t);
  gimple_set_location (g, location);
  gsi_insert_after (gsi, g, GSI_NEW_STMT);

  t = build_int_cst (uintptr_type, asan_shadow_offset ());
  g = gimple_build_assign (make_ssa_name (uintptr_type), PLUS_EXPR,
			   gimple_assign_lhs (g), t);
  gimple_set_location (g, location);
  gsi_insert_after (gsi, g, GSI_NEW_STMT);

  g = gimple_build_assign (make_ssa_name (shadow_ptr_type), NOP_EXPR,
			   gimple_assign_lhs (g));
  gimple_set_location (g, location);
  gsi_insert_after (gsi, g, GSI_NEW_STMT);

  if (!return_address)
    {
      t = build2 (MEM_REF, shadow_type, gimple_assign_lhs (g),
		  build_int_cst (shadow_ptr_type, 0));
      g = gimple_build_assign (make_ssa_name (shadow_type), MEM_REF, t);
      gimple_set_location (g, location);
      gsi_insert_after (gsi, g, GSI_NEW_STMT);
    }

  return gimple_assign_lhs (g);
}

/* BASE can already be an SSA_NAME; in that case, do not create a
   new SSA_NAME for it.  */

static tree
maybe_create_ssa_name (location_t loc, tree base, gimple_stmt_iterator *iter,
		       bool before_p)
{
  STRIP_USELESS_TYPE_CONVERSION (base);
  if (TREE_CODE (base) == SSA_NAME)
    return base;
  gimple *g = gimple_build_assign (make_ssa_name (TREE_TYPE (base)), base);
  gimple_set_location (g, loc);
  if (before_p)
    gsi_insert_before (iter, g, GSI_SAME_STMT);
  else
    gsi_insert_after (iter, g, GSI_NEW_STMT);
  return gimple_assign_lhs (g);
}

/* LEN can already have necessary size and precision;
   in that case, do not create a new variable.  */

tree
maybe_cast_to_ptrmode (location_t loc, tree len, gimple_stmt_iterator *iter,
		       bool before_p)
{
  if (ptrofftype_p (len))
    return len;
  gimple *g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
				  NOP_EXPR, len);
  gimple_set_location (g, loc);
  if (before_p)
    gsi_insert_before (iter, g, GSI_SAME_STMT);
  else
    gsi_insert_after (iter, g, GSI_NEW_STMT);
  return gimple_assign_lhs (g);
}

/* Instrument the memory access instruction BASE.  Insert new
   statements before or after ITER.

   Note that the memory access represented by BASE can be either an
   SSA_NAME, or a non-SSA expression.  LOCATION is the source code
   location.  IS_STORE is TRUE for a store, FALSE for a load.
   BEFORE_P is TRUE for inserting the instrumentation code before
   ITER, FALSE for inserting it after ITER.  IS_SCALAR_ACCESS is TRUE
   for a scalar memory access and FALSE for memory region access.
   NON_ZERO_P is TRUE if memory region is guaranteed to have non-zero
   length.  ALIGN tells alignment of accessed memory object.

   START_INSTRUMENTED and END_INSTRUMENTED are TRUE if start/end of
   memory region have already been instrumented.

   If BEFORE_P is TRUE, *ITER is arranged to still point to the
   statement it was pointing to prior to calling this function,
   otherwise, it points to the statement logically following it.  */

static void
build_check_stmt (location_t loc, tree base, tree len,
		  HOST_WIDE_INT size_in_bytes, gimple_stmt_iterator *iter,
		  bool is_non_zero_len, bool before_p, bool is_store,
		  bool is_scalar_access, unsigned int align = 0)
{
  gimple_stmt_iterator gsi = *iter;
  gimple *g;

  gcc_assert (!(size_in_bytes > 0 && !is_non_zero_len));
  gcc_assert (size_in_bytes == -1 || size_in_bytes >= 1);

  gsi = *iter;

  base = unshare_expr (base);
  base = maybe_create_ssa_name (loc, base, &gsi, before_p);

  if (len)
    {
      len = unshare_expr (len);
      len = maybe_cast_to_ptrmode (loc, len, iter, before_p);
    }
  else
    {
      gcc_assert (size_in_bytes != -1);
      len = build_int_cst (pointer_sized_int_node, size_in_bytes);
    }

  if (size_in_bytes > 1)
    {
      if ((size_in_bytes & (size_in_bytes - 1)) != 0
	  || size_in_bytes > 16)
	is_scalar_access = false;
      else if (align && align < size_in_bytes * BITS_PER_UNIT)
	{
	  /* On non-strict alignment targets, if
	     16-byte access is just 8-byte aligned,
	     this will result in misaligned shadow
	     memory 2 byte load, but otherwise can
	     be handled using one read.  */
	  if (size_in_bytes != 16
	      || STRICT_ALIGNMENT
	      || align < 8 * BITS_PER_UNIT)
	    is_scalar_access = false;
	}
    }

  HOST_WIDE_INT flags = 0;
  if (is_store)
    flags |= ASAN_CHECK_STORE;
  if (is_non_zero_len)
    flags |= ASAN_CHECK_NON_ZERO_LEN;
  if (is_scalar_access)
    flags |= ASAN_CHECK_SCALAR_ACCESS;

  enum internal_fn fn = hwasan_sanitize_p ()
    ? IFN_HWASAN_CHECK
    : IFN_ASAN_CHECK;

  g = gimple_build_call_internal (fn, 4,
				  build_int_cst (integer_type_node, flags),
				  base, len,
				  build_int_cst (integer_type_node,
						 align / BITS_PER_UNIT));
  gimple_set_location (g, loc);
  if (before_p)
    gsi_insert_before (&gsi, g, GSI_SAME_STMT);
  else
    {
      gsi_insert_after (&gsi, g, GSI_NEW_STMT);
      gsi_next (&gsi);
      *iter = gsi;
    }
}

/* If T represents a memory access, add instrumentation code before ITER.
   LOCATION is source code location.
   IS_STORE is either TRUE (for a store) or FALSE (for a load).  */

static void
instrument_derefs (gimple_stmt_iterator *iter, tree t,
		   location_t location, bool is_store)
{
  if (is_store && !(asan_instrument_writes () || hwasan_instrument_writes ()))
    return;
  if (!is_store && !(asan_instrument_reads () || hwasan_instrument_reads ()))
    return;

  tree type, base;
  HOST_WIDE_INT size_in_bytes;
  if (location == UNKNOWN_LOCATION)
    location = EXPR_LOCATION (t);

  type = TREE_TYPE (t);
  switch (TREE_CODE (t))
    {
    case ARRAY_REF:
    case COMPONENT_REF:
    case INDIRECT_REF:
    case MEM_REF:
    case VAR_DECL:
    case BIT_FIELD_REF:
      break;
      /* FALLTHRU */
    default:
      return;
    }

  size_in_bytes = int_size_in_bytes (type);
  if (size_in_bytes <= 0)
    return;

  poly_int64 bitsize, bitpos;
  tree offset;
  machine_mode mode;
  int unsignedp, reversep, volatilep = 0;
  tree inner = get_inner_reference (t, &bitsize, &bitpos, &offset, &mode,
				    &unsignedp, &reversep, &volatilep);

  if (TREE_CODE (t) == COMPONENT_REF
      && DECL_BIT_FIELD_REPRESENTATIVE (TREE_OPERAND (t, 1)) != NULL_TREE)
    {
      tree repr = DECL_BIT_FIELD_REPRESENTATIVE (TREE_OPERAND (t, 1));
      instrument_derefs (iter, build3 (COMPONENT_REF, TREE_TYPE (repr),
				       TREE_OPERAND (t, 0), repr,
				       TREE_OPERAND (t, 2)),
			 location, is_store);
      return;
    }

  if (!multiple_p (bitpos, BITS_PER_UNIT)
      || maybe_ne (bitsize, size_in_bytes * BITS_PER_UNIT))
    return;

  if (VAR_P (inner) && DECL_HARD_REGISTER (inner))
    return;

  poly_int64 decl_size;
  if ((VAR_P (inner) || TREE_CODE (inner) == RESULT_DECL)
      && offset == NULL_TREE
      && DECL_SIZE (inner)
      && poly_int_tree_p (DECL_SIZE (inner), &decl_size)
      && known_subrange_p (bitpos, bitsize, 0, decl_size))
    {
      if (VAR_P (inner) && DECL_THREAD_LOCAL_P (inner))
	return;
      /* If we're not sanitizing globals and we can tell statically that this
	 access is inside a global variable, then there's no point adding
	 instrumentation to check the access.  N.b. hwasan currently never
	 sanitizes globals.  */
      if ((hwasan_sanitize_p () || !param_asan_globals)
	  && is_global_var (inner))
        return;
      if (!TREE_STATIC (inner))
	{
	  /* Automatic vars in the current function will be always
	     accessible.  */
	  if (decl_function_context (inner) == current_function_decl
	      && (!asan_sanitize_use_after_scope ()
		  || !TREE_ADDRESSABLE (inner)))
	    return;
	}
      /* Always instrument external vars, they might be dynamically
	 initialized.  */
      else if (!DECL_EXTERNAL (inner))
	{
	  /* For static vars if they are known not to be dynamically
	     initialized, they will be always accessible.  */
	  varpool_node *vnode = varpool_node::get (inner);
	  if (vnode && !vnode->dynamically_initialized)
	    return;
	}
    }

  if (DECL_P (inner)
      && decl_function_context (inner) == current_function_decl
      && !TREE_ADDRESSABLE (inner))
    mark_addressable (inner);

  base = build_fold_addr_expr (t);
  if (!has_mem_ref_been_instrumented (base, size_in_bytes))
    {
      unsigned int align = get_object_alignment (t);
      build_check_stmt (location, base, NULL_TREE, size_in_bytes, iter,
			/*is_non_zero_len*/size_in_bytes > 0, /*before_p=*/true,
			is_store, /*is_scalar_access*/true, align);
      update_mem_ref_hash_table (base, size_in_bytes);
      update_mem_ref_hash_table (t, size_in_bytes);
    }

}

/*  Insert a memory reference into the hash table if access length
    can be determined in compile time.  */

static void
maybe_update_mem_ref_hash_table (tree base, tree len)
{
  if (!POINTER_TYPE_P (TREE_TYPE (base))
      || !INTEGRAL_TYPE_P (TREE_TYPE (len)))
    return;

  HOST_WIDE_INT size_in_bytes = tree_fits_shwi_p (len) ? tree_to_shwi (len) : -1;

  if (size_in_bytes != -1)
    update_mem_ref_hash_table (base, size_in_bytes);
}

/* Instrument an access to a contiguous memory region that starts at
   the address pointed to by BASE, over a length of LEN (expressed in
   the sizeof (*BASE) bytes).  ITER points to the instruction before
   which the instrumentation instructions must be inserted.  LOCATION
   is the source location that the instrumentation instructions must
   have.  If IS_STORE is true, then the memory access is a store;
   otherwise, it's a load.  */

static void
instrument_mem_region_access (tree base, tree len,
			      gimple_stmt_iterator *iter,
			      location_t location, bool is_store)
{
  if (!POINTER_TYPE_P (TREE_TYPE (base))
      || !INTEGRAL_TYPE_P (TREE_TYPE (len))
      || integer_zerop (len))
    return;

  HOST_WIDE_INT size_in_bytes = tree_fits_shwi_p (len) ? tree_to_shwi (len) : -1;

  if ((size_in_bytes == -1)
      || !has_mem_ref_been_instrumented (base, size_in_bytes))
    {
      build_check_stmt (location, base, len, size_in_bytes, iter,
			/*is_non_zero_len*/size_in_bytes > 0, /*before_p*/true,
			is_store, /*is_scalar_access*/false, /*align*/0);
    }

  maybe_update_mem_ref_hash_table (base, len);
  *iter = gsi_for_stmt (gsi_stmt (*iter));
}

/* Instrument the call to a built-in memory access function that is
   pointed to by the iterator ITER.

   Upon completion, return TRUE iff *ITER has been advanced to the
   statement following the one it was originally pointing to.  */

static bool
instrument_builtin_call (gimple_stmt_iterator *iter)
{
  if (!(asan_memintrin () || hwasan_memintrin ()))
    return false;

  bool iter_advanced_p = false;
  gcall *call = as_a <gcall *> (gsi_stmt (*iter));

  gcc_checking_assert (gimple_call_builtin_p (call, BUILT_IN_NORMAL));

  location_t loc = gimple_location (call);

  asan_mem_ref src0, src1, dest;
  asan_mem_ref_init (&src0, NULL, 1);
  asan_mem_ref_init (&src1, NULL, 1);
  asan_mem_ref_init (&dest, NULL, 1);

  tree src0_len = NULL_TREE, src1_len = NULL_TREE, dest_len = NULL_TREE;
  bool src0_is_store = false, src1_is_store = false, dest_is_store = false,
    dest_is_deref = false, intercepted_p = true;

  if (get_mem_refs_of_builtin_call (call,
				    &src0, &src0_len, &src0_is_store,
				    &src1, &src1_len, &src1_is_store,
				    &dest, &dest_len, &dest_is_store,
				    &dest_is_deref, &intercepted_p, iter))
    {
      if (dest_is_deref)
	{
	  instrument_derefs (iter, dest.start, loc, dest_is_store);
	  gsi_next (iter);
	  iter_advanced_p = true;
	}
      else if (!intercepted_p
	       && (src0_len || src1_len || dest_len))
	{
	  if (src0.start != NULL_TREE)
	    instrument_mem_region_access (src0.start, src0_len,
					  iter, loc, /*is_store=*/false);
	  if (src1.start != NULL_TREE)
	    instrument_mem_region_access (src1.start, src1_len,
					  iter, loc, /*is_store=*/false);
	  if (dest.start != NULL_TREE)
	    instrument_mem_region_access (dest.start, dest_len,
					  iter, loc, /*is_store=*/true);

	  *iter = gsi_for_stmt (call);
	  gsi_next (iter);
	  iter_advanced_p = true;
	}
      else
	{
	  if (src0.start != NULL_TREE)
	    maybe_update_mem_ref_hash_table (src0.start, src0_len);
	  if (src1.start != NULL_TREE)
	    maybe_update_mem_ref_hash_table (src1.start, src1_len);
	  if (dest.start != NULL_TREE)
	    maybe_update_mem_ref_hash_table (dest.start, dest_len);
	}
    }
  return iter_advanced_p;
}

/*  Instrument the assignment statement ITER if it is subject to
    instrumentation.  Return TRUE iff instrumentation actually
    happened.  In that case, the iterator ITER is advanced to the next
    logical expression following the one initially pointed to by ITER,
    and the relevant memory reference that which access has been
    instrumented is added to the memory references hash table.  */

static bool
maybe_instrument_assignment (gimple_stmt_iterator *iter)
{
  gimple *s = gsi_stmt (*iter);

  gcc_assert (gimple_assign_single_p (s));

  tree ref_expr = NULL_TREE;
  bool is_store, is_instrumented = false;

  if (gimple_store_p (s))
    {
      ref_expr = gimple_assign_lhs (s);
      is_store = true;
      instrument_derefs (iter, ref_expr,
			 gimple_location (s),
			 is_store);
      is_instrumented = true;
    }

  if (gimple_assign_load_p (s))
    {
      ref_expr = gimple_assign_rhs1 (s);
      is_store = false;
      instrument_derefs (iter, ref_expr,
			 gimple_location (s),
			 is_store);
      is_instrumented = true;
    }

  if (is_instrumented)
    gsi_next (iter);

  return is_instrumented;
}

/* Instrument the function call pointed to by the iterator ITER, if it
   is subject to instrumentation.  At the moment, the only function
   calls that are instrumented are some built-in functions that access
   memory.  Look at instrument_builtin_call to learn more.

   Upon completion return TRUE iff *ITER was advanced to the statement
   following the one it was originally pointing to.  */

static bool
maybe_instrument_call (gimple_stmt_iterator *iter)
{
  gimple *stmt = gsi_stmt (*iter);
  bool is_builtin = gimple_call_builtin_p (stmt, BUILT_IN_NORMAL);

  if (is_builtin && instrument_builtin_call (iter))
    return true;

  if (gimple_call_noreturn_p (stmt))
    {
      if (is_builtin)
	{
	  tree callee = gimple_call_fndecl (stmt);
	  switch (DECL_FUNCTION_CODE (callee))
	    {
	    case BUILT_IN_UNREACHABLE:
	    case BUILT_IN_TRAP:
	      /* Don't instrument these.  */
	      return false;
	    default:
	      break;
	    }
	}
      /* If a function does not return, then we must handle clearing up the
	 shadow stack accordingly.  For ASAN we can simply set the entire stack
	 to "valid" for accesses by setting the shadow space to 0 and all
	 accesses will pass checks.  That means that some bad accesses may be
	 missed, but we will not report any false positives.

	 This is not possible for HWASAN.  Since there is no "always valid" tag
	 we can not set any space to "always valid".  If we were to clear the
	 entire shadow stack then code resuming from `longjmp` or a caught
	 exception would trigger false positives when correctly accessing
	 variables on the stack.  Hence we need to handle things like
	 `longjmp`, thread exit, and exceptions in a different way.  These
	 problems must be handled externally to the compiler, e.g. in the
	 language runtime.  */
      if (! hwasan_sanitize_p ())
	{
	  tree decl = builtin_decl_implicit (BUILT_IN_ASAN_HANDLE_NO_RETURN);
	  gimple *g = gimple_build_call (decl, 0);
	  gimple_set_location (g, gimple_location (stmt));
	  gsi_insert_before (iter, g, GSI_SAME_STMT);
	}
    }

  bool instrumented = false;
  if (gimple_store_p (stmt))
    {
      tree ref_expr = gimple_call_lhs (stmt);
      instrument_derefs (iter, ref_expr,
			 gimple_location (stmt),
			 /*is_store=*/true);

      instrumented = true;
    }

  /* Walk through gimple_call arguments and check them id needed.  */
  unsigned args_num = gimple_call_num_args (stmt);
  for (unsigned i = 0; i < args_num; ++i)
    {
      tree arg = gimple_call_arg (stmt, i);
      /* If ARG is not a non-aggregate register variable, compiler in general
	 creates temporary for it and pass it as argument to gimple call.
	 But in some cases, e.g. when we pass by value a small structure that
	 fits to register, compiler can avoid extra overhead by pulling out
	 these temporaries.  In this case, we should check the argument.  */
      if (!is_gimple_reg (arg) && !is_gimple_min_invariant (arg))
	{
	  instrument_derefs (iter, arg,
			     gimple_location (stmt),
			     /*is_store=*/false);
	  instrumented = true;
	}
    }
  if (instrumented)
    gsi_next (iter);
  return instrumented;
}

/* Walk each instruction of all basic block and instrument those that
   represent memory references: loads, stores, or function calls.
   In a given basic block, this function avoids instrumenting memory
   references that have already been instrumented.  */

static void
transform_statements (void)
{
  basic_block bb, last_bb = NULL;
  gimple_stmt_iterator i;
  int saved_last_basic_block = last_basic_block_for_fn (cfun);

  FOR_EACH_BB_FN (bb, cfun)
    {
      basic_block prev_bb = bb;

      if (bb->index >= saved_last_basic_block) continue;

      /* Flush the mem ref hash table, if current bb doesn't have
	 exactly one predecessor, or if that predecessor (skipping
	 over asan created basic blocks) isn't the last processed
	 basic block.  Thus we effectively flush on extended basic
	 block boundaries.  */
      while (single_pred_p (prev_bb))
	{
	  prev_bb = single_pred (prev_bb);
	  if (prev_bb->index < saved_last_basic_block)
	    break;
	}
      if (prev_bb != last_bb)
	empty_mem_ref_hash_table ();
      last_bb = bb;

      for (i = gsi_start_bb (bb); !gsi_end_p (i);)
	{
	  gimple *s = gsi_stmt (i);

	  if (has_stmt_been_instrumented_p (s))
	    gsi_next (&i);
	  else if (gimple_assign_single_p (s)
		   && !gimple_clobber_p (s)
		   && maybe_instrument_assignment (&i))
	    /*  Nothing to do as maybe_instrument_assignment advanced
		the iterator I.  */;
	  else if (is_gimple_call (s) && maybe_instrument_call (&i))
	    /*  Nothing to do as maybe_instrument_call
		advanced the iterator I.  */;
	  else
	    {
	      /* No instrumentation happened.

		 If the current instruction is a function call that
		 might free something, let's forget about the memory
		 references that got instrumented.  Otherwise we might
		 miss some instrumentation opportunities.  Do the same
		 for a ASAN_MARK poisoning internal function.  */
	      if (is_gimple_call (s)
		  && (!nonfreeing_call_p (s)
		      || asan_mark_p (s, ASAN_MARK_POISON)))
		empty_mem_ref_hash_table ();

	      gsi_next (&i);
	    }
	}
    }
  free_mem_ref_resources ();
}

/* Build
   __asan_before_dynamic_init (module_name)
   or
   __asan_after_dynamic_init ()
   call.  */

tree
asan_dynamic_init_call (bool after_p)
{
  if (shadow_ptr_types[0] == NULL_TREE)
    asan_init_shadow_ptr_types ();

  tree fn = builtin_decl_implicit (after_p
				   ? BUILT_IN_ASAN_AFTER_DYNAMIC_INIT
				   : BUILT_IN_ASAN_BEFORE_DYNAMIC_INIT);
  tree module_name_cst = NULL_TREE;
  if (!after_p)
    {
      pretty_printer module_name_pp;
      pp_string (&module_name_pp, main_input_filename);

      module_name_cst = asan_pp_string (&module_name_pp);
      module_name_cst = fold_convert (const_ptr_type_node,
				      module_name_cst);
    }

  return build_call_expr (fn, after_p ? 0 : 1, module_name_cst);
}

/* Build
   struct __asan_global
   {
     const void *__beg;
     uptr __size;
     uptr __size_with_redzone;
     const void *__name;
     const void *__module_name;
     uptr __has_dynamic_init;
     __asan_global_source_location *__location;
     char *__odr_indicator;
   } type.  */

static tree
asan_global_struct (void)
{
  static const char *field_names[]
    = { "__beg", "__size", "__size_with_redzone",
	"__name", "__module_name", "__has_dynamic_init", "__location",
	"__odr_indicator" };
  tree fields[ARRAY_SIZE (field_names)], ret;
  unsigned i;

  ret = make_node (RECORD_TYPE);
  for (i = 0; i < ARRAY_SIZE (field_names); i++)
    {
      fields[i]
	= build_decl (UNKNOWN_LOCATION, FIELD_DECL,
		      get_identifier (field_names[i]),
		      (i == 0 || i == 3) ? const_ptr_type_node
		      : pointer_sized_int_node);
      DECL_CONTEXT (fields[i]) = ret;
      if (i)
	DECL_CHAIN (fields[i - 1]) = fields[i];
    }
  tree type_decl = build_decl (input_location, TYPE_DECL,
			       get_identifier ("__asan_global"), ret);
  DECL_IGNORED_P (type_decl) = 1;
  DECL_ARTIFICIAL (type_decl) = 1;
  TYPE_FIELDS (ret) = fields[0];
  TYPE_NAME (ret) = type_decl;
  TYPE_STUB_DECL (ret) = type_decl;
  TYPE_ARTIFICIAL (ret) = 1;
  layout_type (ret);
  return ret;
}

/* Create and return odr indicator symbol for DECL.
   TYPE is __asan_global struct type as returned by asan_global_struct.  */

static tree
create_odr_indicator (tree decl, tree type)
{
  char *name;
  tree uptr = TREE_TYPE (DECL_CHAIN (TYPE_FIELDS (type)));
  tree decl_name
    = (HAS_DECL_ASSEMBLER_NAME_P (decl) ? DECL_ASSEMBLER_NAME (decl)
					: DECL_NAME (decl));
  /* DECL_NAME theoretically might be NULL.  Bail out with 0 in this case.  */
  if (decl_name == NULL_TREE)
    return build_int_cst (uptr, 0);
  const char *dname = IDENTIFIER_POINTER (decl_name);
  if (HAS_DECL_ASSEMBLER_NAME_P (decl))
    dname = targetm.strip_name_encoding (dname);
  size_t len = strlen (dname) + sizeof ("__odr_asan_");
  name = XALLOCAVEC (char, len);
  snprintf (name, len, "__odr_asan_%s", dname);
#ifndef NO_DOT_IN_LABEL
  name[sizeof ("__odr_asan") - 1] = '.';
#elif !defined(NO_DOLLAR_IN_LABEL)
  name[sizeof ("__odr_asan") - 1] = '$';
#endif
  tree var = build_decl (UNKNOWN_LOCATION, VAR_DECL, get_identifier (name),
			 char_type_node);
  TREE_ADDRESSABLE (var) = 1;
  TREE_READONLY (var) = 0;
  TREE_THIS_VOLATILE (var) = 1;
  DECL_ARTIFICIAL (var) = 1;
  DECL_IGNORED_P (var) = 1;
  TREE_STATIC (var) = 1;
  TREE_PUBLIC (var) = 1;
  DECL_VISIBILITY (var) = DECL_VISIBILITY (decl);
  DECL_VISIBILITY_SPECIFIED (var) = DECL_VISIBILITY_SPECIFIED (decl);

  TREE_USED (var) = 1;
  tree ctor = build_constructor_va (TREE_TYPE (var), 1, NULL_TREE,
				    build_int_cst (unsigned_type_node, 0));
  TREE_CONSTANT (ctor) = 1;
  TREE_STATIC (ctor) = 1;
  DECL_INITIAL (var) = ctor;
  DECL_ATTRIBUTES (var) = tree_cons (get_identifier ("asan odr indicator"),
				     NULL, DECL_ATTRIBUTES (var));
  make_decl_rtl (var);
  varpool_node::finalize_decl (var);
  return fold_convert (uptr, build_fold_addr_expr (var));
}

/* Return true if DECL, a global var, might be overridden and needs
   an additional odr indicator symbol.  */

static bool
asan_needs_odr_indicator_p (tree decl)
{
  /* Don't emit ODR indicators for kernel because:
     a) Kernel is written in C thus doesn't need ODR indicators.
     b) Some kernel code may have assumptions about symbols containing specific
        patterns in their names.  Since ODR indicators contain original names
        of symbols they are emitted for, these assumptions would be broken for
        ODR indicator symbols.  */
  return (!(flag_sanitize & SANITIZE_KERNEL_ADDRESS)
	  && !DECL_ARTIFICIAL (decl)
	  && !DECL_WEAK (decl)
	  && TREE_PUBLIC (decl));
}

/* Append description of a single global DECL into vector V.
   TYPE is __asan_global struct type as returned by asan_global_struct.  */

static void
asan_add_global (tree decl, tree type, vec<constructor_elt, va_gc> *v)
{
  tree init, uptr = TREE_TYPE (DECL_CHAIN (TYPE_FIELDS (type)));
  unsigned HOST_WIDE_INT size;
  tree str_cst, module_name_cst, refdecl = decl;
  vec<constructor_elt, va_gc> *vinner = NULL;

  pretty_printer asan_pp, module_name_pp;

  if (DECL_NAME (decl))
    pp_tree_identifier (&asan_pp, DECL_NAME (decl));
  else
    pp_string (&asan_pp, "<unknown>");
  str_cst = asan_pp_string (&asan_pp);

  pp_string (&module_name_pp, main_input_filename);
  module_name_cst = asan_pp_string (&module_name_pp);

  if (asan_needs_local_alias (decl))
    {
      char buf[20];
      ASM_GENERATE_INTERNAL_LABEL (buf, "LASAN", vec_safe_length (v) + 1);
      refdecl = build_decl (DECL_SOURCE_LOCATION (decl),
			    VAR_DECL, get_identifier (buf), TREE_TYPE (decl));
      TREE_ADDRESSABLE (refdecl) = TREE_ADDRESSABLE (decl);
      TREE_READONLY (refdecl) = TREE_READONLY (decl);
      TREE_THIS_VOLATILE (refdecl) = TREE_THIS_VOLATILE (decl);
      DECL_NOT_GIMPLE_REG_P (refdecl) = DECL_NOT_GIMPLE_REG_P (decl);
      DECL_ARTIFICIAL (refdecl) = DECL_ARTIFICIAL (decl);
      DECL_IGNORED_P (refdecl) = DECL_IGNORED_P (decl);
      TREE_STATIC (refdecl) = 1;
      TREE_PUBLIC (refdecl) = 0;
      TREE_USED (refdecl) = 1;
      assemble_alias (refdecl, DECL_ASSEMBLER_NAME (decl));
    }

  tree odr_indicator_ptr
    = (asan_needs_odr_indicator_p (decl) ? create_odr_indicator (decl, type)
					 : build_int_cst (uptr, 0));
  CONSTRUCTOR_APPEND_ELT (vinner, NULL_TREE,
			  fold_convert (const_ptr_type_node,
					build_fold_addr_expr (refdecl)));
  size = tree_to_uhwi (DECL_SIZE_UNIT (decl));
  CONSTRUCTOR_APPEND_ELT (vinner, NULL_TREE, build_int_cst (uptr, size));
  size += asan_red_zone_size (size);
  CONSTRUCTOR_APPEND_ELT (vinner, NULL_TREE, build_int_cst (uptr, size));
  CONSTRUCTOR_APPEND_ELT (vinner, NULL_TREE,
			  fold_convert (const_ptr_type_node, str_cst));
  CONSTRUCTOR_APPEND_ELT (vinner, NULL_TREE,
			  fold_convert (const_ptr_type_node, module_name_cst));
  varpool_node *vnode = varpool_node::get (decl);
  int has_dynamic_init = 0;
  /* FIXME: Enable initialization order fiasco detection in LTO mode once
     proper fix for PR 79061 will be applied.  */
  if (!in_lto_p)
    has_dynamic_init = vnode ? vnode->dynamically_initialized : 0;
  CONSTRUCTOR_APPEND_ELT (vinner, NULL_TREE,
			  build_int_cst (uptr, has_dynamic_init));
  tree locptr = NULL_TREE;
  location_t loc = DECL_SOURCE_LOCATION (decl);
  expanded_location xloc = expand_location (loc);
  if (xloc.file != NULL)
    {
      static int lasanloccnt = 0;
      char buf[25];
      ASM_GENERATE_INTERNAL_LABEL (buf, "LASANLOC", ++lasanloccnt);
      tree var = build_decl (UNKNOWN_LOCATION, VAR_DECL, get_identifier (buf),
			     ubsan_get_source_location_type ());
      TREE_STATIC (var) = 1;
      TREE_PUBLIC (var) = 0;
      DECL_ARTIFICIAL (var) = 1;
      DECL_IGNORED_P (var) = 1;
      pretty_printer filename_pp;
      pp_string (&filename_pp, xloc.file);
      tree str = asan_pp_string (&filename_pp);
      tree ctor = build_constructor_va (TREE_TYPE (var), 3,
					NULL_TREE, str, NULL_TREE,
					build_int_cst (unsigned_type_node,
						       xloc.line), NULL_TREE,
					build_int_cst (unsigned_type_node,
						       xloc.column));
      TREE_CONSTANT (ctor) = 1;
      TREE_STATIC (ctor) = 1;
      DECL_INITIAL (var) = ctor;
      varpool_node::finalize_decl (var);
      locptr = fold_convert (uptr, build_fold_addr_expr (var));
    }
  else
    locptr = build_int_cst (uptr, 0);
  CONSTRUCTOR_APPEND_ELT (vinner, NULL_TREE, locptr);
  CONSTRUCTOR_APPEND_ELT (vinner, NULL_TREE, odr_indicator_ptr);
  init = build_constructor (type, vinner);
  CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, init);
}

/* Initialize sanitizer.def builtins if the FE hasn't initialized them.  */
void
initialize_sanitizer_builtins (void)
{
  tree decl;

  if (builtin_decl_implicit_p (BUILT_IN_ASAN_INIT))
    return;

  tree BT_FN_VOID = build_function_type_list (void_type_node, NULL_TREE);
  tree BT_FN_VOID_PTR
    = build_function_type_list (void_type_node, ptr_type_node, NULL_TREE);
  tree BT_FN_VOID_CONST_PTR
    = build_function_type_list (void_type_node, const_ptr_type_node, NULL_TREE);
  tree BT_FN_VOID_PTR_PTR
    = build_function_type_list (void_type_node, ptr_type_node,
				ptr_type_node, NULL_TREE);
  tree BT_FN_VOID_PTR_PTR_PTR
    = build_function_type_list (void_type_node, ptr_type_node,
				ptr_type_node, ptr_type_node, NULL_TREE);
  tree BT_FN_VOID_PTR_PTRMODE
    = build_function_type_list (void_type_node, ptr_type_node,
				pointer_sized_int_node, NULL_TREE);
  tree BT_FN_VOID_INT
    = build_function_type_list (void_type_node, integer_type_node, NULL_TREE);
  tree BT_FN_SIZE_CONST_PTR_INT
    = build_function_type_list (size_type_node, const_ptr_type_node,
				integer_type_node, NULL_TREE);

  tree BT_FN_VOID_UINT8_UINT8
    = build_function_type_list (void_type_node, unsigned_char_type_node,
				unsigned_char_type_node, NULL_TREE);
  tree BT_FN_VOID_UINT16_UINT16
    = build_function_type_list (void_type_node, uint16_type_node,
				uint16_type_node, NULL_TREE);
  tree BT_FN_VOID_UINT32_UINT32
    = build_function_type_list (void_type_node, uint32_type_node,
				uint32_type_node, NULL_TREE);
  tree BT_FN_VOID_UINT64_UINT64
    = build_function_type_list (void_type_node, uint64_type_node,
				uint64_type_node, NULL_TREE);
  tree BT_FN_VOID_FLOAT_FLOAT
    = build_function_type_list (void_type_node, float_type_node,
				float_type_node, NULL_TREE);
  tree BT_FN_VOID_DOUBLE_DOUBLE
    = build_function_type_list (void_type_node, double_type_node,
				double_type_node, NULL_TREE);
  tree BT_FN_VOID_UINT64_PTR
    = build_function_type_list (void_type_node, uint64_type_node,
				ptr_type_node, NULL_TREE);

  tree BT_FN_PTR_CONST_PTR_UINT8
    = build_function_type_list (ptr_type_node, const_ptr_type_node,
				unsigned_char_type_node, NULL_TREE);
  tree BT_FN_VOID_PTR_UINT8_PTRMODE
    = build_function_type_list (void_type_node, ptr_type_node,
				unsigned_char_type_node,
				pointer_sized_int_node, NULL_TREE);

  tree BT_FN_BOOL_VPTR_PTR_IX_INT_INT[5];
  tree BT_FN_IX_CONST_VPTR_INT[5];
  tree BT_FN_IX_VPTR_IX_INT[5];
  tree BT_FN_VOID_VPTR_IX_INT[5];
  tree vptr
    = build_pointer_type (build_qualified_type (void_type_node,
						TYPE_QUAL_VOLATILE));
  tree cvptr
    = build_pointer_type (build_qualified_type (void_type_node,
						TYPE_QUAL_VOLATILE
						|TYPE_QUAL_CONST));
  tree boolt
    = lang_hooks.types.type_for_size (BOOL_TYPE_SIZE, 1);
  int i;
  for (i = 0; i < 5; i++)
    {
      tree ix = build_nonstandard_integer_type (BITS_PER_UNIT * (1 << i), 1);
      BT_FN_BOOL_VPTR_PTR_IX_INT_INT[i]
	= build_function_type_list (boolt, vptr, ptr_type_node, ix,
				    integer_type_node, integer_type_node,
				    NULL_TREE);
      BT_FN_IX_CONST_VPTR_INT[i]
	= build_function_type_list (ix, cvptr, integer_type_node, NULL_TREE);
      BT_FN_IX_VPTR_IX_INT[i]
	= build_function_type_list (ix, vptr, ix, integer_type_node,
				    NULL_TREE);
      BT_FN_VOID_VPTR_IX_INT[i]
	= build_function_type_list (void_type_node, vptr, ix,
				    integer_type_node, NULL_TREE);
    }
#define BT_FN_BOOL_VPTR_PTR_I1_INT_INT BT_FN_BOOL_VPTR_PTR_IX_INT_INT[0]
#define BT_FN_I1_CONST_VPTR_INT BT_FN_IX_CONST_VPTR_INT[0]
#define BT_FN_I1_VPTR_I1_INT BT_FN_IX_VPTR_IX_INT[0]
#define BT_FN_VOID_VPTR_I1_INT BT_FN_VOID_VPTR_IX_INT[0]
#define BT_FN_BOOL_VPTR_PTR_I2_INT_INT BT_FN_BOOL_VPTR_PTR_IX_INT_INT[1]
#define BT_FN_I2_CONST_VPTR_INT BT_FN_IX_CONST_VPTR_INT[1]
#define BT_FN_I2_VPTR_I2_INT BT_FN_IX_VPTR_IX_INT[1]
#define BT_FN_VOID_VPTR_I2_INT BT_FN_VOID_VPTR_IX_INT[1]
#define BT_FN_BOOL_VPTR_PTR_I4_INT_INT BT_FN_BOOL_VPTR_PTR_IX_INT_INT[2]
#define BT_FN_I4_CONST_VPTR_INT BT_FN_IX_CONST_VPTR_INT[2]
#define BT_FN_I4_VPTR_I4_INT BT_FN_IX_VPTR_IX_INT[2]
#define BT_FN_VOID_VPTR_I4_INT BT_FN_VOID_VPTR_IX_INT[2]
#define BT_FN_BOOL_VPTR_PTR_I8_INT_INT BT_FN_BOOL_VPTR_PTR_IX_INT_INT[3]
#define BT_FN_I8_CONST_VPTR_INT BT_FN_IX_CONST_VPTR_INT[3]
#define BT_FN_I8_VPTR_I8_INT BT_FN_IX_VPTR_IX_INT[3]
#define BT_FN_VOID_VPTR_I8_INT BT_FN_VOID_VPTR_IX_INT[3]
#define BT_FN_BOOL_VPTR_PTR_I16_INT_INT BT_FN_BOOL_VPTR_PTR_IX_INT_INT[4]
#define BT_FN_I16_CONST_VPTR_INT BT_FN_IX_CONST_VPTR_INT[4]
#define BT_FN_I16_VPTR_I16_INT BT_FN_IX_VPTR_IX_INT[4]
#define BT_FN_VOID_VPTR_I16_INT BT_FN_VOID_VPTR_IX_INT[4]
#undef ATTR_NOTHROW_LIST
#define ATTR_NOTHROW_LIST ECF_NOTHROW
#undef ATTR_NOTHROW_LEAF_LIST
#define ATTR_NOTHROW_LEAF_LIST ECF_NOTHROW | ECF_LEAF
#undef ATTR_TMPURE_NOTHROW_LEAF_LIST
#define ATTR_TMPURE_NOTHROW_LEAF_LIST ECF_TM_PURE | ATTR_NOTHROW_LEAF_LIST
#undef ATTR_NORETURN_NOTHROW_LEAF_LIST
#define ATTR_NORETURN_NOTHROW_LEAF_LIST ECF_NORETURN | ATTR_NOTHROW_LEAF_LIST
#undef ATTR_CONST_NORETURN_NOTHROW_LEAF_LIST
#define ATTR_CONST_NORETURN_NOTHROW_LEAF_LIST \
  ECF_CONST | ATTR_NORETURN_NOTHROW_LEAF_LIST
#undef ATTR_TMPURE_NORETURN_NOTHROW_LEAF_LIST
#define ATTR_TMPURE_NORETURN_NOTHROW_LEAF_LIST \
  ECF_TM_PURE | ATTR_NORETURN_NOTHROW_LEAF_LIST
#undef ATTR_COLD_NOTHROW_LEAF_LIST
#define ATTR_COLD_NOTHROW_LEAF_LIST \
  /* ECF_COLD missing */ ATTR_NOTHROW_LEAF_LIST
#undef ATTR_COLD_NORETURN_NOTHROW_LEAF_LIST
#define ATTR_COLD_NORETURN_NOTHROW_LEAF_LIST \
  /* ECF_COLD missing */ ATTR_NORETURN_NOTHROW_LEAF_LIST
#undef ATTR_COLD_CONST_NORETURN_NOTHROW_LEAF_LIST
#define ATTR_COLD_CONST_NORETURN_NOTHROW_LEAF_LIST \
  /* ECF_COLD missing */ ATTR_CONST_NORETURN_NOTHROW_LEAF_LIST
#undef ATTR_PURE_NOTHROW_LEAF_LIST
#define ATTR_PURE_NOTHROW_LEAF_LIST ECF_PURE | ATTR_NOTHROW_LEAF_LIST
#undef DEF_BUILTIN_STUB
#define DEF_BUILTIN_STUB(ENUM, NAME)
#undef DEF_SANITIZER_BUILTIN_1
#define DEF_SANITIZER_BUILTIN_1(ENUM, NAME, TYPE, ATTRS)		\
  do {									\
    decl = add_builtin_function ("__builtin_" NAME, TYPE, ENUM,		\
				 BUILT_IN_NORMAL, NAME, NULL_TREE);	\
    set_call_expr_flags (decl, ATTRS);					\
    set_builtin_decl (ENUM, decl, true);				\
  } while (0)
#undef DEF_SANITIZER_BUILTIN
#define DEF_SANITIZER_BUILTIN(ENUM, NAME, TYPE, ATTRS)	\
  DEF_SANITIZER_BUILTIN_1 (ENUM, NAME, TYPE, ATTRS);

#include "sanitizer.def"

  /* -fsanitize=object-size uses __builtin_dynamic_object_size and
     __builtin_object_size, but they might not be available for e.g. Fortran at
     this point.  We use DEF_SANITIZER_BUILTIN here only as a convenience
     macro.  */
  if (flag_sanitize & SANITIZE_OBJECT_SIZE)
    {
      if (!builtin_decl_implicit_p (BUILT_IN_OBJECT_SIZE))
	DEF_SANITIZER_BUILTIN_1 (BUILT_IN_OBJECT_SIZE, "object_size",
				 BT_FN_SIZE_CONST_PTR_INT,
				 ATTR_PURE_NOTHROW_LEAF_LIST);
      if (!builtin_decl_implicit_p (BUILT_IN_DYNAMIC_OBJECT_SIZE))
	DEF_SANITIZER_BUILTIN_1 (BUILT_IN_DYNAMIC_OBJECT_SIZE,
				 "dynamic_object_size",
				 BT_FN_SIZE_CONST_PTR_INT,
				 ATTR_PURE_NOTHROW_LEAF_LIST);
    }

#undef DEF_SANITIZER_BUILTIN_1
#undef DEF_SANITIZER_BUILTIN
#undef DEF_BUILTIN_STUB
}

/* Called via htab_traverse.  Count number of emitted
   STRING_CSTs in the constant hash table.  */

int
count_string_csts (constant_descriptor_tree **slot,
		   unsigned HOST_WIDE_INT *data)
{
  struct constant_descriptor_tree *desc = *slot;
  if (TREE_CODE (desc->value) == STRING_CST
      && TREE_ASM_WRITTEN (desc->value)
      && asan_protect_global (desc->value))
    ++*data;
  return 1;
}

/* Helper structure to pass two parameters to
   add_string_csts.  */

struct asan_add_string_csts_data
{
  tree type;
  vec<constructor_elt, va_gc> *v;
};

/* Called via hash_table::traverse.  Call asan_add_global
   on emitted STRING_CSTs from the constant hash table.  */

int
add_string_csts (constant_descriptor_tree **slot,
		 asan_add_string_csts_data *aascd)
{
  struct constant_descriptor_tree *desc = *slot;
  if (TREE_CODE (desc->value) == STRING_CST
      && TREE_ASM_WRITTEN (desc->value)
      && asan_protect_global (desc->value))
    {
      asan_add_global (SYMBOL_REF_DECL (XEXP (desc->rtl, 0)),
		       aascd->type, aascd->v);
    }
  return 1;
}

/* Needs to be GTY(()), because cgraph_build_static_cdtor may
   invoke ggc_collect.  */
static GTY(()) tree asan_ctor_statements;

/* Module-level instrumentation.
   - Insert __asan_init_vN() into the list of CTORs.
   - TODO: insert redzones around globals.
 */

void
asan_finish_file (void)
{
  varpool_node *vnode;
  unsigned HOST_WIDE_INT gcount = 0;

  if (shadow_ptr_types[0] == NULL_TREE)
    asan_init_shadow_ptr_types ();
  /* Avoid instrumenting code in the asan ctors/dtors.
     We don't need to insert padding after the description strings,
     nor after .LASAN* array.  */
  flag_sanitize &= ~SANITIZE_ADDRESS;

  /* For user-space we want asan constructors to run first.
     Linux kernel does not support priorities other than default, and the only
     other user of constructors is coverage. So we run with the default
     priority.  */
  int priority = flag_sanitize & SANITIZE_USER_ADDRESS
                 ? MAX_RESERVED_INIT_PRIORITY - 1 : DEFAULT_INIT_PRIORITY;

  if (flag_sanitize & SANITIZE_USER_ADDRESS)
    {
      tree fn = builtin_decl_implicit (BUILT_IN_ASAN_INIT);
      append_to_statement_list (build_call_expr (fn, 0), &asan_ctor_statements);
      fn = builtin_decl_implicit (BUILT_IN_ASAN_VERSION_MISMATCH_CHECK);
      append_to_statement_list (build_call_expr (fn, 0), &asan_ctor_statements);
    }
  FOR_EACH_DEFINED_VARIABLE (vnode)
    if (TREE_ASM_WRITTEN (vnode->decl)
	&& asan_protect_global (vnode->decl))
      ++gcount;
  hash_table<tree_descriptor_hasher> *const_desc_htab = constant_pool_htab ();
  const_desc_htab->traverse<unsigned HOST_WIDE_INT *, count_string_csts>
    (&gcount);
  if (gcount)
    {
      tree type = asan_global_struct (), var, ctor;
      tree dtor_statements = NULL_TREE;
      vec<constructor_elt, va_gc> *v;
      char buf[20];

      type = build_array_type_nelts (type, gcount);
      ASM_GENERATE_INTERNAL_LABEL (buf, "LASAN", 0);
      var = build_decl (UNKNOWN_LOCATION, VAR_DECL, get_identifier (buf),
			type);
      TREE_STATIC (var) = 1;
      TREE_PUBLIC (var) = 0;
      DECL_ARTIFICIAL (var) = 1;
      DECL_IGNORED_P (var) = 1;
      vec_alloc (v, gcount);
      FOR_EACH_DEFINED_VARIABLE (vnode)
	if (TREE_ASM_WRITTEN (vnode->decl)
	    && asan_protect_global (vnode->decl))
	  asan_add_global (vnode->decl, TREE_TYPE (type), v);
      struct asan_add_string_csts_data aascd;
      aascd.type = TREE_TYPE (type);
      aascd.v = v;
      const_desc_htab->traverse<asan_add_string_csts_data *, add_string_csts>
       	(&aascd);
      ctor = build_constructor (type, v);
      TREE_CONSTANT (ctor) = 1;
      TREE_STATIC (ctor) = 1;
      DECL_INITIAL (var) = ctor;
      SET_DECL_ALIGN (var, MAX (DECL_ALIGN (var),
				ASAN_SHADOW_GRANULARITY * BITS_PER_UNIT));

      varpool_node::finalize_decl (var);

      tree fn = builtin_decl_implicit (BUILT_IN_ASAN_REGISTER_GLOBALS);
      tree gcount_tree = build_int_cst (pointer_sized_int_node, gcount);
      append_to_statement_list (build_call_expr (fn, 2,
						 build_fold_addr_expr (var),
						 gcount_tree),
				&asan_ctor_statements);

      fn = builtin_decl_implicit (BUILT_IN_ASAN_UNREGISTER_GLOBALS);
      append_to_statement_list (build_call_expr (fn, 2,
						 build_fold_addr_expr (var),
						 gcount_tree),
				&dtor_statements);
      cgraph_build_static_cdtor ('D', dtor_statements, priority);
    }
  if (asan_ctor_statements)
    cgraph_build_static_cdtor ('I', asan_ctor_statements, priority);
  flag_sanitize |= SANITIZE_ADDRESS;
}

/* Poison or unpoison (depending on IS_CLOBBER variable) shadow memory based
   on SHADOW address.  Newly added statements will be added to ITER with
   given location LOC.  We mark SIZE bytes in shadow memory, where
   LAST_CHUNK_SIZE is greater than zero in situation where we are at the
   end of a variable.  */

static void
asan_store_shadow_bytes (gimple_stmt_iterator *iter, location_t loc,
			 tree shadow,
			 unsigned HOST_WIDE_INT base_addr_offset,
			 bool is_clobber, unsigned size,
			 unsigned last_chunk_size)
{
  tree shadow_ptr_type;

  switch (size)
    {
    case 1:
      shadow_ptr_type = shadow_ptr_types[0];
      break;
    case 2:
      shadow_ptr_type = shadow_ptr_types[1];
      break;
    case 4:
      shadow_ptr_type = shadow_ptr_types[2];
      break;
    default:
      gcc_unreachable ();
    }

  unsigned char c = (char) is_clobber ? ASAN_STACK_MAGIC_USE_AFTER_SCOPE : 0;
  unsigned HOST_WIDE_INT val = 0;
  unsigned last_pos = size;
  if (last_chunk_size && !is_clobber)
    last_pos = BYTES_BIG_ENDIAN ? 0 : size - 1;
  for (unsigned i = 0; i < size; ++i)
    {
      unsigned char shadow_c = c;
      if (i == last_pos)
	shadow_c = last_chunk_size;
      val |= (unsigned HOST_WIDE_INT) shadow_c << (BITS_PER_UNIT * i);
    }

  /* Handle last chunk in unpoisoning.  */
  tree magic = build_int_cst (TREE_TYPE (shadow_ptr_type), val);

  tree dest = build2 (MEM_REF, TREE_TYPE (shadow_ptr_type), shadow,
		      build_int_cst (shadow_ptr_type, base_addr_offset));

  gimple *g = gimple_build_assign (dest, magic);
  gimple_set_location (g, loc);
  gsi_insert_after (iter, g, GSI_NEW_STMT);
}

/* Expand the ASAN_MARK builtins.  */

bool
asan_expand_mark_ifn (gimple_stmt_iterator *iter)
{
  gimple *g = gsi_stmt (*iter);
  location_t loc = gimple_location (g);
  HOST_WIDE_INT flag = tree_to_shwi (gimple_call_arg (g, 0));
  bool is_poison = ((asan_mark_flags)flag) == ASAN_MARK_POISON;

  tree base = gimple_call_arg (g, 1);
  gcc_checking_assert (TREE_CODE (base) == ADDR_EXPR);
  tree decl = TREE_OPERAND (base, 0);

  /* For a nested function, we can have: ASAN_MARK (2, &FRAME.2.fp_input, 4) */
  if (TREE_CODE (decl) == COMPONENT_REF
      && DECL_NONLOCAL_FRAME (TREE_OPERAND (decl, 0)))
    decl = TREE_OPERAND (decl, 0);

  gcc_checking_assert (TREE_CODE (decl) == VAR_DECL);

  if (hwasan_sanitize_p ())
    {
      gcc_assert (param_hwasan_instrument_stack);
      gimple_seq stmts = NULL;
      /* Here we swap ASAN_MARK calls for HWASAN_MARK.
	 This is because we are using the approach of using ASAN_MARK as a
	 synonym until here.
	 That approach means we don't yet have to duplicate all the special
	 cases for ASAN_MARK and ASAN_POISON with the exact same handling but
	 called HWASAN_MARK etc.

	 N.b. __asan_poison_stack_memory (which implements ASAN_MARK for ASAN)
	 rounds the size up to its shadow memory granularity, while
	 __hwasan_tag_memory (which implements the same for HWASAN) does not.
	 Hence we emit HWASAN_MARK with an aligned size unlike ASAN_MARK.  */
      tree len = gimple_call_arg (g, 2);
      tree new_len = gimple_build_round_up (&stmts, loc, size_type_node, len,
					    HWASAN_TAG_GRANULE_SIZE);
      gimple_build (&stmts, loc, CFN_HWASAN_MARK,
		    void_type_node, gimple_call_arg (g, 0),
		    base, new_len);
      gsi_replace_with_seq (iter, stmts, true);
      return false;
    }

  if (is_poison)
    {
      if (asan_handled_variables == NULL)
	asan_handled_variables = new hash_set<tree> (16);
      asan_handled_variables->add (decl);
    }
  tree len = gimple_call_arg (g, 2);

  gcc_assert (tree_fits_shwi_p (len));
  unsigned HOST_WIDE_INT size_in_bytes = tree_to_shwi (len);
  gcc_assert (size_in_bytes);

  g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
			   NOP_EXPR, base);
  gimple_set_location (g, loc);
  gsi_replace (iter, g, false);
  tree base_addr = gimple_assign_lhs (g);

  /* Generate direct emission if size_in_bytes is small.  */
  if (size_in_bytes
      <= (unsigned)param_use_after_scope_direct_emission_threshold)
    {
      const unsigned HOST_WIDE_INT shadow_size
	= shadow_mem_size (size_in_bytes);
      const unsigned int shadow_align
	= (get_pointer_alignment (base) / BITS_PER_UNIT) >> ASAN_SHADOW_SHIFT;

      tree shadow = build_shadow_mem_access (iter, loc, base_addr,
					     shadow_ptr_types[0], true);

      for (unsigned HOST_WIDE_INT offset = 0; offset < shadow_size;)
	{
	  unsigned size = 1;
	  if (shadow_size - offset >= 4
	      && (!STRICT_ALIGNMENT || shadow_align >= 4))
	    size = 4;
	  else if (shadow_size - offset >= 2
		   && (!STRICT_ALIGNMENT || shadow_align >= 2))
	    size = 2;

	  unsigned HOST_WIDE_INT last_chunk_size = 0;
	  unsigned HOST_WIDE_INT s = (offset + size) * ASAN_SHADOW_GRANULARITY;
	  if (s > size_in_bytes)
	    last_chunk_size = ASAN_SHADOW_GRANULARITY - (s - size_in_bytes);

	  asan_store_shadow_bytes (iter, loc, shadow, offset, is_poison,
				   size, last_chunk_size);
	  offset += size;
	}
    }
  else
    {
      g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
			       NOP_EXPR, len);
      gimple_set_location (g, loc);
      gsi_insert_before (iter, g, GSI_SAME_STMT);
      tree sz_arg = gimple_assign_lhs (g);

      tree fun
	= builtin_decl_implicit (is_poison ? BUILT_IN_ASAN_POISON_STACK_MEMORY
				 : BUILT_IN_ASAN_UNPOISON_STACK_MEMORY);
      g = gimple_build_call (fun, 2, base_addr, sz_arg);
      gimple_set_location (g, loc);
      gsi_insert_after (iter, g, GSI_NEW_STMT);
    }

  return false;
}

/* Expand the ASAN_{LOAD,STORE} builtins.  */

bool
asan_expand_check_ifn (gimple_stmt_iterator *iter, bool use_calls)
{
  gcc_assert (!hwasan_sanitize_p ());
  gimple *g = gsi_stmt (*iter);
  location_t loc = gimple_location (g);
  bool recover_p;
  if (flag_sanitize & SANITIZE_USER_ADDRESS)
    recover_p = (flag_sanitize_recover & SANITIZE_USER_ADDRESS) != 0;
  else
    recover_p = (flag_sanitize_recover & SANITIZE_KERNEL_ADDRESS) != 0;

  HOST_WIDE_INT flags = tree_to_shwi (gimple_call_arg (g, 0));
  gcc_assert (flags < ASAN_CHECK_LAST);
  bool is_scalar_access = (flags & ASAN_CHECK_SCALAR_ACCESS) != 0;
  bool is_store = (flags & ASAN_CHECK_STORE) != 0;
  bool is_non_zero_len = (flags & ASAN_CHECK_NON_ZERO_LEN) != 0;

  tree base = gimple_call_arg (g, 1);
  tree len = gimple_call_arg (g, 2);
  HOST_WIDE_INT align = tree_to_shwi (gimple_call_arg (g, 3));

  HOST_WIDE_INT size_in_bytes
    = is_scalar_access && tree_fits_shwi_p (len) ? tree_to_shwi (len) : -1;

  if (use_calls)
    {
      /* Instrument using callbacks.  */
      gimple *g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
				      NOP_EXPR, base);
      gimple_set_location (g, loc);
      gsi_insert_before (iter, g, GSI_SAME_STMT);
      tree base_addr = gimple_assign_lhs (g);

      int nargs;
      tree fun = check_func (is_store, recover_p, size_in_bytes, &nargs);
      if (nargs == 1)
	g = gimple_build_call (fun, 1, base_addr);
      else
	{
	  gcc_assert (nargs == 2);
	  g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
				   NOP_EXPR, len);
	  gimple_set_location (g, loc);
	  gsi_insert_before (iter, g, GSI_SAME_STMT);
	  tree sz_arg = gimple_assign_lhs (g);
	  g = gimple_build_call (fun, nargs, base_addr, sz_arg);
	}
      gimple_set_location (g, loc);
      gsi_replace (iter, g, false);
      return false;
    }

  HOST_WIDE_INT real_size_in_bytes = size_in_bytes == -1 ? 1 : size_in_bytes;

  tree shadow_ptr_type = shadow_ptr_types[real_size_in_bytes == 16 ? 1 : 0];
  tree shadow_type = TREE_TYPE (shadow_ptr_type);

  gimple_stmt_iterator gsi = *iter;

  if (!is_non_zero_len)
    {
      /* So, the length of the memory area to asan-protect is
	 non-constant.  Let's guard the generated instrumentation code
	 like:

	 if (len != 0)
	   {
	     //asan instrumentation code goes here.
	   }
	 // falltrough instructions, starting with *ITER.  */

      g = gimple_build_cond (NE_EXPR,
			    len,
			    build_int_cst (TREE_TYPE (len), 0),
			    NULL_TREE, NULL_TREE);
      gimple_set_location (g, loc);

      basic_block then_bb, fallthrough_bb;
      insert_if_then_before_iter (as_a <gcond *> (g), iter,
				  /*then_more_likely_p=*/true,
				  &then_bb, &fallthrough_bb);
      /* Note that fallthrough_bb starts with the statement that was
	pointed to by ITER.  */

      /* The 'then block' of the 'if (len != 0) condition is where
	we'll generate the asan instrumentation code now.  */
      gsi = gsi_last_bb (then_bb);
    }

  /* Get an iterator on the point where we can add the condition
     statement for the instrumentation.  */
  basic_block then_bb, else_bb;
  gsi = create_cond_insert_point (&gsi, /*before_p*/false,
				  /*then_more_likely_p=*/false,
				  /*create_then_fallthru_edge*/recover_p,
				  &then_bb,
				  &else_bb);

  g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
			   NOP_EXPR, base);
  gimple_set_location (g, loc);
  gsi_insert_before (&gsi, g, GSI_NEW_STMT);
  tree base_addr = gimple_assign_lhs (g);

  tree t = NULL_TREE;
  if (real_size_in_bytes >= 8)
    {
      tree shadow = build_shadow_mem_access (&gsi, loc, base_addr,
					     shadow_ptr_type);
      t = shadow;
    }
  else
    {
      /* Slow path for 1, 2 and 4 byte accesses.  */
      /* Test (shadow != 0)
	 & ((base_addr & 7) + (real_size_in_bytes - 1)) >= shadow).  */
      tree shadow = build_shadow_mem_access (&gsi, loc, base_addr,
					     shadow_ptr_type);
      gimple *shadow_test = build_assign (NE_EXPR, shadow, 0);
      gimple_seq seq = NULL;
      gimple_seq_add_stmt (&seq, shadow_test);
      /* Aligned (>= 8 bytes) can test just
	 (real_size_in_bytes - 1 >= shadow), as base_addr & 7 is known
	 to be 0.  */
      if (align < 8)
	{
	  gimple_seq_add_stmt (&seq, build_assign (BIT_AND_EXPR,
						   base_addr, 7));
	  gimple_seq_add_stmt (&seq,
			       build_type_cast (shadow_type,
						gimple_seq_last (seq)));
	  if (real_size_in_bytes > 1)
	    gimple_seq_add_stmt (&seq,
				 build_assign (PLUS_EXPR,
					       gimple_seq_last (seq),
					       real_size_in_bytes - 1));
	  t = gimple_assign_lhs (gimple_seq_last_stmt (seq));
	}
      else
	t = build_int_cst (shadow_type, real_size_in_bytes - 1);
      gimple_seq_add_stmt (&seq, build_assign (GE_EXPR, t, shadow));
      gimple_seq_add_stmt (&seq, build_assign (BIT_AND_EXPR, shadow_test,
					       gimple_seq_last (seq)));
      t = gimple_assign_lhs (gimple_seq_last (seq));
      gimple_seq_set_location (seq, loc);
      gsi_insert_seq_after (&gsi, seq, GSI_CONTINUE_LINKING);

      /* For non-constant, misaligned or otherwise weird access sizes,
       check first and last byte.  */
      if (size_in_bytes == -1)
	{
	  g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
				   MINUS_EXPR, len,
				   build_int_cst (pointer_sized_int_node, 1));
	  gimple_set_location (g, loc);
	  gsi_insert_after (&gsi, g, GSI_NEW_STMT);
	  tree last = gimple_assign_lhs (g);
	  g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
				   PLUS_EXPR, base_addr, last);
	  gimple_set_location (g, loc);
	  gsi_insert_after (&gsi, g, GSI_NEW_STMT);
	  tree base_end_addr = gimple_assign_lhs (g);

	  tree shadow = build_shadow_mem_access (&gsi, loc, base_end_addr,
						 shadow_ptr_type);
	  gimple *shadow_test = build_assign (NE_EXPR, shadow, 0);
	  gimple_seq seq = NULL;
	  gimple_seq_add_stmt (&seq, shadow_test);
	  gimple_seq_add_stmt (&seq, build_assign (BIT_AND_EXPR,
						   base_end_addr, 7));
	  gimple_seq_add_stmt (&seq, build_type_cast (shadow_type,
						      gimple_seq_last (seq)));
	  gimple_seq_add_stmt (&seq, build_assign (GE_EXPR,
						   gimple_seq_last (seq),
						   shadow));
	  gimple_seq_add_stmt (&seq, build_assign (BIT_AND_EXPR, shadow_test,
						   gimple_seq_last (seq)));
	  gimple_seq_add_stmt (&seq, build_assign (BIT_IOR_EXPR, t,
						   gimple_seq_last (seq)));
	  t = gimple_assign_lhs (gimple_seq_last (seq));
	  gimple_seq_set_location (seq, loc);
	  gsi_insert_seq_after (&gsi, seq, GSI_CONTINUE_LINKING);
	}
    }

  g = gimple_build_cond (NE_EXPR, t, build_int_cst (TREE_TYPE (t), 0),
			 NULL_TREE, NULL_TREE);
  gimple_set_location (g, loc);
  gsi_insert_after (&gsi, g, GSI_NEW_STMT);

  /* Generate call to the run-time library (e.g. __asan_report_load8).  */
  gsi = gsi_start_bb (then_bb);
  int nargs;
  tree fun = report_error_func (is_store, recover_p, size_in_bytes, &nargs);
  g = gimple_build_call (fun, nargs, base_addr, len);
  gimple_set_location (g, loc);
  gsi_insert_after (&gsi, g, GSI_NEW_STMT);

  gsi_remove (iter, true);
  *iter = gsi_start_bb (else_bb);

  return true;
}

/* Create ASAN shadow variable for a VAR_DECL which has been rewritten
   into SSA.  Already seen VAR_DECLs are stored in SHADOW_VARS_MAPPING.  */

static tree
create_asan_shadow_var (tree var_decl,
			hash_map<tree, tree> &shadow_vars_mapping)
{
  tree *slot = shadow_vars_mapping.get (var_decl);
  if (slot == NULL)
    {
      tree shadow_var = copy_node (var_decl);

      copy_body_data id;
      memset (&id, 0, sizeof (copy_body_data));
      id.src_fn = id.dst_fn = current_function_decl;
      copy_decl_for_dup_finish (&id, var_decl, shadow_var);

      DECL_ARTIFICIAL (shadow_var) = 1;
      DECL_IGNORED_P (shadow_var) = 1;
      DECL_SEEN_IN_BIND_EXPR_P (shadow_var) = 0;
      gimple_add_tmp_var (shadow_var);

      shadow_vars_mapping.put (var_decl, shadow_var);
      return shadow_var;
    }
  else
    return *slot;
}

/* Expand ASAN_POISON ifn.  */

bool
asan_expand_poison_ifn (gimple_stmt_iterator *iter,
			bool *need_commit_edge_insert,
			hash_map<tree, tree> &shadow_vars_mapping)
{
  gimple *g = gsi_stmt (*iter);
  tree poisoned_var = gimple_call_lhs (g);
  if (!poisoned_var || has_zero_uses (poisoned_var))
    {
      gsi_remove (iter, true);
      return true;
    }

  if (SSA_NAME_VAR (poisoned_var) == NULL_TREE)
    SET_SSA_NAME_VAR_OR_IDENTIFIER (poisoned_var,
				    create_tmp_var (TREE_TYPE (poisoned_var)));

  tree shadow_var = create_asan_shadow_var (SSA_NAME_VAR (poisoned_var),
					    shadow_vars_mapping);

  bool recover_p;
  if (flag_sanitize & SANITIZE_USER_ADDRESS)
    recover_p = (flag_sanitize_recover & SANITIZE_USER_ADDRESS) != 0;
  else
    recover_p = (flag_sanitize_recover & SANITIZE_KERNEL_ADDRESS) != 0;
  tree size = DECL_SIZE_UNIT (shadow_var);
  gimple *poison_call
    = gimple_build_call_internal (IFN_ASAN_MARK, 3,
				  build_int_cst (integer_type_node,
						 ASAN_MARK_POISON),
				  build_fold_addr_expr (shadow_var), size);

  gimple *use;
  imm_use_iterator imm_iter;
  FOR_EACH_IMM_USE_STMT (use, imm_iter, poisoned_var)
    {
      if (is_gimple_debug (use))
	continue;

      int nargs;
      bool store_p = gimple_call_internal_p (use, IFN_ASAN_POISON_USE);
      gcall *call;
      if (hwasan_sanitize_p ())
	{
	  tree fun = builtin_decl_implicit (BUILT_IN_HWASAN_TAG_MISMATCH4);
	  /* NOTE: hwasan has no __hwasan_report_* functions like asan does.
		We use __hwasan_tag_mismatch4 with arguments that tell it the
		size of access and load to report all tag mismatches.

		The arguments to this function are:
		  Address of invalid access.
		  Bitfield containing information about the access
		    (access_info)
		  Pointer to a frame of registers
		    (for use in printing the contents of registers in a dump)
		    Not used yet -- to be used by inline instrumentation.
		  Size of access.

		The access_info bitfield encodes the following pieces of
		information:
		  - Is this a store or load?
		    access_info & 0x10  =>  store
		  - Should the program continue after reporting the error?
		    access_info & 0x20  =>  recover
		  - What size access is this (not used here since we can always
		    pass the size in the last argument)

		    if (access_info & 0xf == 0xf)
		      size is taken from last argument.
		    else
		      size == 1 << (access_info & 0xf)

		The last argument contains the size of the access iff the
		access_info size indicator is 0xf (we always use this argument
		rather than storing the size in the access_info bitfield).

		See the function definition `__hwasan_tag_mismatch4` in
		libsanitizer/hwasan for the full definition.
		*/
	  unsigned access_info = (0x20 * recover_p)
	    + (0x10 * store_p)
	    + (0xf);
	  call = gimple_build_call (fun, 4,
				    build_fold_addr_expr (shadow_var),
				    build_int_cst (pointer_sized_int_node,
						   access_info),
				    build_int_cst (pointer_sized_int_node, 0),
				    size);
	}
      else
	{
	  tree fun = report_error_func (store_p, recover_p, tree_to_uhwi (size),
					&nargs);
	  call = gimple_build_call (fun, 1,
				    build_fold_addr_expr (shadow_var));
	}
      gimple_set_location (call, gimple_location (use));
      gimple *call_to_insert = call;

      /* The USE can be a gimple PHI node.  If so, insert the call on
	 all edges leading to the PHI node.  */
      if (is_a <gphi *> (use))
	{
	  gphi *phi = dyn_cast<gphi *> (use);
	  for (unsigned i = 0; i < gimple_phi_num_args (phi); ++i)
	    if (gimple_phi_arg_def (phi, i) == poisoned_var)
	      {
		edge e = gimple_phi_arg_edge (phi, i);

		/* Do not insert on an edge we can't split.  */
		if (e->flags & EDGE_ABNORMAL)
		  continue;

		if (call_to_insert == NULL)
		  call_to_insert = gimple_copy (call);

		gsi_insert_seq_on_edge (e, call_to_insert);
		*need_commit_edge_insert = true;
		call_to_insert = NULL;
	      }
	}
      else
	{
	  gimple_stmt_iterator gsi = gsi_for_stmt (use);
	  if (store_p)
	    gsi_replace (&gsi, call, true);
	  else
	    gsi_insert_before (&gsi, call, GSI_NEW_STMT);
	}
    }

  SSA_NAME_IS_DEFAULT_DEF (poisoned_var) = true;
  SSA_NAME_DEF_STMT (poisoned_var) = gimple_build_nop ();
  gsi_replace (iter, poison_call, false);

  return true;
}

/* Instrument the current function.  */

static unsigned int
asan_instrument (void)
{
  if (hwasan_sanitize_p ())
    {
      transform_statements ();
      return 0;
    }

  if (shadow_ptr_types[0] == NULL_TREE)
    asan_init_shadow_ptr_types ();
  transform_statements ();
  last_alloca_addr = NULL_TREE;
  return 0;
}

static bool
gate_asan (void)
{
  return sanitize_flags_p (SANITIZE_ADDRESS);
}

namespace {

const pass_data pass_data_asan =
{
  GIMPLE_PASS, /* type */
  "asan", /* name */
  OPTGROUP_NONE, /* optinfo_flags */
  TV_NONE, /* tv_id */
  ( PROP_ssa | PROP_cfg | PROP_gimple_leh ), /* properties_required */
  0, /* properties_provided */
  0, /* properties_destroyed */
  0, /* todo_flags_start */
  TODO_update_ssa, /* todo_flags_finish */
};

class pass_asan : public gimple_opt_pass
{
public:
  pass_asan (gcc::context *ctxt)
    : gimple_opt_pass (pass_data_asan, ctxt)
  {}

  /* opt_pass methods: */
  opt_pass * clone () { return new pass_asan (m_ctxt); }
  virtual bool gate (function *) { return gate_asan () || gate_hwasan (); }
  virtual unsigned int execute (function *) { return asan_instrument (); }

}; // class pass_asan

} // anon namespace

gimple_opt_pass *
make_pass_asan (gcc::context *ctxt)
{
  return new pass_asan (ctxt);
}

namespace {

const pass_data pass_data_asan_O0 =
{
  GIMPLE_PASS, /* type */
  "asan0", /* name */
  OPTGROUP_NONE, /* optinfo_flags */
  TV_NONE, /* tv_id */
  ( PROP_ssa | PROP_cfg | PROP_gimple_leh ), /* properties_required */
  0, /* properties_provided */
  0, /* properties_destroyed */
  0, /* todo_flags_start */
  TODO_update_ssa, /* todo_flags_finish */
};

class pass_asan_O0 : public gimple_opt_pass
{
public:
  pass_asan_O0 (gcc::context *ctxt)
    : gimple_opt_pass (pass_data_asan_O0, ctxt)
  {}

  /* opt_pass methods: */
  virtual bool gate (function *)
    {
      return !optimize && (gate_asan () || gate_hwasan ());
    }
  virtual unsigned int execute (function *) { return asan_instrument (); }

}; // class pass_asan_O0

} // anon namespace

gimple_opt_pass *
make_pass_asan_O0 (gcc::context *ctxt)
{
  return new pass_asan_O0 (ctxt);
}

/*  HWASAN  */

/* For stack tagging:

   Return the offset from the frame base tag that the "next" expanded object
   should have.  */
uint8_t
hwasan_current_frame_tag ()
{
  return hwasan_frame_tag_offset;
}

/* For stack tagging:

   Return the 'base pointer' for this function.  If that base pointer has not
   yet been created then we create a register to hold it and record the insns
   to initialize the register in `hwasan_frame_base_init_seq` for later
   emission.  */
rtx
hwasan_frame_base ()
{
  if (! hwasan_frame_base_ptr)
    {
      start_sequence ();
      hwasan_frame_base_ptr
	= force_reg (Pmode,
		     targetm.memtag.insert_random_tag (virtual_stack_vars_rtx,
						       NULL_RTX));
      hwasan_frame_base_init_seq = get_insns ();
      end_sequence ();
    }

  return hwasan_frame_base_ptr;
}

/* For stack tagging:

   Check whether this RTX is a standard pointer addressing the base of the
   stack variables for this frame.  Returns true if the RTX is either
   virtual_stack_vars_rtx or hwasan_frame_base_ptr.  */
bool
stack_vars_base_reg_p (rtx base)
{
  return base == virtual_stack_vars_rtx || base == hwasan_frame_base_ptr;
}

/* For stack tagging:

   Emit frame base initialisation.
   If hwasan_frame_base has been used before here then
   hwasan_frame_base_init_seq contains the sequence of instructions to
   initialize it.  This must be put just before the hwasan prologue, so we emit
   the insns before parm_birth_insn (which will point to the first instruction
   of the hwasan prologue if it exists).

   We update `parm_birth_insn` to point to the start of this initialisation
   since that represents the end of the initialisation done by
   expand_function_{start,end} functions and we want to maintain that.  */
void
hwasan_maybe_emit_frame_base_init ()
{
  if (! hwasan_frame_base_init_seq)
    return;
  emit_insn_before (hwasan_frame_base_init_seq, parm_birth_insn);
  parm_birth_insn = hwasan_frame_base_init_seq;
}

/* Record a compile-time constant size stack variable that HWASAN will need to
   tag.  This record of the range of a stack variable will be used by
   `hwasan_emit_prologue` to emit the RTL at the start of each frame which will
   set tags in the shadow memory according to the assigned tag for each object.

   The range that the object spans in stack space should be described by the
   bounds `untagged_base + nearest_offset` and
   `untagged_base + farthest_offset`.
   `tagged_base` is the base address which contains the "base frame tag" for
   this frame, and from which the value to address this object with will be
   calculated.

   We record the `untagged_base` since the functions in the hwasan library we
   use to tag memory take pointers without a tag.  */
void
hwasan_record_stack_var (rtx untagged_base, rtx tagged_base,
			 poly_int64 nearest_offset, poly_int64 farthest_offset)
{
  hwasan_stack_var cur_var;
  cur_var.untagged_base = untagged_base;
  cur_var.tagged_base = tagged_base;
  cur_var.nearest_offset = nearest_offset;
  cur_var.farthest_offset = farthest_offset;
  cur_var.tag_offset = hwasan_current_frame_tag ();

  hwasan_tagged_stack_vars.safe_push (cur_var);
}

/* Return the RTX representing the farthest extent of the statically allocated
   stack objects for this frame.  If hwasan_frame_base_ptr has not been
   initialized then we are not storing any static variables on the stack in
   this frame.  In this case we return NULL_RTX to represent that.

   Otherwise simply return virtual_stack_vars_rtx + frame_offset.  */
rtx
hwasan_get_frame_extent ()
{
  return (hwasan_frame_base_ptr
	  ? plus_constant (Pmode, virtual_stack_vars_rtx, frame_offset)
	  : NULL_RTX);
}

/* For stack tagging:

   Increment the frame tag offset modulo the size a tag can represent.  */
void
hwasan_increment_frame_tag ()
{
  uint8_t tag_bits = HWASAN_TAG_SIZE;
  gcc_assert (HWASAN_TAG_SIZE
	      <= sizeof (hwasan_frame_tag_offset) * CHAR_BIT);
  hwasan_frame_tag_offset = (hwasan_frame_tag_offset + 1) % (1 << tag_bits);
  /* The "background tag" of the stack is zero by definition.
     This is the tag that objects like parameters passed on the stack and
     spilled registers are given.  It is handy to avoid this tag for objects
     whose tags we decide ourselves, partly to ensure that buffer overruns
     can't affect these important variables (e.g. saved link register, saved
     stack pointer etc) and partly to make debugging easier (everything with a
     tag of zero is space allocated automatically by the compiler).

     This is not feasible when using random frame tags (the default
     configuration for hwasan) since the tag for the given frame is randomly
     chosen at runtime.  In order to avoid any tags matching the stack
     background we would need to decide tag offsets at runtime instead of
     compile time (and pay the resulting performance cost).

     When not using random base tags for each frame (i.e. when compiled with
     `--param hwasan-random-frame-tag=0`) the base tag for each frame is zero.
     This means the tag that each object gets is equal to the
     hwasan_frame_tag_offset used in determining it.
     When this is the case we *can* ensure no object gets the tag of zero by
     simply ensuring no object has the hwasan_frame_tag_offset of zero.

     There is the extra complication that we only record the
     hwasan_frame_tag_offset here (which is the offset from the tag stored in
     the stack pointer).  In the kernel, the tag in the stack pointer is 0xff
     rather than zero.  This does not cause problems since tags of 0xff are
     never checked in the kernel.  As mentioned at the beginning of this
     comment the background tag of the stack is zero by definition, which means
     that for the kernel we should skip offsets of both 0 and 1 from the stack
     pointer.  Avoiding the offset of 0 ensures we use a tag which will be
     checked, avoiding the offset of 1 ensures we use a tag that is not the
     same as the background.  */
  if (hwasan_frame_tag_offset == 0 && ! param_hwasan_random_frame_tag)
    hwasan_frame_tag_offset += 1;
  if (hwasan_frame_tag_offset == 1 && ! param_hwasan_random_frame_tag
      && sanitize_flags_p (SANITIZE_KERNEL_HWADDRESS))
    hwasan_frame_tag_offset += 1;
}

/* Clear internal state for the next function.
   This function is called before variables on the stack get expanded, in
   `init_vars_expansion`.  */
void
hwasan_record_frame_init ()
{
  delete asan_used_labels;
  asan_used_labels = NULL;

  /* If this isn't the case then some stack variable was recorded *before*
     hwasan_record_frame_init is called, yet *after* the hwasan prologue for
     the previous frame was emitted.  Such stack variables would not have
     their shadow stack filled in.  */
  gcc_assert (hwasan_tagged_stack_vars.is_empty ());
  hwasan_frame_base_ptr = NULL_RTX;
  hwasan_frame_base_init_seq = NULL;

  /* When not using a random frame tag we can avoid the background stack
     color which gives the user a little better debug output upon a crash.
     Meanwhile, when using a random frame tag it will be nice to avoid adding
     tags for the first object since that is unnecessary extra work.
     Hence set the initial hwasan_frame_tag_offset to be 0 if using a random
     frame tag and 1 otherwise.

     As described in hwasan_increment_frame_tag, in the kernel the stack
     pointer has the tag 0xff.  That means that to avoid 0xff and 0 (the tag
     which the kernel does not check and the background tag respectively) we
     start with a tag offset of 2.  */
  hwasan_frame_tag_offset = param_hwasan_random_frame_tag
    ? 0
    : sanitize_flags_p (SANITIZE_KERNEL_HWADDRESS) ? 2 : 1;
}

/* For stack tagging:
   (Emits HWASAN equivalent of what is emitted by
   `asan_emit_stack_protection`).

   Emits the extra prologue code to set the shadow stack as required for HWASAN
   stack instrumentation.

   Uses the vector of recorded stack variables hwasan_tagged_stack_vars.  When
   this function has completed hwasan_tagged_stack_vars is empty and all
   objects it had pointed to are deallocated.  */
void
hwasan_emit_prologue ()
{
  /* We need untagged base pointers since libhwasan only accepts untagged
    pointers in __hwasan_tag_memory.  We need the tagged base pointer to obtain
    the base tag for an offset.  */

  if (hwasan_tagged_stack_vars.is_empty ())
    return;

  poly_int64 bot = 0, top = 0;
  for (hwasan_stack_var &cur : hwasan_tagged_stack_vars)
    {
      poly_int64 nearest = cur.nearest_offset;
      poly_int64 farthest = cur.farthest_offset;

      if (known_ge (nearest, farthest))
	{
	  top = nearest;
	  bot = farthest;
	}
      else
	{
	  /* Given how these values are calculated, one must be known greater
	     than the other.  */
	  gcc_assert (known_le (nearest, farthest));
	  top = farthest;
	  bot = nearest;
	}
      poly_int64 size = (top - bot);

      /* Assert the edge of each variable is aligned to the HWASAN tag granule
	 size.  */
      gcc_assert (multiple_p (top, HWASAN_TAG_GRANULE_SIZE));
      gcc_assert (multiple_p (bot, HWASAN_TAG_GRANULE_SIZE));
      gcc_assert (multiple_p (size, HWASAN_TAG_GRANULE_SIZE));

      rtx fn = init_one_libfunc ("__hwasan_tag_memory");
      rtx base_tag = targetm.memtag.extract_tag (cur.tagged_base, NULL_RTX);
      rtx tag = plus_constant (QImode, base_tag, cur.tag_offset);
      tag = hwasan_truncate_to_tag_size (tag, NULL_RTX);

      rtx bottom = convert_memory_address (ptr_mode,
					   plus_constant (Pmode,
							  cur.untagged_base,
							  bot));
      emit_library_call (fn, LCT_NORMAL, VOIDmode,
			 bottom, ptr_mode,
			 tag, QImode,
			 gen_int_mode (size, ptr_mode), ptr_mode);
    }
  /* Clear the stack vars, we've emitted the prologue for them all now.  */
  hwasan_tagged_stack_vars.truncate (0);
}

/* For stack tagging:

   Return RTL insns to clear the tags between DYNAMIC and VARS pointers
   into the stack.  These instructions should be emitted at the end of
   every function.

   If `dynamic` is NULL_RTX then no insns are returned.  */
rtx_insn *
hwasan_emit_untag_frame (rtx dynamic, rtx vars)
{
  if (! dynamic)
    return NULL;

  start_sequence ();

  dynamic = convert_memory_address (ptr_mode, dynamic);
  vars = convert_memory_address (ptr_mode, vars);

  rtx top_rtx;
  rtx bot_rtx;
  if (FRAME_GROWS_DOWNWARD)
    {
      top_rtx = vars;
      bot_rtx = dynamic;
    }
  else
    {
      top_rtx = dynamic;
      bot_rtx = vars;
    }

  rtx size_rtx = expand_simple_binop (ptr_mode, MINUS, top_rtx, bot_rtx,
				      NULL_RTX, /* unsignedp = */0,
				      OPTAB_DIRECT);

  rtx fn = init_one_libfunc ("__hwasan_tag_memory");
  emit_library_call (fn, LCT_NORMAL, VOIDmode,
		     bot_rtx, ptr_mode,
		     HWASAN_STACK_BACKGROUND, QImode,
		     size_rtx, ptr_mode);

  do_pending_stack_adjust ();
  rtx_insn *insns = get_insns ();
  end_sequence ();
  return insns;
}

/* Needs to be GTY(()), because cgraph_build_static_cdtor may
   invoke ggc_collect.  */
static GTY(()) tree hwasan_ctor_statements;

/* Insert module initialization into this TU.  This initialization calls the
   initialization code for libhwasan.  */
void
hwasan_finish_file (void)
{
  /* Do not emit constructor initialization for the kernel.
     (the kernel has its own initialization already).  */
  if (flag_sanitize & SANITIZE_KERNEL_HWADDRESS)
    return;

  /* Avoid instrumenting code in the hwasan constructors/destructors.  */
  flag_sanitize &= ~SANITIZE_HWADDRESS;
  int priority = MAX_RESERVED_INIT_PRIORITY - 1;
  tree fn = builtin_decl_implicit (BUILT_IN_HWASAN_INIT);
  append_to_statement_list (build_call_expr (fn, 0), &hwasan_ctor_statements);
  cgraph_build_static_cdtor ('I', hwasan_ctor_statements, priority);
  flag_sanitize |= SANITIZE_HWADDRESS;
}

/* For stack tagging:

   Truncate `tag` to the number of bits that a tag uses (i.e. to
   HWASAN_TAG_SIZE).  Store the result in `target` if it's convenient.  */
rtx
hwasan_truncate_to_tag_size (rtx tag, rtx target)
{
  gcc_assert (GET_MODE (tag) == QImode);
  if (HWASAN_TAG_SIZE != GET_MODE_PRECISION (QImode))
    {
      gcc_assert (GET_MODE_PRECISION (QImode) > HWASAN_TAG_SIZE);
      rtx mask = gen_int_mode ((HOST_WIDE_INT_1U << HWASAN_TAG_SIZE) - 1,
			       QImode);
      tag = expand_simple_binop (QImode, AND, tag, mask, target,
				 /* unsignedp = */1, OPTAB_WIDEN);
      gcc_assert (tag);
    }
  return tag;
}

/* Construct a function tree for __hwasan_{load,store}{1,2,4,8,16,_n}.
   IS_STORE is either 1 (for a store) or 0 (for a load).  */
static combined_fn
hwasan_check_func (bool is_store, bool recover_p, HOST_WIDE_INT size_in_bytes,
		   int *nargs)
{
  static enum built_in_function check[2][2][6]
    = { { { BUILT_IN_HWASAN_LOAD1, BUILT_IN_HWASAN_LOAD2,
	    BUILT_IN_HWASAN_LOAD4, BUILT_IN_HWASAN_LOAD8,
	    BUILT_IN_HWASAN_LOAD16, BUILT_IN_HWASAN_LOADN },
	  { BUILT_IN_HWASAN_STORE1, BUILT_IN_HWASAN_STORE2,
	    BUILT_IN_HWASAN_STORE4, BUILT_IN_HWASAN_STORE8,
	    BUILT_IN_HWASAN_STORE16, BUILT_IN_HWASAN_STOREN } },
	{ { BUILT_IN_HWASAN_LOAD1_NOABORT,
	    BUILT_IN_HWASAN_LOAD2_NOABORT,
	    BUILT_IN_HWASAN_LOAD4_NOABORT,
	    BUILT_IN_HWASAN_LOAD8_NOABORT,
	    BUILT_IN_HWASAN_LOAD16_NOABORT,
	    BUILT_IN_HWASAN_LOADN_NOABORT },
	  { BUILT_IN_HWASAN_STORE1_NOABORT,
	    BUILT_IN_HWASAN_STORE2_NOABORT,
	    BUILT_IN_HWASAN_STORE4_NOABORT,
	    BUILT_IN_HWASAN_STORE8_NOABORT,
	    BUILT_IN_HWASAN_STORE16_NOABORT,
	    BUILT_IN_HWASAN_STOREN_NOABORT } } };
  if (size_in_bytes == -1)
    {
      *nargs = 2;
      return as_combined_fn (check[recover_p][is_store][5]);
    }
  *nargs = 1;
  int size_log2 = exact_log2 (size_in_bytes);
  gcc_assert (size_log2 >= 0 && size_log2 <= 5);
  return as_combined_fn (check[recover_p][is_store][size_log2]);
}

/* Expand the HWASAN_{LOAD,STORE} builtins.  */
bool
hwasan_expand_check_ifn (gimple_stmt_iterator *iter, bool)
{
  gimple *g = gsi_stmt (*iter);
  location_t loc = gimple_location (g);
  bool recover_p;
  if (flag_sanitize & SANITIZE_USER_HWADDRESS)
    recover_p = (flag_sanitize_recover & SANITIZE_USER_HWADDRESS) != 0;
  else
    recover_p = (flag_sanitize_recover & SANITIZE_KERNEL_HWADDRESS) != 0;

  HOST_WIDE_INT flags = tree_to_shwi (gimple_call_arg (g, 0));
  gcc_assert (flags < ASAN_CHECK_LAST);
  bool is_scalar_access = (flags & ASAN_CHECK_SCALAR_ACCESS) != 0;
  bool is_store = (flags & ASAN_CHECK_STORE) != 0;
  bool is_non_zero_len = (flags & ASAN_CHECK_NON_ZERO_LEN) != 0;

  tree base = gimple_call_arg (g, 1);
  tree len = gimple_call_arg (g, 2);

  /* `align` is unused for HWASAN_CHECK, but we pass the argument anyway
     since that way the arguments match ASAN_CHECK.  */
  /* HOST_WIDE_INT align = tree_to_shwi (gimple_call_arg (g, 3));  */

  unsigned HOST_WIDE_INT size_in_bytes
    = is_scalar_access ? tree_to_shwi (len) : -1;

  gimple_stmt_iterator gsi = *iter;

  if (!is_non_zero_len)
    {
      /* So, the length of the memory area to hwasan-protect is
	 non-constant.  Let's guard the generated instrumentation code
	 like:

	 if (len != 0)
	   {
	     // hwasan instrumentation code goes here.
	   }
	 // falltrough instructions, starting with *ITER.  */

      g = gimple_build_cond (NE_EXPR,
			    len,
			    build_int_cst (TREE_TYPE (len), 0),
			    NULL_TREE, NULL_TREE);
      gimple_set_location (g, loc);

      basic_block then_bb, fallthrough_bb;
      insert_if_then_before_iter (as_a <gcond *> (g), iter,
				  /*then_more_likely_p=*/true,
				  &then_bb, &fallthrough_bb);
      /* Note that fallthrough_bb starts with the statement that was
	pointed to by ITER.  */

      /* The 'then block' of the 'if (len != 0) condition is where
	we'll generate the hwasan instrumentation code now.  */
      gsi = gsi_last_bb (then_bb);
    }

  gimple_seq stmts = NULL;
  tree base_addr = gimple_build (&stmts, loc, NOP_EXPR,
				 pointer_sized_int_node, base);

  int nargs = 0;
  combined_fn fn
    = hwasan_check_func (is_store, recover_p, size_in_bytes, &nargs);
  if (nargs == 1)
    gimple_build (&stmts, loc, fn, void_type_node, base_addr);
  else
    {
      gcc_assert (nargs == 2);
      tree sz_arg = gimple_build (&stmts, loc, NOP_EXPR,
				  pointer_sized_int_node, len);
      gimple_build (&stmts, loc, fn, void_type_node, base_addr, sz_arg);
    }

  gsi_insert_seq_after (&gsi, stmts, GSI_NEW_STMT);
  gsi_remove (iter, true);
  *iter = gsi;
  return false;
}

/* For stack tagging:

   Dummy: the HWASAN_MARK internal function should only ever be in the code
   after the sanopt pass.  */
bool
hwasan_expand_mark_ifn (gimple_stmt_iterator *)
{
  gcc_unreachable ();
}

bool
gate_hwasan ()
{
  return hwasan_sanitize_p ();
}

#include "gt-asan.h"
