GCC Middle and Back End API Reference
|
Go to the source code of this file.
Macros | |
#define | ASAN_SHADOW_SHIFT 3 |
#define | ASAN_SHADOW_GRANULARITY (1UL << ASAN_SHADOW_SHIFT) |
#define | ASAN_RED_ZONE_SIZE 32 |
#define | ASAN_MIN_RED_ZONE_SIZE 16 |
#define | ASAN_STACK_MAGIC_LEFT 0xf1 |
#define | ASAN_STACK_MAGIC_MIDDLE 0xf2 |
#define | ASAN_STACK_MAGIC_RIGHT 0xf3 |
#define | ASAN_STACK_MAGIC_USE_AFTER_RET 0xf5 |
#define | ASAN_STACK_MAGIC_USE_AFTER_SCOPE 0xf8 |
#define | ASAN_STACK_FRAME_MAGIC 0x41b58ab3 |
#define | ASAN_STACK_RETIRED_MAGIC 0x45e0360e |
#define | ASAN_USE_AFTER_SCOPE_ATTRIBUTE "use after scope memory" |
#define | HWASAN_TAG_SIZE targetm.memtag.tag_size () |
#define | HWASAN_TAG_GRANULE_SIZE targetm.memtag.granule_size () |
#define | HWASAN_STACK_BACKGROUND gen_int_mode (0, QImode) |
#define | IFN_ASAN_MARK_FLAGS DEF(POISON), DEF(UNPOISON) |
#define | DEF(X) |
Enumerations | |
enum | asan_check_flags { ASAN_CHECK_STORE = 1 << 0 , ASAN_CHECK_SCALAR_ACCESS = 1 << 1 , ASAN_CHECK_NON_ZERO_LEN = 1 << 2 , ASAN_CHECK_LAST = 1 << 3 } |
enum | asan_mark_flags { IFN_ASAN_MARK_FLAGS } |
Variables | |
alias_set_type | asan_shadow_set |
hash_set< tree > * | asan_used_labels |
hash_set< tree > * | asan_handled_variables |
#define ASAN_MIN_RED_ZONE_SIZE 16 |
Stack variable use more compact red zones. The size includes also size of variable itself.
Referenced by asan_emit_stack_protection(), and expand_stack_vars().
#define ASAN_RED_ZONE_SIZE 32 |
Red zone size, stack and global variables are padded by ASAN_RED_ZONE_SIZE up to 2 * ASAN_RED_ZONE_SIZE - 1 bytes.
Referenced by asan_emit_stack_protection(), asan_protect_global(), asan_red_zone_size(), assemble_variable(), asan_redzone_buffer::emit_redzone_byte(), expand_stack_vars(), expand_used_vars(), asan_redzone_buffer::flush_redzone_payload(), handle_builtin_alloca(), output_constant_def_contents(), and place_block_symbol().
#define ASAN_SHADOW_GRANULARITY (1UL << ASAN_SHADOW_SHIFT) |
#define ASAN_SHADOW_SHIFT 3 |
Shadow memory is found at (address >> ASAN_SHADOW_SHIFT) + asan_shadow_offset ().
Referenced by asan_emit_stack_protection(), asan_expand_mark_ifn(), build_shadow_mem_access(), asan_redzone_buffer::emit_redzone_byte(), expand_stack_vars(), and expand_used_vars().
#define ASAN_STACK_FRAME_MAGIC 0x41b58ab3 |
Referenced by asan_emit_stack_protection().
#define ASAN_STACK_MAGIC_LEFT 0xf1 |
Shadow memory values for stack protection. Left is below protected vars, the first pointer in stack corresponding to that offset contains ASAN_STACK_FRAME_MAGIC word, the second pointer to a string describing the frame. Middle is for padding in between variables, right is above the last protected variable and partial immediately after variables up to ASAN_RED_ZONE_SIZE alignment.
Referenced by asan_emit_stack_protection().
#define ASAN_STACK_MAGIC_MIDDLE 0xf2 |
Referenced by asan_emit_stack_protection().
#define ASAN_STACK_MAGIC_RIGHT 0xf3 |
Referenced by asan_emit_stack_protection().
#define ASAN_STACK_MAGIC_USE_AFTER_RET 0xf5 |
Referenced by asan_emit_stack_protection().
#define ASAN_STACK_MAGIC_USE_AFTER_SCOPE 0xf8 |
Referenced by asan_store_shadow_bytes().
#define ASAN_STACK_RETIRED_MAGIC 0x45e0360e |
Referenced by asan_emit_stack_protection().
#define ASAN_USE_AFTER_SCOPE_ATTRIBUTE "use after scope memory" |
Referenced by asan_poison_variables(), and is_asan_mark_p().
#define DEF | ( | X | ) |
#define HWASAN_STACK_BACKGROUND gen_int_mode (0, QImode) |
Define the tag for the stack background. This defines what tag the stack pointer will be and hence what tag all variables that are not given special tags are (e.g. spilled registers, and parameters passed on the stack).
Referenced by expand_HWASAN_ALLOCA_UNPOISON(), expand_HWASAN_MARK(), and hwasan_emit_untag_frame().
#define HWASAN_TAG_GRANULE_SIZE targetm.memtag.granule_size () |
Tag Granule of HWASAN shadow stack. This is the size in real memory that each byte in the shadow memory refers to. I.e. if a variable is X bytes long in memory then its tag in shadow memory will span X / HWASAN_TAG_GRANULE_SIZE bytes. Most variables will need to be aligned to this amount since two variables that are neighbors in memory and share a tag granule would need to share the same tag (the shared tag granule can only store one tag).
Referenced by align_local_variable(), asan_expand_mark_ifn(), asan_poison_variable(), expand_one_stack_var_1(), expand_stack_vars(), handle_builtin_alloca(), and hwasan_emit_prologue().
#define HWASAN_TAG_SIZE targetm.memtag.tag_size () |
NOTE: The values below and the hooks under targetm.memtag define an ABI and are hard-coded to these values in libhwasan, hence they can't be changed independently here.
How many bits are used to store a tag in a pointer. The default version uses the entire top byte of a pointer (i.e. 8 bits).
Referenced by hwasan_increment_frame_tag(), and hwasan_truncate_to_tag_size().
Flags for Asan check builtins.
Referenced by dump_gimple_call_args().
enum asan_check_flags |
enum asan_mark_flags |
Build __asan_before_dynamic_init (module_name) or __asan_after_dynamic_init () call.
References asan_init_shadow_ptr_types(), asan_pp_string(), build_call_expr(), builtin_decl_implicit(), const_ptr_type_node, fold_convert, NULL_TREE, pp_string(), and shadow_ptr_types.
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.
References convert_memory_address, do_pending_stack_adjust(), emit_library_call(), end_sequence(), get_insns(), init_one_libfunc(), insns, LCT_NORMAL, ptr_mode, push_to_sequence(), and start_sequence().
Referenced by expand_used_vars().
|
extern |
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.
References adjust_address, asan_clear_shadow(), asan_detect_stack_use_after_return, asan_dynamic_shadow_offset_p(), asan_handled_variables, asan_init_shadow_ptr_types(), ASAN_MIN_RED_ZONE_SIZE, asan_pp_string(), ASAN_RED_ZONE_SIZE, ASAN_SHADOW_GRANULARITY, asan_shadow_offset(), asan_shadow_set, ASAN_SHADOW_SHIFT, ASAN_STACK_FRAME_MAGIC, ASAN_STACK_MAGIC_LEFT, ASAN_STACK_MAGIC_MIDDLE, ASAN_STACK_MAGIC_RIGHT, ASAN_STACK_MAGIC_USE_AFTER_RET, ASAN_STACK_RETIRED_MAGIC, asan_used_labels, build_decl(), build_fold_addr_expr, builtin_memset_read_str(), BUILTINS_LOCATION, can_store_by_pieces(), char_type_node, const0_rtx, hash_set< KeyId, Lazy, Traits >::contains(), convert_memory_address, crtl, current_function_decl, current_function_funcdef_no, DECL_ALIGN_RAW, DECL_ARTIFICIAL, DECL_EXTERNAL, DECL_IGNORED_P, DECL_INITIAL, DECL_NAME, DECL_P, DECL_SOURCE_LOCATION, decls, do_pending_stack_adjust(), dump_file, dump_flags, emit_cmp_and_jump_insns(), emit_jump(), emit_label(), emit_library_call(), emit_library_call_value(), emit_move_insn(), asan_redzone_buffer::emit_redzone_byte(), end_sequence(), expand_binop(), expand_location(), expand_normal(), expand_simple_binop(), floor_log2(), gcc_assert, gcc_checking_assert, GEN_INT, gen_int_mode(), gen_int_shift_amount(), gen_label_rtx(), gen_reg_rtx(), gen_rtx_MEM(), get_asan_shadow_memory_dynamic_address_decl(), get_identifier(), get_insns(), GET_MODE_ALIGNMENT, GET_MODE_SIZE(), HOST_WIDE_INT_1, IDENTIFIER_LENGTH, IDENTIFIER_POINTER, init_one_libfunc(), insns, integer_type_node, LCT_NORMAL, asan_redzone_buffer::m_shadow_bytes, NULL, NULL_RTX, NULL_TREE, offset, OPTAB_DIRECT, OPTAB_WIDEN, plus_constant(), pointer_sized_int_node, pp_decimal_int, pp_space, pp_string(), pp_tree_identifier(), pp_wide_integer(), PRId64, ptr_mode, RETURN_BEGIN, seen_error(), SET_DECL_ASSEMBLER_NAME, set_mem_alias_set(), set_mem_align(), set_storage_via_setmem(), shadow_ptr_types, start_sequence(), store_by_pieces(), TDF_DETAILS, TREE_ADDRESSABLE, TREE_ASM_WRITTEN, TREE_PUBLIC, TREE_READONLY, TREE_STATIC, TREE_USED, TYPE_MODE, profile_probability::very_likely(), and profile_probability::very_unlikely().
Referenced by expand_used_vars().
|
extern |
Expand the ASAN_{LOAD,STORE} builtins.
References as_a(), ASAN_CHECK_LAST, ASAN_CHECK_NON_ZERO_LEN, ASAN_CHECK_SCALAR_ACCESS, ASAN_CHECK_STORE, build_assign(), build_int_cst(), build_shadow_mem_access(), build_type_cast(), check_func(), create_cond_insert_point(), g, gcc_assert, gimple_assign_lhs(), gimple_build_assign(), gimple_build_call(), gimple_build_cond(), gimple_call_arg(), gimple_location(), gimple_seq_add_stmt(), gimple_seq_last(), gimple_seq_last_stmt(), gimple_seq_set_location(), gimple_set_location(), GSI_CONTINUE_LINKING, gsi_insert_after(), gsi_insert_before(), gsi_insert_seq_after(), gsi_last_bb(), GSI_NEW_STMT, gsi_remove(), gsi_replace(), GSI_SAME_STMT, gsi_start_bb(), gsi_stmt(), hwasan_sanitize_p(), insert_if_then_before_iter(), last, make_ssa_name(), NULL, NULL_TREE, pointer_sized_int_node, report_error_func(), SANITIZE_KERNEL_ADDRESS, SANITIZE_USER_ADDRESS, shadow_ptr_types, size_in_bytes(), tree_fits_shwi_p(), tree_to_shwi(), and TREE_TYPE.
|
extern |
Expand the ASAN_MARK builtins.
References hash_set< KeyId, Lazy, Traits >::add(), asan_handled_variables, ASAN_SHADOW_GRANULARITY, ASAN_SHADOW_SHIFT, asan_store_shadow_bytes(), build_shadow_mem_access(), builtin_decl_implicit(), DECL_NONLOCAL_FRAME, g, gcc_assert, gcc_checking_assert, get_pointer_alignment(), gimple_assign_lhs(), gimple_build(), gimple_build_assign(), gimple_build_call(), gimple_build_round_up(), gimple_call_arg(), gimple_location(), gimple_set_location(), gsi_insert_after(), GSI_NEW_STMT, gsi_replace(), gsi_replace_with_seq(), gsi_safe_insert_before(), gsi_stmt(), hwasan_sanitize_p(), HWASAN_TAG_GRANULE_SIZE, make_ssa_name(), NULL, offset, pointer_sized_int_node, poly_int_tree_p(), shadow_mem_size(), shadow_ptr_types, size_in_bytes(), size_type_node, TREE_CODE, tree_fits_uhwi_p(), TREE_OPERAND, tree_to_shwi(), tree_to_uhwi(), and void_type_node.
|
extern |
Expand ASAN_POISON ifn.
References build_fold_addr_expr, build_int_cst(), builtin_decl_implicit(), create_asan_shadow_var(), create_tmp_var, DECL_SIZE_UNIT, dyn_cast(), FOR_EACH_IMM_USE_STMT, g, gimple_build_call(), gimple_build_call_internal(), gimple_build_nop(), gimple_call_internal_p(), gimple_call_lhs(), gimple_copy(), gimple_location(), gimple_phi_arg_def(), gimple_phi_arg_edge(), gimple_phi_num_args(), gimple_set_location(), gsi_for_stmt(), gsi_insert_before(), gsi_insert_seq_on_edge(), GSI_NEW_STMT, gsi_remove(), gsi_replace(), gsi_stmt(), has_zero_uses(), hwasan_sanitize_p(), i, integer_type_node, is_a(), is_gimple_debug(), NULL, NULL_TREE, pointer_sized_int_node, report_error_func(), SANITIZE_KERNEL_ADDRESS, SANITIZE_USER_ADDRESS, SET_SSA_NAME_VAR_OR_IDENTIFIER, SSA_NAME_DEF_STMT, SSA_NAME_IS_DEFAULT_DEF, SSA_NAME_VAR, tree_to_uhwi(), and TREE_TYPE.
|
extern |
Needs to be tree asan_ctor_statements; /** @verbatim Module-level instrumentation. - Insert __asan_init_vN() into the list of CTORs. - TODO: insert redzones around globals.
References add_string_csts(), append_to_statement_list(), asan_add_global(), asan_global_struct(), asan_init_shadow_ptr_types(), asan_protect_global(), ASAN_SHADOW_GRANULARITY, build_array_type_nelts(), build_call_expr(), build_constructor(), build_decl(), build_fold_addr_expr, build_int_cst(), builtin_decl_implicit(), cgraph_build_static_cdtor(), const_desc_htab, constant_pool_htab(), count_string_csts(), symtab_node::decl, DECL_ALIGN, DECL_ARTIFICIAL, DECL_IGNORED_P, DECL_INITIAL, DEFAULT_INIT_PRIORITY, varpool_node::finalize_decl(), FOR_EACH_DEFINED_VARIABLE, get_identifier(), MAX, MAX_RESERVED_INIT_PRIORITY, NULL_TREE, pointer_sized_int_node, SANITIZE_ADDRESS, SANITIZE_USER_ADDRESS, SET_DECL_ALIGN, shadow_ptr_types, TREE_ASM_WRITTEN, TREE_CONSTANT, TREE_PUBLIC, TREE_STATIC, TREE_TYPE, asan_add_string_csts_data::type, UNKNOWN_LOCATION, asan_add_string_csts_data::v, and vec_alloc().
Referenced by compile_file().
|
extern |
AddressSanitizer, a fast memory error detector. Copyright (C) 2011-2024 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/>.
References asm_out_file, ASM_OUTPUT_DEBUG_LABEL, and current_function_funcdef_no.
Referenced by assemble_function_label_final().
|
inline |
Return TRUE if builtin with given FCODE will be intercepted by libasan.
References hwasan_sanitize_p().
Referenced by expand_builtin(), and get_mem_refs_of_builtin_call().
|
extern |
Return true if STMT is ASAN_MARK with FLAG as first argument.
References gimple_call_arg(), gimple_call_internal_p(), and tree_to_uhwi().
Referenced by execute_update_addresses_taken(), and transform_statements().
|
extern |
References asan_dynamic_shadow_offset_p(), asan_local_shadow_memory_dynamic_address, cfun, create_tmp_var, ENTRY_BLOCK_PTR_FOR_FN, function::function_start_locus, g, get_asan_shadow_memory_dynamic_address_decl(), gimple_build_assign(), gimple_set_location(), gsi_insert_on_edge_immediate(), NULL_TREE, pointer_sized_int_node, and single_succ_edge().
References asan_memfn_rtls, DECL_ASSEMBLER_NAME, DECL_ASSEMBLER_NAME_RAW, DECL_FUNCTION_CODE(), DECL_NAME, DECL_RTL, gcc_unreachable, get_identifier(), i, NULL_RTX, NULL_TREE, SANITIZE_KERNEL_HWADDRESS, and SET_DECL_RTL.
Referenced by expand_builtin().
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.
References ADDR_SPACE_GENERIC_P, asan_needs_local_alias(), ASAN_RED_ZONE_SIZE, CONSTANT_POOL_ADDRESS_P, DECL_ALIGN_UNIT, DECL_ATTRIBUTES, DECL_COMMON, DECL_EXTERNAL, DECL_ONE_ONLY, DECL_RTL, DECL_RTL_SET_P, DECL_SECTION_NAME, DECL_SIZE, DECL_SIZE_UNIT, DECL_THREAD_LOCAL_P, symtab_node::get(), GET_CODE, is_odr_indicator(), lookup_attribute(), MAX_OFILE_ALIGNMENT, MEM_P, NULL, NULL_TREE, section_sanitized_p(), shadow_ptr_types, TARGET_SUPPORTS_ALIASES, TREE_CODE, TREE_CONSTANT_POOL_ADDRESS_P, TREE_PUBLIC, TREE_TYPE, TYPE_ADDR_SPACE, ubsan_get_source_location_type(), valid_constant_size_p(), VAR_P, and XEXP.
Referenced by add_string_csts(), asan_finish_file(), assemble_noswitch_variable(), assemble_variable(), categorize_decl_for_section(), count_string_csts(), get_variable_section(), output_constant_def_contents(), output_object_block(), and place_block_symbol().
Return true if DECL should be guarded on the stack.
References asan_sanitize_use_after_scope(), DECL_ARTIFICIAL, DECL_P, and TREE_ADDRESSABLE.
Referenced by asan_decl_phase_3(), and expand_stack_vars().
|
inline |
Return the size of padding needed to insert after a protected decl of SIZE.
References ASAN_RED_ZONE_SIZE.
Referenced by asan_add_global(), assemble_noswitch_variable(), assemble_variable(), output_constant_def_contents(), output_object_block(), and place_block_symbol().
|
extern |
References asan_sanitize_stack_p().
Referenced by expand_used_vars(), handle_builtin_alloca(), and handle_builtin_stack_restore().
|
extern |
References SANITIZE_ADDRESS, and sanitize_flags_p().
Referenced by asan_sanitize_allocas_p(), asan_sanitize_use_after_scope(), defer_stack_allocation(), expand_stack_vars(), expand_used_vars(), and partition_stack_vars().
|
inline |
Return TRUE if we should instrument for use-after-scope sanity checking.
References asan_sanitize_stack_p(), and hwasan_sanitize_stack_p().
Referenced by asan_protect_stack_decl(), gimplify_function_tree(), instrument_derefs(), and maybe_register_def().
|
extern |
Returns Asan shadow offset has been set.
References asan_shadow_offset_computed.
Referenced by process_options().
|
inline |
Return how much a stack variable occupis on a stack including a space for red zone.
Referenced by expand_stack_vars().
|
extern |
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.
References add_bb_to_loop(), CDI_DOMINATORS, basic_block_def::count, create_empty_bb(), current_loops, dom_info_available_p(), find_edge(), gsi_bb(), gsi_end_p(), gsi_last_bb(), gsi_prev(), gsi_start_bb(), gsi_stmt(), profile_probability::invert(), basic_block_def::loop_father, LOOPS_NEED_FIXUP, loops_state_set(), make_edge(), make_single_succ_edge(), set_immediate_dominator(), split_block(), profile_probability::very_likely(), and profile_probability::very_unlikely().
Referenced by asan_expand_check_ifn(), insert_if_then_before_iter(), instrument_bool_enum_load(), instrument_builtin(), instrument_nonnull_arg(), instrument_nonnull_return(), ubsan_expand_bounds_ifn(), ubsan_expand_objsize_ifn(), and ubsan_expand_vptr_ifn().
|
extern |
Referenced by compile_file().
|
extern |
HWASAN
For stack tagging: Return the offset from the frame base tag that the "next" expanded object should have.
References hwasan_frame_tag_offset.
Referenced by expand_HWASAN_CHOOSE_TAG(), expand_one_stack_var_at(), and hwasan_record_stack_var().
|
extern |
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.
References convert_memory_address, emit_library_call(), gcc_assert, gen_int_mode(), HWASAN_TAG_GRANULE_SIZE, hwasan_tagged_stack_vars, hwasan_truncate_to_tag_size(), init_one_libfunc(), known_ge, known_le, LCT_NORMAL, NULL_RTX, plus_constant(), ptr_mode, and targetm.
Referenced by expand_used_vars().
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.
References convert_memory_address, do_pending_stack_adjust(), emit_library_call(), end_sequence(), expand_simple_binop(), FRAME_GROWS_DOWNWARD, get_insns(), HWASAN_STACK_BACKGROUND, init_one_libfunc(), insns, LCT_NORMAL, NULL, NULL_RTX, OPTAB_DIRECT, ptr_mode, and start_sequence().
Referenced by expand_used_vars().
|
extern |
Expand the HWASAN_{LOAD,STORE} builtins.
|
extern |
For stack tagging: Dummy: the HWASAN_MARK internal function should only ever be in the code after the sanopt pass.
|
extern |
Needs to be tree hwasan_ctor_statements; /** @verbatim Insert module initialization into this TU. This initialization calls the initialization code for libhwasan.
References append_to_statement_list(), build_call_expr(), builtin_decl_implicit(), cgraph_build_static_cdtor(), initialize_sanitizer_builtins(), MAX_RESERVED_INIT_PRIORITY, SANITIZE_HWADDRESS, and SANITIZE_KERNEL_HWADDRESS.
Referenced by compile_file().
|
extern |
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.
References end_sequence(), force_reg(), get_insns(), hwasan_frame_base_init_seq, hwasan_frame_base_ptr, NULL_RTX, start_sequence(), targetm, and virtual_stack_vars_rtx.
Referenced by expand_HWASAN_CHOOSE_TAG(), expand_one_stack_var_1(), and expand_stack_vars().
|
extern |
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.
References frame_offset, hwasan_frame_base_ptr, NULL_RTX, plus_constant(), and virtual_stack_vars_rtx.
Referenced by expand_used_vars().
|
extern |
For stack tagging: Increment the frame tag offset modulo the size a tag can represent.
References CHAR_BIT, gcc_assert, hwasan_frame_tag_offset, HWASAN_TAG_SIZE, sanitize_flags_p(), and SANITIZE_KERNEL_HWADDRESS.
Referenced by expand_HWASAN_CHOOSE_TAG(), expand_one_stack_var_1(), and expand_stack_vars().
|
extern |
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.
References emit_insn_before(), hwasan_frame_base_init_seq, and parm_birth_insn.
|
extern |
Clear internal state for the next function. This function is called before variables on the stack get expanded, in `init_vars_expansion`.
References asan_used_labels, gcc_assert, hwasan_frame_base_init_seq, hwasan_frame_base_ptr, hwasan_frame_tag_offset, hwasan_tagged_stack_vars, NULL, NULL_RTX, sanitize_flags_p(), and SANITIZE_KERNEL_HWADDRESS.
Referenced by init_vars_expansion().
|
extern |
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.
References hwasan_stack_var::farthest_offset, hwasan_current_frame_tag(), hwasan_tagged_stack_vars, hwasan_stack_var::nearest_offset, hwasan_stack_var::tag_offset, hwasan_stack_var::tagged_base, and hwasan_stack_var::untagged_base.
Referenced by expand_one_stack_var_1(), and expand_stack_vars().
|
extern |
Are we tagging alloca objects?
References hwasan_sanitize_stack_p().
Referenced by expand_used_vars(), handle_builtin_alloca(), and handle_builtin_stack_restore().
|
extern |
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.
References sanitize_flags_p(), and SANITIZE_HWADDRESS.
Referenced by asan_expand_check_ifn(), asan_expand_mark_ifn(), asan_expand_poison_ifn(), asan_instrument(), asan_intercepted_p(), asan_poison_variable(), build_check_stmt(), get_mem_refs_of_builtin_call(), hwasan_instrument_reads(), hwasan_instrument_writes(), hwasan_memintrin(), hwasan_sanitize_stack_p(), instrument_derefs(), maybe_instrument_call(), report_error_func(), and sanopt_optimize_walker().
|
extern |
Are we tagging the stack?
References hwasan_sanitize_p().
Referenced by align_local_variable(), asan_poison_variable(), asan_sanitize_use_after_scope(), expand_one_stack_var_1(), expand_one_stack_var_at(), expand_stack_vars(), expand_used_vars(), hwasan_sanitize_allocas_p(), and init_vars_expansion().
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.
References expand_simple_binop(), gcc_assert, gen_int_mode(), GET_MODE, GET_MODE_PRECISION(), HOST_WIDE_INT_1U, HWASAN_TAG_SIZE, and OPTAB_WIDEN.
Referenced by expand_HWASAN_CHOOSE_TAG(), and hwasan_emit_prologue().
|
extern |
Initialize sanitizer.def builtins if the FE hasn't initialized them.
This file contains the definitions and documentation for the Address Sanitizer and Thread Sanitizer builtins used in the GNU compiler. Copyright (C) 2012-2024 Free Software Foundation, Inc. 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/>.
Before including this file, you should define a macro: DEF_BUILTIN_STUB(ENUM, NAME) DEF_SANITIZER_BUILTIN (ENUM, NAME, TYPE, ATTRS) See builtins.def for details. The builtins are created by the C-family of FEs in c-family/c-common.cc, for other FEs by asan.cc.
This has to come before all the sanitizer builtins.
Address Sanitizer
Do not reorder the BUILT_IN_ASAN_{REPORT,CHECK}* builtins, e.g. cfgcleanup.cc relies on this order.
Hardware Address Sanitizer.
Thread Sanitizer
Undefined Behavior Sanitizer
Sanitizer coverage
This has to come after all the sanitizer builtins.
References ATTR_PURE_NOTHROW_LEAF_LIST, BOOL_TYPE_SIZE, build_function_type_list(), build_nonstandard_integer_type(), build_pointer_type(), build_qualified_type(), builtin_decl_implicit_p(), const_ptr_type_node, DEF_SANITIZER_BUILTIN_1, double_type_node, float_type_node, i, integer_type_node, NULL_TREE, pointer_sized_int_node, ptr_type_node, SANITIZE_OBJECT_SIZE, size_type_node, lang_hooks_for_types::type_for_size, TYPE_QUAL_CONST, TYPE_QUAL_VOLATILE, lang_hooks::types, uint16_type_node, uint32_type_node, uint64_type_node, unsigned_char_type_node, and void_type_node.
Referenced by asan_init_shadow_ptr_types(), asan_instrument(), hwasan_finish_file(), tsan_finish_file(), tsan_pass(), and ubsan_create_data().
|
inline |
Return true when coverage sanitization should happend for FN function.
References DECL_ATTRIBUTES, lookup_attribute(), and NULL_TREE.
Referenced by fold_range_test(), fold_truth_andor(), ifcombine_ifandif(), and sanitize_attrs_match_for_inline_p().
|
inline |
Return true when flag_sanitize & FLAG is non-zero. If FN is non-null, remove all flags mentioned in "no_sanitize" of DECL_ATTRIBUTES.
References DECL_ATTRIBUTES, lookup_attribute(), NULL_TREE, and TREE_VALUE.
Referenced by asan_instrument_reads(), asan_instrument_writes(), asan_memintrin(), asan_sanitize_stack_p(), builtin_decl_unreachable(), convert_to_integer_1(), copy_bb(), do_narrow(), expand_builtin(), expand_builtin_unreachable(), fold_builtin_0(), fold_unary_loc(), gate_asan(), gimple_fold_builtin_strlen(), gimple_seq_unreachable_p(), gimplify_function_tree(), hwasan_increment_frame_tag(), hwasan_record_frame_init(), hwasan_sanitize_p(), instrument_bool_enum_load(), instrument_mem_ref(), lower_resx(), ipa_icf::sem_variable::merge(), optimize_atomic_compare_exchange_p(), sanitize_attrs_match_for_inline_p(), sanitize_unreachable_fn(), and ubsan_expand_null_ifn().
|
extern |
Sets shadow offset to value in string VAL.
References asan_shadow_offset_computed, asan_shadow_offset_value, and errno.
Referenced by handle_common_deferred_options().
|
extern |
Set list of user-defined sections that need to be sanitized.
References end(), FOR_EACH_VEC_ELT, free(), i, and sanitized_sections.
Referenced by handle_common_deferred_options().
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.
References hwasan_frame_base_ptr, and virtual_stack_vars_rtx.
Referenced by expand_one_stack_var_at().
Set of variable declarations that are going to be guarded by use-after-scope sanitizer.
Referenced by asan_emit_stack_protection(), asan_expand_mark_ifn(), and expand_stack_vars().
|
extern |
Alias set for accessing the shadow memory.
Referenced by asan_emit_stack_protection(), and asan_init_shadow_ptr_types().
Hash set of labels that are either used in a goto, or their address has been taken.
Referenced by asan_emit_stack_protection(), gimplify_expr(), and hwasan_record_frame_init().