| ; Test that the quarantine for recently freed objects works | |
| ; REQUIRES: no_minimal_build | |
| ; Test with an illegal load from a freed block | |
| ; RUN: llvm-as %s -o - | pnacl-freeze > %t.pexe && %S/../../pydir/szbuild.py \ | |
| ; RUN: --fsanitize-address --sz=-allow-externally-defined-symbols \ | |
| ; RUN: %t.pexe -o %t && %t 2>&1 | FileCheck --check-prefix=LOAD %s | |
| ; RUN: llvm-as %s -o - | pnacl-freeze > %t.pexe && %S/../../pydir/szbuild.py \ | |
| ; RUN: --fsanitize-address --sz=-allow-externally-defined-symbols -O2 \ | |
| ; RUN: %t.pexe -o %t && %t 2>&1 | FileCheck --check-prefix=LOAD %s | |
| ; Test with an illegal store to a freed block | |
| ; RUN: llvm-as %s -o - | pnacl-freeze > %t.pexe && %S/../../pydir/szbuild.py \ | |
| ; RUN: --fsanitize-address --sz=-allow-externally-defined-symbols \ | |
| ; RUN: %t.pexe -o %t && %t 1 2>&1 | FileCheck --check-prefix=STORE %s | |
| ; RUN: llvm-as %s -o - | pnacl-freeze > %t.pexe && %S/../../pydir/szbuild.py \ | |
| ; RUN: --fsanitize-address --sz=-allow-externally-defined-symbols -O2 \ | |
| ; RUN: %t.pexe -o %t && %t 1 2>&1 | FileCheck --check-prefix=STORE %s | |
| ; Test that freed objects eventually get out of quarantine and are unpoisoned | |
| ; RUN: llvm-as %s -o - | pnacl-freeze > %t.pexe && %S/../../pydir/szbuild.py \ | |
| ; RUN: --fsanitize-address --sz=-allow-externally-defined-symbols \ | |
| ; RUN: %t.pexe -o %t && %t 1 2 2>&1 | FileCheck --check-prefix=NONE %s \ | |
| ; RUN: --allow-empty | |
| ; RUN: llvm-as %s -o - | pnacl-freeze > %t.pexe && %S/../../pydir/szbuild.py \ | |
| ; RUN: --fsanitize-address --sz=-allow-externally-defined-symbols -O2 \ | |
| ; RUN: %t.pexe -o %t && %t 1 2 2>&1 | FileCheck --check-prefix=NONE %s \ | |
| ; RUN: --allow-empty | |
| declare external i32 @malloc(i32) | |
| declare external void @free(i32) | |
| declare external void @exit(i32) | |
| ; make three 100MB allocations | |
| define void @_start(i32 %arg) { | |
| %argcaddr = add i32 %arg, 8 | |
| %argcptr = inttoptr i32 %argcaddr to i32* | |
| %argc = load i32, i32* %argcptr, align 1 | |
| %alloc1addr = call i32 @malloc(i32 104857600) | |
| %alloc2addr = call i32 @malloc(i32 104857600) | |
| %alloc3addr = call i32 @malloc(i32 104857600) | |
| %alloc1 = inttoptr i32 %alloc1addr to i32* | |
| %alloc2 = inttoptr i32 %alloc2addr to i32* | |
| %alloc3 = inttoptr i32 %alloc3addr to i32* | |
| call void @free(i32 %alloc1addr) | |
| call void @free(i32 %alloc2addr) | |
| call void @free(i32 %alloc3addr) | |
| switch i32 %argc, label %error [i32 1, label %bad_load | |
| i32 2, label %bad_store | |
| i32 3, label %no_err] | |
| bad_load: | |
| %result_load = load i32, i32* %alloc2, align 1 | |
| br label %error | |
| bad_store: | |
| store i32 42, i32* %alloc3, align 1 | |
| br label %error | |
| no_err: | |
| %result_no_err = load i32, i32* %alloc1, align 1 | |
| call void @exit(i32 0) | |
| unreachable | |
| error: | |
| call void @exit(i32 1) | |
| unreachable | |
| } | |
| ; LOAD: Illegal 4 byte load from freed object at | |
| ; STORE: Illegal 4 byte store to freed object at | |
| ; NONE-NOT: Illegal |