1# Copyright (C) 2020-2021 Free Software Foundation, Inc. 2 3# This program is free software; you can redistribute it and/or modify 4# it under the terms of the GNU General Public License as published by 5# the Free Software Foundation; either version 3 of the License, or 6# (at your option) any later version. 7# 8# This program is distributed in the hope that it will be useful, 9# but WITHOUT ANY WARRANTY; without even the implied warranty of 10# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11# GNU General Public License for more details. 12# 13# You should have received a copy of the GNU General Public License 14# along with GCC; see the file COPYING3. If not see 15# <http://www.gnu.org/licenses/>. 16 17load_lib asan-dg.exp 18 19# Return 1 if target can compile a binary for hardware address 20# sanitization, 0 otherwise. 21# 22# NOTE: This should only be used between calls to hwasan_init and 23# hwasan_finish. It is therefore defined here rather than in 24# target-supports.exp. 25 26proc check_effective_target_fsanitize_hwaddress {} { 27 if ![check_no_compiler_messages fsanitize_hwaddress executable { 28 int main (void) { return 0; } 29 }] { 30 return 0; 31 } 32 return 1; 33} 34 35# Return 1 if target can compile and run a binary for hardware address 36# sanitization, 0 otherwise. 37# 38# NOTE: This should only be used between calls to hwasan_init and 39# hwasan_finish. It is therefore defined here rather than in 40# target-supports.exp. 41 42proc check_effective_target_hwaddress_exec {} { 43 if ![check_runtime hwaddress_exec { 44 #ifdef __cplusplus 45 extern "C" { 46 #endif 47 extern int prctl(int, unsigned long, unsigned long, unsigned long, unsigned long); 48 #ifdef __cplusplus 49 } 50 #endif 51 int main (void) { 52 #define PR_SET_TAGGED_ADDR_CTRL 55 53 #define PR_GET_TAGGED_ADDR_CTRL 56 54 #define PR_TAGGED_ADDR_ENABLE (1UL << 0) 55 if (prctl (PR_GET_TAGGED_ADDR_CTRL, 0, 0, 0, 0) == -1) 56 return 1; 57 if (prctl(PR_SET_TAGGED_ADDR_CTRL, PR_TAGGED_ADDR_ENABLE, 0, 0, 0) == -1 58 || !prctl(PR_GET_TAGGED_ADDR_CTRL, 0, 0, 0, 0)) 59 return 1; 60 return 0; 61 } 62 }] { 63 return 0; 64 } 65 return 1; 66} 67 68proc hwasan_include_flags {} { 69 global srcdir 70 global TESTING_IN_BUILD_TREE 71 72 set flags "" 73 74 if { [is_remote host] || ! [info exists TESTING_IN_BUILD_TREE] } { 75 return "${flags}" 76 } 77 78 set flags "-I$srcdir/../../libsanitizer/include" 79 80 return "$flags" 81} 82 83# 84# hwasan_link_flags -- compute library path and flags to find libhwasan. 85# (implementation in asan-dg.exp) 86# 87 88proc hwasan_link_flags { paths } { 89 return [asan_link_flags_1 $paths hwasan] 90} 91 92# 93# hwasan_init -- called at the start of each subdir of tests 94# 95 96proc hwasan_init { args } { 97 global TEST_ALWAYS_FLAGS 98 global ALWAYS_CXXFLAGS 99 global TOOL_OPTIONS 100 global hwasan_saved_TEST_ALWAYS_FLAGS 101 global hwasan_saved_ALWAYS_CXXFLAGS 102 103 setenv HWASAN_OPTIONS "random_tags=0" 104 105 set link_flags "" 106 if ![is_remote host] { 107 if [info exists TOOL_OPTIONS] { 108 set link_flags "[hwasan_link_flags [get_multilibs ${TOOL_OPTIONS}]]" 109 } else { 110 set link_flags "[hwasan_link_flags [get_multilibs]]" 111 } 112 } 113 114 set include_flags "[hwasan_include_flags]" 115 116 if [info exists TEST_ALWAYS_FLAGS] { 117 set hwasan_saved_TEST_ALWAYS_FLAGS $TEST_ALWAYS_FLAGS 118 } 119 if [info exists ALWAYS_CXXFLAGS] { 120 set hwasan_saved_ALWAYS_CXXFLAGS $ALWAYS_CXXFLAGS 121 set ALWAYS_CXXFLAGS [concat "{ldflags=$link_flags}" $ALWAYS_CXXFLAGS] 122 set ALWAYS_CXXFLAGS [concat "{additional_flags=-fsanitize=hwaddress --param hwasan-random-frame-tag=0 -g $include_flags}" $ALWAYS_CXXFLAGS] 123 } else { 124 if [info exists TEST_ALWAYS_FLAGS] { 125 set TEST_ALWAYS_FLAGS "$link_flags -fsanitize=hwaddress --param hwasan-random-frame-tag=0 -g $include_flags $TEST_ALWAYS_FLAGS" 126 } else { 127 set TEST_ALWAYS_FLAGS "$link_flags -fsanitize=hwaddress --param hwasan-random-frame-tag=0 -g $include_flags" 128 } 129 } 130} 131 132# 133# hwasan_finish -- called at the start of each subdir of tests 134# 135 136proc hwasan_finish { args } { 137 global TEST_ALWAYS_FLAGS 138 global hwasan_saved_TEST_ALWAYS_FLAGS 139 global hwasan_saved_ALWAYS_CXXFLAGS 140 global hwasan_saved_library_path 141 global ld_library_path 142 143 unsetenv HWASAN_OPTIONS 144 145 if [info exists hwasan_saved_ALWAYS_CXXFLAGS ] { 146 set ALWAYS_CXXFLAGS $hwasan_saved_ALWAYS_CXXFLAGS 147 } else { 148 if [info exists hwasan_saved_TEST_ALWAYS_FLAGS] { 149 set TEST_ALWAYS_FLAGS $hwasan_saved_TEST_ALWAYS_FLAGS 150 } else { 151 unset TEST_ALWAYS_FLAGS 152 } 153 } 154 if [info exists hwasan_saved_library_path] { 155 set ld_library_path $hwasan_saved_library_path 156 set_ld_library_path_env_vars 157 } 158 clear_effective_target_cache 159} 160 161# Utility for running gtest hwasan emulation under dejagnu, invoked via dg-final. 162# Call pass if variable has the desired value, otherwise fail. 163# 164# Argument 0 handles expected failures and the like 165proc hwasan-gtest { args } { 166 asan-gtest {*}$args 167} 168