mirror of
https://gcc.gnu.org/git/gcc.git
synced 2024-12-04 01:04:26 +08:00
libsanitizer: Add tests
Only interesting thing here is that we have to make sure the tagging mechanism is deterministic to avoid flaky tests. gcc/testsuite/ChangeLog: * c-c++-common/ubsan/sanitize-recover-7.c: Update error message format. * lib/asan-dg.exp (asan_link_flags): Implement as a helper function asan_link_flags_1 which asan_link_flags and hwasan_link_flags use. (asan_link_flags_1): Parametrised version of asan_link_flags. * c-c++-common/hwasan/aligned-alloc.c: New test. * c-c++-common/hwasan/alloca-array-accessible.c: New test. * c-c++-common/hwasan/alloca-base-init.c: New test. * c-c++-common/hwasan/alloca-gets-different-tag.c: New test. * c-c++-common/hwasan/alloca-outside-caught.c: New test. * c-c++-common/hwasan/arguments-1.c: New test. * c-c++-common/hwasan/arguments-2.c: New test. * c-c++-common/hwasan/arguments-3.c: New test. * c-c++-common/hwasan/arguments.c: New test. * c-c++-common/hwasan/asan-pr63316.c: New test. * c-c++-common/hwasan/asan-pr70541.c: New test. * c-c++-common/hwasan/asan-pr78106.c: New test. * c-c++-common/hwasan/asan-pr79944.c: New test. * c-c++-common/hwasan/asan-rlimit-mmap-test-1.c: New test. * c-c++-common/hwasan/bitfield-1.c: New test. * c-c++-common/hwasan/bitfield-2.c: New test. * c-c++-common/hwasan/builtin-special-handling.c: New test. * c-c++-common/hwasan/check-interface.c: New test. * c-c++-common/hwasan/halt_on_error-1.c: New test. * c-c++-common/hwasan/handles-poly_int-marked-vars.c: New test. * c-c++-common/hwasan/heap-overflow.c: New test. * c-c++-common/hwasan/hwasan-poison-optimisation.c: New test. * c-c++-common/hwasan/hwasan-thread-access-parent.c: New test. * c-c++-common/hwasan/hwasan-thread-basic-failure.c: New test. * c-c++-common/hwasan/hwasan-thread-clears-stack.c: New test. * c-c++-common/hwasan/hwasan-thread-success.c: New test. * c-c++-common/hwasan/kernel-defaults.c: New test. * c-c++-common/hwasan/large-aligned-0.c: New test. * c-c++-common/hwasan/large-aligned-1.c: New test. * c-c++-common/hwasan/large-aligned-untagging-0.c: New test. * c-c++-common/hwasan/large-aligned-untagging-1.c: New test. * c-c++-common/hwasan/large-aligned-untagging-2.c: New test. * c-c++-common/hwasan/large-aligned-untagging-3.c: New test. * c-c++-common/hwasan/large-aligned-untagging-4.c: New test. * c-c++-common/hwasan/large-aligned-untagging-5.c: New test. * c-c++-common/hwasan/large-aligned-untagging-6.c: New test. * c-c++-common/hwasan/large-aligned-untagging-7.c: New test. * c-c++-common/hwasan/macro-definition.c: New test. * c-c++-common/hwasan/no-sanitize-attribute.c: New test. * c-c++-common/hwasan/param-instrument-mem-intrinsics.c: New test. * c-c++-common/hwasan/param-instrument-reads-and-writes.c: New test. * c-c++-common/hwasan/param-instrument-reads.c: New test. * c-c++-common/hwasan/param-instrument-writes.c: New test. * c-c++-common/hwasan/random-frame-tag.c: New test. * c-c++-common/hwasan/sanity-check-pure-c.c: New test. * c-c++-common/hwasan/setjmp-longjmp-0.c: New test. * c-c++-common/hwasan/setjmp-longjmp-1.c: New test. * c-c++-common/hwasan/stack-tagging-basic-0.c: New test. * c-c++-common/hwasan/stack-tagging-basic-1.c: New test. * c-c++-common/hwasan/stack-tagging-disable.c: New test. * c-c++-common/hwasan/unprotected-allocas-0.c: New test. * c-c++-common/hwasan/unprotected-allocas-1.c: New test. * c-c++-common/hwasan/use-after-free.c: New test. * c-c++-common/hwasan/vararray-outside-caught.c: New test. * c-c++-common/hwasan/vararray-stack-restore-correct.c: New test. * c-c++-common/hwasan/very-large-objects.c: New test. * g++.dg/hwasan/hwasan.exp: New test. * g++.dg/hwasan/rvo-handled.C: New test. * gcc.dg/hwasan/hwasan.exp: New test. * gcc.dg/hwasan/nested-functions-0.c: New test. * gcc.dg/hwasan/nested-functions-1.c: New test. * gcc.dg/hwasan/nested-functions-2.c: New test. * lib/hwasan-dg.exp: New file.
This commit is contained in:
parent
93a7325148
commit
a47850552a
16
gcc/testsuite/c-c++-common/hwasan/aligned-alloc.c
Normal file
16
gcc/testsuite/c-c++-common/hwasan/aligned-alloc.c
Normal file
@ -0,0 +1,16 @@
|
||||
/* { dg-do run } */
|
||||
/* { dg-require-effective-target hwaddress_exec } */
|
||||
/* { dg-shouldfail "hwasan" } */
|
||||
/* This program fails at runtime in the libhwasan library.
|
||||
The allocator can't handle the requested invalid alignment. */
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
void *p = __builtin_aligned_alloc (17, 100);
|
||||
if (((unsigned long long)p & 0x10) == 0)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* { dg-output "HWAddressSanitizer: invalid alignment requested in aligned_alloc: 17" } */
|
33
gcc/testsuite/c-c++-common/hwasan/alloca-array-accessible.c
Normal file
33
gcc/testsuite/c-c++-common/hwasan/alloca-array-accessible.c
Normal file
@ -0,0 +1,33 @@
|
||||
/* { dg-do run } */
|
||||
/* { dg-require-effective-target hwaddress_exec } */
|
||||
|
||||
#define alloca __builtin_alloca
|
||||
|
||||
int __attribute__ ((noinline))
|
||||
using_alloca (int num)
|
||||
{
|
||||
int retval = 0;
|
||||
int *big_array = (int*)alloca (num * sizeof (int));
|
||||
for (int i = 0; i < num; ++i) {
|
||||
retval += big_array[i];
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
int __attribute__ ((noinline))
|
||||
using_vararray (int num)
|
||||
{
|
||||
int retval = 0;
|
||||
int big_array[num];
|
||||
for (int i = 0; i < num; ++i) {
|
||||
retval += big_array[i];
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
using_alloca (16);
|
||||
using_vararray (12);
|
||||
return 0;
|
||||
}
|
66
gcc/testsuite/c-c++-common/hwasan/alloca-base-init.c
Normal file
66
gcc/testsuite/c-c++-common/hwasan/alloca-base-init.c
Normal file
@ -0,0 +1,66 @@
|
||||
/* { dg-do run } */
|
||||
/* { dg-require-effective-target hwaddress_exec } */
|
||||
/* { dg-additional-options "--param hwasan-random-frame-tag=1" } */
|
||||
/* { dg-skip-if "" { *-*-* } { "-flto" } { "" } } */
|
||||
#include <alloca.h>
|
||||
|
||||
/* This testcase checks that `alloca` calls ensure the `__hwasan_generate_tag`
|
||||
function is called to initialize the base tag. `alloca` calls are treated
|
||||
differently to standard variables. The prologue/epilogue sequence is
|
||||
generated mainly based on normal stack-allocated objects.
|
||||
|
||||
We want to ensure that though the `alloca` call is not poisoned/unpoisoned
|
||||
by the prologue and epilogue, the use of them in a given function still
|
||||
triggers the prologue sequence to emit a call to __hwasan_generate_tag (and
|
||||
hence that any call to __hwasan_generate_tag is emitted in the unconditional
|
||||
part of the function code). */
|
||||
|
||||
int choice = 0;
|
||||
int record = 1;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
__attribute__ ((noinline))
|
||||
unsigned char
|
||||
__hwasan_generate_tag ()
|
||||
{
|
||||
record = 0;
|
||||
return 3;
|
||||
}
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
__attribute__ ((noinline))
|
||||
int
|
||||
generate_tag_was_missed (void)
|
||||
{
|
||||
return record;
|
||||
}
|
||||
|
||||
__attribute__((noinline, noclone)) int
|
||||
foo (char *a)
|
||||
{
|
||||
int i, j = 0;
|
||||
asm volatile ("" : "+r" (a) : : "memory");
|
||||
for (i = 0; i < 12; i++)
|
||||
j += a[i];
|
||||
return j;
|
||||
}
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
if (choice)
|
||||
{
|
||||
char *x = (char *)alloca(100);
|
||||
foo(x);
|
||||
}
|
||||
else
|
||||
{
|
||||
char *y = (char *)alloca(20);
|
||||
foo(y);
|
||||
}
|
||||
return generate_tag_was_missed ();
|
||||
}
|
@ -0,0 +1,65 @@
|
||||
/* { dg-do run } */
|
||||
/* { dg-require-effective-target hwaddress_exec } */
|
||||
|
||||
/* Alloca is given a different tag to other variables.
|
||||
vararray should behave in the same way. */
|
||||
|
||||
#define alloca __builtin_alloca
|
||||
#define assert(x) if (!(x)) __builtin_abort ()
|
||||
|
||||
struct two_values {
|
||||
int left;
|
||||
int right;
|
||||
};
|
||||
|
||||
/* Require default hwasan tag ABI.
|
||||
Know we're using AArch64 since that's the only architecture we run hwasan
|
||||
tests on. */
|
||||
char tag_of (void * x) { return ((unsigned long long)x) >> 56; }
|
||||
|
||||
int __attribute__ ((noinline))
|
||||
alloca_different_tag (int num)
|
||||
{
|
||||
struct two_values tmp_object = {
|
||||
.left = 100,
|
||||
.right = num,
|
||||
};
|
||||
int *big_array = (int *)alloca (num * sizeof (int));
|
||||
int other_array[100];
|
||||
|
||||
char first_tag = tag_of (&tmp_object);
|
||||
char second_tag = tag_of (big_array);
|
||||
char other_tag = tag_of (other_array);
|
||||
assert (first_tag != second_tag);
|
||||
assert (second_tag != other_tag);
|
||||
assert (first_tag != other_tag);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int __attribute__ ((noinline))
|
||||
vararray_different_tag (int num)
|
||||
{
|
||||
struct two_values tmp_object = {
|
||||
.left = 100,
|
||||
.right = num,
|
||||
};
|
||||
int big_array[num];
|
||||
int other_array[100];
|
||||
|
||||
char first_tag = tag_of (&tmp_object);
|
||||
char second_tag = tag_of (big_array);
|
||||
char other_tag = tag_of (other_array);
|
||||
assert (first_tag != second_tag);
|
||||
assert (second_tag != other_tag);
|
||||
assert (first_tag != other_tag);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int __attribute__ ((noinline))
|
||||
main ()
|
||||
{
|
||||
alloca_different_tag (10);
|
||||
vararray_different_tag (8);
|
||||
return 0;
|
||||
}
|
||||
|
25
gcc/testsuite/c-c++-common/hwasan/alloca-outside-caught.c
Normal file
25
gcc/testsuite/c-c++-common/hwasan/alloca-outside-caught.c
Normal file
@ -0,0 +1,25 @@
|
||||
/* { dg-do run } */
|
||||
/* { dg-require-effective-target hwaddress_exec } */
|
||||
/* { dg-shouldfail "hwasan" } */
|
||||
|
||||
#define alloca __builtin_alloca
|
||||
|
||||
int __attribute__ ((noinline))
|
||||
check_alloca (int num)
|
||||
{
|
||||
volatile int *allocd_array = (int*)alloca (num * sizeof(int));
|
||||
int other_array[10];
|
||||
return allocd_array[12];
|
||||
}
|
||||
|
||||
int __attribute__ ((noinline))
|
||||
main ()
|
||||
{
|
||||
check_alloca (3);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* { dg-output "HWAddressSanitizer: tag-mismatch on address 0x\[0-9a-f\]*.*" } */
|
||||
/* { dg-output "READ of size 4 at 0x\[0-9a-f\]* tags: \[\[:xdigit:\]\]\[\[:xdigit:\]\]/00 \\(ptr/mem\\) in thread T0.*" } */
|
||||
/* { dg-output "Address 0x\[0-9a-f\]* is located in stack of thread T0.*" } */
|
||||
/* { dg-output "SUMMARY: HWAddressSanitizer: tag-mismatch \[^\n\]*.*" } */
|
3
gcc/testsuite/c-c++-common/hwasan/arguments-1.c
Normal file
3
gcc/testsuite/c-c++-common/hwasan/arguments-1.c
Normal file
@ -0,0 +1,3 @@
|
||||
/* { dg-do compile } */
|
||||
/* { dg-additional-options "-fsanitize=kernel-hwaddress" } */
|
||||
/* { dg-error ".*'-fsanitize=hwaddress' is incompatible with '-fsanitize=kernel-hwaddress'.*" "" { target *-*-* } 0 } */
|
3
gcc/testsuite/c-c++-common/hwasan/arguments-2.c
Normal file
3
gcc/testsuite/c-c++-common/hwasan/arguments-2.c
Normal file
@ -0,0 +1,3 @@
|
||||
/* { dg-do compile } */
|
||||
/* { dg-additional-options "-fsanitize=kernel-address" } */
|
||||
/* { dg-error ".*'-fsanitize=hwaddress' is incompatible with '-fsanitize=kernel-address'.*" "" { target *-*-* } 0 } */
|
3
gcc/testsuite/c-c++-common/hwasan/arguments-3.c
Normal file
3
gcc/testsuite/c-c++-common/hwasan/arguments-3.c
Normal file
@ -0,0 +1,3 @@
|
||||
/* { dg-do compile } */
|
||||
/* { dg-additional-options "-fsanitize=thread" } */
|
||||
/* { dg-error ".*'-fsanitize=thread' is incompatible with '-fsanitize=hwaddress'.*" "" { target *-*-* } 0 } */
|
3
gcc/testsuite/c-c++-common/hwasan/arguments.c
Normal file
3
gcc/testsuite/c-c++-common/hwasan/arguments.c
Normal file
@ -0,0 +1,3 @@
|
||||
/* { dg-do compile } */
|
||||
/* { dg-additional-options "-fsanitize=address" } */
|
||||
/* { dg-error ".*'-fsanitize=hwaddress' is incompatible with '-fsanitize=address'.*" "" { target *-*-* } 0 } */
|
24
gcc/testsuite/c-c++-common/hwasan/asan-pr63316.c
Normal file
24
gcc/testsuite/c-c++-common/hwasan/asan-pr63316.c
Normal file
@ -0,0 +1,24 @@
|
||||
/* PR sanitizer/63316 */
|
||||
/* { dg-do run } */
|
||||
/* { dg-require-effective-target hwaddress_exec } */
|
||||
/* { dg-skip-if "" { *-*-* } { "*" } { "-O2" } } */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
extern void *malloc (__SIZE_TYPE__);
|
||||
extern void free (void *);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
int *p = (int *) malloc (sizeof (int));
|
||||
*p = 3;
|
||||
asm volatile ("" : : "r" (p) : "memory");
|
||||
free (p);
|
||||
return 0;
|
||||
}
|
||||
|
36
gcc/testsuite/c-c++-common/hwasan/asan-pr70541.c
Normal file
36
gcc/testsuite/c-c++-common/hwasan/asan-pr70541.c
Normal file
@ -0,0 +1,36 @@
|
||||
/* { dg-do run } */
|
||||
/* { dg-require-effective-target hwaddress_exec } */
|
||||
/* { dg-options "-fno-builtin-malloc -fno-builtin-free" } */
|
||||
/* { dg-skip-if "" { *-*-* } { "*" } { "-O0" } } */
|
||||
/* { dg-shouldfail "hwasan" } */
|
||||
|
||||
#include <stdio.h>
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
extern void *malloc (__SIZE_TYPE__);
|
||||
extern void free (void *);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
struct Simple {
|
||||
int value;
|
||||
};
|
||||
|
||||
int f(struct Simple simple) {
|
||||
return simple.value;
|
||||
}
|
||||
|
||||
int main() {
|
||||
struct Simple *psimple = (struct Simple *) malloc(sizeof(struct Simple));
|
||||
psimple->value = 42;
|
||||
free(psimple);
|
||||
printf("%d\n", f(*psimple));
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* { dg-output "HWAddressSanitizer: tag-mismatch on address 0x\[0-9a-f\]*.*" } */
|
||||
/* { dg-output "READ of size 4 at 0x\[0-9a-f\]* tags: \[\[:xdigit:\]\]\[\[:xdigit:\]\]/\[\[:xdigit:\]\]\[\[:xdigit:\]\] \\(ptr/mem\\) in thread T0.*" } */
|
||||
/* { dg-output "freed by thread T0 here:.*" } */
|
||||
/* { dg-output "previously allocated here:" } */
|
31
gcc/testsuite/c-c++-common/hwasan/asan-pr78106.c
Normal file
31
gcc/testsuite/c-c++-common/hwasan/asan-pr78106.c
Normal file
@ -0,0 +1,31 @@
|
||||
/* PR sanitizer/78106 */
|
||||
/* { dg-do compile } */
|
||||
/* { dg-options "-fsanitize=hwaddress -fdump-tree-sanopt-details -ffat-lto-objects" } */
|
||||
|
||||
int *variable;
|
||||
|
||||
void __attribute__((used)) release()
|
||||
{
|
||||
__builtin_free (variable);
|
||||
}
|
||||
|
||||
int main2(int argc)
|
||||
{
|
||||
*variable = 2;
|
||||
|
||||
if (argc <= 5)
|
||||
asm volatile ("call release");
|
||||
|
||||
*variable = 2;
|
||||
__builtin_abort ();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
variable = (int *)__builtin_malloc (sizeof(int));
|
||||
return main2(argc);
|
||||
}
|
||||
|
||||
/* { dg-final { scan-tree-dump-not "Optimizing out(\n|\r\n|\r) HWASAN_CHECK \\(7, variable.*" "sanopt" } } */
|
19
gcc/testsuite/c-c++-common/hwasan/asan-pr79944.c
Normal file
19
gcc/testsuite/c-c++-common/hwasan/asan-pr79944.c
Normal file
@ -0,0 +1,19 @@
|
||||
/* PR sanitizer/79944 */
|
||||
/* { dg-do run } */
|
||||
/* { dg-require-effective-target hwaddress_exec } */
|
||||
|
||||
struct S { int i; char p[1024]; };
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
struct S *p = (struct S *) __builtin_malloc (__builtin_offsetof (struct S, p) + 64);
|
||||
p->i = 5;
|
||||
asm volatile ("" : "+r" (p) : : "memory");
|
||||
__atomic_fetch_add ((int *) p, 5, __ATOMIC_RELAXED);
|
||||
asm volatile ("" : "+r" (p) : : "memory");
|
||||
if (p->i != 10)
|
||||
__builtin_abort ();
|
||||
__builtin_free (p);
|
||||
return 0;
|
||||
}
|
24
gcc/testsuite/c-c++-common/hwasan/asan-rlimit-mmap-test-1.c
Normal file
24
gcc/testsuite/c-c++-common/hwasan/asan-rlimit-mmap-test-1.c
Normal file
@ -0,0 +1,24 @@
|
||||
/* Check that we properly report mmap failure. */
|
||||
|
||||
/* { dg-do run { target setrlimit } } */
|
||||
/* { dg-require-effective-target hwaddress_exec } */
|
||||
/* { dg-skip-if "" { *-*-* } { "*" } { "-O0" } } */
|
||||
/* { dg-require-effective-target hw } */
|
||||
/* { dg-shouldfail "hwasan" } */
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/resource.h>
|
||||
|
||||
static volatile void *x;
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
struct rlimit mmap_resource_limit = { 0, 0 };
|
||||
if (setrlimit(RLIMIT_AS, &mmap_resource_limit)) return 1;
|
||||
x = malloc(10000000);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* { dg-output "ERROR: Failed to mmap" } */
|
||||
|
31
gcc/testsuite/c-c++-common/hwasan/bitfield-1.c
Normal file
31
gcc/testsuite/c-c++-common/hwasan/bitfield-1.c
Normal file
@ -0,0 +1,31 @@
|
||||
/* { dg-do run } */
|
||||
/* { dg-require-effective-target hwaddress_exec } */
|
||||
|
||||
struct bitmapped_struct {
|
||||
unsigned one : 1;
|
||||
unsigned two : 1;
|
||||
unsigned three : 1;
|
||||
unsigned four : 1;
|
||||
unsigned five : 1;
|
||||
unsigned six : 1;
|
||||
unsigned seven : 1;
|
||||
unsigned eight : 1;
|
||||
};
|
||||
|
||||
/* Check that hwasan allows valid bitfield accesses. */
|
||||
int __attribute__ ((noinline))
|
||||
handle_unaligned_access (struct bitmapped_struct *foo)
|
||||
{
|
||||
if (foo->three)
|
||||
return foo->four;
|
||||
|
||||
foo->five = 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
struct bitmapped_struct myvar = {0};
|
||||
handle_unaligned_access (&myvar);
|
||||
return 0;
|
||||
}
|
30
gcc/testsuite/c-c++-common/hwasan/bitfield-2.c
Normal file
30
gcc/testsuite/c-c++-common/hwasan/bitfield-2.c
Normal file
@ -0,0 +1,30 @@
|
||||
/* { dg-do run } */
|
||||
/* { dg-require-effective-target hwaddress_exec } */
|
||||
/* { dg-shouldfail "hwasan" } */
|
||||
|
||||
/* Ensure that hwasan instruments bitfield accesses. */
|
||||
struct A
|
||||
{
|
||||
/* Ensure the offset from the start of this struct to the bitfield we access
|
||||
is large enough to be in a different tag. */
|
||||
char base[16];
|
||||
int : 4;
|
||||
long x : 7;
|
||||
};
|
||||
|
||||
int __attribute__ ((noinline, noclone))
|
||||
f (void *p) {
|
||||
return ((struct A *)p)->x;
|
||||
}
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
char a = 0;
|
||||
return f (&a);
|
||||
}
|
||||
|
||||
/* { dg-output "HWAddressSanitizer: tag-mismatch on address 0x\[0-9a-f\]*.*" } */
|
||||
/* { dg-output "READ of size 2 at 0x\[0-9a-f\]* tags: \[\[:xdigit:\]\]\[\[:xdigit:\]\]/00 \\(ptr/mem\\) in thread T0.*" } */
|
||||
/* { dg-output "Address 0x\[0-9a-f\]* is located in stack of thread T0.*" } */
|
||||
/* { dg-output "SUMMARY: HWAddressSanitizer: tag-mismatch \[^\n\]*.*" } */
|
31
gcc/testsuite/c-c++-common/hwasan/builtin-special-handling.c
Normal file
31
gcc/testsuite/c-c++-common/hwasan/builtin-special-handling.c
Normal file
@ -0,0 +1,31 @@
|
||||
/* { dg-do compile } */
|
||||
/* { dg-additional-options "-fdump-tree-asan" } */
|
||||
/* { dg-skip-if "" { *-*-* } { "-O0" } { "" } } */
|
||||
/* Only skip the -flto tests without the -flto-partition=none.
|
||||
With -flto-partition=none we still get a asan1 dump file, without that
|
||||
parameter we only get the lto dump files (which means scan-tree-dump-times
|
||||
doesn't work. */
|
||||
/* { dg-skip-if "" { *-*-* } { "-flto" } { "-flto-partition=none" } } */
|
||||
|
||||
typedef __SIZE_TYPE__ size_t;
|
||||
/* Functions to observe that HWASAN instruments memory builtins in the expected
|
||||
manner. */
|
||||
void * __attribute__((noinline))
|
||||
memset_builtin (void *dest, int value, size_t len)
|
||||
{
|
||||
return __builtin_memset (dest, value, len);
|
||||
}
|
||||
|
||||
/* HWASAN avoids strlen because it doesn't know the size of the memory access
|
||||
until *after* the function call. */
|
||||
size_t __attribute__ ((noinline))
|
||||
strlen_builtin (char *element)
|
||||
{
|
||||
return __builtin_strlen (element);
|
||||
}
|
||||
|
||||
/* First test ensures that the HWASAN_CHECK was emitted before the
|
||||
memset. Second test ensures there was only HWASAN_CHECK (which demonstrates
|
||||
that strlen was not instrumented). */
|
||||
/* { dg-final { scan-tree-dump-times "HWASAN_CHECK.*memset" 1 "asan1" } } */
|
||||
/* { dg-final { scan-tree-dump-times "HWASAN_CHECK" 1 "asan1" } } */
|
26
gcc/testsuite/c-c++-common/hwasan/check-interface.c
Normal file
26
gcc/testsuite/c-c++-common/hwasan/check-interface.c
Normal file
@ -0,0 +1,26 @@
|
||||
/* { dg-do run } */
|
||||
/* { dg-require-effective-target hwaddress_exec } */
|
||||
/*
|
||||
Test taken from LLVM
|
||||
compiler-rt/test/hwasan/TestCases/check-interface.cpp
|
||||
*/
|
||||
// Utilizes all flavors of __hwasan_load/store interface functions to verify
|
||||
// that the instrumentation and the interface provided by HWASan do match.
|
||||
// In case of a discrepancy, this test fails to link.
|
||||
|
||||
typedef __UINT8_TYPE__ uint8_t;
|
||||
typedef __UINT16_TYPE__ uint16_t;
|
||||
typedef __UINT32_TYPE__ uint32_t;
|
||||
typedef __UINT64_TYPE__ uint64_t;
|
||||
|
||||
#define F(T) void f_##T(T *a, T *b) { *a = *b; }
|
||||
|
||||
F(uint8_t)
|
||||
F(uint16_t)
|
||||
F(uint32_t)
|
||||
F(uint64_t)
|
||||
|
||||
typedef unsigned V32 __attribute__((__vector_size__(32)));
|
||||
F(V32)
|
||||
|
||||
int main() {}
|
24
gcc/testsuite/c-c++-common/hwasan/halt_on_error-1.c
Normal file
24
gcc/testsuite/c-c++-common/hwasan/halt_on_error-1.c
Normal file
@ -0,0 +1,24 @@
|
||||
/* Test recovery mode. */
|
||||
/* { dg-do run } */
|
||||
/* { dg-require-effective-target hwaddress_exec } */
|
||||
/* { dg-options "-fsanitize-recover=hwaddress" } */
|
||||
/* { dg-set-target-env-var HWASAN_OPTIONS "halt_on_error=false" } */
|
||||
/* { dg-shouldfail "hwasan" } */
|
||||
|
||||
volatile int sixteen = 16;
|
||||
|
||||
int main() {
|
||||
char x[16];
|
||||
__builtin_memset(x, 0, sixteen + 1);
|
||||
asm volatile ("" : : : "memory");
|
||||
volatile int res = x[sixteen];
|
||||
x[sixteen] = res + 3;
|
||||
res = x[sixteen];
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* { dg-output "WRITE of size 17 at 0x\[0-9a-f\]+.*" } */
|
||||
/* { dg-output "READ of size 1 at 0x\[0-9a-f\]+.*" } */
|
||||
/* { dg-output "WRITE of size 1 at 0x\[0-9a-f\]+.*" } */
|
||||
/* { dg-output "READ of size 1 at 0x\[0-9a-f\]+.*" } */
|
||||
|
@ -0,0 +1,37 @@
|
||||
/* { dg-do compile { target aarch64-*-* } } */
|
||||
/* { dg-additional-options "-march=armv8.6-a+sve -fsanitize-address-use-after-scope" } */
|
||||
|
||||
#include <arm_sve.h>
|
||||
|
||||
__attribute__((noinline, noclone)) int
|
||||
foo (char *a)
|
||||
{
|
||||
int i, j = 0;
|
||||
asm volatile ("" : "+r" (a) : : "memory");
|
||||
for (i = 0; i < 12; i++)
|
||||
j += a[i];
|
||||
return j;
|
||||
}
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
int i, j = 0;
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
char a[12];
|
||||
__SVInt8_t freq;
|
||||
/* Just do something with that `freq` variable so that the compiler
|
||||
doesn't optimise its use away. */
|
||||
if (__builtin_bcmp (&freq, a, 10))
|
||||
j += 1;
|
||||
__builtin_memset (a, 0, sizeof (a));
|
||||
j += foo (a);
|
||||
}
|
||||
return j;
|
||||
}
|
||||
|
||||
/* Just ensure this compiles without giving an ICE.
|
||||
This is the equivalent of PR 97696 but for HWASAN. HWASAN can handle
|
||||
poly_int sized variables, and this testcase ensures that we don't ICE when
|
||||
given them. */
|
29
gcc/testsuite/c-c++-common/hwasan/heap-overflow.c
Normal file
29
gcc/testsuite/c-c++-common/hwasan/heap-overflow.c
Normal file
@ -0,0 +1,29 @@
|
||||
/* { dg-do run } */
|
||||
/* { dg-require-effective-target hwaddress_exec } */
|
||||
/* { dg-options "-fno-builtin-malloc -fno-builtin-free -fno-builtin-memset" } */
|
||||
/* { dg-shouldfail "hwasan" } */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
void *memset (void *, int, __SIZE_TYPE__);
|
||||
void *malloc (__SIZE_TYPE__);
|
||||
void free (void *);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
volatile int ten = 10;
|
||||
int main(int argc, char **argv) {
|
||||
char *x = (char*)malloc(10);
|
||||
memset(x, 0, 10);
|
||||
int res = x[ten]; /* BOOOM */
|
||||
free(x);
|
||||
return res;
|
||||
}
|
||||
|
||||
/* { dg-output "HWAddressSanitizer: tag-mismatch on address 0x\[0-9a-f\]*.*" } */
|
||||
/* { dg-output "READ of size 1 at 0x\[0-9a-f\]* tags: \[\[:xdigit:\]\]\[\[:xdigit:\]\]/\[\[:xdigit:\]\]\[\[:xdigit:\]\] \\(ptr/mem\\) in thread T0.*" } */
|
||||
/* { dg-output "located 0 bytes to the right of 10-byte region.*" } */
|
||||
/* { dg-output "allocated here:.*" } */
|
||||
/* { dg-output "#1 0x\[0-9a-f\]+ +in _*main \[^\n\r]*heap-overflow.c:18" } */
|
@ -0,0 +1,29 @@
|
||||
/* { dg-do run } */
|
||||
/* { dg-require-effective-target hwaddress_exec } */
|
||||
/* { dg-shouldfail "hwasan" } */
|
||||
/* { dg-skip-if "" { *-*-* } { "-O0" } { "" } } */
|
||||
/* { dg-additional-options "-fdump-tree-asan1 -save-temps" } */
|
||||
|
||||
/* Here to check that the ASAN_POISON stuff works just fine.
|
||||
This mechanism isn't very often used, but I should at least go through the
|
||||
code-path once in my testfile. */
|
||||
int
|
||||
main ()
|
||||
{
|
||||
int *ptr = 0;
|
||||
|
||||
{
|
||||
int a;
|
||||
ptr = &a;
|
||||
*ptr = 12345;
|
||||
}
|
||||
|
||||
return *ptr;
|
||||
}
|
||||
|
||||
/* { dg-final { scan-tree-dump-times "ASAN_POISON" 1 "asan1" } } */
|
||||
/* { dg-final { scan-assembler-times "bl\\s*__hwasan_tag_mismatch4" 1 } } */
|
||||
/* { dg-output "HWAddressSanitizer: tag-mismatch on address 0x\[0-9a-f\]*.*" } */
|
||||
/* { dg-output "READ of size 4 at 0x\[0-9a-f\]* tags: \[\[:xdigit:\]\]\[\[:xdigit:\]\]/00 \\(ptr/mem\\) in thread T0.*" } */
|
||||
/* { dg-output "Address 0x\[0-9a-f\]* is located in stack of thread T0.*" } */
|
||||
/* { dg-output "SUMMARY: HWAddressSanitizer: tag-mismatch \[^\n\]*.*" } */
|
@ -0,0 +1,51 @@
|
||||
/* { dg-do run } */
|
||||
/* { dg-require-effective-target hwaddress_exec } */
|
||||
/* { dg-shouldfail "hwasan" } */
|
||||
/* { dg-additional-options "-lpthread" } */
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
extern int printf (char const *, ...);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
typedef __UINTPTR_TYPE__ uintptr_t;
|
||||
typedef __UINT64_TYPE__ uint64_t;
|
||||
|
||||
/* Test that tags are checked across different threads.
|
||||
i.e. if this thread tries to access a different threads memory with the
|
||||
incorrect tag, then this thread fails. */
|
||||
void *
|
||||
failing_thread_function (void *argument)
|
||||
{
|
||||
void * other = (void *)((uint64_t)argument & 0xffffffffffffffULL);
|
||||
int *num = (int*)argument;
|
||||
printf ("(should succeed): first number = %d\n", num[0]);
|
||||
printf ("(now should fail):\n");
|
||||
|
||||
int *othernum = (int*)other;
|
||||
printf (" second number = %d\n", othernum[0]);
|
||||
return (void *)1;
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
int argument[100] = {0};
|
||||
argument[1] = 10;
|
||||
pthread_t thread_index;
|
||||
pthread_create (&thread_index, NULL, failing_thread_function, (void*)argument);
|
||||
|
||||
void *retval;
|
||||
pthread_join (thread_index, &retval);
|
||||
|
||||
return (uintptr_t)retval;
|
||||
}
|
||||
|
||||
/* { dg-output "HWAddressSanitizer: tag-mismatch on address 0x\[0-9a-f\]*.*" } */
|
||||
/* { dg-output "READ of size 4 at 0x\[0-9a-f\]* tags: 00/\[\[:xdigit:\]\]\[\[:xdigit:\]\] \\(ptr/mem\\) in thread T1.*" } */
|
||||
/* { dg-output "Address 0x\[0-9a-f\]* is located in stack of thread T0.*" } */
|
||||
/* { dg-output "SUMMARY: HWAddressSanitizer: tag-mismatch \[^\n\]*.*" } */
|
@ -0,0 +1,48 @@
|
||||
/* { dg-do run } */
|
||||
/* { dg-require-effective-target hwaddress_exec } */
|
||||
/* { dg-shouldfail "hwasan" } */
|
||||
/* { dg-additional-options "-lpthread" } */
|
||||
|
||||
/* Ensure the failure mode for hwasan under pthreads looks sane.
|
||||
(Looks sane means that the same error message is printed out rather than an
|
||||
opaque message due to mishandling). */
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
extern int printf (char const *, ...);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
typedef __UINTPTR_TYPE__ uintptr_t;
|
||||
typedef __UINT64_TYPE__ uint64_t;
|
||||
|
||||
void *
|
||||
failing_from_stack (void * argument)
|
||||
{
|
||||
int internal_array[16] = {0};
|
||||
printf ("(now should fail):");
|
||||
printf (" problem number is %d\n", internal_array[17]);
|
||||
return (void *)1;
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
int argument[100] = {0};
|
||||
argument[1] = 10;
|
||||
pthread_t thread_index;
|
||||
pthread_create (&thread_index, NULL, failing_from_stack, (void*)argument);
|
||||
|
||||
void *retval;
|
||||
pthread_join (thread_index, &retval);
|
||||
|
||||
return (uintptr_t)retval;
|
||||
}
|
||||
|
||||
/* { dg-output "HWAddressSanitizer: tag-mismatch on address 0x\[0-9a-f\]*.*" } */
|
||||
/* { dg-output "READ of size 4 at 0x\[0-9a-f\]* tags: \[\[:xdigit:\]\]\[\[:xdigit:\]\]/00 \\(ptr/mem\\) in thread T1.*" } */
|
||||
/* { dg-output "Address 0x\[0-9a-f\]* is located in stack of thread T1.*" } */
|
||||
/* { dg-output "SUMMARY: HWAddressSanitizer: tag-mismatch \[^\n\]*.*" } */
|
@ -0,0 +1,56 @@
|
||||
/* { dg-do run } */
|
||||
/* { dg-require-effective-target hwaddress_exec } */
|
||||
/* { dg-shouldfail "hwasan" } */
|
||||
/* { dg-additional-options "-lpthread" } */
|
||||
|
||||
/* This checks the interceptor ABI pthread hooks.
|
||||
The stack of the thread that is finishing must be cleared of shadow tags
|
||||
when that thread exits. */
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
extern int printf (char const *, ...);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
typedef __UINTPTR_TYPE__ uintptr_t;
|
||||
typedef __UINT64_TYPE__ uint64_t;
|
||||
|
||||
__attribute__ ((noinline))
|
||||
void * Ident (void * argument)
|
||||
{
|
||||
return argument;
|
||||
}
|
||||
|
||||
void *
|
||||
pthread_stack_is_cleared (void *argument)
|
||||
{
|
||||
(void)argument;
|
||||
int internal_array[16] = {0};
|
||||
return Ident((void*)internal_array);
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
int argument[100] = {0};
|
||||
argument[1] = 10;
|
||||
pthread_t thread_index;
|
||||
pthread_create (&thread_index, NULL, pthread_stack_is_cleared, (void*)argument);
|
||||
|
||||
void *retval;
|
||||
pthread_join (thread_index, &retval);
|
||||
|
||||
printf ("(should fail): ");
|
||||
printf ("value left in stack is: %d\n", ((int *)retval)[0]);
|
||||
|
||||
return (uintptr_t)retval;
|
||||
}
|
||||
|
||||
/* { dg-output "HWAddressSanitizer: tag-mismatch on address 0x\[0-9a-f\]*.*" } */
|
||||
/* { dg-output "READ of size 4 at 0x\[0-9a-f\]* tags: \[\[:xdigit:\]\]\[\[:xdigit:\]\]/00 \\(ptr/mem\\) in thread T0.*" } */
|
||||
/* { dg-output "HWAddressSanitizer can not describe address in more detail\..*" } */
|
||||
/* { dg-output "SUMMARY: HWAddressSanitizer: tag-mismatch \[^\n\]*.*" } */
|
35
gcc/testsuite/c-c++-common/hwasan/hwasan-thread-success.c
Normal file
35
gcc/testsuite/c-c++-common/hwasan/hwasan-thread-success.c
Normal file
@ -0,0 +1,35 @@
|
||||
/* { dg-do run } */
|
||||
/* { dg-require-effective-target hwaddress_exec } */
|
||||
/* { dg-additional-options "-lpthread" } */
|
||||
|
||||
/* Just ensure that a basic threaded program works while running with hwasan.
|
||||
*/
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
extern int printf (const char *, ...);
|
||||
typedef __UINTPTR_TYPE__ uintptr_t;
|
||||
typedef __UINT64_TYPE__ uint64_t;
|
||||
|
||||
void *
|
||||
successful_thread_function (void * argument)
|
||||
{
|
||||
int *deref = (int *)argument;
|
||||
if (deref[0] == 100)
|
||||
deref[1] = 10;
|
||||
return (void *)0;
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
int argument[100] = {0};
|
||||
argument[1] = 10;
|
||||
pthread_t thread_index;
|
||||
pthread_create (&thread_index, NULL, successful_thread_function, (void*)argument);
|
||||
|
||||
void *retval;
|
||||
pthread_join (thread_index, &retval);
|
||||
|
||||
return (uintptr_t)retval;
|
||||
}
|
37
gcc/testsuite/c-c++-common/hwasan/kernel-defaults.c
Normal file
37
gcc/testsuite/c-c++-common/hwasan/kernel-defaults.c
Normal file
@ -0,0 +1,37 @@
|
||||
/* { dg-do compile } */
|
||||
/* { dg-additional-options "-fno-sanitize=hwaddress -fsanitize=kernel-hwaddress" } */
|
||||
|
||||
|
||||
/* Defaults to check for kernel-hwaddress.
|
||||
1) No stack tagging => no calls to __hwasan_tag_memory.
|
||||
2) No block scope tagging (same again).
|
||||
3) Use sanitize-recover by default (everything ends in noabort). */
|
||||
int __attribute__ ((noinline))
|
||||
accessing_pointers (int *left, int *right)
|
||||
{
|
||||
int x = right[2];
|
||||
left[3] = right[1];
|
||||
return right[1] + left[2];
|
||||
}
|
||||
|
||||
int __attribute__ ((noinline))
|
||||
using_stack (int num)
|
||||
{
|
||||
int big_array[10];
|
||||
int other_array[20];
|
||||
accessing_pointers(other_array, big_array);
|
||||
return big_array[num];
|
||||
}
|
||||
|
||||
#ifndef ARG
|
||||
#define ARG 0
|
||||
#endif
|
||||
int __attribute__ ((noinline))
|
||||
main ()
|
||||
{
|
||||
using_stack (ARG);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* { dg-final { scan-assembler-not "__hwasan_tag_memory" } } */
|
||||
/* { dg-final { scan-assembler-not "__hwasan_(load|store)\\d(?!_noabort)" } } */
|
33
gcc/testsuite/c-c++-common/hwasan/large-aligned-0.c
Normal file
33
gcc/testsuite/c-c++-common/hwasan/large-aligned-0.c
Normal file
@ -0,0 +1,33 @@
|
||||
/* { dg-do run } */
|
||||
/* { dg-require-effective-target hwaddress_exec } */
|
||||
|
||||
/* Handling large aligned variables.
|
||||
Large aligned variables take a different code-path through expand_stack_vars
|
||||
in cfgexpand.c. This testcase is just to exercise that code-path.
|
||||
|
||||
The alternate code-path produces a second base-pointer through some
|
||||
instructions emitted in the prologue.
|
||||
|
||||
Test cases are:
|
||||
0) Valid access works without complaint.
|
||||
1) Invalid access is caught. */
|
||||
int __attribute__ ((noinline))
|
||||
handle_large_alignment (int num)
|
||||
{
|
||||
int other_array[10];
|
||||
int big_array[100] __attribute__ ((aligned (32)));
|
||||
return big_array[num] + other_array[num];
|
||||
}
|
||||
|
||||
#ifndef ARG
|
||||
#define ARG 1
|
||||
#endif
|
||||
|
||||
int global;
|
||||
|
||||
int __attribute__ ((noinline))
|
||||
main ()
|
||||
{
|
||||
global += handle_large_alignment (ARG);
|
||||
return 0;
|
||||
}
|
14
gcc/testsuite/c-c++-common/hwasan/large-aligned-1.c
Normal file
14
gcc/testsuite/c-c++-common/hwasan/large-aligned-1.c
Normal file
@ -0,0 +1,14 @@
|
||||
/* { dg-do run } */
|
||||
/* { dg-require-effective-target hwaddress_exec } */
|
||||
/* { dg-shouldfail "hwasan" } */
|
||||
|
||||
#define ARG 12
|
||||
#include "large-aligned-0.c"
|
||||
#undef ARG
|
||||
|
||||
/* { dg-output "HWAddressSanitizer: tag-mismatch on address 0x\[0-9a-f\]*.*" } */
|
||||
/* NOTE: This assumes the current tagging mechanism (one at a time from the
|
||||
base and large aligned variables being handled first). */
|
||||
/* { dg-output "READ of size 4 at 0x\[0-9a-f\]* tags: \[\[:xdigit:\]\]\[\[:xdigit:\]\]/\[\[:xdigit:\]\]\[\[:xdigit:\]\] \\(ptr/mem\\) in thread T0.*" } */
|
||||
/* { dg-output "Address 0x\[0-9a-f\]* is located in stack of thread T0.*" } */
|
||||
/* { dg-output "SUMMARY: HWAddressSanitizer: tag-mismatch \[^\n\]*.*" } */
|
@ -0,0 +1,75 @@
|
||||
/* { dg-do run } */
|
||||
/* { dg-require-effective-target hwaddress_exec } */
|
||||
/* { dg-shouldfail "hwasan" } */
|
||||
/* Don't really need this option since there are no vararray/alloca objects in
|
||||
the interesting function, however it never hurts to make doubly sure and
|
||||
make it explicit that we're checking the alternate approach to deallocation.
|
||||
*/
|
||||
/* { dg-additional-options "--param hwasan-instrument-allocas=0" } */
|
||||
|
||||
/* Handling large aligned variables.
|
||||
Large aligned variables take a different code-path through expand_stack_vars
|
||||
in cfgexpand.c. This testcase is just to exercise that code-path.
|
||||
|
||||
The alternate code-path produces a second base-pointer through some
|
||||
instructions emitted in the prologue.
|
||||
|
||||
This eventually follows a different code path for untagging when not tagging
|
||||
allocas. The untagging needs to work at the top of the frame, and this
|
||||
should account for this different base when large aligned variables are
|
||||
around. */
|
||||
__attribute__ ((noinline))
|
||||
void * Ident (void * argument)
|
||||
{
|
||||
return argument;
|
||||
}
|
||||
|
||||
#ifndef ALIGNMENT
|
||||
#define ALIGNMENT
|
||||
#endif
|
||||
void __attribute__ ((noinline))
|
||||
large_alignment_untagging (int num, int *retval, int **big, int **other)
|
||||
{
|
||||
int other_array[100] ALIGNMENT;
|
||||
int big_array[100] __attribute__ ((aligned (32)));
|
||||
*retval = big_array[num] + other_array[num];
|
||||
*big = (int*)Ident(big_array);
|
||||
*other = (int*)Ident(other_array);
|
||||
}
|
||||
|
||||
#ifndef ARG
|
||||
#define ARG 0
|
||||
#endif
|
||||
|
||||
int global;
|
||||
|
||||
int __attribute__ ((noinline))
|
||||
main ()
|
||||
{
|
||||
int retval;
|
||||
int *big, *other;
|
||||
large_alignment_untagging (0, &retval, &big, &other);
|
||||
/* Want to test that both ends of both variables are untagged. */
|
||||
switch (ARG) {
|
||||
case 0:
|
||||
global += big[0];
|
||||
break;
|
||||
case 1:
|
||||
global += big[99];
|
||||
break;
|
||||
case 2:
|
||||
global += other[0];
|
||||
break;
|
||||
case 3:
|
||||
global += other[99];
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* { dg-output "HWAddressSanitizer: tag-mismatch on address 0x\[0-9a-f\]*.*" } */
|
||||
/* NOTE: This assumes the current tagging mechanism (one at a time from the
|
||||
base and large aligned variables being handled first). */
|
||||
/* { dg-output "READ of size 4 at 0x\[0-9a-f\]* tags: \[\[:xdigit:\]\]\[\[:xdigit:\]\]/\[\[:xdigit:\]\]\[\[:xdigit:\]\] \\(ptr/mem\\) in thread T0.*" } */
|
||||
/* { dg-output "Address 0x\[0-9a-f\]* is located in stack of thread T0.*" } */
|
||||
/* { dg-output "SUMMARY: HWAddressSanitizer: tag-mismatch \[^\n\]*.*" } */
|
@ -0,0 +1,15 @@
|
||||
/* { dg-do run } */
|
||||
/* { dg-require-effective-target hwaddress_exec } */
|
||||
/* { dg-shouldfail "hwasan" } */
|
||||
/* { dg-additional-options "--param hwasan-instrument-allocas=0" } */
|
||||
|
||||
#define ARG 1
|
||||
#include "large-aligned-untagging-0.c"
|
||||
#undef ARG
|
||||
|
||||
/* { dg-output "HWAddressSanitizer: tag-mismatch on address 0x\[0-9a-f\]*.*" } */
|
||||
/* NOTE: This assumes the current tagging mechanism (one at a time from the
|
||||
base and large aligned variables being handled first). */
|
||||
/* { dg-output "READ of size 4 at 0x\[0-9a-f\]* tags: \[\[:xdigit:\]\]\[\[:xdigit:\]\]/\[\[:xdigit:\]\]\[\[:xdigit:\]\] \\(ptr/mem\\) in thread T0.*" } */
|
||||
/* { dg-output "Address 0x\[0-9a-f\]* is located in stack of thread T0.*" } */
|
||||
/* { dg-output "SUMMARY: HWAddressSanitizer: tag-mismatch \[^\n\]*.*" } */
|
@ -0,0 +1,15 @@
|
||||
/* { dg-do run } */
|
||||
/* { dg-require-effective-target hwaddress_exec } */
|
||||
/* { dg-shouldfail "hwasan" } */
|
||||
/* { dg-additional-options "--param hwasan-instrument-allocas=0" } */
|
||||
|
||||
#define ARG 2
|
||||
#include "large-aligned-untagging-0.c"
|
||||
#undef ARG
|
||||
|
||||
/* { dg-output "HWAddressSanitizer: tag-mismatch on address 0x\[0-9a-f\]*.*" } */
|
||||
/* NOTE: This assumes the current tagging mechanism (one at a time from the
|
||||
base and large aligned variables being handled first). */
|
||||
/* { dg-output "READ of size 4 at 0x\[0-9a-f\]* tags: \[\[:xdigit:\]\]\[\[:xdigit:\]\]/\[\[:xdigit:\]\]\[\[:xdigit:\]\] \\(ptr/mem\\) in thread T0.*" } */
|
||||
/* { dg-output "Address 0x\[0-9a-f\]* is located in stack of thread T0.*" } */
|
||||
/* { dg-output "SUMMARY: HWAddressSanitizer: tag-mismatch \[^\n\]*.*" } */
|
@ -0,0 +1,15 @@
|
||||
/* { dg-do run } */
|
||||
/* { dg-require-effective-target hwaddress_exec } */
|
||||
/* { dg-shouldfail "hwasan" } */
|
||||
/* { dg-additional-options "--param hwasan-instrument-allocas=0" } */
|
||||
|
||||
#define ARG 3
|
||||
#include "large-aligned-untagging-0.c"
|
||||
#undef ARG
|
||||
|
||||
/* { dg-output "HWAddressSanitizer: tag-mismatch on address 0x\[0-9a-f\]*.*" } */
|
||||
/* NOTE: This assumes the current tagging mechanism (one at a time from the
|
||||
base and large aligned variables being handled first). */
|
||||
/* { dg-output "READ of size 4 at 0x\[0-9a-f\]* tags: \[\[:xdigit:\]\]\[\[:xdigit:\]\]/\[\[:xdigit:\]\]\[\[:xdigit:\]\] \\(ptr/mem\\) in thread T0.*" } */
|
||||
/* { dg-output "Address 0x\[0-9a-f\]* is located in stack of thread T0.*" } */
|
||||
/* { dg-output "SUMMARY: HWAddressSanitizer: tag-mismatch \[^\n\]*.*" } */
|
@ -0,0 +1,16 @@
|
||||
/* { dg-do run } */
|
||||
/* { dg-require-effective-target hwaddress_exec } */
|
||||
/* { dg-shouldfail "hwasan" } */
|
||||
/* { dg-additional-options "--param hwasan-instrument-allocas=0" } */
|
||||
|
||||
#define ARG 0
|
||||
#define ALIGNMENT __attribute__ ((aligned (32)))
|
||||
#include "large-aligned-untagging-0.c"
|
||||
#undef ARG
|
||||
|
||||
/* { dg-output "HWAddressSanitizer: tag-mismatch on address 0x\[0-9a-f\]*.*" } */
|
||||
/* NOTE: This assumes the current tagging mechanism (one at a time from the
|
||||
base and large aligned variables being handled first). */
|
||||
/* { dg-output "READ of size 4 at 0x\[0-9a-f\]* tags: \[\[:xdigit:\]\]\[\[:xdigit:\]\]/\[\[:xdigit:\]\]\[\[:xdigit:\]\] \\(ptr/mem\\) in thread T0.*" } */
|
||||
/* { dg-output "Address 0x\[0-9a-f\]* is located in stack of thread T0.*" } */
|
||||
/* { dg-output "SUMMARY: HWAddressSanitizer: tag-mismatch \[^\n\]*.*" } */
|
@ -0,0 +1,16 @@
|
||||
/* { dg-do run } */
|
||||
/* { dg-require-effective-target hwaddress_exec } */
|
||||
/* { dg-shouldfail "hwasan" } */
|
||||
/* { dg-additional-options "--param hwasan-instrument-allocas=0" } */
|
||||
|
||||
#define ARG 1
|
||||
#define ALIGNMENT __attribute__ ((aligned (32)))
|
||||
#include "large-aligned-untagging-0.c"
|
||||
#undef ARG
|
||||
|
||||
/* { dg-output "HWAddressSanitizer: tag-mismatch on address 0x\[0-9a-f\]*.*" } */
|
||||
/* NOTE: This assumes the current tagging mechanism (one at a time from the
|
||||
base and large aligned variables being handled first). */
|
||||
/* { dg-output "READ of size 4 at 0x\[0-9a-f\]* tags: \[\[:xdigit:\]\]\[\[:xdigit:\]\]/\[\[:xdigit:\]\]\[\[:xdigit:\]\] \\(ptr/mem\\) in thread T0.*" } */
|
||||
/* { dg-output "Address 0x\[0-9a-f\]* is located in stack of thread T0.*" } */
|
||||
/* { dg-output "SUMMARY: HWAddressSanitizer: tag-mismatch \[^\n\]*.*" } */
|
@ -0,0 +1,16 @@
|
||||
/* { dg-do run } */
|
||||
/* { dg-require-effective-target hwaddress_exec } */
|
||||
/* { dg-shouldfail "hwasan" } */
|
||||
/* { dg-additional-options "--param hwasan-instrument-allocas=0" } */
|
||||
|
||||
#define ARG 2
|
||||
#define ALIGNMENT __attribute__ ((aligned (32)))
|
||||
#include "large-aligned-untagging-0.c"
|
||||
#undef ARG
|
||||
|
||||
/* { dg-output "HWAddressSanitizer: tag-mismatch on address 0x\[0-9a-f\]*.*" } */
|
||||
/* NOTE: This assumes the current tagging mechanism (one at a time from the
|
||||
base and large aligned variables being handled first). */
|
||||
/* { dg-output "READ of size 4 at 0x\[0-9a-f\]* tags: \[\[:xdigit:\]\]\[\[:xdigit:\]\]/\[\[:xdigit:\]\]\[\[:xdigit:\]\] \\(ptr/mem\\) in thread T0.*" } */
|
||||
/* { dg-output "Address 0x\[0-9a-f\]* is located in stack of thread T0.*" } */
|
||||
/* { dg-output "SUMMARY: HWAddressSanitizer: tag-mismatch \[^\n\]*.*" } */
|
@ -0,0 +1,16 @@
|
||||
/* { dg-do run } */
|
||||
/* { dg-require-effective-target hwaddress_exec } */
|
||||
/* { dg-shouldfail "hwasan" } */
|
||||
/* { dg-additional-options "--param hwasan-instrument-allocas=0" } */
|
||||
|
||||
#define ARG 3
|
||||
#define ALIGNMENT __attribute__ ((aligned (32)))
|
||||
#include "large-aligned-untagging-0.c"
|
||||
#undef ARG
|
||||
|
||||
/* { dg-output "HWAddressSanitizer: tag-mismatch on address 0x\[0-9a-f\]*.*" } */
|
||||
/* NOTE: This assumes the current tagging mechanism (one at a time from the
|
||||
base and large aligned variables being handled first). */
|
||||
/* { dg-output "READ of size 4 at 0x\[0-9a-f\]* tags: \[\[:xdigit:\]\]\[\[:xdigit:\]\]/\[\[:xdigit:\]\]\[\[:xdigit:\]\] \\(ptr/mem\\) in thread T0.*" } */
|
||||
/* { dg-output "Address 0x\[0-9a-f\]* is located in stack of thread T0.*" } */
|
||||
/* { dg-output "SUMMARY: HWAddressSanitizer: tag-mismatch \[^\n\]*.*" } */
|
11
gcc/testsuite/c-c++-common/hwasan/macro-definition.c
Normal file
11
gcc/testsuite/c-c++-common/hwasan/macro-definition.c
Normal file
@ -0,0 +1,11 @@
|
||||
/* { dg-do compile } */
|
||||
extern void testfunc(int);
|
||||
int foo()
|
||||
{
|
||||
#ifndef __SANITIZE_HWADDRESS__
|
||||
testfunc(1);
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* { dg-final { scan-assembler-not "testfunc" } } */
|
12
gcc/testsuite/c-c++-common/hwasan/no-sanitize-attribute.c
Normal file
12
gcc/testsuite/c-c++-common/hwasan/no-sanitize-attribute.c
Normal file
@ -0,0 +1,12 @@
|
||||
/* { dg-do compile } */
|
||||
|
||||
__attribute__((no_sanitize("hwaddress"))) int
|
||||
f (int *p, int *q)
|
||||
{
|
||||
*p = 42;
|
||||
return *q;
|
||||
}
|
||||
|
||||
/* Only have one instance of __hwasan, it is __hwasan_init (the module
|
||||
* constructor) there is no instrumentation in the function. */
|
||||
/* { dg-final { scan-assembler-times "__hwasan" 1 } } */
|
@ -0,0 +1,10 @@
|
||||
/* { dg-do compile } */
|
||||
/* { dg-skip-if "" { *-*-* } { "-O0" } { "" } } */
|
||||
/* { dg-additional-options "--param hwasan-instrument-mem-intrinsics=0" } */
|
||||
|
||||
#include "builtin-special-handling.c"
|
||||
|
||||
/* With this flag there should be no checking of builtins.
|
||||
The above file only has builtins, and hence there should be no checking
|
||||
after compilation. */
|
||||
/* { dg-final { scan-assembler-not "__hwasan_(load|store)" } } */
|
@ -0,0 +1,7 @@
|
||||
/* { dg-do compile } */
|
||||
/* { dg-additional-options "--param hwasan-instrument-writes=0" } */
|
||||
|
||||
#include "param-instrument-reads.c"
|
||||
|
||||
/* { dg-final { scan-assembler "__hwasan_load" } } */
|
||||
/* { dg-final { scan-assembler-not "__hwasan_store" } } */
|
21
gcc/testsuite/c-c++-common/hwasan/param-instrument-reads.c
Normal file
21
gcc/testsuite/c-c++-common/hwasan/param-instrument-reads.c
Normal file
@ -0,0 +1,21 @@
|
||||
/* { dg-do compile } */
|
||||
/* { dg-additional-options "--param hwasan-instrument-reads=0" } */
|
||||
|
||||
typedef __SIZE_TYPE__ size_t;
|
||||
/* Particular code doesn't really matter, the requirement is that it has both
|
||||
loads and stores in it. */
|
||||
__attribute__ ((noinline))
|
||||
int reader (int *array, size_t num)
|
||||
{
|
||||
return array[num];
|
||||
}
|
||||
|
||||
int __attribute__ ((noinline))
|
||||
writer (int *array, size_t num, int value)
|
||||
{
|
||||
array[num] = value;
|
||||
return num + value;
|
||||
}
|
||||
|
||||
/* { dg-final { scan-assembler-not "__hwasan_load" } } */
|
||||
/* { dg-final { scan-assembler "__hwasan_store" } } */
|
@ -0,0 +1,7 @@
|
||||
/* { dg-do compile } */
|
||||
/* { dg-additional-options "--param hwasan-instrument-reads=0 --param hwasan-instrument-writes=0" } */
|
||||
|
||||
#include "param-instrument-reads.c"
|
||||
|
||||
/* { dg-final { scan-assembler-not "__hwasan_load" } } */
|
||||
/* { dg-final { scan-assembler-not "__hwasan_store" } } */
|
7
gcc/testsuite/c-c++-common/hwasan/random-frame-tag.c
Normal file
7
gcc/testsuite/c-c++-common/hwasan/random-frame-tag.c
Normal file
@ -0,0 +1,7 @@
|
||||
/* { dg-do compile } */
|
||||
/* { dg-additional-options "--param hwasan-random-frame-tag=1" } */
|
||||
|
||||
#include "stack-tagging-basic-0.c"
|
||||
|
||||
/* Random frame tag => call to __hwasan_generate_tag. */
|
||||
/* { dg-final { scan-assembler "__hwasan_generate_tag" } } */
|
25
gcc/testsuite/c-c++-common/hwasan/sanity-check-pure-c.c
Normal file
25
gcc/testsuite/c-c++-common/hwasan/sanity-check-pure-c.c
Normal file
@ -0,0 +1,25 @@
|
||||
/* { dg-do run } */
|
||||
/* { dg-require-effective-target hwaddress_exec } */
|
||||
/* { dg-options "-fno-builtin-malloc -fno-builtin-free" } */
|
||||
/* { dg-shouldfail "asan" } */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
void *malloc (__SIZE_TYPE__);
|
||||
void free (void *);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
int main() {
|
||||
char *x = (char*)malloc(10);
|
||||
free(x);
|
||||
return x[5];
|
||||
}
|
||||
|
||||
/* { dg-output "HWAddressSanitizer: tag-mismatch on address 0x\[0-9a-f\]*.*" } */
|
||||
/* { dg-output "READ of size 1 at 0x\[0-9a-f\]* tags: \[\[:xdigit:\]\]\[\[:xdigit:\]\]/\[\[:xdigit:\]\]\[\[:xdigit:\]\] \\(ptr/mem\\) in thread T0.*" } */
|
||||
/* { dg-output "located 5 bytes inside of 10-byte region.*" } */
|
||||
/* { dg-output "freed by thread T0 here:.*" } */
|
||||
/* { dg-output "previously allocated here:" } */
|
54
gcc/testsuite/c-c++-common/hwasan/setjmp-longjmp-0.c
Normal file
54
gcc/testsuite/c-c++-common/hwasan/setjmp-longjmp-0.c
Normal file
@ -0,0 +1,54 @@
|
||||
/* { dg-do run } */
|
||||
/* { dg-require-effective-target hwaddress_exec } */
|
||||
|
||||
#include <setjmp.h>
|
||||
#include <stdio.h>
|
||||
|
||||
/*
|
||||
Testing longjmp/setjmp should test.
|
||||
|
||||
0) Nothing special happens with the jmp_buf.
|
||||
1) Accesses to scopes jmp'd over are caught.
|
||||
*/
|
||||
int __attribute__ ((noinline))
|
||||
uses_longjmp (int **other_array, int num, jmp_buf env)
|
||||
{
|
||||
int internal_array[100] = {0};
|
||||
*other_array = &internal_array[0];
|
||||
if (num % 2)
|
||||
longjmp (env, num);
|
||||
else
|
||||
return num % 8;
|
||||
}
|
||||
|
||||
int __attribute__ ((noinline))
|
||||
uses_setjmp (int num)
|
||||
{
|
||||
int big_array[100];
|
||||
int *other_array = NULL;
|
||||
sigjmp_buf cur_env;
|
||||
int temp = 0;
|
||||
if ((temp = sigsetjmp (cur_env, 1)) != 0)
|
||||
{
|
||||
if (other_array != NULL)
|
||||
printf ("Value pointed to in other_array[0]: %d\n",
|
||||
other_array[0]);
|
||||
|
||||
printf ("Longjmp returned %d.\n", temp);
|
||||
return 10;
|
||||
}
|
||||
else
|
||||
{
|
||||
return uses_longjmp (&other_array, num, cur_env);
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef ARG
|
||||
#define ARG 0
|
||||
#endif
|
||||
int __attribute__ ((noinline))
|
||||
main ()
|
||||
{
|
||||
uses_setjmp (ARG);
|
||||
return 0;
|
||||
}
|
19
gcc/testsuite/c-c++-common/hwasan/setjmp-longjmp-1.c
Normal file
19
gcc/testsuite/c-c++-common/hwasan/setjmp-longjmp-1.c
Normal file
@ -0,0 +1,19 @@
|
||||
/* { dg-do run } */
|
||||
/* { dg-require-effective-target hwaddress_exec } */
|
||||
/* { dg-shouldfail "hwasan" } */
|
||||
|
||||
/*
|
||||
Testing longjmp/setjmp should test.
|
||||
|
||||
0) Nothing special happens with the jmp_buf.
|
||||
1) Accesses to scopes jmp'd over are caught.
|
||||
*/
|
||||
|
||||
#define ARG 1
|
||||
#include "setjmp-longjmp-0.c"
|
||||
#undef ARG
|
||||
|
||||
/* { dg-output "HWAddressSanitizer: tag-mismatch on address 0x\[0-9a-f\]*.*" } */
|
||||
/* { dg-output "READ of size 4 at 0x\[0-9a-f\]* tags: \[\[:xdigit:\]\]\[\[:xdigit:\]\]/00 \\(ptr/mem\\) in thread T0.*" } */
|
||||
/* { dg-output "Address 0x\[0-9a-f\]* is located in stack of thread T0.*" } */
|
||||
/* { dg-output "SUMMARY: HWAddressSanitizer: tag-mismatch \[^\n\]*.*" } */
|
37
gcc/testsuite/c-c++-common/hwasan/stack-tagging-basic-0.c
Normal file
37
gcc/testsuite/c-c++-common/hwasan/stack-tagging-basic-0.c
Normal file
@ -0,0 +1,37 @@
|
||||
/* { dg-do run } */
|
||||
/* { dg-require-effective-target hwaddress_exec } */
|
||||
|
||||
/* Basic tests for stack tagging.
|
||||
|
||||
0) Valid accesses work.
|
||||
1) Accesses outside of a variable crash.
|
||||
*/
|
||||
int __attribute__ ((noinline))
|
||||
accessing_pointers (int *left, int *right)
|
||||
{
|
||||
int x = right[2];
|
||||
left[3] = right[1];
|
||||
return right[1] + left[2];
|
||||
}
|
||||
|
||||
int __attribute__ ((noinline))
|
||||
using_stack (int num)
|
||||
{
|
||||
int big_array[10];
|
||||
int other_array[20];
|
||||
accessing_pointers(other_array, big_array);
|
||||
return big_array[num];
|
||||
}
|
||||
|
||||
#ifndef ARG
|
||||
#define ARG 0
|
||||
#endif
|
||||
|
||||
int global;
|
||||
|
||||
int __attribute__ ((noinline))
|
||||
main ()
|
||||
{
|
||||
global += using_stack (ARG);
|
||||
return 0;
|
||||
}
|
18
gcc/testsuite/c-c++-common/hwasan/stack-tagging-basic-1.c
Normal file
18
gcc/testsuite/c-c++-common/hwasan/stack-tagging-basic-1.c
Normal file
@ -0,0 +1,18 @@
|
||||
/* { dg-do run } */
|
||||
/* { dg-require-effective-target hwaddress_exec } */
|
||||
/* { dg-shouldfail "hwasan" } */
|
||||
|
||||
/* Basic tests for stack tagging.
|
||||
|
||||
0) Accesses outside of a variable crash.
|
||||
1) Valid accesses work.
|
||||
*/
|
||||
|
||||
#define ARG 17
|
||||
#include "stack-tagging-basic-0.c"
|
||||
#undef ARG
|
||||
|
||||
/* { dg-output "HWAddressSanitizer: tag-mismatch on address 0x\[0-9a-f\]*.*" } */
|
||||
/* { dg-output "READ of size 4 at 0x\[0-9a-f\]* tags: \[\[:xdigit:\]\]\[\[:xdigit:\]\]/\[\[:xdigit:\]\]\[\[:xdigit:\]\] \\(ptr/mem\\) in thread T0.*" } */
|
||||
/* { dg-output "Address 0x\[0-9a-f\]* is located in stack of thread T0.*" } */
|
||||
/* { dg-output "SUMMARY: HWAddressSanitizer: tag-mismatch \[^\n\]*.*" } */
|
33
gcc/testsuite/c-c++-common/hwasan/stack-tagging-disable.c
Normal file
33
gcc/testsuite/c-c++-common/hwasan/stack-tagging-disable.c
Normal file
@ -0,0 +1,33 @@
|
||||
/* { dg-do compile } */
|
||||
/* { dg-additional-options "--param hwasan-instrument-stack=0" } */
|
||||
|
||||
|
||||
/* No stack tagging => no calls to __hwasan_tag_memory. */
|
||||
int __attribute__ ((noinline))
|
||||
accessing_pointers (int *left, int *right)
|
||||
{
|
||||
int x = right[2];
|
||||
left[3] = right[1];
|
||||
return right[1] + left[2];
|
||||
}
|
||||
|
||||
int __attribute__ ((noinline))
|
||||
using_stack (int num)
|
||||
{
|
||||
int big_array[10];
|
||||
int other_array[20];
|
||||
accessing_pointers(other_array, big_array);
|
||||
return big_array[num];
|
||||
}
|
||||
|
||||
#ifndef ARG
|
||||
#define ARG 0
|
||||
#endif
|
||||
int __attribute__ ((noinline))
|
||||
main ()
|
||||
{
|
||||
using_stack (ARG);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* { dg-final { scan-assembler-not "__hwasan_tag_memory" } } */
|
46
gcc/testsuite/c-c++-common/hwasan/unprotected-allocas-0.c
Normal file
46
gcc/testsuite/c-c++-common/hwasan/unprotected-allocas-0.c
Normal file
@ -0,0 +1,46 @@
|
||||
/* { dg-do run } */
|
||||
/* { dg-require-effective-target hwaddress_exec } */
|
||||
/* { dg-additional-options "--param hwasan-instrument-allocas=0 -save-temps" } */
|
||||
/* Only run this test without optimisation. When running with optimisation we
|
||||
use the unprotected-allocas-1.c file that also checks there are no memory
|
||||
tagging calls (since when optimised the only variable on the stack should be
|
||||
the vararray/alloca). */
|
||||
/* { dg-skip-if "" { *-*-* } { "-O1" "-O2" "-O3" } { "" } } */
|
||||
|
||||
#define alloca __builtin_alloca
|
||||
#define assert(x) if (!(x)) __builtin_abort ()
|
||||
|
||||
char tag_of (void * x) { return ((unsigned long long)x) >> 56; }
|
||||
|
||||
int __attribute__ ((noinline))
|
||||
using_alloca (int num)
|
||||
{
|
||||
int retval = 0;
|
||||
int *big_array = (int*)alloca (num * sizeof (int));
|
||||
char alloca_tag = tag_of (big_array);
|
||||
assert (alloca_tag == 0);
|
||||
for (int i = 0; i < num; ++i) {
|
||||
retval += big_array[i];
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
int __attribute__ ((noinline))
|
||||
using_vararray (int num)
|
||||
{
|
||||
int retval = 0;
|
||||
int big_array[num];
|
||||
char vararray_tag = tag_of (big_array);
|
||||
assert (vararray_tag == 0);
|
||||
for (int i = 0; i < num; ++i) {
|
||||
retval += big_array[i];
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
using_alloca (16);
|
||||
using_vararray (12);
|
||||
return 0;
|
||||
}
|
16
gcc/testsuite/c-c++-common/hwasan/unprotected-allocas-1.c
Normal file
16
gcc/testsuite/c-c++-common/hwasan/unprotected-allocas-1.c
Normal file
@ -0,0 +1,16 @@
|
||||
/* { dg-do run } */
|
||||
/* { dg-require-effective-target hwaddress_exec } */
|
||||
/* { dg-additional-options "--param hwasan-instrument-allocas=0 -save-temps" } */
|
||||
/* Only test there's no tagging done when not at -O0. Without optimisation
|
||||
the compiler creates a bunch of other variables on the stack other than the
|
||||
vararray/alloca object.
|
||||
We also avoid checking when using -flto, since with LTO the compiler can
|
||||
recognise the vararray is only used with one size and that size is known at
|
||||
compile time -- when the compiler recognises that it instead creates a
|
||||
static array, which gets tagged as is expected but not as the test expects.
|
||||
*/
|
||||
/* { dg-skip-if "" { *-*-* } { "-O0" "-flto" } { "" } } */
|
||||
|
||||
#include "unprotected-allocas-0.c"
|
||||
|
||||
/* { dg-final { scan-assembler-not "__hwasan_tag_memory" } } */
|
28
gcc/testsuite/c-c++-common/hwasan/use-after-free.c
Normal file
28
gcc/testsuite/c-c++-common/hwasan/use-after-free.c
Normal file
@ -0,0 +1,28 @@
|
||||
/* { dg-do run } */
|
||||
/* { dg-require-effective-target hwaddress_exec } */
|
||||
/* { dg-options "-fno-builtin-malloc -fno-builtin-free" } */
|
||||
/* { dg-shouldfail "hwasan" } */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
void *malloc (__SIZE_TYPE__);
|
||||
void free (void *);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
int main() {
|
||||
char *x = (char*)malloc(10);
|
||||
free(x);
|
||||
return x[5];
|
||||
}
|
||||
|
||||
|
||||
/* { dg-output "HWAddressSanitizer: tag-mismatch on address 0x\[0-9a-f\]*.*" } */
|
||||
/* { dg-output "READ of size 1 at 0x\[0-9a-f\]* tags: \[\[:xdigit:\]\]\[\[:xdigit:\]\]/\[\[:xdigit:\]\]\[\[:xdigit:\]\] \\(ptr/mem\\) in thread T0.*" } */
|
||||
/* { dg-output "is located 5 bytes inside of 10-byte region.*" } */
|
||||
/* { dg-output "freed by thread T0 here:.*" } */
|
||||
/* { dg-output "#1\[^\n\r]*main\[^\n\r]*use-after-free.c:17.*" } */
|
||||
/* { dg-output "previously allocated here:.*" } */
|
||||
/* { dg-output "#1\[^\n\r]*main\[^\n\r]*use-after-free.c:16" } */
|
22
gcc/testsuite/c-c++-common/hwasan/vararray-outside-caught.c
Normal file
22
gcc/testsuite/c-c++-common/hwasan/vararray-outside-caught.c
Normal file
@ -0,0 +1,22 @@
|
||||
/* { dg-do run } */
|
||||
/* { dg-require-effective-target hwaddress_exec } */
|
||||
/* { dg-shouldfail "hwasan" } */
|
||||
|
||||
int __attribute__ ((noinline))
|
||||
check_vararray (int num)
|
||||
{
|
||||
int var_array[num];
|
||||
int other_array[10];
|
||||
return var_array[12];
|
||||
}
|
||||
|
||||
int __attribute__ ((noinline))
|
||||
main ()
|
||||
{
|
||||
return check_vararray (3);
|
||||
}
|
||||
|
||||
/* { dg-output "HWAddressSanitizer: tag-mismatch on address 0x\[0-9a-f\]*.*" } */
|
||||
/* { dg-output "READ of size 4 at 0x\[0-9a-f\]* tags: \[\[:xdigit:\]\]\[\[:xdigit:\]\]/00 \\(ptr/mem\\) in thread T0.*" } */
|
||||
/* { dg-output "Address 0x\[0-9a-f\]* is located in stack of thread T0.*" } */
|
||||
/* { dg-output "SUMMARY: HWAddressSanitizer: tag-mismatch \[^\n\]*.*" } */
|
@ -0,0 +1,43 @@
|
||||
/* { dg-do run } */
|
||||
/* { dg-require-effective-target hwaddress_exec } */
|
||||
/* { dg-shouldfail "hwasan" } */
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
/* Testing that a function with outgoing arguments correctly decrements the
|
||||
stack pointer when a vararray goes out of scope. */
|
||||
|
||||
const char *
|
||||
other (int argc, int a, int b, int c, int d, int e, int f, int g, int h, int i, int j, int k, int l)
|
||||
{
|
||||
const char ** other;
|
||||
{
|
||||
const char * test_array[argc];
|
||||
test_array[0] = "test string";
|
||||
test_array[argc - 1] = "hello";
|
||||
/* To prevent optimisation. */
|
||||
printf("While the value stored in our test_array is: %s\n",
|
||||
test_array[argc - 1]);
|
||||
other = test_array;
|
||||
}
|
||||
/* With the below function call (the one with many arguments), some of the
|
||||
arguments have to be put on the stack, which means we have to reserve some
|
||||
space on the stack for these arguments and that the VLA is stored at a
|
||||
position that is not the stack pointer. */
|
||||
printf("Hello there!\nOur numbers today are: %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d\n",
|
||||
a, b, c, d, e, f, g, h, i, j, k, l);
|
||||
/* This should fail due to a bad read access. */
|
||||
return other[0];
|
||||
}
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
int a, b, c, d, e, f, g, h, i, j, k, l;
|
||||
const char * retval = other (1, a, b, c, d, e, f, g, h, i, j, k, l);
|
||||
/* Numbers don't matter here, just want to ensure the program is reading them
|
||||
so we know they won't be optimised out. */
|
||||
if (retval)
|
||||
return 1;
|
||||
return 10;
|
||||
}
|
68
gcc/testsuite/c-c++-common/hwasan/very-large-objects.c
Normal file
68
gcc/testsuite/c-c++-common/hwasan/very-large-objects.c
Normal file
@ -0,0 +1,68 @@
|
||||
/* { dg-do compile } */
|
||||
|
||||
/* Ensure the sanitizer can handle very large offsets (i.e. that the hooks
|
||||
handle offsets too large for the relevant instructions).
|
||||
Just want to make sure this compiles without an ICE. */
|
||||
#ifndef ASIZE
|
||||
# define ASIZE 0x10000000000UL
|
||||
#endif
|
||||
|
||||
typedef __UINT64_TYPE__ uint64_t;
|
||||
|
||||
#if __LONG_MAX__ < 8 * ASIZE
|
||||
# undef ASIZE
|
||||
# define ASIZE 4096
|
||||
#endif
|
||||
|
||||
extern void abort (void);
|
||||
|
||||
int __attribute__((noinline))
|
||||
foo (const char *s)
|
||||
{
|
||||
if (!s)
|
||||
return 1;
|
||||
if (s[0] != 'a')
|
||||
abort ();
|
||||
s += ASIZE - 1;
|
||||
if (s[0] != 'b')
|
||||
abort ();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int (*fn) (const char *) = foo;
|
||||
|
||||
int __attribute__((noinline))
|
||||
bar (void)
|
||||
{
|
||||
char s[ASIZE];
|
||||
s[0] = 'a';
|
||||
s[ASIZE - 1] = 'b';
|
||||
foo (s);
|
||||
foo (s);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int __attribute__((noinline))
|
||||
baz (long i)
|
||||
{
|
||||
if (i)
|
||||
return fn (0);
|
||||
else
|
||||
{
|
||||
char s[ASIZE];
|
||||
s[0] = 'a';
|
||||
s[ASIZE - 1] = 'b';
|
||||
foo (s);
|
||||
foo (s);
|
||||
return fn (0);
|
||||
}
|
||||
}
|
||||
|
||||
int __attribute__((noinline))
|
||||
very_large_offset (int *p)
|
||||
{
|
||||
char init_array[(uint64_t)0xfefefef];
|
||||
char other_array[(uint64_t)0xfefefef];
|
||||
return (int)init_array[p[1]] + (int)other_array[p[0]];
|
||||
}
|
||||
|
@ -3,4 +3,4 @@
|
||||
|
||||
int i;
|
||||
|
||||
/* { dg-error ".-fsanitize=thread. is incompatible with .-fsanitize=address|kernel-address." "" { target *-*-* } 0 } */
|
||||
/* { dg-error ".-fsanitize=thread. is incompatible with .-fsanitize=address." "" { target *-*-* } 0 } */
|
||||
|
34
gcc/testsuite/g++.dg/hwasan/hwasan.exp
Normal file
34
gcc/testsuite/g++.dg/hwasan/hwasan.exp
Normal file
@ -0,0 +1,34 @@
|
||||
# Copyright (C) 2012-2019 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/>.
|
||||
|
||||
# Load support procs.
|
||||
load_lib g++-dg.exp
|
||||
load_lib hwasan-dg.exp
|
||||
|
||||
# Initialize `dg'.
|
||||
dg-init
|
||||
hwasan_init
|
||||
|
||||
# Main loop.
|
||||
if [check_effective_target_fsanitize_hwaddress] {
|
||||
gcc-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.C $srcdir/c-c++-common/hwasan/*.c]] "" ""
|
||||
}
|
||||
|
||||
# All done.
|
||||
hwasan_finish
|
||||
dg-finish
|
46
gcc/testsuite/g++.dg/hwasan/rvo-handled.C
Normal file
46
gcc/testsuite/g++.dg/hwasan/rvo-handled.C
Normal file
@ -0,0 +1,46 @@
|
||||
/* { dg-do run } */
|
||||
/* { dg-require-effective-target hwaddress_exec } */
|
||||
/* { dg-skip-if "" { *-*-* } { "-O0" } { "" } } */
|
||||
|
||||
#define assert(x) if (!(x)) __builtin_abort ()
|
||||
typedef __UINTPTR_TYPE__ uintptr_t;
|
||||
void *untagged (void *ptr)
|
||||
{
|
||||
/* Untag by removing the top byte. */
|
||||
return (void*)((uintptr_t)ptr & 0xffffffffffffff);
|
||||
}
|
||||
|
||||
struct big_struct {
|
||||
int left;
|
||||
int right;
|
||||
void *ptr;
|
||||
int big_array[100];
|
||||
};
|
||||
|
||||
/*
|
||||
Tests for RVO (basically, checking -fsanitize=hwaddress has not broken RVO
|
||||
in any way).
|
||||
|
||||
0) The value is accessible in both functions without a hwasan complaint.
|
||||
1) RVO does happen.
|
||||
*/
|
||||
|
||||
struct big_struct __attribute__ ((noinline))
|
||||
return_on_stack()
|
||||
{
|
||||
struct big_struct x;
|
||||
x.left = 100;
|
||||
x.right = 20;
|
||||
x.big_array[10] = 30;
|
||||
x.ptr = untagged(&x);
|
||||
return x;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
struct big_struct x;
|
||||
x = return_on_stack();
|
||||
/* Check that RVO happens by checking the address that the callee saw. */
|
||||
assert (x.ptr == untagged(&x));
|
||||
return 0;
|
||||
}
|
36
gcc/testsuite/gcc.dg/hwasan/hwasan.exp
Normal file
36
gcc/testsuite/gcc.dg/hwasan/hwasan.exp
Normal file
@ -0,0 +1,36 @@
|
||||
# Copyright (C) 2012-2019 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/>.
|
||||
|
||||
# GCC testsuite that uses the `dg.exp' driver.
|
||||
|
||||
# Load support procs.
|
||||
load_lib gcc-dg.exp
|
||||
load_lib hwasan-dg.exp
|
||||
|
||||
# Initialize `dg'.
|
||||
dg-init
|
||||
hwasan_init
|
||||
|
||||
# Main loop.
|
||||
if [check_effective_target_fsanitize_hwaddress] {
|
||||
gcc-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.c $srcdir/c-c++-common/hwasan/*.c]] "" ""
|
||||
}
|
||||
|
||||
# All done.
|
||||
hwasan_finish
|
||||
dg-finish
|
53
gcc/testsuite/gcc.dg/hwasan/nested-functions-0.c
Normal file
53
gcc/testsuite/gcc.dg/hwasan/nested-functions-0.c
Normal file
@ -0,0 +1,53 @@
|
||||
/* { dg-do run } */
|
||||
/* { dg-require-effective-target hwaddress_exec } */
|
||||
|
||||
/*
|
||||
Tests of nested funtions are:
|
||||
0) Accessing closed over variables works.
|
||||
1) Accesses outside of variables is caught.
|
||||
2) Accessing variable out of scope is caught.
|
||||
|
||||
Here we test that accessing closed over variables works.
|
||||
*/
|
||||
|
||||
/* We need a second layer of indirection so that GCC doesn't notice we're
|
||||
returning the address of a local variable and put 0 in it's place. */
|
||||
__attribute__((noinline))
|
||||
int *Ident(void *x) {
|
||||
return x;
|
||||
}
|
||||
|
||||
int __attribute__ ((noinline))
|
||||
intermediate (void (*f) (int, char),
|
||||
char num)
|
||||
{
|
||||
if (num == 1)
|
||||
/* NOTE: We need to overrun by an amount greater than the "extra data" in a
|
||||
nonlocal goto structure. The entire structure is allocated on the stack
|
||||
with a single tag, which means hwasan can't tell if a closed-over buffer
|
||||
was overrun by an amount small enough that the access was still to some
|
||||
data in that nonlocal goto structure. */
|
||||
f (100, 100);
|
||||
else
|
||||
f (3, 100);
|
||||
/* Just return something ... */
|
||||
return num % 3;
|
||||
}
|
||||
|
||||
int* __attribute__ ((noinline))
|
||||
nested_function (char num)
|
||||
{
|
||||
int big_array[16];
|
||||
int other_array[16];
|
||||
void store (int index, char value)
|
||||
{ big_array[index] = value; }
|
||||
return Ident(&other_array[intermediate (store, num)]);
|
||||
}
|
||||
|
||||
#ifndef MAIN
|
||||
int main ()
|
||||
{
|
||||
nested_function (0);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
27
gcc/testsuite/gcc.dg/hwasan/nested-functions-1.c
Normal file
27
gcc/testsuite/gcc.dg/hwasan/nested-functions-1.c
Normal file
@ -0,0 +1,27 @@
|
||||
/* { dg-do run } */
|
||||
/* { dg-require-effective-target hwaddress_exec } */
|
||||
/* { dg-shouldfail "hwasan" } */
|
||||
|
||||
/*
|
||||
Tests of nested funtions are:
|
||||
0) Accessing closed over variables works.
|
||||
1) Accesses outside of variables is caught.
|
||||
2) Accessing variable out of scope is caught.
|
||||
|
||||
Here we test option 1.
|
||||
*/
|
||||
|
||||
#define MAIN 0
|
||||
#include "nested-functions-0.c"
|
||||
#undef MAIN
|
||||
|
||||
int main ()
|
||||
{
|
||||
nested_function (1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* { dg-output "HWAddressSanitizer: tag-mismatch on address 0x\[0-9a-f\]*.*" } */
|
||||
/* { dg-output "WRITE of size 4 at 0x\[0-9a-f\]* tags: \[\[:xdigit:\]\]\[\[:xdigit:\]\]/00 \\(ptr/mem\\) in thread T0.*" } */
|
||||
/* { dg-output "Address 0x\[0-9a-f\]* is located in stack of thread T0.*" } */
|
||||
/* { dg-output "SUMMARY: HWAddressSanitizer: tag-mismatch \[^\n\]*.*" } */
|
28
gcc/testsuite/gcc.dg/hwasan/nested-functions-2.c
Normal file
28
gcc/testsuite/gcc.dg/hwasan/nested-functions-2.c
Normal file
@ -0,0 +1,28 @@
|
||||
/* { dg-do run } */
|
||||
/* { dg-require-effective-target hwaddress_exec } */
|
||||
/* { dg-shouldfail "hwasan" } */
|
||||
|
||||
/*
|
||||
Tests of nested funtions are:
|
||||
0) Accessing closed over variables works.
|
||||
1) Accesses outside of variables is caught.
|
||||
2) Accessing variable out of scope is caught.
|
||||
|
||||
Here we test option 2.
|
||||
*/
|
||||
|
||||
#define MAIN 0
|
||||
#include "nested-functions-0.c"
|
||||
#undef MAIN
|
||||
|
||||
int main ()
|
||||
{
|
||||
int *retval = nested_function (2);
|
||||
*retval = 100;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* { dg-output "HWAddressSanitizer: tag-mismatch on address 0x\[0-9a-f\]*.*" } */
|
||||
/* { dg-output "WRITE of size 4 at 0x\[0-9a-f\]* tags: \[\[:xdigit:\]\]\[\[:xdigit:\]\]/00 \\(ptr/mem\\) in thread T0.*" } */
|
||||
/* { dg-output "Address 0x\[0-9a-f\]* is located in stack of thread T0.*" } */
|
||||
/* { dg-output "SUMMARY: HWAddressSanitizer: tag-mismatch \[^\n\]*.*" } */
|
@ -16,6 +16,9 @@
|
||||
|
||||
# Return 1 if compilation with -fsanitize=address is error-free for trivial
|
||||
# code, 0 otherwise.
|
||||
#
|
||||
# NOTE: This should only be used between calls to asan_init and asan_finish.
|
||||
# It is therefore defined here rather than in target-supports.exp.
|
||||
|
||||
proc check_effective_target_fsanitize_address {} {
|
||||
if ![check_no_compiler_messages fsanitize_address executable {
|
||||
@ -58,33 +61,33 @@ proc asan_include_flags {} {
|
||||
# (originally from g++.exp)
|
||||
#
|
||||
|
||||
proc asan_link_flags { paths } {
|
||||
proc asan_link_flags_1 { paths lib } {
|
||||
global srcdir
|
||||
global ld_library_path
|
||||
global shlib_ext
|
||||
global asan_saved_library_path
|
||||
global ${lib}_saved_library_path
|
||||
|
||||
set gccpath ${paths}
|
||||
set flags ""
|
||||
|
||||
set shlib_ext [get_shlib_extension]
|
||||
set asan_saved_library_path $ld_library_path
|
||||
set ${lib}_saved_library_path $ld_library_path
|
||||
|
||||
if { $gccpath != "" } {
|
||||
if { [file exists "${gccpath}/libsanitizer/asan/.libs/libasan.a"]
|
||||
|| [file exists "${gccpath}/libsanitizer/asan/.libs/libasan.${shlib_ext}"] } {
|
||||
if { [file exists "${gccpath}/libsanitizer/${lib}/.libs/lib${lib}.a"]
|
||||
|| [file exists "${gccpath}/libsanitizer/${lib}/.libs/lib${lib}.${shlib_ext}"] } {
|
||||
append flags " -B${gccpath}/libsanitizer/ "
|
||||
append flags " -B${gccpath}/libsanitizer/asan/ "
|
||||
append flags " -L${gccpath}/libsanitizer/asan/.libs "
|
||||
append ld_library_path ":${gccpath}/libsanitizer/asan/.libs"
|
||||
append flags " -B${gccpath}/libsanitizer/${lib}/ "
|
||||
append flags " -L${gccpath}/libsanitizer/${lib}/.libs "
|
||||
append ld_library_path ":${gccpath}/libsanitizer/${lib}/.libs"
|
||||
}
|
||||
} else {
|
||||
global tool_root_dir
|
||||
|
||||
set libasan [lookfor_file ${tool_root_dir} libasan]
|
||||
if { $libasan != "" } {
|
||||
append flags "-L${libasan} "
|
||||
append ld_library_path ":${libasan}"
|
||||
set libdir [lookfor_file ${tool_root_dir} lib${lib}]
|
||||
if { $libdir != "" } {
|
||||
append flags "-L${libdir} "
|
||||
append ld_library_path ":${libdir}"
|
||||
}
|
||||
}
|
||||
|
||||
@ -93,6 +96,10 @@ proc asan_link_flags { paths } {
|
||||
return "$flags"
|
||||
}
|
||||
|
||||
proc asan_link_flags { paths } {
|
||||
return [asan_link_flags_1 $paths asan]
|
||||
}
|
||||
|
||||
#
|
||||
# asan_init -- called at the start of each subdir of tests
|
||||
#
|
||||
|
150
gcc/testsuite/lib/hwasan-dg.exp
Normal file
150
gcc/testsuite/lib/hwasan-dg.exp
Normal file
@ -0,0 +1,150 @@
|
||||
# Copyright (C) 2020 Free Software Foundation, Inc.
|
||||
|
||||
# This program 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 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program 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/>.
|
||||
|
||||
load_lib asan-dg.exp
|
||||
|
||||
# Return 1 if target can compile a binary for hardware address
|
||||
# sanitization, 0 otherwise.
|
||||
#
|
||||
# NOTE: This should only be used between calls to hwasan_init and
|
||||
# hwasan_finish. It is therefore defined here rather than in
|
||||
# target-supports.exp.
|
||||
|
||||
proc check_effective_target_fsanitize_hwaddress {} {
|
||||
if ![check_no_compiler_messages fsanitize_hwaddress executable {
|
||||
int main (void) { return 0; }
|
||||
}] {
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
# Return 1 if target can compile and run a binary for hardware address
|
||||
# sanitization, 0 otherwise.
|
||||
#
|
||||
# NOTE: This should only be used between calls to hwasan_init and
|
||||
# hwasan_finish. It is therefore defined here rather than in
|
||||
# target-supports.exp.
|
||||
|
||||
proc check_effective_target_hwaddress_exec {} {
|
||||
if ![check_runtime hwaddress_exec {
|
||||
int main (void) { return 0; }
|
||||
}] {
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
proc hwasan_include_flags {} {
|
||||
global srcdir
|
||||
global TESTING_IN_BUILD_TREE
|
||||
|
||||
set flags ""
|
||||
|
||||
if { [is_remote host] || ! [info exists TESTING_IN_BUILD_TREE] } {
|
||||
return "${flags}"
|
||||
}
|
||||
|
||||
set flags "-I$srcdir/../../libsanitizer/include"
|
||||
|
||||
return "$flags"
|
||||
}
|
||||
|
||||
#
|
||||
# hwasan_link_flags -- compute library path and flags to find libhwasan.
|
||||
# (implementation in asan-dg.exp)
|
||||
#
|
||||
|
||||
proc hwasan_link_flags { paths } {
|
||||
return [asan_link_flags_1 $paths hwasan]
|
||||
}
|
||||
|
||||
#
|
||||
# hwasan_init -- called at the start of each subdir of tests
|
||||
#
|
||||
|
||||
proc hwasan_init { args } {
|
||||
global TEST_ALWAYS_FLAGS
|
||||
global ALWAYS_CXXFLAGS
|
||||
global TOOL_OPTIONS
|
||||
global hwasan_saved_TEST_ALWAYS_FLAGS
|
||||
global hwasan_saved_ALWAYS_CXXFLAGS
|
||||
|
||||
setenv HWASAN_OPTIONS "random_tags=0"
|
||||
|
||||
set link_flags ""
|
||||
if ![is_remote host] {
|
||||
if [info exists TOOL_OPTIONS] {
|
||||
set link_flags "[hwasan_link_flags [get_multilibs ${TOOL_OPTIONS}]]"
|
||||
} else {
|
||||
set link_flags "[hwasan_link_flags [get_multilibs]]"
|
||||
}
|
||||
}
|
||||
|
||||
set include_flags "[hwasan_include_flags]"
|
||||
|
||||
if [info exists TEST_ALWAYS_FLAGS] {
|
||||
set hwasan_saved_TEST_ALWAYS_FLAGS $TEST_ALWAYS_FLAGS
|
||||
}
|
||||
if [info exists ALWAYS_CXXFLAGS] {
|
||||
set hwasan_saved_ALWAYS_CXXFLAGS $ALWAYS_CXXFLAGS
|
||||
set ALWAYS_CXXFLAGS [concat "{ldflags=$link_flags}" $ALWAYS_CXXFLAGS]
|
||||
set ALWAYS_CXXFLAGS [concat "{additional_flags=-fsanitize=hwaddress --param hwasan-random-frame-tag=0 -g $include_flags}" $ALWAYS_CXXFLAGS]
|
||||
} else {
|
||||
if [info exists TEST_ALWAYS_FLAGS] {
|
||||
set TEST_ALWAYS_FLAGS "$link_flags -fsanitize=hwaddress --param hwasan-random-frame-tag=0 -g $include_flags $TEST_ALWAYS_FLAGS"
|
||||
} else {
|
||||
set TEST_ALWAYS_FLAGS "$link_flags -fsanitize=hwaddress --param hwasan-random-frame-tag=0 -g $include_flags"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#
|
||||
# hwasan_finish -- called at the start of each subdir of tests
|
||||
#
|
||||
|
||||
proc hwasan_finish { args } {
|
||||
global TEST_ALWAYS_FLAGS
|
||||
global hwasan_saved_TEST_ALWAYS_FLAGS
|
||||
global hwasan_saved_ALWAYS_CXXFLAGS
|
||||
global hwasan_saved_library_path
|
||||
global ld_library_path
|
||||
|
||||
unsetenv HWASAN_OPTIONS
|
||||
|
||||
if [info exists hwasan_saved_ALWAYS_CXXFLAGS ] {
|
||||
set ALWAYS_CXXFLAGS $hwasan_saved_ALWAYS_CXXFLAGS
|
||||
} else {
|
||||
if [info exists hwasan_saved_TEST_ALWAYS_FLAGS] {
|
||||
set TEST_ALWAYS_FLAGS $hwasan_saved_TEST_ALWAYS_FLAGS
|
||||
} else {
|
||||
unset TEST_ALWAYS_FLAGS
|
||||
}
|
||||
}
|
||||
if [info exists hwasan_saved_library_path] {
|
||||
set ld_library_path $hwasan_saved_library_path
|
||||
set_ld_library_path_env_vars
|
||||
}
|
||||
clear_effective_target_cache
|
||||
}
|
||||
|
||||
# Utility for running gtest hwasan emulation under dejagnu, invoked via dg-final.
|
||||
# Call pass if variable has the desired value, otherwise fail.
|
||||
#
|
||||
# Argument 0 handles expected failures and the like
|
||||
proc hwasan-gtest { args } {
|
||||
asan-gtest {*}$args
|
||||
}
|
Loading…
Reference in New Issue
Block a user