├── scripts ├── svcomp │ ├── __init__.py │ ├── utils │ │ ├── __init__.py │ │ ├── log.py │ │ ├── properties.py │ │ ├── config.py │ │ └── model.py │ ├── README │ ├── setup-submission.sh │ └── NOTES.md ├── benchmark │ ├── verify.sh │ └── Dockerfile └── build.sh ├── external └── CMakeLists.txt ├── lamp ├── dataflow-blacklist.txt ├── zero.cpp ├── interval.cpp ├── bitvec-interval.cpp ├── cmake │ └── lamp.cmake ├── README.md ├── term.cpp ├── constant.cpp ├── unit.cpp ├── tracing-term.cpp ├── floats.cpp ├── tracing-unit.cpp ├── include │ ├── lamp-pointers.h │ └── lamp │ │ └── adaptor │ │ └── pa.hpp ├── sign.cpp ├── tracing-floats.cpp ├── tracing-interval.cpp ├── tracing-sign.cpp ├── tracing-zero.cpp ├── tracing-bitvec-interval.cpp ├── CMakeLists.txt ├── memory.hpp ├── trivial.cpp └── pa.cpp ├── pres ├── simulator example │ ├── .mypy.ini │ └── simulator.py └── dataflow render example │ └── dataflow.py ├── benchmarks └── example │ ├── correct.c │ └── error.c ├── .gitmodules ├── ports └── svf │ ├── svf_usage │ ├── vcpkg.json │ └── portfile.cmake ├── test ├── basic │ ├── dump-unit.c │ ├── dump-term-a.c │ ├── funcast-a.c │ ├── call-a.c │ ├── assert-a.c │ ├── call-e.c │ ├── mem-a.c │ ├── arith-b.c │ ├── cast-a.c │ ├── cast-b.c │ ├── compare-f.c │ ├── addr-fun-b.c │ ├── cast-j.c │ ├── call-b.c │ ├── cast-c.c │ ├── compare-d.c │ ├── boolnot.c │ ├── compare-a.c │ ├── insertvalue.c │ ├── bool-arith-a.c │ ├── any-a.c │ ├── addr-fun-a.c │ ├── compare-c.c │ ├── mem-b.c │ ├── call-g.c │ ├── join-a.c │ ├── call-c.c │ ├── addr-fun-c.c │ ├── call-h.c │ ├── mem-c.c │ ├── cast-k.c │ ├── compare-e.c │ ├── mem-d.c │ ├── arith-a.c │ ├── any-b.c │ ├── bool-arith-c.c │ ├── compare-b.c │ ├── float-a.c │ ├── call-f.c │ ├── array-a.c │ ├── array-c.c │ ├── array-d.c │ ├── cast-l.c │ ├── float-c.c │ ├── funptr.c │ ├── cast-d.c │ ├── cast-e.c │ ├── bool-arith-b.c │ ├── cast-g.c │ ├── cast-h.c │ ├── call-d.c │ ├── cast-i.c │ ├── bool-arith-d.c │ ├── any-c.c │ ├── float-b.c │ ├── call-i.c │ ├── input-arg-a.c │ ├── array-f.c │ ├── float-d.c │ ├── cast-f.c │ ├── float-e.c │ ├── array-b.c │ ├── array-e.c │ ├── freeze-into-other-a.c │ ├── freeze-into-other-b.c │ └── freeze-in-store.c ├── unittests │ ├── unit.cpp │ ├── catch-main.cpp │ └── CMakeLists.txt ├── scripts │ └── testrun.sh.in ├── pa │ ├── nondet-b.c │ ├── nondet-a.c │ ├── store-b.c │ ├── free-a.c │ ├── simple-a.c │ ├── compare-a.c │ ├── tristate-a.cpp │ ├── store-a.c │ ├── dealloca-a.c │ ├── compare-b.c │ ├── compare-c.c │ ├── nondet-c.c │ ├── compare-d.c │ ├── decompose-a.c │ ├── store-c.cpp │ ├── decompose-b.c │ └── xor-swap.cpp ├── include │ └── utils.h ├── lit.site.cfg.py.in ├── svcomp │ └── basic.c ├── CMakeLists.txt └── lit.cfg.py ├── vcpkg.json ├── setup.sh ├── lava ├── CMakeLists.txt ├── include │ └── lava │ │ ├── support │ │ ├── pointer.hpp │ │ └── mmaped_pointer.hpp │ │ └── empty.hpp └── README.md ├── .dockerignore ├── runtime ├── CMakeLists.txt ├── native │ ├── choose.hpp │ ├── utils.hpp │ ├── trace.cpp │ ├── CMakeLists.txt │ ├── stash.cpp │ ├── stash.hpp │ ├── trace.hpp │ ├── lart.cpp │ ├── choose.cpp │ ├── config.cpp │ └── svcomp.cpp └── include │ └── runtime │ ├── config.hpp │ ├── shadow.hpp │ ├── stream.hpp │ └── lart.h ├── .gitignore ├── .vscode └── launch.json ├── .devcontainer ├── devcontainer.json ├── Dockerfile └── reinstall-cmake.sh ├── CMakeLists.txt ├── lartcc ├── alias.cpp ├── include │ └── cc │ │ ├── logger.hpp │ │ ├── stats.hpp │ │ ├── driver.hpp │ │ ├── pass.hpp │ │ ├── taint.hpp │ │ ├── lifter.hpp │ │ ├── backend │ │ ├── base.hpp │ │ └── native │ │ │ └── native.hpp │ │ ├── preprocess.hpp │ │ ├── util.hpp │ │ ├── arguments.hpp │ │ ├── assume.hpp │ │ ├── ir.hpp │ │ ├── tristate.hpp │ │ ├── syntactic.hpp │ │ ├── shadow.hpp │ │ └── roots.hpp ├── lartcc.in ├── backend │ └── base.cpp ├── pass.cpp ├── assume.cpp └── taint.cpp ├── LICENSE ├── cmake ├── static_analyzers.cmake ├── project_settings.cmake └── sanitizers.cmake ├── CMakeUserPresets.json ├── .clang-format ├── .clang-tidy ├── doc └── lart-pontos-build.md └── README.md /scripts/svcomp/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /external/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_subdirectory( sc ) 2 | -------------------------------------------------------------------------------- /lamp/dataflow-blacklist.txt: -------------------------------------------------------------------------------- 1 | fun:Z3_*=uninstrumented 2 | fun:Z3_*=discard -------------------------------------------------------------------------------- /pres/simulator example/.mypy.ini: -------------------------------------------------------------------------------- 1 | [mypy] 2 | 3 | [mypy-ipywidgets] 4 | ignore_missing_imports = True -------------------------------------------------------------------------------- /benchmarks/example/correct.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main() { 4 | int x = __lamp_any_i32(); 5 | } 6 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "external/sc"] 2 | path = external/sc 3 | url = https://github.com/xlauko/llvm-sc.git 4 | -------------------------------------------------------------------------------- /benchmarks/example/error.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main() { 5 | int x = __lamp_any_i32(); 6 | assert( x ); 7 | } 8 | -------------------------------------------------------------------------------- /ports/svf/svf_usage: -------------------------------------------------------------------------------- 1 | The package svf provides CMake targets: 2 | 3 | find_package(svf CONFIG REQUIRED) 4 | target_link_libraries(main PRIVATE svf::svf) 5 | -------------------------------------------------------------------------------- /scripts/svcomp/utils/__init__.py: -------------------------------------------------------------------------------- 1 | from . config import config 2 | from . log import setup_logger, error, logger 3 | from . properties import property, property_names 4 | from . runner import runner 5 | 6 | setup_logger() 7 | -------------------------------------------------------------------------------- /test/basic/dump-unit.c: -------------------------------------------------------------------------------- 1 | // RUN: %testrun %lartcc unit %s -o %t | %filecheck %s 2 | 3 | #include 4 | 5 | int main() { 6 | int a = __lamp_any_i32(); 7 | __lamp_dump(&a); 8 | // CHECK: unit 9 | } 10 | -------------------------------------------------------------------------------- /vcpkg.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "main", 3 | "version-string": "latest", 4 | "dependencies": [ 5 | "catch2", 6 | "doctest", 7 | "fmt", 8 | "spdlog", 9 | "svf" 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /test/basic/dump-term-a.c: -------------------------------------------------------------------------------- 1 | // RUN: %testrun %lartcc term -lz3 %s -o %t | %filecheck %s 2 | 3 | #include 4 | 5 | int main() { 6 | int a = __lamp_any_i32(); 7 | __lamp_dump(&a); 8 | // CHECK: var_1 9 | } 10 | -------------------------------------------------------------------------------- /test/unittests/unit.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | // #include 4 | extern "C" void* __lamp_wrap_i32( uint32_t v ); 5 | TEST_CASE( "wrap a unit value", "[unit]" ) { 6 | auto v = __lamp_wrap_i32(5); 7 | REQUIRE( v ); 8 | } 9 | -------------------------------------------------------------------------------- /test/unittests/catch-main.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file is split of from the test cases to help with incremental builds 3 | */ 4 | #define CATCH_CONFIG_MAIN 5 | /* This tells Catch to provide a main() - only do this in one cpp file*/ 6 | 7 | #include 8 | -------------------------------------------------------------------------------- /test/basic/funcast-a.c: -------------------------------------------------------------------------------- 1 | /* TAGS: error sym c */ 2 | /* VERIFY_OPTS: --symbolic */ 3 | 4 | #include 5 | 6 | int __VERIFIER_nondet_int(); /* note the absence of void in the arg list */ 7 | int main() 8 | { 9 | assert( __VERIFIER_nondet_int() != 3 ); /* ERROR */ 10 | } 11 | -------------------------------------------------------------------------------- /test/scripts/testrun.sh.in: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | RUNNER=$1 4 | OPTS="${@:2}" 5 | PROG=${!#} 6 | 7 | compile () { 8 | ${RUNNER} ${OPTS} -I@CMAKE_CURRENT_BINARY_DIR@/include 9 | } 10 | 11 | execute () { 12 | export LART_NO_FAIL_MODE=ON 13 | ${PROG} 2>&1 14 | } 15 | 16 | compile; execute 17 | -------------------------------------------------------------------------------- /test/basic/call-a.c: -------------------------------------------------------------------------------- 1 | // RUN: %testrun %lartcc unit %s -o %t | %filecheck %s 2 | 3 | #include 4 | #include "utils.h" 5 | 6 | void fn(int i) { 7 | if (i) 8 | REACHABLE 9 | } 10 | 11 | int main() { 12 | int x = __lamp_any_i32(); 13 | fn(x); 14 | // CHECK-COUNT-1: lart-reachable 15 | } -------------------------------------------------------------------------------- /scripts/svcomp/README: -------------------------------------------------------------------------------- 1 | See https://github.com/xlauko/lart for information about LART and its usage. 2 | 3 | For SV-COMP LART comes with a wrapper which handles SV-COMP specific settings. 4 | 5 | This binary distribution should work on Ubuntu 20.04 and needs only the 6 | following packages: libz3-4, clang-12, llvm-12, python3. 7 | -------------------------------------------------------------------------------- /setup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | export LART_INSTALL_DIR=./install 4 | ./scripts/build.sh 5 | 6 | rm -rf submission/ 7 | ./scripts/svcomp/setup-submission.sh /workspaces/lart/install/ submission 8 | 9 | rm lart.zip 10 | cp -r submission lart 11 | rm -rf rm -rf ./lart/utils/__pycache__/ 12 | zip -r lart.zip lart 13 | rm -rf lart 14 | -------------------------------------------------------------------------------- /lamp/zero.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | namespace __lamp 6 | { 7 | using zero = __lava::zero< wrapped_storage >; 8 | using meta_domain = __lava::relational< zero, wrapped_storage >; 9 | } // namespace __lamp 10 | 11 | #include "wrapper.hpp" 12 | -------------------------------------------------------------------------------- /test/basic/assert-a.c: -------------------------------------------------------------------------------- 1 | // RUN: %testrun %lartcc term -lz3 %s -o %t | %filecheck %s 2 | // RUN: %testrun %lartcc unit %s -o %t | %filecheck %s 3 | 4 | #include 5 | #include 6 | 7 | #include "utils.h" 8 | 9 | int main() { 10 | int i = __lamp_any_i32(); 11 | assert( i != 0 ); // CHECK: assertion i != 0 failed 12 | } 13 | -------------------------------------------------------------------------------- /lava/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_library( lava INTERFACE ) 2 | 3 | target_include_directories( lava 4 | INTERFACE 5 | $ 6 | ${CMAKE_CURRENT_SOURCE_DIR}/include 7 | ) 8 | 9 | target_link_libraries( lava INTERFACE lart-runtime ) 10 | 11 | target_link_libraries( lava INTERFACE lart_project_options lart_project_warnings ) 12 | -------------------------------------------------------------------------------- /test/pa/nondet-b.c: -------------------------------------------------------------------------------- 1 | // RUN: %testrun %lartcc pa -lz3 %s -o %t | %filecheck %s 2 | // REQUIRES: pa 3 | 4 | #include 5 | #include 6 | #include "utils.h" 7 | 8 | int arr[] = {1, 2, 3}; 9 | 10 | int main() { 11 | int * ptr = (int*)__lamp_any_ptr(); 12 | assert(ptr != arr); // CHECK: assertion ptr != val failed 13 | } 14 | -------------------------------------------------------------------------------- /test/basic/call-e.c: -------------------------------------------------------------------------------- 1 | // RUN: %testrun %lartcc term -lz3 %s -o %t | %filecheck %s 2 | 3 | #include 4 | #include 5 | 6 | #include "utils.h" 7 | 8 | bool is_zero( int v ) { return v == 0; } 9 | 10 | int main() { 11 | int input = __lamp_any_i32(); 12 | assert( is_zero( input ) ); // CHECK: assertion is_zero( input ) failed 13 | } 14 | -------------------------------------------------------------------------------- /test/basic/mem-a.c: -------------------------------------------------------------------------------- 1 | // RUN: %testrun %lartcc term -lz3 %s -o %t | %filecheck %s 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include "utils.h" 8 | 9 | int main() { 10 | int x = __lamp_any_i32(); 11 | int *a = &x; 12 | int y = *a; 13 | assert( x == y ); 14 | REACHABLE // CHECK: lart-reachable 15 | } 16 | -------------------------------------------------------------------------------- /lamp/interval.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | namespace __lamp 6 | { 7 | using interval = __lava::interval< wrapped_storage >; 8 | using meta_domain = __lava::relational< interval, wrapped_storage >; 9 | } // namespace __lamp 10 | 11 | 12 | #include "wrapper.hpp" -------------------------------------------------------------------------------- /test/pa/nondet-a.c: -------------------------------------------------------------------------------- 1 | // RUN: %testrun %lartcc pa -lz3 %s -o %t | %filecheck %s 2 | // REQUIRES: pa 3 | 4 | #include 5 | #include 6 | #include "utils.h" 7 | 8 | int main() 9 | { 10 | int *val = (int*)malloc(4); 11 | int *ptr = (int*)__lamp_any_ptr(); 12 | assert(ptr != val); // CHECK: assertion ptr != val failed 13 | } 14 | -------------------------------------------------------------------------------- /test/basic/arith-b.c: -------------------------------------------------------------------------------- 1 | // RUN: %testrun %lartcc term -lz3 %s -o %t | %filecheck %s 2 | 3 | #include 4 | #include 5 | 6 | #include "utils.h" 7 | 8 | int main() { 9 | short a = __lamp_any_i16(); 10 | int b = __lamp_any_i32(); 11 | int r = a + b; 12 | __lamp_dump(&r); 13 | // CHECK: (bvadd ((_ sign_extend 16) var_1) var_2) 14 | } 15 | -------------------------------------------------------------------------------- /test/basic/cast-a.c: -------------------------------------------------------------------------------- 1 | // RUN: %testrun %lartcc term -lz3 %s -o %t | %filecheck %s 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | int main() { 8 | int x = __lamp_any_i32(); 9 | if ( x < 0 ) 10 | return 0; 11 | short y = x; 12 | ++y; 13 | assert( x + 1 == y ); // CHECK: assertion x + 1 == y failed 14 | } 15 | -------------------------------------------------------------------------------- /test/basic/cast-b.c: -------------------------------------------------------------------------------- 1 | // RUN: %testrun %lartcc term -lz3 %s -o %t | %filecheck %s 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | int main() { 8 | int x = __lamp_any_i32(); 9 | if ( x < 0 ) 10 | return 0; 11 | short y = x; 12 | ++y; 13 | assert( y != -32768 ); // CHECK: assertion y != -32768 failed 14 | } 15 | -------------------------------------------------------------------------------- /test/pa/store-b.c: -------------------------------------------------------------------------------- 1 | // RUN: %testrun %lartcc pa -lz3 %s -o %t | %filecheck %s 2 | // REQUIRES: pa 3 | 4 | #include 5 | #include 6 | #include "utils.h" 7 | 8 | int main() 9 | { 10 | int a = 1; 11 | int *p = (int*)__lamp_lift_objid( &a ); 12 | *p = 4; 13 | assert( a == 4 ); 14 | REACHABLE // CHECK: lart-reachable 15 | } 16 | -------------------------------------------------------------------------------- /test/basic/compare-f.c: -------------------------------------------------------------------------------- 1 | // RUN: %testrun %lartcc term -lz3 %s -o %t | %filecheck %s 2 | // RUN: %testrun %lartcc unit %s -o %t | %filecheck %s 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #include "utils.h" 9 | 10 | int main() { 11 | int x = __lamp_any_i32(); 12 | assert( x <= 0 ); // CHECK: assertion x <= 0 failed 13 | } 14 | -------------------------------------------------------------------------------- /test/pa/free-a.c: -------------------------------------------------------------------------------- 1 | // RUN: %testrun %lartcc pa -lz3 %s -o %t | %filecheck %s 2 | // REQUIRES: pa 3 | 4 | #include 5 | #include 6 | #include 7 | #include "utils.h" 8 | 9 | int main() 10 | { 11 | int* ptr = (int *)( __lamp_lift_objid( malloc( sizeof( int ) ) ) ); 12 | free( ptr ); 13 | REACHABLE // CHECK: lart-reachable 14 | } 15 | -------------------------------------------------------------------------------- /lamp/bitvec-interval.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | namespace __lamp 6 | { 7 | using interval = __lava::bitvec_interval< wrapped_storage >; 8 | using meta_domain = __lava::relational< interval, wrapped_storage >; 9 | } // namespace __lamp 10 | 11 | #include "wrapper.hpp" 12 | -------------------------------------------------------------------------------- /test/basic/addr-fun-b.c: -------------------------------------------------------------------------------- 1 | // TODO: 2 | 3 | #include 4 | #include 5 | 6 | #include 7 | #include 8 | 9 | void foo( int val ) { 10 | assert( val < 0 ); 11 | } 12 | 13 | extern void vbari( int val ); 14 | 15 | int main() { 16 | int val = __lamp_any_i32(); 17 | auto fn = val < 0 ? &foo : &vbari; 18 | fn( val ); /* ERROR */ 19 | } -------------------------------------------------------------------------------- /test/pa/simple-a.c: -------------------------------------------------------------------------------- 1 | // RUN: %testrun %lartcc pa -lz3 %s -o %t | %filecheck %s 2 | // REQUIRES: pa 3 | 4 | #include 5 | #include 6 | #include "utils.h" 7 | 8 | int main() 9 | { 10 | int x[3] = { 1, 2, 3 }; 11 | int *p = (int*)__lamp_lift_objid( &x ); 12 | int *o = p + 1; 13 | assert( *o == 2 ); 14 | REACHABLE // CHECK: lart-reachable 15 | } 16 | -------------------------------------------------------------------------------- /test/basic/cast-j.c: -------------------------------------------------------------------------------- 1 | // RUN: %testrun %lartcc term -lz3 %s -o %t | %filecheck %s 2 | // REQUIRES: fix 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | void *foo() { /* creates inttoptr instuction */ 9 | return __lamp_any_i64(); 10 | } 11 | 12 | 13 | int main() { 14 | _Bool b = foo(); 15 | assert( !b ); // CHECK: assertion !b failed 16 | } 17 | -------------------------------------------------------------------------------- /test/basic/call-b.c: -------------------------------------------------------------------------------- 1 | // RUN: %testrun %lartcc unit %s -o %t | %filecheck %s 2 | 3 | #include 4 | #include "utils.h" 5 | 6 | void fn(int i, int j) { 7 | if (i) 8 | REACHABLE 9 | if (j) 10 | REACHABLE 11 | } 12 | 13 | int main() { 14 | int x = __lamp_any_i32(); 15 | int y = __lamp_any_i32(); 16 | fn(x, y); 17 | // CHECK-COUNT-2: lart-reachable 18 | } -------------------------------------------------------------------------------- /test/basic/cast-c.c: -------------------------------------------------------------------------------- 1 | // RUN: %testrun %lartcc term -lz3 %s -o %t | %filecheck %s 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | int main() { 9 | int x = __lamp_any_i32(); 10 | if ( x < 0 ) 11 | return 0; 12 | short y = x; 13 | ++y; 14 | assert( y != SHRT_MIN ); // CHECK: assertion y != SHRT_MIN failed 15 | } 16 | -------------------------------------------------------------------------------- /test/basic/compare-d.c: -------------------------------------------------------------------------------- 1 | // RUN: %testrun %lartcc term -lz3 %s -o %t | %filecheck %s 2 | // RUN: %testrun %lartcc unit %s -o %t | %filecheck %s 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #include "utils.h" 9 | 10 | int y = 0; 11 | 12 | int main() { 13 | uint64_t x = __lamp_any_i64(); 14 | assert( x != y ); // CHECK: assertion x != y failed 15 | } 16 | -------------------------------------------------------------------------------- /test/basic/boolnot.c: -------------------------------------------------------------------------------- 1 | // RUN: %testrun %lartcc term -lz3 %s -o %t | %filecheck %s 2 | // RUN: %testrun %lartcc unit %s -o %t | %filecheck %s 3 | 4 | #include 5 | #include "utils.h" 6 | 7 | #include 8 | #include 9 | 10 | int main() 11 | { 12 | bool a = __lamp_any_i1(); 13 | bool b = !a; 14 | 15 | assert( a == b ); // CHECK: assertion a == b failed 16 | } 17 | -------------------------------------------------------------------------------- /test/basic/compare-a.c: -------------------------------------------------------------------------------- 1 | // RUN: %testrun %lartcc term -lz3 %s -o %t | %filecheck %s 2 | // RUN: %testrun %lartcc unit %s -o %t | %filecheck %s 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #include "utils.h" 9 | 10 | int main() { 11 | uint64_t x = __lamp_any_i64(); 12 | uint64_t y = 0; 13 | assert( x != y ); // CHECK: assertion x != y failed 14 | } 15 | -------------------------------------------------------------------------------- /test/basic/insertvalue.c: -------------------------------------------------------------------------------- 1 | /* TAGS: error todo sym c++ */ 2 | /* VERIFY_OPTS: --symbolic */ 3 | /* CC_OPTS: -O1 */ 4 | 5 | #include 6 | 7 | extern "C" { 8 | int __lamp_any_i32(); 9 | } 10 | 11 | struct S { int a, b, c; }; 12 | 13 | S foo() { 14 | S s; 15 | s.b = __lamp_any_i32(); 16 | return s; 17 | } 18 | 19 | int main() { 20 | assert( foo().b == 0 ); /* ERROR */ 21 | } 22 | -------------------------------------------------------------------------------- /test/include/utils.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | void reachable() 6 | { 7 | fprintf( stderr, "lart-reachable\n" ); 8 | } 9 | void unreachable() 10 | { 11 | fprintf( stderr, "lart-unreachable\n" ); 12 | } 13 | 14 | #define REACHABLE reachable(); 15 | #define UNREACHABLE unreachable(); 16 | 17 | #define noinline __attribute__((__noinline__)) 18 | -------------------------------------------------------------------------------- /test/pa/compare-a.c: -------------------------------------------------------------------------------- 1 | // RUN: %testrun %lartcc pa -lz3 %s -o %t | %filecheck %s 2 | // REQUIRES: pa 3 | 4 | #include 5 | #include 6 | #include "utils.h" 7 | 8 | int main() 9 | { 10 | int arr[3]; 11 | int *p = (int*)__lamp_lift_objid( arr ); 12 | int *a = p; 13 | int *b = p + 1; 14 | assert( a != b ); 15 | REACHABLE // CHECK: lart-reachable 16 | } 17 | -------------------------------------------------------------------------------- /test/pa/tristate-a.cpp: -------------------------------------------------------------------------------- 1 | // RUN: %testrun %lartcc++ pa -lz3 %s -o %t | %filecheck %s 2 | // REQUIRES: pa 3 | 4 | #include 5 | #include 6 | #include "utils.h" 7 | 8 | int main() 9 | { 10 | char * x = (char *)__lamp_lift_objid( malloc(1) ); 11 | if ( reinterpret_cast< uintptr_t >( x ) & 0x1 ) 12 | free( x ); 13 | REACHABLE // CHECK: lart-reachable 14 | } 15 | -------------------------------------------------------------------------------- /test/basic/bool-arith-a.c: -------------------------------------------------------------------------------- 1 | // RUN: %testrun %lartcc term -lz3 %s -o %t | %filecheck %s 2 | // RUN: %testrun %lartcc unit %s -o %t | %filecheck %s 3 | 4 | #include 5 | #include "utils.h" 6 | 7 | #include 8 | #include 9 | 10 | int main() 11 | { 12 | bool a = __lamp_any_i1(); 13 | bool b = __lamp_any_i1(); 14 | assert( a && b ); // CHECK: assertion a && b failed 15 | } -------------------------------------------------------------------------------- /test/pa/store-a.c: -------------------------------------------------------------------------------- 1 | // RUN: %testrun %lartcc pa -lz3 %s -o %t | %filecheck %s 2 | // REQUIRES: pa 3 | 4 | #include 5 | #include 6 | #include "utils.h" 7 | 8 | int main() 9 | { 10 | int x[3] = { 1, 2, 3 }; 11 | int *p = (int*)__lamp_lift_objid( x ); 12 | p[1] = 4; 13 | int *o = p + 1; 14 | assert( *o == 4 ); 15 | REACHABLE // CHECK: lart-reachable 16 | } 17 | -------------------------------------------------------------------------------- /test/basic/any-a.c: -------------------------------------------------------------------------------- 1 | // RUN: %testrun %lartcc term -lz3 %s -o %t | %filecheck %s 2 | // RUN: %testrun %lartcc unit %s -o %t | %filecheck %s 3 | 4 | #include 5 | #include 6 | #include "utils.h" 7 | 8 | int main() { 9 | uint8_t x = __lamp_any_i8(); 10 | if ( x ) { 11 | REACHABLE 12 | } else { 13 | REACHABLE 14 | } 15 | // CHECK-COUNT-2: lart-reachable 16 | } 17 | -------------------------------------------------------------------------------- /test/pa/dealloca-a.c: -------------------------------------------------------------------------------- 1 | // RUN: %testrun %lartcc pa -lz3 %s -o %t | %filecheck %s 2 | // REQUIRES: pa 3 | 4 | #include 5 | #include 6 | #include "utils.h" 7 | 8 | int main() 9 | { 10 | void *p = NULL; 11 | void *x = __lamp_lift_objid( p ); 12 | 13 | struct S { int x, y; } s; 14 | void *y = __lamp_lift_objid( &s.y ); 15 | REACHABLE // CHECK: lart-reachable 16 | } 17 | -------------------------------------------------------------------------------- /test/basic/addr-fun-a.c: -------------------------------------------------------------------------------- 1 | // TODO: 2 | #include 3 | #include 4 | #include "utils.h" 5 | 6 | #include 7 | #include 8 | 9 | void foo( int val ) { 10 | assert( val < 0 ); 11 | } 12 | 13 | void bar( int val ) { 14 | assert( val >= 0 ); 15 | } 16 | 17 | int main() { 18 | int val = __lamp_any_i32(); 19 | auto fn = val < 0 ? &foo : &bar; 20 | fn( val ); 21 | } 22 | -------------------------------------------------------------------------------- /test/basic/compare-c.c: -------------------------------------------------------------------------------- 1 | // RUN: %testrun %lartcc term -lz3 %s -o %t | %filecheck %s 2 | // RUN: %testrun %lartcc unit %s -o %t | %filecheck %s 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #include "utils.h" 9 | 10 | int foo() { return 0; } 11 | 12 | int main() { 13 | uint64_t x = __lamp_any_i64(); 14 | assert( x != foo() ); // CHECK: assertion x != foo() failed 15 | } 16 | -------------------------------------------------------------------------------- /.dockerignore: -------------------------------------------------------------------------------- 1 | **/.classpath 2 | **/.dockerignore 3 | **/.env 4 | **/.git 5 | **/.gitignore 6 | **/.project 7 | **/.settings 8 | **/.toolstarget 9 | **/.vs 10 | **/.vscode 11 | **/*.*proj.user 12 | **/*.dbmdl 13 | **/*.jfm 14 | **/azds.yaml 15 | **/bin 16 | **/charts 17 | **/docker-compose* 18 | **/Dockerfile* 19 | **/node_modules 20 | **/npm-debug.log 21 | **/obj 22 | **/secrets.dev.yaml 23 | **/values.dev.yaml 24 | README.md -------------------------------------------------------------------------------- /test/basic/mem-b.c: -------------------------------------------------------------------------------- 1 | // RUN: %testrun %lartcc term -lz3 %s -o %t | %filecheck %s 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include "utils.h" 8 | 9 | int main() { 10 | int x = __lamp_any_i32(); 11 | if ( x == 0 ) { 12 | short *a = (short*) &x; 13 | ++(*a); 14 | assert( *a == 1 ); 15 | } 16 | REACHABLE // CHECK-COUNT-2: lart-reachable 17 | } 18 | -------------------------------------------------------------------------------- /test/basic/call-g.c: -------------------------------------------------------------------------------- 1 | // RUN: %testrun %lartcc term -lz3 %s -o %t | %filecheck %s 2 | 3 | #include 4 | #include 5 | 6 | #include "utils.h" 7 | 8 | int id( int a ) { return a; } 9 | 10 | int plus( int a, int b ) { return id( a ) + id( b ); } 11 | 12 | int main() { 13 | int input = __lamp_any_i32(); 14 | assert( plus( input, 10 ) == input + 10 ); 15 | // CHECK-NOT: assertion {{.*}} failed 16 | } 17 | -------------------------------------------------------------------------------- /test/basic/join-a.c: -------------------------------------------------------------------------------- 1 | // RUN: %testrun %lartcc trivial %s -o %t | %filecheck %s 2 | // RUN: %testrun %lartcc unit %s -o %t | %filecheck %s 3 | 4 | #include 5 | #include 6 | #include 7 | #include "utils.h" 8 | 9 | int main() { 10 | uint8_t x = __lamp_any_i8(); 11 | uint8_t y = __lamp_lift_i8( 10 ); 12 | uint8_t z = x + y; 13 | assert( x != z ); // CHECK: assertion x != z failed 14 | } 15 | -------------------------------------------------------------------------------- /test/pa/compare-b.c: -------------------------------------------------------------------------------- 1 | // RUN: %testrun %lartcc pa -lz3 %s -o %t | %filecheck %s 2 | // REQUIRES: pa 3 | 4 | #include 5 | #include 6 | 7 | #include "utils.h" 8 | 9 | int main() 10 | { 11 | struct S { int x, y; } s; 12 | int *a = ( int * )__lamp_lift_objid( &s.x ); 13 | int *b = ( int * )__lamp_lift_objid( &s.y ); 14 | assert( b > a ); 15 | REACHABLE // CHECK: lart-reachable 16 | } 17 | -------------------------------------------------------------------------------- /test/basic/call-c.c: -------------------------------------------------------------------------------- 1 | // RUN: %testrun %lartcc term -lz3 %s -o %t | %filecheck %s 2 | 3 | #include 4 | #include "utils.h" 5 | 6 | void fn(int i, int j) { 7 | if (i) { 8 | REACHABLE 9 | } 10 | if (j) { 11 | REACHABLE 12 | } 13 | } 14 | 15 | int main() { 16 | int x = 0; 17 | int y = __lamp_any_i32(); 18 | fn(x, y); 19 | fn(y, x); 20 | // CHECK-COUNT-2: lart-reachable 21 | } 22 | -------------------------------------------------------------------------------- /test/basic/addr-fun-c.c: -------------------------------------------------------------------------------- 1 | // TODO: 2 | #include 3 | #include 4 | 5 | #include 6 | #include 7 | 8 | int foo( int val ) { 9 | return val; 10 | } 11 | 12 | extern int ibari( int val ); 13 | 14 | int main() { 15 | int val = __lamp_any_i32(); 16 | if ( val < 0 ) { 17 | auto fn = val < 0 ? &foo : &ibari; 18 | int ret = fn( val ); 19 | assert( val < 0 ); 20 | } 21 | } -------------------------------------------------------------------------------- /test/basic/call-h.c: -------------------------------------------------------------------------------- 1 | // TODO: %testrun %lartcc term -lz3 %s -o %t | %filecheck %s 2 | 3 | #include 4 | #include 5 | 6 | #include "utils.h" 7 | 8 | // test output argument 9 | void init( int *i, int v ) { *i = v; } 10 | 11 | int main() { 12 | int val = __lamp_any_i32(); 13 | int i; 14 | 15 | init( &i, val ); 16 | 17 | assert( i == val ); 18 | 19 | // CHECK-NOT: assertion {{.*}} failed 20 | } 21 | -------------------------------------------------------------------------------- /test/basic/mem-c.c: -------------------------------------------------------------------------------- 1 | // RUN: %testrun %lartcc term -lz3 %s -o %t | %filecheck %s 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include "utils.h" 8 | 9 | void plus(int *a) { 10 | *a += 1; 11 | } 12 | 13 | int main() { 14 | int x = __lamp_any_i32(); 15 | if ( x == 0 ) { 16 | plus(&x); 17 | assert( x == 1 ); 18 | } 19 | REACHABLE // CHECK-COUNT-2: lart-reachable 20 | } 21 | -------------------------------------------------------------------------------- /test/pa/compare-c.c: -------------------------------------------------------------------------------- 1 | // RUN: %testrun %lartcc pa -lz3 %s -o %t | %filecheck %s 2 | // REQUIRES: pa 3 | 4 | #include 5 | #include 6 | #include "utils.h" 7 | 8 | noinline void test( int * a, int * b ) { assert( a == b ); } 9 | 10 | int main() 11 | { 12 | int * x = (int *)__lamp_lift_objid( malloc( sizeof(int) ) ); 13 | test( x, x ); 14 | free( x ); 15 | REACHABLE // CHECK: lart-reachable 16 | } 17 | -------------------------------------------------------------------------------- /test/basic/cast-k.c: -------------------------------------------------------------------------------- 1 | // RUN: %testrun %lartcc term -lz3 %s -o %t | %filecheck %s 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "utils.h" 9 | 10 | int main() { 11 | int x = __lamp_any_i32(); 12 | if ( x >= SHRT_MIN && x <= SHRT_MAX ) { 13 | short y = (short)x; 14 | assert( x == y ); 15 | } 16 | 17 | REACHABLE // CHECK-COUNT-2: lart-reachable 18 | } 19 | -------------------------------------------------------------------------------- /test/basic/compare-e.c: -------------------------------------------------------------------------------- 1 | // RUN: %testrun %lartcc term -lz3 %s -o %t | %filecheck %s 2 | // RUN: %testrun %lartcc unit %s -o %t | %filecheck %s 3 | 4 | #include 5 | #include 6 | 7 | #include 8 | #include "utils.h" 9 | 10 | uint32_t __lamp_any_i32(void); // test bitcast from different function type 11 | 12 | int main() { 13 | int x = __lamp_any_i32(); 14 | assert( x <= 0 ); // CHECK: assertion x <= 0 failed 15 | } 16 | -------------------------------------------------------------------------------- /test/basic/mem-d.c: -------------------------------------------------------------------------------- 1 | // RUN: %testrun %lartcc term -lz3 %s -o %t | %filecheck %s 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include "utils.h" 8 | 9 | int plus(int *a) { 10 | *a += 1; 11 | return *a; 12 | } 13 | 14 | int main() { 15 | int *a; 16 | int x = __lamp_any_i32(); 17 | a = &x; 18 | int r = plus(a); 19 | assert( x == r ); 20 | REACHABLE // CHECK-COUNT-1: lart-reachable 21 | } 22 | -------------------------------------------------------------------------------- /test/pa/nondet-c.c: -------------------------------------------------------------------------------- 1 | // RUN: %testrun %lartcc pa -lz3 %s -o %t | %filecheck %s 2 | // REQUIRES: pa 3 | 4 | #include 5 | #include 6 | #include "utils.h" 7 | 8 | int main() 9 | { 10 | int *val = (int*)malloc(4); 11 | int *ptr = (int*)__lamp_any_ptr(); 12 | if (val == ptr) { 13 | assert(ptr == val); 14 | REACHABLE // CHECK: lart-reachable 15 | } 16 | REACHABLE // CHECK: lart-reachable 17 | } 18 | -------------------------------------------------------------------------------- /test/basic/arith-a.c: -------------------------------------------------------------------------------- 1 | // RUN: %testrun %lartcc term -lz3 %s -o %t | %filecheck %s 2 | 3 | #include 4 | #include 5 | 6 | #include "utils.h" 7 | 8 | int plus( int a, int b ) { return a + b; } 9 | 10 | int main() { 11 | int a = __lamp_any_i32(); 12 | int b = plus( a, 10 ); 13 | assert( b == a + 10 ); 14 | 15 | int c = plus( 10, a ); 16 | assert( c == 10 + a ); 17 | 18 | // CHECK-NOT: assertion {{.*}} failed 19 | } 20 | -------------------------------------------------------------------------------- /test/basic/any-b.c: -------------------------------------------------------------------------------- 1 | // RUN: %testrun %lartcc term -lz3 %s -o %t | %filecheck %s 2 | 3 | #include 4 | #include 5 | 6 | #include "utils.h" 7 | 8 | int main() { 9 | uint8_t x = __lamp_any_i8(); 10 | uint8_t y = __lamp_any_i8(); 11 | if ( x < y ) { 12 | if ( x > y ) { 13 | UNREACHABLE 14 | } 15 | REACHABLE 16 | } 17 | // CHECK-NOT: lart-unreachable 18 | // CHECK: lart-reachable 19 | } 20 | -------------------------------------------------------------------------------- /test/basic/bool-arith-c.c: -------------------------------------------------------------------------------- 1 | // RUN: %testrun %lartcc term -lz3 %s -o %t | %filecheck %s 2 | // RUN: %testrun %lartcc unit %s -o %t | %filecheck %s 3 | 4 | #include 5 | #include "utils.h" 6 | 7 | #include 8 | #include 9 | 10 | int main() 11 | { 12 | bool a = __lamp_any_i1(); 13 | bool b = __lamp_any_i1(); 14 | int test = (int)a == b; 15 | test += 1; 16 | assert( test == 2 ); // CHECK: assertion test == 2 failed 17 | } 18 | -------------------------------------------------------------------------------- /test/basic/compare-b.c: -------------------------------------------------------------------------------- 1 | // RUN: %testrun %lartcc term -lz3 %s -o %t | %filecheck %s 2 | // RUN: %testrun %lartcc unit %s -o %t | %filecheck %s 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #include "utils.h" 9 | 10 | int main() { 11 | uint64_t x = __lamp_any_i64(); 12 | uint64_t y = __lamp_any_i64(); 13 | 14 | y = 0; 15 | 16 | assert( y == 0 ); 17 | assert( x != y ); // CHECK: assertion x != y failed 18 | } 19 | -------------------------------------------------------------------------------- /test/basic/float-a.c: -------------------------------------------------------------------------------- 1 | /* TAGS: sym c++ float todo */ 2 | /* VERIFY_OPTS: --symbolic */ 3 | /* CC_OPTS: */ 4 | 5 | // V: v.O0 CC_OPT: -O0 TAGS: min 6 | // V: v.O1 CC_OPT: -O1 7 | // V: v.O2 CC_OPT: -O2 8 | // V: v.Os CC_OPT: -Os 9 | #include 10 | #include 11 | 12 | #include 13 | #include 14 | 15 | int main() { 16 | float x = __lamp_any_float32(); 17 | float y = 0; 18 | if ( x != 0 ) 19 | assert( x != y ); 20 | } 21 | -------------------------------------------------------------------------------- /test/basic/call-f.c: -------------------------------------------------------------------------------- 1 | // RUN: %testrun %lartcc term -lz3 %s -o %t | %filecheck %s 2 | 3 | #include 4 | #include 5 | 6 | #include "utils.h" 7 | 8 | int plus( int a, int b ) { return a + b; } 9 | 10 | int main() { 11 | int a = __lamp_any_i32(); 12 | int b = __lamp_any_i32(); 13 | assert( plus( a, 10 ) == a + 10 ); 14 | assert( plus( 10, b ) == 10 + b ); 15 | assert( plus( a, b ) == a + b ); 16 | REACHABLE // CHECK: lart-reachable 17 | } 18 | -------------------------------------------------------------------------------- /test/basic/array-a.c: -------------------------------------------------------------------------------- 1 | // RUN: %testrun %lartcc term -lz3 %s -o %t | %filecheck %s 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "utils.h" 9 | 10 | int main() { 11 | uint64_t array[ 4 ] = { 1, 2, 3, 4 }; 12 | array[ 0 ] = __lamp_any_i64(); 13 | 14 | if ( array[ 0 ] > array[ 3 ] ) { 15 | assert( array[ 0 ] - array[ 3 ] > 0 ); 16 | } 17 | REACHABLE // CHECK-COUNT-2: lart-reachable 18 | } 19 | -------------------------------------------------------------------------------- /test/basic/array-c.c: -------------------------------------------------------------------------------- 1 | /* TAGS: error sym c++ */ 2 | /* VERIFY_OPTS: --symbolic */ 3 | /* CC_OPTS: */ 4 | 5 | // V: v.O0 CC_OPT: -O0 TAGS: error min 6 | // V: v.O1 CC_OPT: -O1 7 | // V: v.O2 CC_OPT: -O2 8 | // V: v.Os CC_OPT: -Os 9 | #include 10 | #include 11 | 12 | #include 13 | #include 14 | 15 | int main() { 16 | uint64_t array[ 4 ] = { 0 }; 17 | uint64_t x = __lamp_any_i64(); 18 | assert( x == array[ 0 ] ); /* ERROR */ 19 | } 20 | -------------------------------------------------------------------------------- /test/basic/array-d.c: -------------------------------------------------------------------------------- 1 | /* TAGS: sym c++ */ 2 | /* VERIFY_OPTS: --symbolic */ 3 | /* CC_OPTS: */ 4 | 5 | // V: v.O0 CC_OPT: -O0 TAGS: min 6 | // V: v.O1 CC_OPT: -O1 7 | // V: v.O2 CC_OPT: -O2 8 | // V: v.Os CC_OPT: -Os 9 | #include 10 | #include 11 | 12 | #include 13 | #include 14 | 15 | int main() { 16 | uint64_t array[ 4 ] = { 0 }; 17 | uint64_t x = __lamp_any_i64(); 18 | array[ 2 ] = x; 19 | assert( array[ 2 ] == x ); 20 | } 21 | -------------------------------------------------------------------------------- /test/basic/cast-l.c: -------------------------------------------------------------------------------- 1 | // RUN: %testrun %lartcc term -lz3 %s -o %t | %filecheck %s 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "utils.h" 9 | 10 | int main() { 11 | int x = __lamp_any_i32(); 12 | if ( x >= SHRT_MIN && x < SHRT_MAX ) { 13 | short y = (short)x; 14 | y++; 15 | x++; 16 | assert( x == y ); 17 | } 18 | 19 | REACHABLE // CHECK-COUNT-2: lart-reachable 20 | } 21 | -------------------------------------------------------------------------------- /test/basic/float-c.c: -------------------------------------------------------------------------------- 1 | /* TAGS: sym c++ float todo */ 2 | /* VERIFY_OPTS: --symbolic */ 3 | /* CC_OPTS: */ 4 | 5 | // V: v.O0 CC_OPT: -O0 TAGS: min 6 | // V: v.O1 CC_OPT: -O1 7 | // V: v.O2 CC_OPT: -O2 8 | // V: v.Os CC_OPT: -Os 9 | #include 10 | #include 11 | 12 | #include 13 | #include 14 | 15 | int main() { 16 | float x = __lamp_any_float32(); 17 | float y = 3.14f; 18 | float z = x + y; 19 | assert( z == x + 3.14f ); 20 | } 21 | -------------------------------------------------------------------------------- /test/basic/funptr.c: -------------------------------------------------------------------------------- 1 | /* TAGS: todo */ 2 | /* VERIFY_OPTS: --symbolic */ 3 | #include 4 | #include 5 | #include 6 | 7 | int indirect_add( int a, int b ) 8 | { 9 | return a + b; 10 | } 11 | 12 | int (*add)() = 0; 13 | 14 | int main() 15 | { 16 | add = indirect_add; 17 | 18 | int a = __lamp_any_i32(); 19 | int b = 1; 20 | 21 | if ( a > 0 && a < 100 ) 22 | assert( add( a, b ) > 1 ); 23 | else 24 | return 0; 25 | } 26 | -------------------------------------------------------------------------------- /test/basic/cast-d.c: -------------------------------------------------------------------------------- 1 | // TODO: %testrun %lartcc term -lz3 %s -o %t | %filecheck %s 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | int main() { 8 | union { 9 | int x; 10 | short y; 11 | } u; 12 | 13 | u.x = (int)__lamp_any_i32(); 14 | 15 | if ( (short)u.x < 0 ) 16 | return 0; 17 | ++u.y; 18 | assert( u.y == -32768 || u.y >= 1 ); 19 | assert( u.y != -32768 ); // CHECK: assertion u.y != -32768 failed 20 | } 21 | -------------------------------------------------------------------------------- /test/basic/cast-e.c: -------------------------------------------------------------------------------- 1 | // TODO: %testrun %lartcc term -lz3 %s -o %t | %filecheck %s 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | int main() { 8 | union { 9 | int x; 10 | short y; 11 | } u; 12 | 13 | u.y = (int)__lamp_any_i32(); 14 | 15 | if ( (short) u.x < 0 ) 16 | return 0; 17 | ++u.y; 18 | assert( u.y == -32768 || u.y >= 1 ); 19 | assert( u.y != -32768 ); // CHECK: assertion u.y != -32768 failed 20 | } 21 | -------------------------------------------------------------------------------- /test/basic/bool-arith-b.c: -------------------------------------------------------------------------------- 1 | // RUN: %testrun %lartcc term -lz3 %s -o %t | %filecheck %s 2 | // RUN: %testrun %lartcc unit %s -o %t | %filecheck %s 3 | 4 | #include 5 | #include "utils.h" 6 | 7 | #include 8 | #include 9 | 10 | int main() 11 | { 12 | int a = __lamp_any_i32(); 13 | int b = __lamp_any_i32(); 14 | bool check = a == b; 15 | 16 | bool boolean = __lamp_any_i1(); 17 | assert( check & boolean ); // CHECK: assertion check & boolean failed 18 | } -------------------------------------------------------------------------------- /test/basic/cast-g.c: -------------------------------------------------------------------------------- 1 | // RUN: %testrun %lartcc term -lz3 %s -o %t | %filecheck %s 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | 8 | int nondet() { 9 | return (int)__lamp_any_i32(); 10 | } 11 | 12 | int main() { 13 | int x = nondet(); 14 | if ( (short) x < 0 ) 15 | return 0; 16 | short y = *(short *)( &x ); 17 | ++y; 18 | assert( y == -32768 || y >= 1 ); 19 | assert( y != -32768 ); // CHECK: assertion y != -32768 failed 20 | } 21 | -------------------------------------------------------------------------------- /test/basic/cast-h.c: -------------------------------------------------------------------------------- 1 | // TODO: %testrun %lartcc term -lz3 %s -o %t | %filecheck %s 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | int nondet() { 8 | return __lamp_any_i32(); 9 | } 10 | 11 | int main() { 12 | int x; 13 | x = nondet(); 14 | if ( x < 0 ) 15 | return 0; 16 | short *y = ( short * )( &x ); 17 | *y = 0; 18 | ++(*y); 19 | assert( *y == 1 ); 20 | assert( x == 0 ); // CHECK: assertion x == 0 failed 21 | } 22 | 23 | -------------------------------------------------------------------------------- /test/basic/call-d.c: -------------------------------------------------------------------------------- 1 | // RUN: %testrun %lartcc term -lz3 %s -o %t | %filecheck %s 2 | 3 | #include 4 | #include "utils.h" 5 | 6 | int fn(int i, int j) { 7 | if (j) 8 | return j; 9 | return i; 10 | } 11 | 12 | int main() { 13 | int x = 0; 14 | int y = __lamp_any_i32(); 15 | if (fn(x, y)) { 16 | REACHABLE 17 | if (fn(!y, x)) 18 | UNREACHABLE 19 | } 20 | // CHECK-NOT: lart-unreachable 21 | // CHECK-COUNT-1: lart-reachable 22 | } 23 | -------------------------------------------------------------------------------- /ports/svf/vcpkg.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "svf", 3 | "version": "2.4.0", 4 | "description": "A source code analysis tool that enables interprocedural dependence analysis", 5 | "homepage": "https://github.com/SVF-tools/SVF", 6 | "license": "GPL-3.0", 7 | "dependencies": [ 8 | { 9 | "name": "vcpkg-cmake", 10 | "host": true 11 | }, 12 | { 13 | "name": "vcpkg-cmake-config", 14 | "host": true 15 | } 16 | ] 17 | } 18 | -------------------------------------------------------------------------------- /test/basic/cast-i.c: -------------------------------------------------------------------------------- 1 | // RUN: %testrun %lartcc term -lz3 %s -o %t | %filecheck %s 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | int nondet() { 8 | return __lamp_any_i32(); 9 | } 10 | 11 | int main() { 12 | int x; 13 | x = nondet(); 14 | if ( x < 0 ) 15 | return 0; 16 | short *y = ( short * )( &x ); 17 | *y = 0; 18 | ++(*y); 19 | assert( *y == 1 ); 20 | assert( x <= 0x7fff0001 ); // CHECK: assertion x <= 0x7fff0001 failed 21 | } 22 | -------------------------------------------------------------------------------- /test/basic/bool-arith-d.c: -------------------------------------------------------------------------------- 1 | // RUN: %testrun %lartcc term -lz3 %s -o %t | %filecheck %s 2 | 3 | #include 4 | #include 5 | 6 | 7 | int nondet() { 8 | return (int)__lamp_any_i32(); 9 | } 10 | 11 | int main() { 12 | int x = nondet(); 13 | if ( (short) x < 0 ) 14 | return 0; 15 | short y = *(short *)( &x ); 16 | __lamp_dump(&y); 17 | // CHECK: ((_ extract 15 0) var_1) 18 | y++; 19 | __lamp_dump(&y); 20 | // CHECK: (bvadd ((_ extract 15 0) var_1) #x0001) 21 | } 22 | -------------------------------------------------------------------------------- /test/basic/any-c.c: -------------------------------------------------------------------------------- 1 | // RUN: %testrun %lartcc term -lz3 %s -o %t | %filecheck %s 2 | // RUN: %testrun %lartcc unit %s -o %t | %filecheck %s 3 | 4 | #include 5 | #include 6 | 7 | #include "utils.h" 8 | 9 | int main() 10 | { 11 | uint8_t a = __lamp_any_i8(); 12 | uint16_t b = __lamp_any_i16(); 13 | uint32_t c = __lamp_any_i32(); 14 | uint64_t d = __lamp_any_i64(); 15 | 16 | float e = __lamp_any_f32(); 17 | double f = __lamp_any_f64(); 18 | REACHABLE // CHECK: lart-reachable 19 | } 20 | 21 | -------------------------------------------------------------------------------- /test/basic/float-b.c: -------------------------------------------------------------------------------- 1 | /* TAGS: error sym c++ float todo */ 2 | /* VERIFY_OPTS: --symbolic */ 3 | /* CC_OPTS: */ 4 | 5 | // V: v.O0 CC_OPT: -O0 TAGS: error min 6 | // V: v.O1 CC_OPT: -O1 7 | // V: v.O2 CC_OPT: -O2 8 | // V: v.Os CC_OPT: -Os 9 | #include 10 | #include 11 | 12 | #include 13 | #include 14 | 15 | int main() { 16 | float x = __lamp_any_float32(); 17 | float y = __lamp_any_float32(); 18 | 19 | float z = x + y; // test addition 20 | assert( z == y ); /* ERROR */ 21 | } 22 | -------------------------------------------------------------------------------- /test/pa/compare-d.c: -------------------------------------------------------------------------------- 1 | // RUN: %testrun %lartcc pa -lz3 %s -o %t | %filecheck %s 2 | // REQUIRES: pa 3 | 4 | #include 5 | #include 6 | #include "utils.h" 7 | 8 | noinline void test( char * a, char * b ) { assert( a != b ); } 9 | 10 | int main() 11 | { 12 | char * x = (char *)__lamp_lift_objid( malloc(1) ); 13 | char * y = (char *)__lamp_lift_objid( malloc(1) ); 14 | if ( x && y ) 15 | test( x, y ); 16 | free( x ); 17 | free( y ); 18 | REACHABLE // CHECK: lart-reachable 19 | } 20 | -------------------------------------------------------------------------------- /scripts/svcomp/utils/log.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import logging 4 | import sys 5 | 6 | def logger(): 7 | return logging.getLogger('root') 8 | 9 | 10 | def error(msg: str) -> None: 11 | logger().error(msg) 12 | sys.exit() 13 | 14 | def setup_logger(): 15 | formatter = logging.Formatter(fmt='%(levelname)s: %(message)s') 16 | 17 | handler = logging.StreamHandler() 18 | handler.setFormatter(formatter) 19 | 20 | logger = logging.getLogger('root') 21 | logger.addHandler(handler) 22 | return logger 23 | -------------------------------------------------------------------------------- /test/basic/call-i.c: -------------------------------------------------------------------------------- 1 | // TODO: %testrun %lartcc term -lz3 %s -o %t | %filecheck %s 2 | 3 | #include 4 | #include 5 | 6 | #include "utils.h" 7 | 8 | int* init_and_pass( int* val ) { 9 | *val = __lamp_any_i32(); 10 | return val; 11 | } 12 | 13 | int process( int* addr ) { 14 | auto ret = init_and_pass( addr ); 15 | return *ret; 16 | } 17 | 18 | int main() { 19 | int i; 20 | int j = process( &i ); 21 | assert( i == j ); 22 | 23 | // CHECK-NOT: assertion {{.*}} failed 24 | } 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /test/basic/input-arg-a.c: -------------------------------------------------------------------------------- 1 | /* TAGS: sym c++ */ 2 | /* VERIFY_OPTS: --symbolic */ 3 | /* CC_OPTS: */ 4 | 5 | // V: v.O0 CC_OPT: -O0 TAGS: min 6 | // V: v.O1 CC_OPT: -O1 TAGS: min 7 | #include 8 | #include 9 | #include 10 | 11 | #define INLINE __attribute__((__noinline__)) 12 | 13 | INLINE int choose( int a, int b ) { return ( __lamp_any_i8() ) ? a : b; } 14 | 15 | int main() { 16 | int one = __lamp_any_i32(); 17 | int chosen = choose( one, one ); 18 | assert( chosen == one ); 19 | } 20 | 21 | #undef INLINE 22 | -------------------------------------------------------------------------------- /test/pa/decompose-a.c: -------------------------------------------------------------------------------- 1 | // RUN: %testrun %lartcc pa -lz3 %s -o %t | %filecheck %s 2 | // REQUIRES: pa 3 | 4 | #include 5 | #include 6 | #include 7 | #include "utils.h" 8 | 9 | int main() 10 | { 11 | int val = 42; 12 | int *ptr = (int*)__lamp_lift_objid( &val ); 13 | uint32_t hi = (uintptr_t)(ptr) >> 32; 14 | uint32_t lo = (uintptr_t)(ptr) & 0x00000000FFFFFFFF; 15 | int *res = (int *)(((uintptr_t)hi << 32) | lo); 16 | assert( *res == val ); 17 | REACHABLE // CHECK: lart-reachable 18 | } 19 | -------------------------------------------------------------------------------- /test/basic/array-f.c: -------------------------------------------------------------------------------- 1 | /* TAGS: sym c++ min todo */ 2 | /* VERIFY_OPTS: --symbolic */ 3 | #include 4 | #include 5 | 6 | #include 7 | #include 8 | 9 | int main() { 10 | uint8_t array[ 4 ] = { 0 }; 11 | uint8_t x = __lamp_any_i8(); 12 | array[ 1 ] = x; 13 | 14 | uint32_t val = *reinterpret_cast< uint32_t * >( array ); 15 | assert( ( val & 0xff ) == 0 ); 16 | assert( ( ( val >> 8 ) & 0xff ) == x ); 17 | assert( ( ( val >> 16 ) & 0xff ) == 0 ); 18 | assert( ( ( val >> 24 ) & 0xff ) == 0 ); 19 | } -------------------------------------------------------------------------------- /test/basic/float-d.c: -------------------------------------------------------------------------------- 1 | /* TAGS: error sym c++ float todo */ 2 | /* VERIFY_OPTS: --symbolic */ 3 | /* CC_OPTS: */ 4 | 5 | // V: v.O0 CC_OPT: -O0 TAGS: error min 6 | // V: v.O1 CC_OPT: -O1 7 | // V: v.O2 CC_OPT: -O2 8 | // V: v.Os CC_OPT: -Os 9 | #include 10 | #include 11 | 12 | #include 13 | #include 14 | 15 | int main() { 16 | float x = __lamp_any_float32(); // float 17 | double y = __lamp_any_float64(); // double 18 | 19 | double f = static_cast< double >( x ); 20 | assert( f == y ); /* ERROR */ 21 | } 22 | -------------------------------------------------------------------------------- /test/basic/cast-f.c: -------------------------------------------------------------------------------- 1 | // RUN: %testrun %lartcc term -lz3 %s -o %t | %filecheck %s 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | int nondet() 8 | { 9 | return __lamp_any_i32(); 10 | } 11 | 12 | int main() 13 | { 14 | union 15 | { 16 | int x; 17 | short y; 18 | }u; 19 | 20 | u.x = nondet(); 21 | 22 | if ( (short) u.x < 0 ) 23 | return 0; 24 | ++u.y; 25 | 26 | assert( u.y == -32768 || u.y >= 1 ); 27 | assert( u.y != -32768 ); // CHECK: assertion u.y != -32768 failed 28 | } 29 | -------------------------------------------------------------------------------- /test/basic/float-e.c: -------------------------------------------------------------------------------- 1 | /* TAGS: sym c++ float todo */ 2 | /* VERIFY_OPTS: --symbolic -o nofail:malloc */ 3 | /* CC_OPTS: */ 4 | 5 | // V: v.O0 CC_OPT: -O0 TAGS: min 6 | // V: v.O1 CC_OPT: -O1 7 | // V: v.O2 CC_OPT: -O2 8 | // V: v.Os CC_OPT: -Os 9 | #include 10 | #include 11 | 12 | #include 13 | #include 14 | #include 15 | 16 | int main() { 17 | float * a = static_cast< float * >( malloc( sizeof( float ) ) ); 18 | float y = __lamp_any_float32(); 19 | *a = y; 20 | assert( *a == y ); 21 | free( a ); 22 | } 23 | -------------------------------------------------------------------------------- /test/basic/array-b.c: -------------------------------------------------------------------------------- 1 | /* TAGS: error sym c++ */ 2 | /* VERIFY_OPTS: --symbolic */ 3 | /* CC_OPTS: */ 4 | 5 | // V: v.O0 CC_OPT: -O0 TAGS: error min 6 | #include 7 | #include 8 | 9 | #include 10 | #include 11 | 12 | __attribute__(( __noinline__)) int id ( int a ) { return a; } 13 | 14 | int main() { 15 | uint64_t array[ 4 ]; 16 | for ( int i = 0; i < 4; ++i ) 17 | array[ i ] = __lamp_any_i64(); 18 | if ( array[ 4 ] ) /* ERROR */ // this is undefined behaviour, it is optimized out with -O2 19 | return id( 0 ); 20 | return id( 1 ); 21 | } 22 | -------------------------------------------------------------------------------- /test/basic/array-e.c: -------------------------------------------------------------------------------- 1 | /* TAGS: sym c++ */ 2 | /* VERIFY_OPTS: --symbolic */ 3 | /* CC_OPTS: */ 4 | 5 | // V: v.O0 CC_OPT: -O0 TAGS: min 6 | // V: v.O1 CC_OPT: -O1 7 | // V: v.O2 CC_OPT: -O2 TAGS: min 8 | // V: v.Os CC_OPT: -Os 9 | #include 10 | #include 11 | 12 | #include 13 | #include 14 | 15 | int main() { 16 | uint32_t array[ 2 ] = { 0 }; 17 | uint32_t x = __lamp_any_i32(); 18 | array[ 0 ] = x; 19 | 20 | uint64_t val = *reinterpret_cast< uint64_t * >( array ); 21 | assert( array[ 0 ] == val ); 22 | assert( array[ 1 ] == val >> 32 ); 23 | } 24 | -------------------------------------------------------------------------------- /runtime/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_subdirectory( native ) 2 | 3 | add_library( runtime INTERFACE ) 4 | 5 | set( RUNTIME_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/native PARENT_SCOPE ) 6 | 7 | set_target_properties( runtime PROPERTIES PUBLIC_HEADER 8 | "include/runtime/lart.h;include/runtime/shadow.hpp" 9 | ) 10 | 11 | target_include_directories( runtime 12 | INTERFACE 13 | $ 14 | ${CMAKE_CURRENT_SOURCE_DIR}/include 15 | ) 16 | 17 | install(TARGETS runtime 18 | RUNTIME DESTINATION bin 19 | LIBRARY DESTINATION lib 20 | ARCHIVE DESTINATION lib 21 | PUBLIC_HEADER DESTINATION include 22 | ) 23 | -------------------------------------------------------------------------------- /scripts/benchmark/verify.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | domain=$1 6 | 7 | RED='\033[0;31m' 8 | NC='\033[0m' # No Color 9 | 10 | if [ -z $domain ]; then 11 | echo -e "${RED}[LART ERROR]${NC} No domain provided. Please specify a domain name." 12 | exit 1 13 | fi 14 | 15 | trace_file="trace.out" 16 | 17 | export LART_NO_FAIL_MODE=ON 18 | export LART_TRACE_FILE=$trace_file 19 | 20 | lartcc $domain ${@:2} -o abstracted 21 | 22 | ./abstracted 23 | 24 | if [ -s $trace_file ]; then 25 | echo {\"result\": \"`cat $trace_file`\"} > /artefact/results.json 26 | else 27 | echo {\"result\": \"correct\"} > /artefact/results.json 28 | fi 29 | -------------------------------------------------------------------------------- /test/basic/freeze-into-other-a.c: -------------------------------------------------------------------------------- 1 | /* TAGS: sym c++ */ 2 | /* VERIFY_OPTS: --symbolic */ 3 | /* CC_OPTS: */ 4 | 5 | // V: v.O0 CC_OPT: -O0 TAGS: min 6 | // V: v.O1 CC_OPT: -O1 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | int main() { 13 | int8_t arr[128] = { 0 }; 14 | int32_t *i32ptr = ( int32_t * ) arr; 15 | int64_t *i64ptr = ( int64_t * ) arr; 16 | 17 | i64ptr[ 1 ] = __lamp_any_i64(); 18 | int32_t expected = i32ptr[ 3 ]; 19 | 20 | i32ptr[ 2 ] = __lamp_any_i32(); 21 | 22 | assert( i32ptr[ 3 ] == expected ); 23 | assert( i32ptr[ 2 ] != expected ); /* ERROR */ 24 | } 25 | -------------------------------------------------------------------------------- /test/basic/freeze-into-other-b.c: -------------------------------------------------------------------------------- 1 | /* TAGS: sym c++ */ 2 | /* VERIFY_OPTS: --symbolic */ 3 | /* CC_OPTS: */ 4 | 5 | // V: v.O0 CC_OPT: -O0 TAGS: min 6 | // V: v.O1 CC_OPT: -O1 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | int main() { 13 | int8_t arr[128] = { 0 }; 14 | int32_t *i32ptr = ( int32_t * ) arr; 15 | int64_t *i64ptr = ( int64_t * ) arr; 16 | 17 | i64ptr[ 0 ] = __lamp_any_i64(); 18 | int32_t expected = i32ptr[ 1 ]; 19 | 20 | i32ptr[ 0 ] = __lamp_any_i32(); 21 | 22 | assert( i32ptr[ 1 ] == expected ); 23 | assert( i32ptr[ 0 ] != expected ); /* ERROR */ 24 | } 25 | -------------------------------------------------------------------------------- /test/pa/store-c.cpp: -------------------------------------------------------------------------------- 1 | // RUN: %testrun %lartcc++ pa -lz3 %s -o %t | %filecheck %s 2 | // REQUIRES: pa 3 | 4 | #include 5 | #include 6 | #include "utils.h" 7 | 8 | struct node 9 | { 10 | int val; 11 | node * next = nullptr; 12 | }; 13 | 14 | int main() 15 | { 16 | node a{ .val = 1 }, b{ .val = 2 }; 17 | auto ap = (node *)__lamp_lift_objid( &a ); 18 | auto bp = (node *)__lamp_lift_objid( &b ); 19 | ap->next = bp; 20 | assert( ap->val == 1 ); 21 | assert( ap->next == bp ); 22 | assert( ap->next->val == 2 ); 23 | assert( ap->next->next == nullptr ); 24 | REACHABLE // CHECK: lart-reachable 25 | } 26 | -------------------------------------------------------------------------------- /test/pa/decompose-b.c: -------------------------------------------------------------------------------- 1 | // RUN: %testrun %lartcc pa -lz3 %s -o %t | %filecheck %s 2 | // REQUIRES: pa 3 | 4 | #include 5 | #include 6 | #include 7 | #include "utils.h" 8 | 9 | int main() 10 | { 11 | int val; 12 | int* ptr = (int*)__lamp_lift_objid( &val ); 13 | *ptr = 10; 14 | uint32_t hi = (uintptr_t)(ptr) >> 32; 15 | uint32_t lo = (uintptr_t)(ptr) & 0x00000000FFFFFFFF; 16 | 17 | uint32_t* hip = (uint32_t*)__lamp_lift_objid( &hi ); 18 | uint32_t* lop = (uint32_t*)__lamp_lift_objid( &lo ); 19 | int* res = (int *)(((uintptr_t)(*hip) << 32) | (*lop)); 20 | assert( res == ptr ); 21 | assert( *res == 10 ); 22 | } 23 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Prerequisites 2 | *.d 3 | 4 | # Compiled Object files 5 | *.slo 6 | *.lo 7 | *.o 8 | *.obj 9 | *.pyc 10 | 11 | # Precompiled Headers 12 | *.gch 13 | *.pch 14 | 15 | # Compiled Dynamic libraries 16 | *.so 17 | *.dylib 18 | *.dll 19 | 20 | # Fortran module files 21 | *.mod 22 | *.smod 23 | 24 | # Compiled Static libraries 25 | *.lai 26 | *.la 27 | *.a 28 | *.lib 29 | 30 | # Executables 31 | *.exe 32 | *.out 33 | *.app 34 | 35 | # Build 36 | build/* 37 | builds/* 38 | build-lart/* 39 | build-runtime/* 40 | .cache/* 41 | 42 | # VS Code 43 | .vscode/ 44 | !.vscode/launch.json 45 | 46 | # CMake 47 | cmake_install.cmake 48 | CMakeCache.txt 49 | CMakeFiles/ 50 | 51 | # install 52 | install/* 53 | 54 | submission/* 55 | 56 | # benchexec 57 | results/* 58 | -------------------------------------------------------------------------------- /test/basic/freeze-in-store.c: -------------------------------------------------------------------------------- 1 | /* TAGS: sym c++ min */ 2 | /* VERIFY_OPTS: --symbolic */ 3 | /* CC_OPTS: */ 4 | 5 | // V: v.O0 CC_OPT: -O0 6 | // V: v.O1 CC_OPT: -O1 7 | // V: v.O2 CC_OPT: -O2 8 | // V: v.Os CC_OPT: -Os 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | int x = 0; 15 | 16 | int *make_abstract( uintptr_t local ) 17 | { 18 | if ( x ) { 19 | local += __lamp_any_i32(); 20 | return ( int * )local; 21 | } 22 | return ( int * )local; 23 | } 24 | 25 | __attribute__((__noinline__)) 26 | int get() { return x; } 27 | 28 | int main() { 29 | int p_local[12]; 30 | int *local = make_abstract( uintptr_t( p_local ) ); 31 | local[2] = 21; 32 | local[3] = get(); 33 | assert( local[3] == x ); 34 | } 35 | -------------------------------------------------------------------------------- /test/pa/xor-swap.cpp: -------------------------------------------------------------------------------- 1 | // RUN: %testrun %lartcc++ pa -lz3 %s -o %t | %filecheck %s 2 | // REQUIRES: pa 3 | 4 | #include 5 | #include 6 | #include 7 | #include "utils.h" 8 | 9 | 10 | void pointer_xor_swap(char **x, char **y) 11 | { 12 | uintptr_t a = (uintptr_t)*x; 13 | uintptr_t b = (uintptr_t)*y; 14 | 15 | a = a ^ b; 16 | b = a ^ b; 17 | a = a ^ b; 18 | 19 | *x = (char*)a; 20 | *y = (char*)b; 21 | } 22 | 23 | int main () { 24 | char * x = (char *)__lamp_lift_objid( malloc(1) ); 25 | char * y = (char *)__lamp_lift_objid( malloc(1) ); 26 | 27 | char * u = x; 28 | char * v = y; 29 | 30 | pointer_xor_swap( &u, &v ); 31 | assert( x == v ); 32 | assert( y == u ); 33 | 34 | free( x ); 35 | free( y ); 36 | } 37 | -------------------------------------------------------------------------------- /scripts/svcomp/setup-submission.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | help() 4 | { 5 | echo "call from lart root directory" 6 | echo "syntax: setup.sh " 7 | } 8 | 9 | if [[ $# -ne 2 ]]; then 10 | echo "wrong arguments supplied" 11 | help 12 | exit 1 13 | fi 14 | 15 | if [[ -L ./lart ]]; then 16 | echo "lart is a symlink!" 17 | exit 1 18 | fi 19 | 20 | LART=$1 21 | DEST=$2 22 | 23 | if [[ -d $DEST ]]; then 24 | echo "$DEST already exists!" 25 | exit 1 26 | fi 27 | 28 | SVCOMP=./scripts/svcomp 29 | 30 | mkdir -p $DEST 31 | mkdir -p $DEST/utils 32 | mkdir -p $DEST/bin 33 | 34 | cp -t $DEST LICENSE $SVCOMP/README $SVCOMP/lart $SVCOMP/__init__.py 35 | cp -r $SVCOMP/utils $DEST 36 | cp -r $LART/bin $DEST 37 | cp -r $LART/include $DEST 38 | cp -r $LART/lib $DEST 39 | -------------------------------------------------------------------------------- /scripts/svcomp/NOTES.md: -------------------------------------------------------------------------------- 1 | ## Test Benchexec 2 | 3 | `python3 -m benchexec.test_tool_info lart --no-container` 4 | 5 | ## Run Tool from Submission File 6 | 7 | To create submission file execute `setup-submission.sh`. 8 | 9 | `./lart --property=/sv-benchmarks/c/properties/unreach-call.prp ` 10 | 11 | 12 | ## Run Benchexec 13 | 14 | from submission folder: 15 | 16 | `benchexec ../scripts/svcomp/benchexec.xml --no-container --tool-directory=./ -T 60 -t ReachSafety-BitVectors -N 20` 17 | 18 | ## Docker run: 19 | 20 | `docker run -v /sys/fs/cgroup:/sys/fs/cgroup:rw -v /Users/Casual/src/lart:/usr/src/lart:rw --privileged --cap-drop=all -it lart` 21 | `docker run -v /sv-benchmarks/:/usr/set/sv-benchmarks:rw -v /sys/fs/cgroup:/sys/fs/cgroup:rw -v /lart:/usr/src/lart:rw --privileged --cap-drop=all -it lart` -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0.2.0", 3 | "configurations": [ 4 | { 5 | "name": "(gdb) Launch", 6 | "type": "cppdbg", 7 | "request": "launch", 8 | "program": "/usr/bin/bash", 9 | "args": ["${workspaceFolder}/build/lartcc/lartcc", "term", "faulty.c"], 10 | "stopAtEntry": false, 11 | "cwd": "${workspaceFolder}", 12 | "environment": [], 13 | "externalConsole": false, 14 | "setupCommands": [ 15 | { 16 | "description": "Enable pretty-printing for gdb", 17 | "text": "-enable-pretty-printing", 18 | "ignoreFailures": true 19 | }, 20 | {"text": "-gdb-set follow-fork-mode child"} 21 | ] 22 | } 23 | ] 24 | } -------------------------------------------------------------------------------- /.devcontainer/devcontainer.json: -------------------------------------------------------------------------------- 1 | // For format details, see https://aka.ms/devcontainer.json. For config options, see the README at: 2 | // https://github.com/microsoft/vscode-dev-containers/tree/v0.245.2/containers/cpp 3 | { 4 | "name": "C++", 5 | // to run local build of devcontainer 6 | "build": { "dockerfile": "./Dockerfile" }, 7 | "runArgs": ["--cap-add=SYS_PTRACE", "--security-opt", "seccomp=unconfined"], 8 | 9 | // Configure tool-specific properties. 10 | "customizations": { 11 | // Configure properties specific to VS Code. 12 | "vscode": { 13 | // Add the IDs of extensions you want installed when the container is created. 14 | "extensions": [ 15 | "ms-vscode.cpptools", 16 | "ms-vscode.cmake-tools" 17 | ] 18 | } 19 | }, 20 | 21 | "remoteUser": "vscode", 22 | "features": { 23 | "git": "os-provided", 24 | "python": "os-provided" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required( VERSION 3.23 ) 2 | 3 | if ( DEFINED ENV{VCPKG_ROOT} AND NOT DEFINED CMAKE_TOOLCHAIN_FILE ) 4 | set( CMAKE_TOOLCHAIN_FILE "$ENV{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake" 5 | CACHE STRING "" ) 6 | endif() 7 | 8 | if (NOT DEFINED VCPKG_OVERLAY_PORTS) 9 | set(VCPKG_OVERLAY_PORTS "${CURRENT_LIST_DIR}/ports") 10 | endif() 11 | 12 | project( lart VERSION 0.1.0 13 | DESCRIPTION "LLVM Abstraction and Refinement Tool" 14 | HOMEPAGE_URL "https://github.com/xlauko/lart" 15 | ) 16 | 17 | # Globally set the required C++ standard 18 | set( CMAKE_CXX_STANDARD 20 ) 19 | set( CMAKE_CXX_EXTENSIONS ON ) 20 | 21 | add_subdirectory( external ) 22 | 23 | add_subdirectory( runtime ) 24 | add_subdirectory( lava ) 25 | add_subdirectory( lamp ) 26 | 27 | add_subdirectory( lartcc ) 28 | 29 | 30 | if ( ENABLE_TESTING ) 31 | enable_testing() 32 | add_subdirectory( test ) 33 | endif() 34 | -------------------------------------------------------------------------------- /test/lit.site.cfg.py.in: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | config.llvm_tools_dir = "@LLVM_INSTALL_DIR@/Release/bin" 4 | config.llvm_shlib_ext = "@LART_TEST_SHLIBEXT@" 5 | config.llvm_shlib_dir = "@CMAKE_LIBRARY_OUTPUT_DIRECTORY@" 6 | 7 | config.lart_install_dir = "@CMAKE_INSTALL_PREFIX@/bin" 8 | config.lart_binary_dir = "@CMAKE_BINARY_DIR@/lartcc/" 9 | 10 | config.my_src_root = r'@CMAKE_CURRENT_SOURCE_DIR@' 11 | config.my_obj_root = r'@CMAKE_CURRENT_BINARY_DIR@' 12 | 13 | import lit.llvm 14 | # lit_config is a global instance of LitConfig 15 | lit.llvm.initialize(lit_config, config) 16 | 17 | # test_exec_root: The root path where tests should be run. 18 | config.test_exec_root = os.path.join(config.my_obj_root) 19 | 20 | # Let the main config do the real work. 21 | lit_config.load_config(config, os.path.join(config.my_src_root, "lit.cfg.py")) 22 | 23 | config.substitutions += [ 24 | ("%filecheck", "FileCheck-12 @LART_FILECHECK_ARGS@"), 25 | ] 26 | -------------------------------------------------------------------------------- /test/unittests/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | find_package( Catch2 CONFIG REQUIRED ) 2 | include(CTest) 3 | include(Catch) 4 | 5 | # catch2 main 6 | add_library( catch-main STATIC catch-main.cpp ) 7 | target_link_libraries( catch-main 8 | PRIVATE lart_project_options 9 | PUBLIC doctest::doctest 10 | ) 11 | 12 | target_include_directories( catch-main 13 | PRIVATE $ 14 | ) 15 | 16 | # test configs 17 | add_library( test-properties INTERFACE ) 18 | target_link_libraries( test-properties 19 | INTERFACE 20 | catch-main 21 | lamp-api 22 | lart-runtime 23 | lart_project_options 24 | lart_project_warnings 25 | ) 26 | target_compile_options( test-properties INTERFACE "-g" ) 27 | 28 | # test packages 29 | add_executable( lamp-unit-tests unit.cpp ) 30 | target_link_libraries( lamp-unit-tests PRIVATE unit-src test-properties ) 31 | catch_discover_tests( lamp-unit-tests ) 32 | -------------------------------------------------------------------------------- /lartcc/alias.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * (c) 2020, 2021 Henrich Lauko 3 | * 4 | * Permission to use, copy, modify, and distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | #include 18 | 19 | namespace lart::aa 20 | { 21 | 22 | } // namespace lart::aa 23 | -------------------------------------------------------------------------------- /lartcc/include/cc/logger.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * (c) 2021 Henrich Lauko 3 | * 4 | * Permission to use, copy, modify, and distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | #include "spdlog/spdlog.h" 18 | #include "spdlog/cfg/env.h" 19 | #include "spdlog/fmt/ostr.h" 20 | -------------------------------------------------------------------------------- /runtime/native/choose.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * (c) 2021 Henrich Lauko 3 | * 4 | * Permission to use, copy, modify, and distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | #pragma once 18 | 19 | namespace __lart::rt 20 | { 21 | int choose( int count ); 22 | } 23 | -------------------------------------------------------------------------------- /scripts/build.sh: -------------------------------------------------------------------------------- 1 | cmake \ 2 | -GNinja \ 3 | -DCMAKE_C_COMPILER=clang \ 4 | -DCMAKE_CXX_COMPILER=clang++ \ 5 | -DBUILD_LART_RUNTIME=ON \ 6 | -DCMAKE_BUILD_TYPE=Debug \ 7 | -DLLVM_INSTALL_DIR=${LLVM_INSTALL_DIR} \ 8 | -DLIBCXX_INSTALL_DIR=${LIBCXX_DATAFLOW_DIR} \ 9 | -DCMAKE_TOOLCHAIN_FILE=${VCPKG_TOOLCHAIN} \ 10 | -DCMAKE_INSTALL_PREFIX=${LART_INSTALL_DIR} \ 11 | -B build-runtime \ 12 | -S . 13 | 14 | cmake --build build-runtime 15 | cmake --build build-runtime --target install 16 | 17 | cmake \ 18 | -GNinja \ 19 | -DBUILD_LART_CC=ON \ 20 | -DENABLE_TESTING=OFF \ 21 | -DCMAKE_BUILD_TYPE=Release \ 22 | -DLLVM_INSTALL_DIR=${LLVM_INSTALL_DIR}/build/ \ 23 | -DSVF_INSTALL_DIR=${SVF_INSTALL_DIR} \ 24 | -DCMAKE_TOOLCHAIN_FILE=${VCPKG_TOOLCHAIN} \ 25 | -DCMAKE_INSTALL_PREFIX=${LART_INSTALL_DIR} \ 26 | -B build \ 27 | -S . 28 | 29 | cmake --build build 30 | cmake --build build --target install -------------------------------------------------------------------------------- /lartcc/include/cc/stats.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * (c) 2020 Henrich Lauko 3 | * 4 | * Permission to use, copy, modify, and distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | #pragma once 18 | 19 | #include 20 | 21 | namespace lart 22 | { 23 | using llvm::dbgs; 24 | } 25 | -------------------------------------------------------------------------------- /lamp/cmake/lamp.cmake: -------------------------------------------------------------------------------- 1 | 2 | macro( register_domain domain ) 3 | option( ${domain}_build "Build domain ${domain}" ON ) 4 | 5 | if ( ${domain}_build ) 6 | # general domain build properties/setup 7 | add_library( ${domain}-prop INTERFACE ) 8 | 9 | target_include_directories( ${domain}-prop 10 | INTERFACE 11 | ${CMAKE_CURRENT_SOURCE_DIR}/include 12 | ${CMAKE_CURRENT_SOURCE_DIR} 13 | ) 14 | 15 | add_library( ${domain} STATIC ${domain}.cpp ) 16 | target_link_libraries( ${domain} 17 | PUBLIC ${domain}-prop 18 | PRIVATE lava runtime llvmsc::llvmsc 19 | ) 20 | 21 | set_property( TARGET ${domain} PROPERTY POSITION_INDEPENDENT_CODE ON ) 22 | set_property( TARGET ${domain} PROPERTY CXX_STANDARD 20 ) 23 | 24 | install (TARGETS ${domain} 25 | RUNTIME DESTINATION bin 26 | LIBRARY DESTINATION lib 27 | ARCHIVE DESTINATION lib 28 | PUBLIC_HEADER DESTINATION include 29 | ) 30 | 31 | endif() 32 | endmacro() 33 | -------------------------------------------------------------------------------- /lamp/README.md: -------------------------------------------------------------------------------- 1 | # LAMP: A Library of Abstract Metadomain Packages 2 | 3 | Each C++ source file (module) in this directory implements a single abstract 4 | meta-domain, which mediates interaction between abstract domains from LAVA 5 | (which represent values at runtime), and the abstract program as generated 6 | (transformed) by LART. 7 | 8 | A program abstracted by LART, before it is executed or further analysed in 9 | some way, needs to be linked to exactly one of the LAME modules (in bitcode 10 | form). Interface-wise, all modules are equivalent and LART does not need to 11 | know which is going to be used. The difference lies in which abstract domains 12 | they combine, and how -- i.e. different LAME modules will give different 13 | abstract semantics to the same program (syntactically) abstracted by LART. 14 | 15 | The C interface between LART and LAMP is defined in `wrapper.hpp` (the same 16 | file also effectively describes the C++ interface between LAMP and LAVA, via 17 | the C++ calls the C wrappers perform). 18 | -------------------------------------------------------------------------------- /runtime/native/utils.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * (c) 2020 Henrich Lauko 3 | * 4 | * Permission to use, copy, modify, and distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | #pragma once 18 | 19 | #define constructor __attribute__( ( constructor ) ) // NOLINT 20 | #define destructor __attribute__( ( destructor ) ) // NOLINT 21 | -------------------------------------------------------------------------------- /lartcc/lartcc.in: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if [ "$1" == "--version" ]; then 4 | echo "LART @CMAKE_PROJECT_VERSION@" 5 | exit 0 6 | fi 7 | 8 | domain=$1 9 | runtime="native" 10 | 11 | RUNTIME="@RUNTIME_BINARY_DIR@/lib${runtime}.a" 12 | DOMAIN="@LAMP_BINARY_DIR@/lib${domain}.a" 13 | PASS="@LARTCC_BINARY_DIR@/liblartcc.so" 14 | 15 | LART_INTERFACE="@LART_INTERFACE_DIR@" 16 | 17 | LDFLAGS="${LDFLAGS} -lstdc++" 18 | 19 | RED='\033[0;31m' 20 | NC='\033[0m' # No Color 21 | 22 | if [ -z $domain ]; then 23 | echo -e "${RED}[LART ERROR]${NC} No domain provided. Please specify a domain name." 24 | exit 1 25 | fi 26 | 27 | exec @CLANG_BINARY@ \ 28 | -fpass-plugin="$PASS" \ 29 | ${CFLAGS} \ 30 | "${@:2}" \ 31 | ${LDFLAGS} \ 32 | "$DOMAIN" \ 33 | "$RUNTIME" \ 34 | -I"$LART_INTERFACE" 35 | -------------------------------------------------------------------------------- /runtime/native/trace.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * (c) 2021 Henrich Lauko 3 | * 4 | * Permission to use, copy, modify, and distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | #include "trace.hpp" 18 | 19 | #include 20 | #include 21 | 22 | namespace __lart::rt 23 | { 24 | trace_t trace; 25 | } // namespace __lart::rt 26 | -------------------------------------------------------------------------------- /lamp/term.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * (c) 2021 Henrich Lauko 3 | * 4 | * Permission to use, copy, modify, and distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | #include 18 | #include 19 | 20 | namespace __lamp 21 | { 22 | using meta_domain = __lava::term< wrapped_storage >; 23 | } 24 | 25 | #include "wrapper.hpp" 26 | -------------------------------------------------------------------------------- /lamp/constant.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * (c) 2020 Henrich Lauko 3 | * 4 | * Permission to use, copy, modify, and distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | #include 18 | #include 19 | 20 | namespace __lamp 21 | { 22 | using meta_domain = __lava::constant< wrapped_storage >; 23 | } 24 | 25 | #include "wrapper.hpp" 26 | -------------------------------------------------------------------------------- /lamp/unit.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * (c) 2020 Henrich Lauko 3 | * 4 | * Permission to use, copy, modify, and distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | #include 18 | #include 19 | 20 | namespace __lamp 21 | { 22 | using meta_domain = __lava::unit< wrapped_storage >; 23 | } // namespace __lamp 24 | 25 | #include "wrapper.hpp" 26 | -------------------------------------------------------------------------------- /lamp/tracing-term.cpp: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | * (c) 2021 Henrich Lauko 4 | * 5 | * Permission to use, copy, modify, and distribute this software for any 6 | * purpose with or without fee is hereby granted, provided that the above 7 | * copyright notice and this permission notice appear in all copies. 8 | * 9 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 | */ 17 | 18 | #include 19 | #include 20 | #include 21 | 22 | namespace __lamp 23 | { 24 | using meta_domain = tracing< __lava::term< wrapped_storage > >; 25 | } 26 | 27 | #include "wrapper.hpp" 28 | -------------------------------------------------------------------------------- /lamp/floats.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * (c) 2020 Henrich Lauko 3 | * (c) 2021 Hugo Adamove 4 | * 5 | * Permission to use, copy, modify, and distribute this software for any 6 | * purpose with or without fee is hereby granted, provided that the above 7 | * copyright notice and this permission notice appear in all copies. 8 | * 9 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 | */ 17 | 18 | #include 19 | #include 20 | 21 | namespace __lamp 22 | { 23 | using meta_domain = __lava::floats< wrapped_storage >; 24 | } // namespace __lamp 25 | 26 | #include "wrapper.hpp" 27 | -------------------------------------------------------------------------------- /lamp/tracing-unit.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * (c) 2020 Henrich Lauko 3 | * 4 | * Permission to use, copy, modify, and distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | #include 18 | #include 19 | #include 20 | 21 | namespace __lamp 22 | { 23 | using meta_domain = tracing< __lava::unit< wrapped_storage > >; 24 | } // namespace __lamp 25 | 26 | #include "wrapper.hpp" 27 | -------------------------------------------------------------------------------- /.devcontainer/Dockerfile: -------------------------------------------------------------------------------- 1 | # See here for image contents: https://github.com/microsoft/vscode-dev-containers/tree/v0.245.2/containers/cpp/.devcontainer/base.Dockerfile 2 | 3 | ARG VARIANT="ubuntu-22.04" 4 | FROM mcr.microsoft.com/vscode/devcontainers/cpp:0-${VARIANT} as base 5 | 6 | # 7 | # setup cmake 8 | # 9 | ARG REINSTALL_CMAKE_VERSION_FROM_SOURCE="3.24.2" 10 | 11 | RUN chmod +x ./reinstall-cmake.sh && ./reinstall-cmake.sh ${REINSTALL_CMAKE_VERSION_FROM_SOURCE} 12 | 13 | # 14 | # install deps 15 | # 16 | ENV DEBIAN_FRONTEND noninteractive 17 | 18 | RUN apt-get update \ 19 | && apt-get -y install --no-install-recommends \ 20 | software-properties-common python3-pip ccache cmake lld \ 21 | llvm-13 clang-13 libz3-dev z3 zip unzip tar llvm-13-dev \ 22 | && rm -rf /var/lib/apt/lists/* 23 | 24 | WORKDIR /usr/src/ 25 | 26 | ENV LLVM_INSTALL_DIR="/usr/lib/llvm-13/" 27 | ENV Z3_DIR "/usr/opt/z3-4.11.2-x64-glibc-2.31/" 28 | RUN mkdir -p "/usr/opt/" 29 | 30 | RUN wget -c "https://github.com/Z3Prover/z3/releases/download/z3-4.11.2/z3-4.11.2-x64-glibc-2.31.zip" -O z3.zip 31 | RUN unzip -q z3.zip -d /usr/opt 32 | RUN rm z3.zip 33 | -------------------------------------------------------------------------------- /test/svcomp/basic.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | extern void abort(void); 4 | 5 | extern void __assert_fail (const char *__assertion, const char *__file, 6 | unsigned int __line, const char *__function) 7 | __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__noreturn__)); 8 | extern void __assert_perror_fail (int __errnum, const char *__file, 9 | unsigned int __line, const char *__function) 10 | __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__noreturn__)); 11 | extern void __assert (const char *__assertion, const char *__file, int __line) 12 | __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__noreturn__)); 13 | 14 | void reach_error() { ((void) sizeof ((0) ? 1 : 0), __extension__ ({ if (0) ; else __assert_fail ("0", "byte_add-1.c", 3, __extension__ __PRETTY_FUNCTION__); })); } 15 | 16 | extern unsigned int __VERIFIER_nondet_uint(void); 17 | void __VERIFIER_assert(int cond) { 18 | if (!(cond)) { 19 | ERROR: {reach_error();abort();} 20 | } 21 | return; 22 | } 23 | 24 | int main() 25 | { 26 | unsigned int a = __VERIFIER_nondet_uint(); 27 | if (a) 28 | reach_error(); 29 | } -------------------------------------------------------------------------------- /lamp/include/lamp-pointers.h: -------------------------------------------------------------------------------- 1 | /* 2 | * (c) 2021 Henrich Lauko 3 | * 4 | * Permission to use, copy, modify, and distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | #pragma once 18 | 19 | #include 20 | 21 | 22 | __lart_ignore_diagnostic 23 | 24 | #ifdef __cplusplus 25 | extern "C" { 26 | #endif 27 | 28 | __lamp_scalar void* __lamp_lift_objid( void *ptr ) __lart_stub; 29 | 30 | #ifdef __cplusplus 31 | } 32 | #endif 33 | 34 | __lart_pop_diagnostic -------------------------------------------------------------------------------- /test/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | include( CTest ) 2 | 3 | # add_subdirectory( unittests ) 4 | 5 | set( LART_TEST_SHLIBEXT "${CMAKE_SHARED_LIBRARY_SUFFIX}" ) 6 | 7 | set( LART_TEST_SITE_CFG_INPUT "${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.py.in" ) 8 | set( LART_TEST_CFG_INPUT "${CMAKE_CURRENT_SOURCE_DIR}/lit.cfg.py.in" ) 9 | set( LART_TEST_SRC_DIR "${CMAKE_CURRENT_SOURCE_DIR}" ) 10 | 11 | set( LART_FILECHECK_ARGS "" ) 12 | 13 | set( LIT_SITE_CFG_IN_HEADER 14 | "## Autogenerated from ${LART_TEST_SITE_CFG_INPUT}\n## Do not edit!" ) 15 | 16 | configure_file( "${LART_TEST_SITE_CFG_INPUT}" 17 | "${CMAKE_CURRENT_BINARY_DIR}/lit.site.cfg.py" @ONLY 18 | ) 19 | 20 | configure_file( "scripts/testrun.sh.in" 21 | "${CMAKE_CURRENT_BINARY_DIR}/scripts/testrun.sh" @ONLY 22 | FILE_PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE 23 | ) 24 | 25 | file( COPY "include" DESTINATION "." ) 26 | 27 | add_test( 28 | NAME lit 29 | COMMAND 30 | lit -v "${CMAKE_CURRENT_BINARY_DIR}" 31 | ) 32 | 33 | set_tests_properties( lit 34 | PROPERTIES 35 | ENVIROMENT "LARTCC_LIBCXX_PATH=${LIBCXX_INSTALL_DIR}" 36 | ) 37 | -------------------------------------------------------------------------------- /runtime/native/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_library( lart-runtime INTERFACE ) 2 | target_include_directories( lart-runtime 3 | INTERFACE 4 | $ 5 | ${CMAKE_CURRENT_SOURCE_DIR}/include 6 | ) 7 | 8 | add_library( native 9 | STATIC 10 | svcomp.cpp 11 | config.cpp 12 | choose.cpp 13 | shadow.cpp 14 | stash.cpp 15 | lart.cpp 16 | trace.cpp 17 | fault.cpp 18 | ) 19 | 20 | set_property( TARGET native PROPERTY POSITION_INDEPENDENT_CODE ON ) 21 | set_property( TARGET native PROPERTY CXX_STANDARD 20 ) 22 | 23 | target_include_directories( native 24 | PUBLIC 25 | $ 26 | ${CMAKE_CURRENT_SOURCE_DIR}/../include/runtime 27 | PRIVATE 28 | ${CMAKE_CURRENT_SOURCE_DIR}/src 29 | ) 30 | 31 | set_property( TARGET llvmsc PROPERTY POSITION_INDEPENDENT_CODE ON ) 32 | 33 | target_link_libraries( native 34 | PRIVATE 35 | project_warnings 36 | project_options 37 | llvmsc::llvmsc 38 | ) 39 | 40 | install (TARGETS native 41 | RUNTIME DESTINATION bin 42 | LIBRARY DESTINATION lib 43 | ARCHIVE DESTINATION lib 44 | PUBLIC_HEADER DESTINATION include 45 | ) 46 | 47 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019-2021 Henrich Lauko 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /lamp/sign.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * (c) 2022 Henrich Lauko 3 | * 4 | * Permission to use, copy, modify, and distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | #include 18 | #include 19 | #include 20 | 21 | namespace __lamp 22 | { 23 | using sign = __lava::sign< wrapped_storage >; 24 | using meta_domain = __lava::relational< sign, wrapped_storage >; 25 | } // namespace __lamp 26 | 27 | #include "wrapper.hpp" 28 | -------------------------------------------------------------------------------- /cmake/static_analyzers.cmake: -------------------------------------------------------------------------------- 1 | option(ENABLE_CPPCHECK "Enable static analysis with cppcheck" OFF) 2 | option(ENABLE_CLANG_TIDY "Enable static analysis with clang-tidy" OFF) 3 | option(ENABLE_INCLUDE_WHAT_YOU_USE "Enable static analysis with include-what-you-use" OFF) 4 | 5 | if(ENABLE_CPPCHECK) 6 | find_program(CPPCHECK cppcheck) 7 | if(CPPCHECK) 8 | set(CMAKE_CXX_CPPCHECK ${CPPCHECK} 9 | --suppress=missingInclude --enable=all --inconclusive) 10 | else() 11 | message(SEND_ERROR "cppcheck requested but executable not found") 12 | endif() 13 | endif() 14 | 15 | if(ENABLE_CLANG_TIDY) 16 | find_program(CLANGTIDY clang-tidy) 17 | if(CLANGTIDY) 18 | set(CMAKE_CXX_CLANG_TIDY ${CLANGTIDY} -extra-arg=-Wno-unknown-warning-option) 19 | else() 20 | message(SEND_ERROR "clang-tidy requested but executable not found") 21 | endif() 22 | endif() 23 | 24 | if(ENABLE_INCLUDE_WHAT_YOU_USE) 25 | find_program(INCLUDE_WHAT_YOU_USE include-what-you-use) 26 | if(INCLUDE_WHAT_YOU_USE) 27 | set(CMAKE_CXX_INCLUDE_WHAT_YOU_USE ${INCLUDE_WHAT_YOU_USE}) 28 | else() 29 | message(SEND_ERROR "include-what-you-use requested but executable not found") 30 | endif() 31 | endif() 32 | -------------------------------------------------------------------------------- /lamp/tracing-floats.cpp: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | * (c) 2020 Henrich Lauko 4 | * (c) 2021 Hugo Adamove 5 | * 6 | * Permission to use, copy, modify, and distribute this software for any 7 | * purpose with or without fee is hereby granted, provided that the above 8 | * copyright notice and this permission notice appear in all copies. 9 | * 10 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 | */ 18 | 19 | #include 20 | #include 21 | #include 22 | 23 | namespace __lamp 24 | { 25 | using meta_domain = tracing< __lava::floats< wrapped_storage > >; 26 | } // namespace __lamp 27 | 28 | #include "wrapper.hpp" 29 | -------------------------------------------------------------------------------- /lava/include/lava/support/pointer.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * (c) 2021 Henrich Lauko 3 | * 4 | * Permission to use, copy, modify, and distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | #include 18 | #include 19 | 20 | namespace __lava 21 | { 22 | struct pointer_t { uint32_t off, obj; }; 23 | 24 | pointer_t pointer_split( void* ptr ) 25 | { 26 | pointer_t rv; 27 | std::memcpy( &rv, &ptr, sizeof( rv ) ); 28 | return rv; 29 | } 30 | 31 | } // namespace __lava 32 | -------------------------------------------------------------------------------- /lamp/tracing-interval.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * (c) 2021 Henrich Lauko 3 | * 4 | * Permission to use, copy, modify, and distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | #include 18 | #include 19 | 20 | #include 21 | #include 22 | 23 | namespace __lamp 24 | { 25 | using interval = __lava::interval< wrapped_storage >; 26 | using meta_domain = tracing< __lava::relational< interval, wrapped_storage > >; 27 | } 28 | 29 | #include "wrapper.hpp" -------------------------------------------------------------------------------- /lamp/tracing-sign.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * (c) 2022 Henrich Lauko 3 | * 4 | * Permission to use, copy, modify, and distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | #include 18 | #include 19 | 20 | #include 21 | #include 22 | 23 | namespace __lamp 24 | { 25 | using sign = __lava::sign< wrapped_storage >; 26 | using meta_domain = tracing< __lava::relational< sign, wrapped_storage > >; 27 | } // namespace __lamp 28 | 29 | #include "wrapper.hpp" 30 | -------------------------------------------------------------------------------- /lamp/tracing-zero.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * (c) 2021 Henrich Lauko 3 | * 4 | * Permission to use, copy, modify, and distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | #include 18 | #include 19 | 20 | #include 21 | #include 22 | 23 | namespace __lamp 24 | { 25 | using zero = __lava::zero< wrapped_storage >; 26 | using meta_domain = tracing< __lava::relational< zero, wrapped_storage > >; 27 | } // namespace __lamp 28 | 29 | #include "wrapper.hpp" 30 | -------------------------------------------------------------------------------- /lamp/tracing-bitvec-interval.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * (c) 2022 Henrich Lauko 3 | * 4 | * Permission to use, copy, modify, and distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | #include 18 | #include 19 | 20 | #include 21 | #include 22 | 23 | namespace __lamp 24 | { 25 | using interval = __lava::bitvec_interval< wrapped_storage >; 26 | using meta_domain = tracing< __lava::relational< interval, wrapped_storage > >; 27 | } 28 | 29 | #include "wrapper.hpp" 30 | -------------------------------------------------------------------------------- /lartcc/include/cc/driver.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * (c) 2020 Henrich Lauko 3 | * 4 | * Permission to use, copy, modify, and distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | #pragma once 18 | 19 | #include 20 | #include 21 | 22 | #include 23 | 24 | namespace lart 25 | { 26 | struct driver : sc::with_context 27 | { 28 | explicit driver( llvm::Module &m ) : sc::with_context( m ), module( m ) {} 29 | 30 | llvm::PreservedAnalyses run(); 31 | 32 | llvm::Module &module; 33 | }; 34 | 35 | } // namespace lart 36 | -------------------------------------------------------------------------------- /lartcc/include/cc/pass.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * (c) 2020 Henrich Lauko 3 | * 4 | * Permission to use, copy, modify, and distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | #pragma once 18 | 19 | #include "driver.hpp" 20 | 21 | #include 22 | #include 23 | 24 | namespace lart 25 | { 26 | struct lartcc : llvm::PassInfoMixin< lartcc > { 27 | llvm::PreservedAnalyses run( 28 | llvm::Module &mod, llvm::ModuleAnalysisManager &mgr 29 | ); 30 | 31 | private: 32 | std::unique_ptr< driver > _driver; 33 | }; 34 | 35 | } // namespace lart 36 | -------------------------------------------------------------------------------- /lartcc/include/cc/taint.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * (c) 2021 Henrich Lauko 3 | * 4 | * Permission to use, copy, modify, and distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | #pragma once 18 | 19 | #include 20 | #include 21 | #include 22 | 23 | #include 24 | 25 | #include 26 | #include 27 | 28 | namespace lart::taint 29 | { 30 | using operation = lart::op::operation; 31 | 32 | llvm::CallInst * make_call( const lifter &lift ); 33 | 34 | sc::generator< ir::argument > paired_view( const ir::intrinsic &test ); 35 | 36 | } // namespace lart::taint 37 | -------------------------------------------------------------------------------- /cmake/project_settings.cmake: -------------------------------------------------------------------------------- 1 | # Set a default build type if none was specified 2 | if( NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES ) 3 | message( STATUS "Setting build type to 'RelWithDebInfo' as none was specified." ) 4 | set(CMAKE_BUILD_TYPE 5 | RelWithDebInfo 6 | CACHE STRING "Choose the type of build." FORCE) 7 | # Set the possible values of build type for cmake-gui, ccmake 8 | set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release" 9 | "MinSizeRel" "RelWithDebInfo") 10 | endif() 11 | 12 | find_program( CCACHE ccache ) 13 | if ( CCACHE ) 14 | message( STATUS "Using ccache" ) 15 | set( CMAKE_CXX_COMPILER_LAUNCHER ${CCACHE} ) 16 | else() 17 | message( WARNING "CCache was not found." ) 18 | endif() 19 | 20 | # Generate compile_commands.json to make it easier to work with clang based tools 21 | set( CMAKE_EXPORT_COMPILE_COMMANDS ON ) 22 | 23 | option( ENABLE_IPO 24 | "Enable Interprocedural Optimization, aka Link Time Optimization (LTO)" OFF 25 | ) 26 | 27 | if( ENABLE_IPO ) 28 | include( CheckIPOSupported ) 29 | check_ipo_supported( RESULT result OUTPUT output ) 30 | if( result ) 31 | set( CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE ) 32 | else() 33 | message( SEND_ERROR "IPO is not supported: ${output}" ) 34 | endif() 35 | endif() 36 | 37 | -------------------------------------------------------------------------------- /lamp/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required( VERSION 3.22 ) 2 | 3 | include( cmake/lamp.cmake ) 4 | 5 | set( LAMP_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR} PARENT_SCOPE ) 6 | 7 | register_domain( unit ) 8 | register_domain( tracing-unit ) 9 | register_domain( interval ) 10 | register_domain( tracing-interval ) 11 | register_domain( bitvec-interval ) 12 | register_domain( tracing-bitvec-interval ) 13 | register_domain( constant ) 14 | register_domain( trivial ) 15 | register_domain( term ) 16 | register_domain( tracing-term ) 17 | # register_domain( pa ) 18 | # register_domain( zero ) 19 | # register_domain( tracing-zero ) 20 | register_domain( sign ) 21 | register_domain( tracing-sign ) 22 | register_domain( floats ) 23 | register_domain( tracing-floats ) 24 | 25 | add_library( lamp-api INTERFACE ) 26 | target_include_directories( lamp-api 27 | INTERFACE 28 | $ 29 | ${CMAKE_CURRENT_SOURCE_DIR}/include 30 | ) 31 | 32 | set( LART_INTERFACE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/include PARENT_SCOPE ) 33 | 34 | set_target_properties( lamp-api PROPERTIES PUBLIC_HEADER 35 | "include/lamp.h;include/lamp-pointers.h;include/svcomp.h" 36 | ) 37 | 38 | install(TARGETS lamp-api 39 | RUNTIME DESTINATION bin 40 | LIBRARY DESTINATION lib 41 | ARCHIVE DESTINATION lib 42 | PUBLIC_HEADER DESTINATION include 43 | ) 44 | -------------------------------------------------------------------------------- /lamp/memory.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * (c) 2022 Henrich Lauko 3 | * 4 | * Permission to use, copy, modify, and distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | #include 18 | 19 | namespace lart { 20 | 21 | struct frame_t { 22 | std::vector< dom > values; 23 | }; 24 | 25 | std::vector< frame_t > frames; 26 | std::vector< dom > globs; 27 | 28 | void push_frame() { frames.push_back({}); } 29 | 30 | void pop_frame() { frames.pop_back(); } 31 | 32 | } // namespace lart 33 | 34 | 35 | extern "C" { 36 | 37 | void __lart_push_frame() { lart::push_frame(); } 38 | void __lart_pop_frame() { lart::pop_frame(); } 39 | 40 | // TODO make global 41 | } 42 | -------------------------------------------------------------------------------- /lartcc/backend/base.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * (c) 2021 Henrich Lauko 3 | * 4 | * Permission to use, copy, modify, and distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | #include 18 | #include 19 | 20 | namespace lart::backend 21 | { 22 | void base::lower( ir::intrinsic i ) 23 | { 24 | if ( op::emit_test_taint( i.op ) ) 25 | lower_test_taint( i ); 26 | else 27 | std::visit( [&] (auto &&a) { this->lower( i.call, a ); }, i.op ); 28 | } 29 | 30 | void base::lower( llvm::CallInst *, op::operation ) 31 | { 32 | llvm_unreachable( "not implementeted lowering operation" ); 33 | } 34 | 35 | } // namespace lart::backend 36 | -------------------------------------------------------------------------------- /runtime/native/stash.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * (c) 2020 Henrich Lauko 3 | * 4 | * Permission to use, copy, modify, and distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | #include "stash.hpp" 18 | 19 | namespace __lart::rt 20 | { 21 | thread_local std::uint8_t stash_stack_top = 0; 22 | thread_local stash_stack_value_t stash_stack[abstract_stack_size] = {}; 23 | 24 | thread_local std::uint8_t taint_stack_top = 0; 25 | thread_local bool taint_stack[abstract_stack_size] = {}; 26 | 27 | void stash_taint( bool taint ) 28 | { 29 | taint_stack[ taint_stack_top++ ] = taint; 30 | } 31 | 32 | bool unstash_taint() 33 | { 34 | return taint_stack[ --taint_stack_top ]; 35 | } 36 | } // namespace __lart::rt 37 | -------------------------------------------------------------------------------- /runtime/include/runtime/config.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * (c) 2020 Henrich Lauko 3 | * 4 | * Permission to use, copy, modify, and distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | #pragma once 18 | 19 | #include 20 | #include 21 | 22 | namespace __lart::rt 23 | { 24 | struct config_t 25 | { 26 | bool backtrace = false; 27 | bool trace_choices = false; 28 | bool ask_choices = false; 29 | 30 | unsigned choose_bound = 0; 31 | bool choose_increasing = false; 32 | 33 | bool error_found = false; 34 | 35 | bool no_fail_mode = false; 36 | 37 | std::FILE *trace_file = nullptr; 38 | }; 39 | 40 | extern config_t *config; 41 | 42 | } // namespace __lart::rt 43 | -------------------------------------------------------------------------------- /CMakeUserPresets.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": 3, 3 | "cmakeMinimumRequired": { 4 | "major": 3, 5 | "minor": 23, 6 | "patch": 0 7 | }, 8 | "configurePresets": [ 9 | { 10 | "name": "ninja-multi-default-custom", 11 | "displayName": "Ninja Multi-Config Custom", 12 | "binaryDir": "${sourceDir}/builds/${presetName}", 13 | "generator": "Ninja Multi-Config", 14 | "inherits": "ninja-multi-default", 15 | "environment": { 16 | "VCPKG_ROOT": "/home/xlauko1/src/vcpkg", 17 | "Z3_DIR": "/home/xlauko1/opt/z3", 18 | "LLVM_INSTALL_DIR": "/usr/lib/llvm-13/" 19 | } 20 | } 21 | ], 22 | "buildPresets": [ 23 | { 24 | "name": "ninja-rel-custom", 25 | "configurePreset": "ninja-multi-default-custom", 26 | "displayName": "Build ninja-multi-rel-custom", 27 | "configuration": "Release" 28 | }, 29 | { 30 | "name": "ninja-rel-with-deb-custom", 31 | "configurePreset": "ninja-multi-default-custom", 32 | "displayName": "Build ninja-multi-rel-with-deb-custom", 33 | "configuration": "RelWithDebInfo" 34 | }, 35 | { 36 | "name": "ninja-deb-custom", 37 | "configurePreset": "ninja-multi-default-custom", 38 | "displayName": "Build ninja-multi-deb-custom", 39 | "configuration": "Debug" 40 | } 41 | ] 42 | } 43 | -------------------------------------------------------------------------------- /pres/simulator example/simulator.py: -------------------------------------------------------------------------------- 1 | from IPython.core.magic import register_cell_magic 2 | from pygdbmi.gdbcontroller import GdbController 3 | from pprint import pprint 4 | 5 | from typing import List, Optional 6 | from argparse import ArgumentParser 7 | 8 | class GDBSimulator: 9 | def __init__(self) -> None: 10 | self.file = None 11 | self.gdb = GdbController() 12 | 13 | def load(self, file: str) -> None: 14 | if file == self.file: 15 | return 16 | self.file = file 17 | self.restart() 18 | return self.run(f'file {self.file}') 19 | 20 | def restart(self) -> None: 21 | self.gdb.spawn_new_gdb_subprocess() 22 | 23 | def run(self, cmd: str): 24 | return self.gdb.write(cmd) 25 | 26 | 27 | sim = GDBSimulator() 28 | 29 | 30 | def print_console_payload(response): 31 | for part in response: 32 | if part['type'] == 'console': 33 | print(part['payload'].encode('utf-8').decode('unicode_escape'), end='') 34 | 35 | 36 | @register_cell_magic('lart.simulator') 37 | def simulator(line, cell): 38 | args = line.split() 39 | cmds = cell.splitlines() 40 | 41 | parser = ArgumentParser(description="lart simulator") 42 | parser.add_argument('file', metavar='path', type=str, help='file to simulate') 43 | parsed = parser.parse_args(args) 44 | 45 | response = sim.load(parsed.file) 46 | if response: 47 | print_console_payload(response) 48 | 49 | for cmd in cmds: 50 | print_console_payload(sim.run(cmd)) 51 | -------------------------------------------------------------------------------- /runtime/include/runtime/shadow.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * (c) 2022 Henrich Lauko 3 | * 4 | * Permission to use, copy, modify, and distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | #pragma once 18 | 19 | #include 20 | #include 21 | 22 | #include 23 | 24 | namespace __lart::rt 25 | { 26 | struct shadow_label_info 27 | { 28 | void *value; 29 | void *origin; 30 | size_t bytes; 31 | }; 32 | 33 | // uniquely identifies shadow memory chunk 34 | using shadow_label_t = std::uint64_t; 35 | 36 | // assigns value to shadow of memory range [addr, addr + bytes) 37 | void poke( void *addr, std::size_t bytes, void *value ); 38 | 39 | sc::generator< shadow_label_info > peek( const void *addr, size_t bytes ); 40 | 41 | bool test_taint( void *addr, size_t bytes ); 42 | } 43 | -------------------------------------------------------------------------------- /lartcc/include/cc/lifter.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * (c) 2021 Henrich Lauko 3 | * 4 | * Permission to use, copy, modify, and distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | #pragma once 18 | 19 | #include 20 | #include 21 | 22 | namespace lart 23 | { 24 | 25 | struct lifter 26 | { 27 | using operation = lart::op::operation; 28 | 29 | explicit lifter( sc::module_ref m, operation o, const shadow_map &s ) 30 | : module( m ), op( o ), shadows( s ) 31 | { 32 | if ( function()->empty() ) 33 | generate(); 34 | } 35 | 36 | std::string name() const; 37 | llvm::Function* function() const; 38 | 39 | private: 40 | void generate() const; 41 | 42 | mutable llvm::Function *_function = nullptr; 43 | sc::module_ref module; 44 | 45 | public: 46 | operation op; 47 | const shadow_map &shadows; 48 | }; 49 | 50 | } // namespace lart 51 | -------------------------------------------------------------------------------- /scripts/svcomp/utils/properties.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | from enum import Enum 4 | 5 | from . log import error 6 | 7 | class property(Enum): 8 | """ 9 | Property names based on https://sv-comp.sosy-lab.org/2022/rules.php 10 | """ 11 | 12 | reach = 'unreach-call' 13 | termination = 'termination' 14 | overflow = 'no-overflow' 15 | deadlock = 'no-deadlock' 16 | defbehavior = 'def-behavior' 17 | deref = 'valid-deref' 18 | free = 'valid-free' 19 | memtrack = 'valid-memtrack' 20 | memcleanup = 'valid-memcleanup' 21 | memsafety = 'valid-memsafety' # internal meta property 22 | 23 | def is_memsafety(self): 24 | return self in [ self.deref, self.free, self.memtrack, self.memsafety ] 25 | 26 | def __str__(self): 27 | return self.value 28 | 29 | @staticmethod 30 | def from_string(s): 31 | try: 32 | return config[s] 33 | except KeyError: 34 | error("unknown property") 35 | 36 | """ 37 | This maps content of property files to property name 38 | """ 39 | property_names = { 40 | 'LTL(G ! call(reach_error()))' : property.reach, 41 | 'LTL(F end)' : property.termination, 42 | 'LTL(G valid-free)' : property.free, 43 | 'LTL(G valid-deref)' : property.deref, 44 | 'LTL(G valid-memtrack)' : property.memtrack, 45 | 'LTL(G valid-memcleanup)' : property.memcleanup, 46 | 'LTL(G ! overflow)' : property.overflow, 47 | 'LTL(G ! deadlock)' : property.deadlock, 48 | 'LTL(G def-behavior)' : property.defbehavior 49 | } 50 | -------------------------------------------------------------------------------- /cmake/sanitizers.cmake: -------------------------------------------------------------------------------- 1 | function( enable_sanitizers project_name ) 2 | 3 | if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID MATCHES 4 | ".*Clang") 5 | option(ENABLE_COVERAGE "Enable coverage reporting for gcc/clang" FALSE) 6 | 7 | if(ENABLE_COVERAGE) 8 | target_compile_options( lart_project_options INTERFACE --coverage -O0 -g) 9 | target_link_libraries( lart_project_options INTERFACE --coverage) 10 | endif() 11 | 12 | set(SANITIZERS "") 13 | 14 | option(ENABLE_SANITIZER_ADDRESS "Enable address sanitizer" OFF) 15 | if(ENABLE_SANITIZER_ADDRESS) 16 | list(APPEND SANITIZERS "address") 17 | endif() 18 | 19 | option(ENABLE_SANITIZER_MEMORY "Enable memory sanitizer" OFF) 20 | if(ENABLE_SANITIZER_MEMORY) 21 | list(APPEND SANITIZERS "memory") 22 | endif() 23 | 24 | option(ENABLE_SANITIZER_UNDEFINED_BEHAVIOR 25 | "Enable undefined behavior sanitizer" OFF) 26 | if(ENABLE_SANITIZER_UNDEFINED_BEHAVIOR) 27 | list(APPEND SANITIZERS "undefined") 28 | endif() 29 | 30 | option(ENABLE_SANITIZER_THREAD "Enable thread sanitizer" OFF) 31 | if(ENABLE_SANITIZER_THREAD) 32 | list(APPEND SANITIZERS "thread") 33 | endif() 34 | 35 | list(JOIN SANITIZERS "," LIST_OF_SANITIZERS) 36 | 37 | endif() 38 | 39 | if(LIST_OF_SANITIZERS) 40 | if(NOT "${LIST_OF_SANITIZERS}" STREQUAL "") 41 | target_compile_options(${project_name} 42 | INTERFACE -fsanitize=${LIST_OF_SANITIZERS}) 43 | target_link_libraries(${project_name} 44 | INTERFACE -fsanitize=${LIST_OF_SANITIZERS}) 45 | endif() 46 | endif() 47 | 48 | endfunction() 49 | -------------------------------------------------------------------------------- /lartcc/include/cc/backend/base.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * (c) 2021 Henrich Lauko 3 | * 4 | * Permission to use, copy, modify, and distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | #pragma once 18 | 19 | #include 20 | 21 | #include 22 | 23 | #include 24 | 25 | namespace lart::backend 26 | { 27 | struct base 28 | { 29 | struct testtaint { }; 30 | 31 | virtual ~base() = default; 32 | 33 | void lower( ir::intrinsic i ); 34 | void lower( llvm::CallInst *call, op::operation ); 35 | 36 | using callinst = llvm::CallInst*; 37 | virtual void lower_test_taint( ir::intrinsic ) = 0; 38 | 39 | virtual void lower( callinst c, op::freeze f ) = 0; 40 | virtual void lower( callinst c, op::unstash u ) = 0; 41 | virtual void lower( callinst c, op::unstash_taint u ) = 0; 42 | virtual void lower( callinst c, op::stash s ) = 0; 43 | 44 | virtual void lower( callinst c, op::dump s ) = 0; 45 | }; 46 | 47 | } // namespace lart::backend 48 | -------------------------------------------------------------------------------- /scripts/benchmark/Dockerfile: -------------------------------------------------------------------------------- 1 | # See here for image contents: https://github.com/microsoft/vscode-dev-containers/tree/v0.245.2/containers/cpp/.devcontainer/base.Dockerfile 2 | 3 | ARG VARIANT="ubuntu-22.04" 4 | FROM mcr.microsoft.com/vscode/devcontainers/cpp:0-${VARIANT} 5 | 6 | # 7 | # install deps 8 | # 9 | ENV DEBIAN_FRONTEND noninteractive 10 | 11 | RUN apt-get update \ 12 | && apt-get -y install --no-install-recommends \ 13 | software-properties-common python3-pip ccache cmake lld \ 14 | llvm-13 clang-13 libz3-dev z3 zip unzip tar llvm-13-dev \ 15 | ca-certificates apt-transport-https stress git \ 16 | && rm -rf /var/lib/apt/lists/* 17 | 18 | # 19 | # download lart 20 | # 21 | WORKDIR /usr/src/ 22 | RUN git clone --recurse-submodules -j8 https://github.com/xlauko/lart.git 23 | 24 | # 25 | # setup cmake 26 | # 27 | 28 | ARG REINSTALL_CMAKE_VERSION_FROM_SOURCE="3.24.2" 29 | 30 | RUN chmod +x /usr/src/lart/.devcontainer/reinstall-cmake.sh \ 31 | && /usr/src/lart/.devcontainer/reinstall-cmake.sh ${REINSTALL_CMAKE_VERSION_FROM_SOURCE} 32 | 33 | WORKDIR /usr/src/ 34 | 35 | ENV LLVM_INSTALL_DIR="/usr/lib/llvm-13/" 36 | ENV Z3_DIR "/usr/opt/z3-4.11.2-x64-glibc-2.31/" 37 | RUN mkdir -p "/usr/opt/" 38 | 39 | RUN wget -c "https://github.com/Z3Prover/z3/releases/download/z3-4.11.2/z3-4.11.2-x64-glibc-2.31.zip" -O z3.zip 40 | RUN unzip -q z3.zip -d /usr/opt 41 | RUN rm z3.zip 42 | 43 | # 44 | # build lart 45 | # 46 | WORKDIR /usr/src/lart 47 | 48 | RUN cmake --preset ninja-surveyor \ 49 | -DCMAKE_C_COMPILER=clang-14 \ 50 | -DCMAKE_CXX_COMPILER=clang++-14 51 | 52 | RUN cmake --build ./builds/ninja-surveyor 53 | 54 | ENV PATH="/usr/src/lart/scripts/benchmark:${PATH}" 55 | ENV PATH="/usr/src/lart/builds/ninja-surveyor/lartcc:${PATH}" 56 | -------------------------------------------------------------------------------- /lava/README.md: -------------------------------------------------------------------------------- 1 | # LAVA: A Library of Abstract VAlues 2 | 3 | This is a header-only C++ library which provides a number of abstract (value) 4 | domains. Each domain is implemented as a class (or class template, for 5 | parametric domains) and provides a number of methods which implement the 6 | individual operations of the domain. Not all domains need to implement all 7 | operations (more on that below), but all operations come from a fixed set that 8 | LART and LAMP understand. 9 | 10 | The domains in LAVA can come in three basic flavours, depending on the 11 | operations and semantics they possess. 12 | 13 | ## Scalar Domains 14 | 15 | These represent values that behave as the familiar scalars of a programming 16 | language: integers, floating-point numbers, booleans and similar types, each 17 | made up of a fixed number of bits with specific semantics. A scalar domain 18 | needs to implement basic operations from the LLVM instruction set: arithmetic, 19 | bit manipulation, conversions and comparisons (see `lamp/wrapper.hpp` for a 20 | definitive list). 21 | 22 | ## Array Domains 23 | 24 | An array domain has two other associated domains: the scalar 'index' domain, 25 | and the 'value' domain (which can be of arbitrary type and not necessarily a 26 | scalar). Arrays, unlike scalars, also have an 'identity' (an abstraction of 27 | 'address') and are *mutable*: the content of an array can be changed during a 28 | computation, but the altered array will still have the same identity. 29 | 30 | Since it is advantageous to model program memory as a disjoint set of objects 31 | (instead of a flat array of bytes), the indices we use are also split into two 32 | parts: one that identifies the object and another, which corresponds to the 33 | byte offset into that object. This essentially means that the 'index' domain 34 | models tuples (object, offset). 35 | -------------------------------------------------------------------------------- /lava/include/lava/support/mmaped_pointer.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * (c) 2021 Henrich Lauko 3 | * 4 | * Permission to use, copy, modify, and distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | #pragma once 18 | 19 | #include 20 | #include 21 | 22 | namespace __lava { 23 | 24 | template< typename T > struct mmap_deleter 25 | { 26 | void operator()( T *ptr ) const 27 | { 28 | ptr->~T(); 29 | munmap( ptr, sizeof( T ) ); 30 | } 31 | }; 32 | 33 | template< typename T > 34 | using unique_mapped_ptr = std::unique_ptr< T, mmap_deleter< T > >; 35 | 36 | template< typename T, typename... Args > 37 | unique_mapped_ptr< T > make_mmap_unique( Args &&... args ) 38 | { 39 | constexpr auto PROT_RW = PROT_READ | PROT_WRITE; 40 | constexpr auto MAP_ALLOC = MAP_PRIVATE | MAP_ANONYMOUS; 41 | 42 | if ( auto ptr = mmap( NULL, sizeof( T ), PROT_RW, MAP_ALLOC, -1, 0 ) ) { 43 | return unique_mapped_ptr< T >( new ( ptr ) T{ std::forward< Args >( args )... } ); 44 | } 45 | 46 | std::abort(); 47 | } 48 | 49 | } // namespace __lava 50 | -------------------------------------------------------------------------------- /test/lit.cfg.py: -------------------------------------------------------------------------------- 1 | # -*- Python -*- 2 | 3 | # Configuration file for the 'lit' test runner. 4 | 5 | import platform 6 | 7 | import lit.formats 8 | # Global instance of LLVMConfig provided by lit 9 | from lit.llvm import llvm_config 10 | from lit.llvm.subst import ToolSubst 11 | 12 | # name: The name of this test suite. 13 | # (config is an instance of TestingConfig created when discovering tests) 14 | config.name = 'lartcc' 15 | 16 | # testFormat: The test format to use to interpret tests. 17 | config.test_format = lit.formats.ShTest(not llvm_config.use_lit_shell) 18 | 19 | # suffixes: A list of file extensions to treat as test files. This is overriden 20 | # by individual lit.local.cfg files in the test subdirectories. 21 | config.suffixes = ['.ll', '.c', '.cpp'] 22 | 23 | # test_source_root: The root path where tests are located. 24 | config.test_source_root = os.path.dirname(__file__) 25 | 26 | config.test_exec_root = os.path.join(config.my_obj_root, 'test') 27 | 28 | # excludes: A list of directories to exclude from the testsuite. The 'Inputs' 29 | # subdirectories contain auxiliary inputs for various tests in their parent 30 | # directories. 31 | config.excludes = [] 32 | 33 | tool_substitutions = [ 34 | ToolSubst('%lartcc', os.path.join(config.lart_binary_dir, 'Debug/lartcc')), 35 | ToolSubst('%lartcc++', os.path.join(config.lart_binary_dir, 'Debug/lartcc')), 36 | ToolSubst('%testrun', os.path.join(config.my_obj_root, 'scripts/testrun.sh')) 37 | ] 38 | 39 | llvm_config.add_tool_substitutions(tool_substitutions) 40 | 41 | # The LIT variable to hold the file extension for shared libraries (this is 42 | # platform dependent) 43 | config.substitutions.append(('%shlibext', config.llvm_shlib_ext)) 44 | # The LIT variable to hold the location of plugins/libraries 45 | config.substitutions.append(('%shlibdir', config.llvm_shlib_dir)) 46 | 47 | 48 | -------------------------------------------------------------------------------- /lamp/trivial.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * (c) 2020 Henrich Lauko 3 | * (c) 2020 Petr Ročkai 4 | * 5 | * Permission to use, copy, modify, and distribute this software for any 6 | * purpose with or without fee is hereby granted, provided that the above 7 | * copyright notice and this permission notice appear in all copies. 8 | * 9 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 | */ 17 | 18 | #include 19 | #include 20 | 21 | #include 22 | #include 23 | 24 | namespace __lamp 25 | { 26 | struct trivial 27 | { 28 | using unit = __lava::unit< tagged_storage >; 29 | using constant = __lava::constant< tagged_storage >; 30 | using doms = domain_list< unit, constant >; 31 | 32 | using scalar_lift_dom = constant; 33 | using scalar_any_dom = unit; 34 | using array_lift_dom = unit; 35 | using array_any_dom = unit; 36 | 37 | static constexpr int join( int a, int b ) noexcept 38 | { 39 | if ( a == doms::idx< constant > ) return b; 40 | if ( b == doms::idx< constant > ) return a; 41 | 42 | return doms::idx< unit >; 43 | } 44 | }; 45 | 46 | using meta_domain = semilattice< trivial >; 47 | 48 | } // namespace __lamp 49 | 50 | #include "wrapper.hpp" 51 | -------------------------------------------------------------------------------- /lartcc/include/cc/preprocess.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * (c) 2021 Henrich Lauko 3 | * 4 | * Permission to use, copy, modify, and distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | #pragma once 18 | 19 | #include 20 | #include 21 | #include 22 | 23 | #include 24 | 25 | #include 26 | 27 | #include 28 | #include 29 | 30 | #include 31 | 32 | namespace lart 33 | { 34 | using operation = lart::op::operation; 35 | 36 | struct preprocessor : sc::with_context 37 | { 38 | explicit preprocessor( llvm::Module &m ) : sc::with_context( m ), module( m ) {} 39 | 40 | void run( llvm::Function *fn ); 41 | 42 | void lower_cmps( llvm::Function *fn ); 43 | 44 | void lower_selects( llvm::Function *fn ); 45 | 46 | inline static const std::string tag = "lart.abstract.preprocessed"; 47 | 48 | llvm::Module &module; 49 | }; 50 | 51 | using dependence = std::pair< llvm::Value*, llvm::Instruction* >; 52 | 53 | sc::generator< dependence > lower_pointer_arithmetic( llvm::GetElementPtrInst *gep ); 54 | 55 | } // namespace lart 56 | -------------------------------------------------------------------------------- /scripts/svcomp/utils/config.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import tempfile 4 | from typing import List, Optional 5 | 6 | from . properties import property 7 | from . log import error, logger 8 | 9 | 10 | def unsupported(prp: property) -> None: 11 | error(f"property {prp} not supported yet") 12 | 13 | 14 | class config: 15 | def __init__(self, lartcc, benchmark, properties, property_strings, architecture, lamp, workdir): 16 | # path to lartcc binary 17 | self.lartcc : str = lartcc 18 | 19 | self.workdir : str = workdir if workdir else tempfile.mkdtemp() 20 | self.tmpworkdir : bool = workdir is None 21 | 22 | # path to benchmark 23 | self.benchmark : str = benchmark 24 | 25 | # property setup 26 | self.properties : List[property] = properties 27 | self.property_strings : List[str] = property_strings 28 | 29 | # architecture 30 | self.architecture = architecture 31 | 32 | # lart options config 33 | self.symbolic : bool = False 34 | self.leakcheck : bool = False 35 | self.floats : bool = False 36 | self.pointer : bool = False 37 | self.globals : bool = False 38 | self.sequential : bool = True 39 | self.witness : bool = True 40 | self.report : Optional[str] = None 41 | self.lamp : str = lamp 42 | 43 | # compiler options 44 | self.libm : bool = False 45 | 46 | # file offset for line debug info 47 | self.file_offset = 0 48 | 49 | self.setup_property_options() 50 | 51 | def setup_property_options(self): 52 | supported_list = [property.reach] 53 | 54 | for prp in self.properties: 55 | if prp not in supported_list: 56 | unsupported(prp) 57 | if prp == property.memsafety: 58 | self.leakcheck = True 59 | -------------------------------------------------------------------------------- /lartcc/include/cc/util.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * (c) 2021 Henrich Lauko 3 | * 4 | * Permission to use, copy, modify, and distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | #pragma once 18 | 19 | #include 20 | 21 | namespace lart::util 22 | { 23 | template< typename... Ts > 24 | bool is_one_of( llvm::Value *v ) { 25 | return ( llvm::isa< Ts >( v ) || ... ); 26 | } 27 | 28 | // Type is not under Value, therefore we need separate function 29 | template< typename ... Ts > 30 | bool is_one_of_types( llvm::Type *t ) 31 | { 32 | return ( llvm::isa< Ts >( t ) || ... ); 33 | } 34 | 35 | inline bool tag_function_with_metadata( llvm::Function &fn, std::string tag ) { 36 | if ( fn.getMetadata( tag ) ) 37 | return false; 38 | auto & ctx = fn.getContext(); 39 | auto dummy = llvm::MDString::get( ctx, "dummy" ); 40 | auto meta = llvm::MDTuple::get( ctx , { dummy } ); 41 | fn.setMetadata( tag, meta ); 42 | return true; 43 | } 44 | 45 | template struct overloaded : Ts... { using Ts::operator()...; }; 46 | template overloaded(Ts...) -> overloaded; 47 | 48 | } // namespace lart 49 | -------------------------------------------------------------------------------- /lartcc/include/cc/arguments.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * (c) 2022 Henrich Lauko 3 | * 4 | * Permission to use, copy, modify, and distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | #include 18 | #include 19 | 20 | #include 21 | 22 | namespace lart::op { 23 | 24 | static inline sc::generator< sc::value > duplicated_arguments(const operation &op, const shadow_map &shadows) 25 | { 26 | for ( auto arg : op::arguments(op) ) { 27 | switch (arg.type) { 28 | case argtype::abstract: 29 | co_yield arg.value; 30 | co_yield op::abstract_pointer(); 31 | break; 32 | case argtype::unpack: 33 | case argtype::with_taint: 34 | co_yield shadows.get(arg.value); 35 | co_yield arg.value; 36 | co_yield op::abstract_pointer(); 37 | break; 38 | case argtype::test: 39 | co_yield shadows.get(arg.value); 40 | break; 41 | case argtype::concrete: 42 | co_yield arg.value; 43 | } 44 | } 45 | } 46 | 47 | } // namesapce lart::op 48 | -------------------------------------------------------------------------------- /lartcc/include/cc/assume.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * (c) 2016 Henrich Lauko 3 | * 4 | * Permission to use, copy, modify, and distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | #include 18 | #include 19 | #include 20 | 21 | #include 22 | 23 | #include 24 | 25 | namespace lart::constrain 26 | { 27 | struct assumption 28 | { 29 | assumption( llvm::Value *con, llvm::Constant *exp ) 30 | : cond( con ), expect( exp ) 31 | {} 32 | 33 | llvm::Value *cond; 34 | llvm::Constant *expect; 35 | }; 36 | 37 | using basicblock = llvm::BasicBlock; 38 | 39 | struct bbedge 40 | { 41 | bbedge( basicblock *f, basicblock *t ) : from( f ), to( t ) {} 42 | 43 | void hide(); 44 | void show(); 45 | 46 | basicblock *from; 47 | basicblock *to; 48 | }; 49 | 50 | struct assume_edge : bbedge 51 | { 52 | assume_edge( basicblock *f, basicblock *t ) : bbedge( f, t ) {} 53 | 54 | op::operation assume( assumption ass ); 55 | unsigned succ_idx() const; 56 | }; 57 | 58 | sc::generator< op::operation > assume( llvm::BranchInst *br, llvm::Value *cond ); 59 | 60 | } // namespace lart::constrain 61 | -------------------------------------------------------------------------------- /lamp/pa.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * (c) 2020 Henrich Lauko 3 | * 4 | * Permission to use, copy, modify, and distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | #include 18 | #include 19 | 20 | namespace __lamp 21 | { 22 | using term = __lava::term< tagged_storage >; 23 | using pointers = adaptor::pointers< tagged_storage, term >; 24 | using meta_domain = semilattice< pointers >; 25 | 26 | } // namespace __lamp 27 | 28 | #include "wrapper.hpp" 29 | 30 | namespace __lava 31 | { 32 | void * __pointers_state; 33 | } 34 | 35 | [[gnu::constructor]] void __lamp_pointers_init() 36 | { 37 | using namespace __lava; 38 | using state_t = __lamp::pointers::pa::state_t; 39 | __pointers_state = std::malloc( sizeof( state_t ) ); 40 | new ( __pointers_state ) state_t; 41 | } 42 | 43 | [[gnu::destructor]] void __lamp_pointers_fini() 44 | { 45 | using namespace __lava; 46 | using state_t = __lamp::pointers::pa::state_t; 47 | 48 | auto state = static_cast< state_t* >( __pointers_state ); 49 | state->map.clear(); 50 | std::free( state ); 51 | } 52 | 53 | 54 | extern "C" void* __lamp_lift_objid( void* p ) 55 | { 56 | return lift( [] ( auto ptr ) { 57 | return __lamp::meta_domain( __lamp::pointers::lift_objid( ptr ) ); 58 | }, p ); 59 | } -------------------------------------------------------------------------------- /lartcc/include/cc/ir.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * (c) 2021 Henrich Lauko 3 | * 4 | * Permission to use, copy, modify, and distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | #pragma once 18 | 19 | #include 20 | 21 | #include 22 | 23 | #include 24 | 25 | namespace lart::ir 26 | { 27 | using operation = lart::op::operation; 28 | 29 | struct intrinsic 30 | { 31 | llvm::CallInst *call; 32 | operation op; 33 | }; 34 | 35 | namespace arg 36 | { 37 | struct with_taint 38 | { 39 | llvm::Use &taint; 40 | llvm::Use &concrete; 41 | llvm::Use &abstract; 42 | }; 43 | 44 | struct without_taint_concrete 45 | { 46 | llvm::Use &concrete; 47 | }; 48 | 49 | struct without_taint_abstract 50 | { 51 | llvm::Use &concrete; 52 | llvm::Use &abstract; 53 | }; 54 | 55 | } // namespace arg 56 | 57 | using argument = std::variant< arg::with_taint, arg::without_taint_concrete, arg::without_taint_abstract >; 58 | 59 | namespace detail 60 | { 61 | static auto invoke = [] (auto f) { return [=] ( auto a ) { return std::visit(f, a); }; }; 62 | } // namespace detail 63 | 64 | } // namespace lart::ir 65 | -------------------------------------------------------------------------------- /.devcontainer/reinstall-cmake.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | #------------------------------------------------------------------------------------------------------------- 3 | # Copyright (c) Microsoft Corporation. All rights reserved. 4 | # Licensed under the MIT License. See https://go.microsoft.com/fwlink/?linkid=2090316 for license information. 5 | #------------------------------------------------------------------------------------------------------------- 6 | # 7 | set -e 8 | 9 | CMAKE_VERSION=${1:-"none"} 10 | 11 | if [ "${CMAKE_VERSION}" = "none" ]; then 12 | echo "No CMake version specified, skipping CMake reinstallation" 13 | exit 0 14 | fi 15 | 16 | # Cleanup temporary directory and associated files when exiting the script. 17 | cleanup() { 18 | EXIT_CODE=$? 19 | set +e 20 | if [[ -n "${TMP_DIR}" ]]; then 21 | echo "Executing cleanup of tmp files" 22 | rm -Rf "${TMP_DIR}" 23 | fi 24 | exit $EXIT_CODE 25 | } 26 | trap cleanup EXIT 27 | 28 | 29 | echo "Installing CMake..." 30 | apt-get -y purge --auto-remove cmake 31 | mkdir -p /opt/cmake 32 | 33 | architecture=$(dpkg --print-architecture) 34 | case "${architecture}" in 35 | arm64) 36 | ARCH=aarch64 ;; 37 | amd64) 38 | ARCH=x86_64 ;; 39 | *) 40 | echo "Unsupported architecture ${architecture}." 41 | exit 1 42 | ;; 43 | esac 44 | 45 | CMAKE_BINARY_NAME="cmake-${CMAKE_VERSION}-linux-${ARCH}.sh" 46 | CMAKE_CHECKSUM_NAME="cmake-${CMAKE_VERSION}-SHA-256.txt" 47 | TMP_DIR=$(mktemp -d -t cmake-XXXXXXXXXX) 48 | 49 | echo "${TMP_DIR}" 50 | cd "${TMP_DIR}" 51 | 52 | curl -sSL "https://github.com/Kitware/CMake/releases/download/v${CMAKE_VERSION}/${CMAKE_BINARY_NAME}" -O 53 | curl -sSL "https://github.com/Kitware/CMake/releases/download/v${CMAKE_VERSION}/${CMAKE_CHECKSUM_NAME}" -O 54 | 55 | sha256sum -c --ignore-missing "${CMAKE_CHECKSUM_NAME}" 56 | sh "${TMP_DIR}/${CMAKE_BINARY_NAME}" --prefix=/opt/cmake --skip-license 57 | 58 | ln -s /opt/cmake/bin/cmake /usr/local/bin/cmake 59 | -------------------------------------------------------------------------------- /lartcc/include/cc/tristate.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * (c) 2021 Henrich Lauko 3 | * 4 | * Permission to use, copy, modify, and distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | #pragma once 18 | 19 | #include 20 | 21 | namespace lart 22 | { 23 | struct tristate 24 | { 25 | enum { no, yes, maybe } value; 26 | explicit tristate( bool v ) : value( v ? yes : no ) {} 27 | tristate( decltype( value ) v ) : value( v ) {} 28 | 29 | auto operator<=>( const tristate & ) const = default; 30 | 31 | operator bool() const 32 | { 33 | return value != no; 34 | } 35 | 36 | template< typename stream > 37 | friend auto operator<<( stream &s, tristate t ) -> decltype( s << "" ) 38 | { 39 | switch ( t.value ) { 40 | case no: return s << "no"; 41 | case yes: return s << "yes"; 42 | case maybe: return s << "maybe"; 43 | default: llvm_unreachable( "unknown tristate value" ); 44 | } 45 | } 46 | }; 47 | 48 | inline tristate join( tristate a, tristate b ) 49 | { 50 | if ( a.value == b.value ) 51 | return a; 52 | return tristate( tristate::maybe ); 53 | } 54 | 55 | } // namespace lart 56 | -------------------------------------------------------------------------------- /lava/include/lava/empty.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * (c) 2021 Henrich Lauko 3 | * 4 | * Permission to use, copy, modify, and distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | #pragma once 18 | 19 | #include 20 | #include 21 | #include 22 | 23 | namespace __lava 24 | { 25 | struct empty_storage {}; 26 | 27 | /* Minimal domain example. */ 28 | template< template< typename > typename storage > 29 | struct empty : storage< empty_storage > 30 | , domain_mixin< empty< storage > > 31 | { 32 | using base = storage< empty_storage >; 33 | using mixin = domain_mixin< unit >; 34 | using bw = typename mixin::bw; 35 | 36 | using base::base; 37 | 38 | using ev = empty; 39 | using er = const empty &; 40 | 41 | template< typename type > static ev lift( const type& ) { return {}; } 42 | template< typename type > static ev any() { return {}; } 43 | template< typename type > static ev any(const variadic_list & /* args */) { return {}; } 44 | template< typename type > static ev any( type /* from */, type /* to */) { return {}; } 45 | 46 | static void assume( er, bool ) {} 47 | 48 | static tristate to_tristate( er ) { return maybe; } 49 | }; 50 | 51 | } // namespace __lava 52 | -------------------------------------------------------------------------------- /runtime/native/stash.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * (c) 2020 Henrich Lauko 3 | * 4 | * Permission to use, copy, modify, and distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | #pragma once 18 | 19 | #include 20 | #include 21 | 22 | namespace __lart::rt 23 | { 24 | constexpr std::size_t abstract_stack_size = 256; 25 | 26 | using stash_stack_value_t = std::uint64_t; 27 | 28 | extern thread_local std::uint8_t stash_stack_top; 29 | extern thread_local stash_stack_value_t stash_stack[]; 30 | 31 | extern thread_local std::uint8_t taint_stack_top; 32 | extern thread_local bool taint_stack[]; 33 | 34 | template< typename T > void stash( T value ) 35 | { 36 | auto &place = stash_stack[ stash_stack_top++ ]; 37 | if constexpr ( std::is_pointer_v< T > ) 38 | place = reinterpret_cast< std::uintptr_t >( value ); 39 | else 40 | place = static_cast< std::uint64_t >( value ); 41 | } 42 | 43 | template< typename T > T unstash() 44 | { 45 | if constexpr ( std::is_pointer_v< T > ) 46 | return reinterpret_cast< T >( stash_stack[ --stash_stack_top ] ); 47 | else 48 | return static_cast< T >( stash_stack[ --stash_stack_top ] ); 49 | } 50 | 51 | void stash_taint( bool taint ); 52 | bool unstash_taint(); 53 | 54 | } // namespace __lart::rt 55 | -------------------------------------------------------------------------------- /runtime/native/trace.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * (c) 2020 Henrich Lauko 3 | * 4 | * Permission to use, copy, modify, and distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | #pragma once 18 | 19 | #include 20 | #include 21 | 22 | namespace __lart::rt 23 | { 24 | struct trace_t 25 | { 26 | struct choices_t { 27 | 28 | ~choices_t() { free( trace ); } 29 | 30 | inline void push( int choice ) 31 | { 32 | size += 1; 33 | trace = static_cast< int* >( 34 | realloc( trace, size * sizeof( int ) ) 35 | ); 36 | trace[size - 1] = choice; 37 | } 38 | 39 | inline auto begin() { return trace; } 40 | inline auto end() { return trace + size; } 41 | 42 | unsigned size = 0; 43 | int* trace = nullptr; 44 | }; 45 | 46 | ~trace_t() 47 | { 48 | if ( choices.trace ) { 49 | for ( auto c : choices ) 50 | fprintf( stderr, "[lart-choice] %d\n", c ); 51 | fprintf( stderr, "----------------\n" ); 52 | } 53 | } 54 | 55 | inline void push_choice( int c ) { choices.push( c ); } 56 | 57 | choices_t choices; 58 | }; 59 | 60 | extern trace_t trace; 61 | } // namespace __lart::rt 62 | -------------------------------------------------------------------------------- /lartcc/include/cc/syntactic.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * (c) 2020 Henrich Lauko 3 | * 4 | * Permission to use, copy, modify, and distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | #pragma once 18 | 19 | #include 20 | #include 21 | #include 22 | #include 23 | 24 | #include 25 | 26 | #include 27 | #include 28 | 29 | namespace lart 30 | { 31 | using operation = lart::op::operation; 32 | 33 | struct syntactic : sc::with_context 34 | { 35 | explicit syntactic( sc::module_ref m, const dfa::types &t, shadow_map &s ) 36 | : sc::with_context( m ), types( t ), shadows( s ), module( m ) 37 | {} 38 | 39 | std::optional< operation > make_operation( sc::value value ); 40 | 41 | sc::generator< operation > unstash_toprocess(); 42 | sc::generator< operation > toprocess(); 43 | std::optional< ir::intrinsic > process( operation op ); 44 | 45 | void propagate_identity( sc::value from ); 46 | 47 | void update_places( sc::value concrete ); 48 | 49 | std::map< sc::value, sc::value > abstract; 50 | std::map< sc::value, sc::value > identity; 51 | std::map< sc::value, std::vector< ir::argument > > places; 52 | 53 | const dfa::types &types; 54 | shadow_map &shadows; 55 | sc::module_ref module; 56 | }; 57 | 58 | } // namespace lart 59 | -------------------------------------------------------------------------------- /runtime/native/lart.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * (c) 2020 Henrich Lauko 3 | * 4 | * Permission to use, copy, modify, and distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | #include "fault.hpp" 18 | #include "stash.hpp" 19 | #include "shadow.hpp" 20 | #include "choose.hpp" 21 | 22 | #include 23 | 24 | extern "C" 25 | { 26 | 27 | void * __lart_unstash() 28 | { 29 | return __lart::rt::unstash< void * >(); 30 | } 31 | 32 | bool __lart_unstash_taint() 33 | { 34 | return __lart::rt::unstash_taint(); 35 | } 36 | 37 | void __lart_stash( bool taint, void *val ) 38 | { 39 | __lart::rt::stash( val ); 40 | __lart::rt::stash_taint( taint ); 41 | } 42 | 43 | int __lart_choose(int count) 44 | { 45 | return __lart::rt::choose(count); 46 | } 47 | 48 | void __lart_cancel() 49 | { 50 | std::exit( EXIT_SUCCESS ); 51 | } 52 | 53 | bool __lart_test_taint( void *addr, size_t bytes ) 54 | { 55 | return __lart::rt::test_taint( addr, bytes ); 56 | } 57 | 58 | void __assert_fail(const char *assertion, const char *file, unsigned int line, const char *func) 59 | { 60 | using fault_event = __lart::rt::fault_event; 61 | using fault_type = __lart::rt::fault_type; 62 | 63 | auto loc = __lart::rt::source_location(file, func, line); 64 | auto msg = __lart::rt::report_payload(assertion); 65 | __lart::rt::fault(fault_event{fault_type::assert_failed, loc, msg}); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /ports/svf/portfile.cmake: -------------------------------------------------------------------------------- 1 | vcpkg_from_github( 2 | OUT_SOURCE_PATH SOURCE_PATH 3 | REPO xlauko/SVF 4 | REF 76e14b2a51db9f6ece094975f049cfbbbc58347a 5 | SHA512 ec2fd7d48ac64610f681ce24298c0208ecd0612ee8b0f663feca58f50a030ff9c8faa853d77a0b15165a995d041c6c6552cc8dce6fba170751b70f348986662e 6 | HEAD_REF main 7 | ) 8 | 9 | # Set this to a valid LLVM installation dir 10 | if ( DEFINED ENV{LLVM_INSTALL_DIR} AND NOT DEFINED LLVM_INSTALL_DIR ) 11 | set( LLVM_INSTALL_DIR "$ENV{LLVM_INSTALL_DIR}" ) 12 | endif() 13 | 14 | set( LLVM_INSTALL_DIR "" CACHE PATH "LLVM installation directory" ) 15 | message( STATUS "Using LLVM_INSTALL_DIR: ${LLVM_INSTALL_DIR}" ) 16 | 17 | # A bit of a sanity checking 18 | set( LLVM_INCLUDE_DIR "${LLVM_INSTALL_DIR}/include/llvm" ) 19 | if( NOT EXISTS "${LLVM_INCLUDE_DIR}" ) 20 | message( FATAL_ERROR " LLVM_INCLUDE_DIR (${LLVM_INCLUDE_DIR}) is invalid." ) 21 | endif() 22 | 23 | set( LLVM_CMAKE_FILE "${LLVM_INSTALL_DIR}/lib/cmake/llvm/LLVMConfig.cmake" ) 24 | if( NOT EXISTS "${LLVM_CMAKE_FILE}" ) 25 | message(FATAL_ERROR " LLVM_CMAKE_FILE (${LLVM_CMAKE_FILE}) is invalid.") 26 | endif() 27 | 28 | set( LLVM_DIR "${LLVM_INSTALL_DIR}/lib/cmake/llvm/" CACHE PATH "LLVM config path" ) 29 | message( STATUS "Using LLVM_DIR: ${LLVM_DIR}" ) 30 | 31 | # Set this to a valid Z3 installation dir 32 | if ( DEFINED ENV{Z3_DIR} AND NOT DEFINED Z3_DIR ) 33 | set( Z3_DIR "$ENV{Z3_DIR}" ) 34 | endif() 35 | 36 | set( Z3_DIR "" CACHE PATH "Z3 installation directory" ) 37 | message( STATUS "Using Z3_DIR: ${Z3_DIR}" ) 38 | 39 | vcpkg_cmake_configure( 40 | SOURCE_PATH "${SOURCE_PATH}" 41 | OPTIONS 42 | -DLLVM_DIR=${LLVM_DIR} 43 | -DZ3_DIR=${Z3_DIR} 44 | -DCMAKE_CXX_FLAGS=-Wno-unused-variable 45 | ) 46 | 47 | vcpkg_cmake_install() 48 | vcpkg_cmake_config_fixup( 49 | PACKAGE_NAME "svf" 50 | CONFIG_PATH lib/cmake/SVF 51 | ) 52 | 53 | file( REMOVE_RECURSE "${CURRENT_PACKAGES_DIR}/debug/include" ) 54 | 55 | file( 56 | INSTALL "${SOURCE_PATH}/LICENSE.TXT" 57 | DESTINATION "${CURRENT_PACKAGES_DIR}/share/${PORT}" 58 | RENAME copyright 59 | ) 60 | 61 | if ( EXISTS "${CMAKE_CURRENT_LIST_DIR}/${lower_package}_usage" ) 62 | file( 63 | INSTALL "${CMAKE_CURRENT_LIST_DIR}/${lower_package}_usage" 64 | DESTINATION "${CURRENT_PACKAGES_DIR}/share/${lower_package}" 65 | RENAME usage 66 | ) 67 | endif() 68 | -------------------------------------------------------------------------------- /lamp/include/lamp/adaptor/pa.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * (c) 2020 Henrich Lauko 3 | * 4 | * Permission to use, copy, modify, and distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | #pragma once 18 | 19 | #include 20 | #include 21 | #include 22 | 23 | #include 24 | 25 | namespace __lamp::adaptor 26 | { 27 | template< template< typename > typename storage, typename arithmetic > 28 | struct pointers 29 | { 30 | using pa = __lava::pointer_arith< tagged_storage, arithmetic >; 31 | using constant = __lava::constant< tagged_storage >; 32 | 33 | using doms = domain_list< constant, arithmetic, pa >; 34 | using top = arithmetic; 35 | 36 | static constexpr auto pa_idx = doms::template idx< pa >; 37 | static constexpr auto ar_idx = doms::template idx< arithmetic >; 38 | static constexpr auto co_idx = doms::template idx< constant >; 39 | 40 | using scalar_lift_dom = constant; 41 | using scalar_any_dom = arithmetic; 42 | using array_lift_dom = constant; 43 | using array_any_dom = arithmetic; 44 | 45 | static constexpr int join( int a, int b ) noexcept 46 | { 47 | if ( a == co_idx ) 48 | return b; 49 | if ( b == co_idx ) 50 | return a; 51 | if ( a == pa_idx || b == pa_idx ) 52 | return pa_idx; 53 | return ar_idx; 54 | } 55 | 56 | static pa lift_objid( void* p ) { return pa::lift_objid( p ); } 57 | }; 58 | 59 | } // namespace __lamp::adaptor -------------------------------------------------------------------------------- /lartcc/pass.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * (c) 2020 Henrich Lauko 3 | * 4 | * Permission to use, copy, modify, and distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | #include 18 | #include 19 | 20 | #include 21 | #include 22 | 23 | namespace lart 24 | { 25 | llvm::PreservedAnalyses lartcc::run( 26 | llvm::Module & mod, llvm::ModuleAnalysisManager & /* mgr */ 27 | ) { 28 | _driver = std::make_unique< driver >( mod ); 29 | return _driver->run(); 30 | } 31 | 32 | } // namespace lart 33 | 34 | llvm::PassPluginLibraryInfo get_lartcc_plugin_info() { 35 | return {LLVM_PLUGIN_API_VERSION, "lartcc", LLVM_VERSION_STRING, 36 | [](llvm::PassBuilder &bld) { 37 | // TODO find out the best spot to run lart 38 | bld.registerPipelineStartEPCallback( 39 | [](llvm::ModulePassManager &mgr, llvm::PassBuilder::OptimizationLevel) { 40 | return mgr.addPass(lart::lartcc()), true; 41 | } 42 | ); 43 | 44 | bld.registerPipelineParsingCallback( 45 | [](llvm::StringRef name, llvm::ModulePassManager &mgr, 46 | llvm::ArrayRef) 47 | { 48 | if (name == "lartcc") 49 | return mgr.addPass(lart::lartcc()), true; 50 | return false; 51 | } 52 | ); 53 | } 54 | }; 55 | } 56 | 57 | extern "C" LLVM_ATTRIBUTE_WEAK 58 | llvm::PassPluginLibraryInfo llvmGetPassPluginInfo() { 59 | return get_lartcc_plugin_info(); 60 | } 61 | -------------------------------------------------------------------------------- /runtime/include/runtime/stream.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * (c) 2021 Henrich Lauko 3 | * 4 | * Permission to use, copy, modify, and distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | #pragma once 18 | 19 | namespace __lart::rt 20 | { 21 | struct file_stream 22 | { 23 | explicit file_stream(std::FILE *file = stderr) : _file(file) {} 24 | ~file_stream() { std::fflush(_file); } 25 | 26 | file_stream& operator<<(std::string_view str) noexcept 27 | { 28 | std::fwrite( str.data(), sizeof(char), str.size(), _file ); 29 | return *this; 30 | } 31 | 32 | file_stream& operator<<(char c) noexcept 33 | { 34 | std::fprintf( _file, "%c", c ); 35 | return *this; 36 | } 37 | 38 | file_stream& operator<<(unsigned int ui) noexcept 39 | { 40 | std::fprintf( _file, "%u", ui ); 41 | return *this; 42 | } 43 | 44 | file_stream& operator<<(int si) noexcept 45 | { 46 | std::fprintf( _file, "%d", si ); 47 | return *this; 48 | } 49 | 50 | file_stream& operator<<(unsigned short us) noexcept 51 | { 52 | std::fprintf( _file, "%hu", us ); 53 | return *this; 54 | } 55 | 56 | file_stream& operator<<(short ss) noexcept 57 | { 58 | std::fprintf( _file, "%hd", ss ); 59 | return *this; 60 | } 61 | 62 | file_stream& operator<<(unsigned long ul) noexcept 63 | { 64 | std::fprintf( _file, "%lu", ul ); 65 | return *this; 66 | } 67 | 68 | file_stream& operator<<(long sl) noexcept 69 | { 70 | std::fprintf( _file, "%ld", sl ); 71 | return *this; 72 | } 73 | 74 | std::FILE* stream() { return _file; } 75 | 76 | protected: 77 | std::FILE *_file; 78 | }; 79 | 80 | } // namespace __lart::rt -------------------------------------------------------------------------------- /pres/dataflow render example/dataflow.py: -------------------------------------------------------------------------------- 1 | from IPython.display import display, Javascript, HTML 2 | 3 | from enum import Enum, auto 4 | from graphviz import Digraph 5 | from typing import Optional 6 | 7 | 8 | class NodeKind(Enum): 9 | Entry = auto() 10 | Expr = auto() 11 | Choose = auto() 12 | Error = auto() 13 | 14 | 15 | NodeId = str 16 | 17 | 18 | class Node: 19 | def __init__(self, id: NodeId, label: str, kind: NodeKind) -> None: 20 | self.id: NodeId = id 21 | self.label: str = label 22 | self.kind: NodeKind = kind 23 | 24 | 25 | class Edge: 26 | def __init__(self, src: NodeId, dst: NodeId) -> None: 27 | self.src: NodeId = src 28 | self.dst: NodeId = dst 29 | 30 | 31 | class Dataflow: 32 | def __init__(self) -> None: 33 | self.nodes: List[Node] = [] 34 | self.edges: List[Edge] = [] 35 | self.prev: Optional[NodeId] = None 36 | 37 | def set_node_style(self, 38 | dot: Digraph, 39 | kind: NodeKind, 40 | id: NodeId) -> None: 41 | if kind == NodeKind.Entry: 42 | dot.attr('node', shape='none') 43 | if kind == NodeKind.Expr: 44 | if id == self.prev: 45 | dot.attr('node', shape='box', style='filled', color='lightgrey') 46 | else: 47 | dot.attr('node', shape='box') 48 | if kind == NodeKind.Choose: 49 | if id == self.prev: 50 | dot.attr('node', shape='diamond', style='filled', color='lightgrey') 51 | else: 52 | dot.attr('node', shape='diamond') 53 | 54 | def render_edge(self, dot: Digraph, e: Edge) -> None: 55 | dot.edge(e.src, e.dst) 56 | 57 | def render_node(self, dot: Digraph, n: Node) -> Node: 58 | self.set_node_style(dot, n.kind, n.id) 59 | dot.node(n.id, n.label) 60 | 61 | def render(self) -> None: 62 | dot = Digraph() 63 | 64 | for n in self.nodes: 65 | self.render_node(dot, n) 66 | for e in self.edges: 67 | self.render_edge(dot, e) 68 | 69 | draw_dataflow_graph(dot_to_string(dot)) 70 | 71 | def add_edge(self, e: Edge) -> None: 72 | self.edges.append(e) 73 | 74 | def add_node(self, n: Node) -> None: 75 | self.nodes.append(n) 76 | 77 | if self.prev: 78 | self.add_edge(Edge(self.prev, n.id)) 79 | self.prev = n.id 80 | 81 | 82 | def draw_dataflow_graph(dot: str) -> None: 83 | display( 84 | Javascript(""" 85 | d3.select("#graph").graphviz() 86 | .renderDot('%s'); 87 | """ % dot)) 88 | 89 | 90 | def dot_to_string(dot: Digraph) -> str: 91 | return str(dot.source.replace('\n', '\\n').replace('\t', '\\t')) 92 | -------------------------------------------------------------------------------- /.clang-format: -------------------------------------------------------------------------------- 1 | Language: Cpp 2 | Standard: c++20 3 | ColumnLimit: 90 4 | IndentWidth: 4 5 | TabWidth: 4 6 | UseTab: Never 7 | AccessModifierOffset: -4 8 | AlignAfterOpenBracket: Align 9 | AlignConsecutiveAssignments: true 10 | AlignConsecutiveDeclarations: false 11 | AlignConsecutiveMacros: false 12 | AlignEscapedNewlines: true 13 | AlignOperands: true 14 | AlignTrailingComments: true 15 | AllowAllArgumentsOnNextLine: false 16 | AllowAllConstructorInitializersOnNextLine: false 17 | AllowShortBlocksOnASingleLine: true 18 | AllowShortCaseLabelsOnASingleLine: true 19 | AllowShortFunctionsOnASingleLine: true 20 | AllowShortIfStatementsOnASingleLine: true 21 | AllowShortLambdasOnASingleLine: true 22 | AllowShortLoopsOnASingleLine: true 23 | AlwaysBreakAfterReturnType: None 24 | AlwaysBreakBeforeMultilineStrings: false 25 | AlwaysBreakTemplateDeclarations: MultiLine 26 | BinPackArguments: false 27 | BinPackParameters: false 28 | BreakBeforeBraces: Custom 29 | BraceWrapping: 30 | AfterCaseLabel: false 31 | AfterClass: false 32 | AfterControlStatement: MultiLine 33 | AfterEnum: false 34 | AfterFunction: true 35 | AfterNamespace: true 36 | AfterStruct: true 37 | AfterUnion: true 38 | AfterExternBlock: true 39 | BeforeCatch: false 40 | BeforeElse: false 41 | IndentBraces: true 42 | SplitEmptyFunction: false 43 | SplitEmptyRecord: false 44 | SplitEmptyNamespace: false 45 | BreakBeforeBinaryOperators: NonAssignment 46 | BreakBeforeTernaryOperators: true 47 | BreakConstructorInitializers: BeforeComma 48 | BreakInheritanceList: BeforeComma 49 | BreakStringLiterals: false 50 | CompactNamespaces: false 51 | ConstructorInitializerAllOnOneLineOrOnePerLine: true 52 | ConstructorInitializerIndentWidth: 4 53 | ContinuationIndentWidth: 4 54 | Cpp11BracedListStyle: false 55 | FixNamespaceComments: true 56 | IncludeBlocks: Regroup 57 | IndentCaseLabels: true 58 | IndentGotoLabels: false 59 | IndentPPDirectives: BeforeHash 60 | IndentWrappedFunctionNames: false 61 | KeepEmptyLinesAtTheStartOfBlocks: false 62 | MaxEmptyLinesToKeep: 1 63 | NamespaceIndentation: All 64 | PointerAlignment: Right 65 | SortIncludes: true 66 | SortUsingDeclarations: true 67 | SpaceAfterCStyleCast: true 68 | SpaceAfterLogicalNot: false 69 | SpaceAfterTemplateKeyword: false 70 | SpaceBeforeAssignmentOperators: true 71 | SpaceBeforeCpp11BracedList: true 72 | SpaceBeforeCtorInitializerColon: true 73 | SpaceBeforeInheritanceColon: true 74 | SpaceBeforeParens: ControlStatements 75 | SpaceBeforeRangeBasedForLoopColon: true 76 | SpaceBeforeSquareBrackets: false 77 | SpaceInEmptyBlock: false 78 | SpaceInEmptyParentheses: false 79 | SpacesBeforeTrailingComments: 1 80 | SpacesInAngles: true 81 | SpacesInCStyleCastParentheses: true 82 | SpacesInConditionalStatement: true 83 | SpacesInContainerLiterals: true 84 | SpacesInParentheses: true 85 | SpacesInSquareBrackets: true 86 | -------------------------------------------------------------------------------- /lartcc/include/cc/shadow.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * (c) 2022 Henrich Lauko 3 | * 4 | * Permission to use, copy, modify, and distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | #pragma once 18 | 19 | #include 20 | #include 21 | #include 22 | 23 | #include 24 | #include 25 | 26 | namespace lart 27 | { 28 | using operation = lart::op::operation; 29 | 30 | enum class shadow_op_kind { 31 | source, memory, global, forward, store, load, freeze, melt, arg, ret 32 | }; 33 | 34 | struct shadow_operation { 35 | sc::value value; 36 | shadow_op_kind kind; 37 | }; 38 | 39 | struct shadow_map : sc::with_context 40 | { 41 | explicit shadow_map( sc::module_ref &m, const dfa::types &t ) 42 | : sc::with_context( m ), types( t ), module( m ) 43 | {} 44 | 45 | sc::generator< shadow_operation > toprocess(); 46 | 47 | sc::value process( shadow_operation op ); 48 | sc::value process( sc::value op ); 49 | 50 | sc::value process_source( shadow_operation op ); 51 | 52 | sc::value process_memory( shadow_operation op ); 53 | 54 | sc::value process_forward( shadow_operation op ); 55 | 56 | sc::value process_load( shadow_operation op ); 57 | 58 | sc::value process_store( shadow_operation op ); 59 | 60 | sc::value process_freeze( shadow_operation op ); 61 | 62 | sc::value process_melt( shadow_operation op ); 63 | 64 | sc::value process_argument( shadow_operation op ); 65 | 66 | sc::value process_return( shadow_operation op ); 67 | 68 | sc::value process_global( shadow_operation op ); 69 | 70 | sc::value get( sc::value op ) const; 71 | 72 | std::optional< shadow_op_kind > operation_kind( sc::value val ); 73 | 74 | // maps concrete value to shadow value 75 | std::unordered_map< sc::value, sc::value > ops; 76 | 77 | const dfa::types &types; 78 | sc::module_ref module; 79 | }; 80 | 81 | void make_shadow_frame(sc::function fn); 82 | 83 | } // namespace lart 84 | -------------------------------------------------------------------------------- /runtime/native/choose.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * (c) 2021 Henrich Lauko 3 | * 4 | * Permission to use, copy, modify, and distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | #include "choose.hpp" 18 | #include "config.hpp" 19 | #include "trace.hpp" 20 | 21 | #include 22 | #include 23 | 24 | namespace __lart::rt 25 | { 26 | static unsigned depth = 0; 27 | 28 | void check_terminate(int status = 0) 29 | { 30 | if (status != 0) { 31 | std::exit(status); 32 | } 33 | 34 | if (config->error_found) { 35 | std::exit(EXIT_SUCCESS); 36 | } 37 | 38 | auto bound = config->choose_bound; 39 | if ( bound && depth >= bound ) { 40 | fprintf(stderr, "[lart status] bounded exit\n"); 41 | std::exit(EXIT_SUCCESS); 42 | } 43 | } 44 | 45 | int fork_choose_dec( int count ) 46 | { 47 | if ( count == 1 ) 48 | return 0; 49 | auto pid = fork(); 50 | if ( pid == 0 ) 51 | return count - 1; 52 | int status; 53 | pid_t done = wait(&status); 54 | 55 | check_terminate( status ); 56 | return choose( count - 1 ); 57 | } 58 | 59 | int fork_choose_inc( int count ) 60 | { 61 | for (int i = 0; i < count - 1; i++) { 62 | auto pid = fork(); 63 | if ( pid == 0 ) 64 | return count - 1; 65 | int status; 66 | pid_t done = wait(&status); 67 | check_terminate( status ); 68 | } 69 | 70 | return count - 1; 71 | } 72 | 73 | int choose( int count ) 74 | { 75 | int result = 0; 76 | if ( config->ask_choices ) { 77 | int ret = std::scanf( "%d", &result ); 78 | // TODO: remove unnecessary condition 79 | } else if ( config->choose_increasing ) { 80 | result = fork_choose_inc( count ); 81 | } else { 82 | result = fork_choose_dec( count ); 83 | } 84 | 85 | if ( config->trace_choices ) 86 | trace.push_choice( result ); 87 | 88 | ++depth; 89 | return result; 90 | } 91 | 92 | } // namespace __lart::rt 93 | -------------------------------------------------------------------------------- /runtime/native/config.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * (c) 2021 Henrich Lauko 3 | * 4 | * Permission to use, copy, modify, and distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | #include "config.hpp" 18 | 19 | #include "fault.hpp" 20 | #include "utils.hpp" 21 | 22 | #include 23 | 24 | #include 25 | #include 26 | #include 27 | 28 | #include 29 | 30 | namespace __lart::rt 31 | { 32 | config_t *config = NULL; 33 | 34 | bool option( std::string_view option, std::string_view msg ) 35 | { 36 | auto is_set = [] ( auto opt ) { return opt && strcmp( opt, "ON" ) == 0; }; 37 | if ( auto opt = std::getenv( option.data() ); is_set( opt ) ) { 38 | fprintf( stderr, "[lart config] %s\n", msg.data() ); 39 | return true; 40 | } 41 | return false; 42 | } 43 | 44 | void load_config() 45 | { 46 | config->backtrace = option( "LART_ERROR_BACKTRACE", "trace error backtrace" ); 47 | config->trace_choices = option( "LART_TRACE_CHOICES", "trace choices" ); 48 | config->ask_choices = option( "LART_ASK_CHOICES", "ask choices" ); 49 | config->choose_increasing = option( "LART_INC_CHOOSE", "increasing choices" ); 50 | 51 | config->no_fail_mode = option( "LART_NO_FAIL_MODE", "run in no fail mode (useful for testing)" ); 52 | 53 | if ( auto opt = std::getenv( "LART_CHOOSE_BOUND" ); opt ) { 54 | fprintf( stderr, "[lart config] choose bound = %s\n", opt ); 55 | config->choose_bound = std::atoi( opt ); 56 | } 57 | 58 | if ( auto opt = std::getenv( "LART_TRACE_FILE" ); opt ) { 59 | fprintf( stderr, "[lart config] trace file = %s\n", opt ); 60 | config->trace_file = std::fopen( opt, "w" ); 61 | } 62 | } 63 | 64 | constructor void lart_setup() 65 | { 66 | config = (config_t*)mmap(NULL, sizeof(config_t), PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0); 67 | 68 | load_config(); 69 | 70 | init_fault_handler(); 71 | } 72 | 73 | destructor void lart_cleanup() 74 | { 75 | if ( config->trace_file ) { 76 | std::fclose( config->trace_file ); 77 | } 78 | 79 | munmap( config, sizeof(config_t) ); 80 | } 81 | 82 | } // namespace __lart::rt 83 | -------------------------------------------------------------------------------- /lartcc/include/cc/backend/native/native.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * (c) 2021 Henrich Lauko 3 | * 4 | * Permission to use, copy, modify, and distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | #pragma once 18 | 19 | #include 20 | #include 21 | 22 | #include 23 | 24 | #include 25 | 26 | #include 27 | 28 | namespace lart::backend 29 | { 30 | struct native : base 31 | { 32 | native( llvm::Module &m ) : module( m ) 33 | { 34 | auto getfunction = [&] ( auto name, auto fty ) { 35 | return llvm::cast< llvm::Function >( 36 | module.getOrInsertFunction( name, fty ).getCallee() 37 | ); 38 | }; 39 | 40 | // TODO unify with operation impl 41 | stash_fn = getfunction( "__lart_stash", 42 | llvm::FunctionType::get( sc::void_t(), { sc::i1(), sc::i8p() }, false ) 43 | ); 44 | 45 | unstash_fn = getfunction( "__lart_unstash", 46 | llvm::FunctionType::get( sc::i8p(), {}, false ) 47 | ); 48 | 49 | unstash_taint_fn = getfunction( "__lart_unstash_taint", 50 | llvm::FunctionType::get( sc::i1(), {}, false ) 51 | ); 52 | 53 | freeze_fn = getfunction( "__lamp_freeze", 54 | llvm::FunctionType::get( sc::void_t(), { sc::i8p(), sc::i8p(), sc::i64() }, false ) 55 | ); 56 | 57 | dump_fn = getfunction( "__lamp_dump", 58 | llvm::FunctionType::get( sc::void_t(), { sc::i8p() }, false ) 59 | ); 60 | } 61 | 62 | using base::lower; 63 | using base::testtaint; 64 | using base::callinst; 65 | 66 | void lower_test_taint( ir::intrinsic ) override; 67 | 68 | void lower( callinst c, op::freeze f ) override; 69 | void lower( callinst c, op::unstash u ) override; 70 | void lower( callinst c, op::unstash_taint u ) override; 71 | void lower( callinst c, op::stash s ) override; 72 | 73 | void lower( callinst c, op::dump s ) override; 74 | 75 | private: 76 | llvm::Function *stash_fn; 77 | llvm::Function *unstash_fn; 78 | llvm::Function *unstash_taint_fn; 79 | llvm::Function *freeze_fn; 80 | llvm::Function *dump_fn; 81 | 82 | llvm::Module &module; 83 | }; 84 | } 85 | -------------------------------------------------------------------------------- /.clang-tidy: -------------------------------------------------------------------------------- 1 | --- 2 | Checks: > 3 | -*, 4 | clang-diagnostic-*, 5 | clang-analyzer-*, 6 | -clang-analyzer-alpha*, 7 | boost-use-to-string, 8 | cert-*, 9 | bugprone-*, 10 | google-*, 11 | misc-*, 12 | modernize-*, 13 | performance-*, 14 | portability-*, 15 | readability-*, 16 | llvm-namespace-comment, 17 | cppcoreguidelines-*, 18 | -google-readability-braces-around-statements, 19 | -google-readability-namespace-comments, 20 | -google-runtime-references, 21 | -cert-err58-cpp, 22 | -cppcoreguidelines-pro-bounds-constant-array-index, 23 | -cppcoreguidelines-avoid-magic-numbers, 24 | -cppcoreguidelines-owning-memory, 25 | -misc-non-private-member-variables-in-classes, 26 | -modernize-deprecated-headers, 27 | -modernize-return-braced-init-list, 28 | -modernize-use-trailing-return-type, 29 | -modernize-avoid-c-arrays, 30 | -performance-move-const-arg, 31 | -readability-identifier-naming, 32 | -readability-braces-around-statements, 33 | -readability-magic-numbers, 34 | -readability-named-parameter, 35 | -readability-redundant-declaration 36 | 37 | # Turn all the warnings from the checks above into errors. 38 | WarningsAsErrors: "*" 39 | 40 | CheckOptions: 41 | - { key: readability-identifier-naming.NamespaceCase, value: lower_case } 42 | - { key: readability-identifier-naming.ClassCase, value: lower_case } 43 | - { key: readability-identifier-naming.StructCase, value: lower_case } 44 | - { key: readability-identifier-naming.TemplateParameterCase, value: lower_case } 45 | - { key: readability-identifier-naming.FunctionCase, value: lower_case } 46 | - { key: readability-identifier-naming.VariableCase, value: lower_case } 47 | - { key: readability-identifier-naming.ClassMemberCase, value: lower_case } 48 | - { key: readability-identifier-naming.ClassMemberPrefix, value: _ } 49 | - { key: readability-identifier-naming.PrivateMemberPrefix, value: _ } 50 | - { key: readability-identifier-naming.ProtectedMemberPrefix, value: _ } 51 | - { key: readability-identifier-naming.EnumConstantCase, value: CamelCase } 52 | - { key: readability-identifier-naming.EnumConstantPrefix, value: k } 53 | - { key: readability-identifier-naming.ConstexprVariableCase, value: lower_case } 54 | - { key: readability-identifier-naming.ConstexprVariablePrefix, value: k } 55 | - { key: readability-identifier-naming.GlobalConstantCase, value: lower_case } 56 | - { key: readability-identifier-naming.GlobalConstantPrefix, value: k } 57 | - { key: readability-identifier-naming.MemberConstantCase, value: lower_case } 58 | - { key: readability-identifier-naming.MemberConstantPrefix, value: k } 59 | - { key: readability-identifier-naming.StaticConstantCase, value: lower_case } 60 | - { key: readability-identifier-naming.StaticConstantPrefix, value: k } 61 | - { key: readability-implicit-bool-conversion.AllowIntegerConditions, value: 1 } 62 | - { key: readability-implicit-bool-conversion.AllowPointerConditions, value: 1 } 63 | -------------------------------------------------------------------------------- /lartcc/assume.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * (c) 2016 Henrich Lauko 3 | * 4 | * Permission to use, copy, modify, and distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | #include 18 | 19 | #include 20 | #include 21 | 22 | namespace lart::constrain 23 | { 24 | void bbedge::hide() 25 | { 26 | assert( from->getUniqueSuccessor() ); 27 | from->getTerminator()->setSuccessor( 0, from ); 28 | } 29 | 30 | void bbedge::show() 31 | { 32 | assert( from->getUniqueSuccessor() ); 33 | from->getTerminator()->setSuccessor( 0, to ); 34 | } 35 | 36 | void replace_phis_incoming_bbs( basicblock *bb, basicblock *oldbb, basicblock *newbb ) 37 | { 38 | for ( auto& inst : *bb ) 39 | if ( auto phi = llvm::dyn_cast< llvm::PHINode >( &inst ) ) 40 | { 41 | int bbidx = phi->getBasicBlockIndex( oldbb ); 42 | if ( bbidx >= 0 ) 43 | phi->setIncomingBlock( static_cast< unsigned >( bbidx ), newbb ); 44 | } 45 | } 46 | 47 | op::operation assume_edge::assume( assumption ass ) 48 | { 49 | auto succ = succ_idx(); 50 | llvm::SplitEdge( from, to ); 51 | auto edge = from->getTerminator()->getSuccessor( succ ); 52 | to = edge->getSingleSuccessor(); 53 | 54 | // Correct phis after edge splitting 55 | replace_phis_incoming_bbs( to, from, edge ); 56 | return op::assume( ass.cond, &*edge->getFirstInsertionPt(), ass.expect ); 57 | } 58 | 59 | unsigned assume_edge::succ_idx() const 60 | { 61 | auto term = from->getTerminator(); 62 | 63 | for ( unsigned i = 0; i < term->getNumSuccessors(); ++i ) 64 | if ( term->getSuccessor( i ) == to ) 65 | return i; 66 | 67 | llvm_unreachable( "BasicBlock 'to' is not a successor of BasicBlock 'from'." ); 68 | } 69 | 70 | sc::generator< op::operation > assume( llvm::BranchInst *br, llvm::Value *cond ) 71 | { 72 | auto &ctx = br->getContext(); 73 | 74 | assume_edge true_br = { br->getParent(), br->getSuccessor( 0 ) }; 75 | co_yield true_br.assume( { cond, llvm::ConstantInt::getTrue( ctx ) } ); 76 | 77 | assume_edge false_br = { br->getParent(), br->getSuccessor( 1 ) }; 78 | co_yield false_br.assume( { cond, llvm::ConstantInt::getFalse( ctx ) } ); 79 | } 80 | 81 | } // namespace lart::constrain 82 | -------------------------------------------------------------------------------- /runtime/native/svcomp.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * (c) 2021 Henrich Lauko 3 | * 4 | * Permission to use, copy, modify, and distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | #include "config.hpp" 18 | #include "fault.hpp" 19 | 20 | #include "stream.hpp" 21 | 22 | #include 23 | 24 | #include 25 | #include 26 | #include 27 | 28 | #pragma GCC diagnostic push 29 | #pragma GCC diagnostic ignored "-Wuninitialized" 30 | 31 | void trace_any_call(std::string_view file, std::string_view func, unsigned int line) 32 | { 33 | // if (!trace.nondets) 34 | // return; 35 | __lart::rt::file_stream out( stderr ); 36 | out << "[lamp any] " << func << ':' << file << ':' << line << '\n'; 37 | } 38 | 39 | #define TRACED(function) trace_any_call(file, func, line), function(); 40 | 41 | extern "C" { 42 | 43 | uint8_t __lamp_any_i1(void); 44 | uint8_t __lamp_any_i8(void); 45 | uint16_t __lamp_any_i16(void); 46 | uint32_t __lamp_any_i32(void); 47 | uint64_t __lamp_any_i64(void); 48 | float __lamp_any_f32(void); 49 | double __lamp_any_f64(void); 50 | void* __lamp_any_ptr(void); 51 | 52 | uint8_t __lamp_any_i1_traced(const char *file, unsigned int line, const char *func) 53 | { 54 | return TRACED( __lamp_any_i1 ); 55 | } 56 | 57 | uint8_t __lamp_any_i8_traced(const char *file, unsigned int line, const char *func) 58 | { 59 | return TRACED( __lamp_any_i8 ); 60 | } 61 | 62 | uint16_t __lamp_any_i16_traced(const char *file, unsigned int line, const char *func) 63 | { 64 | return TRACED( __lamp_any_i16 ); 65 | } 66 | 67 | uint32_t __lamp_any_i32_traced(const char *file, unsigned int line, const char *func) 68 | { 69 | return TRACED( __lamp_any_i32 ); 70 | } 71 | 72 | uint64_t __lamp_any_i64_traced(const char *file, unsigned int line, const char *func) 73 | { 74 | return TRACED( __lamp_any_i64 ); 75 | } 76 | 77 | float __lamp_any_f32_traced(const char *file, unsigned int line, const char *func) 78 | { 79 | return TRACED( __lamp_any_f32 ); 80 | } 81 | 82 | float __lamp_any_f64_traced(const char *file, unsigned int line, const char *func) 83 | { 84 | return TRACED( __lamp_any_f64 ); 85 | } 86 | 87 | void* __lamp_any_ptr_traced(const char *file, unsigned int line, const char *func) 88 | { 89 | return TRACED( __lamp_any_ptr ); 90 | } 91 | } 92 | 93 | #pragma clang diagnostic pop 94 | -------------------------------------------------------------------------------- /scripts/svcomp/utils/model.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import ctypes 4 | from . log import logger 5 | 6 | class ModelVar: 7 | def __init__(self, call, line, value): 8 | self.call = call 9 | self.line = line 10 | self.value = value 11 | 12 | def __str__(self): 13 | return f"var: {self.call}:{self.line} = {self.value}" 14 | 15 | class Model: 16 | def __init__(self): 17 | self.vars = [] 18 | 19 | def parse(self, report, line_offset): 20 | nondet_calls = [] 21 | model = dict() 22 | 23 | for line in report: 24 | if line.startswith("[lamp any]"): 25 | nondet_calls.append(self.parse_nondet_call(line)) 26 | if line.startswith("[term model]"): 27 | name, value = self.parse_term_var(line) 28 | index = self.parse_index(name) - 1 29 | model[index] = value 30 | 31 | for idx, call in enumerate(nondet_calls): 32 | value = self.parse_value(call[0], model.get(idx, "0")) 33 | line = str(int(call[2]) - line_offset) 34 | var = ModelVar(call[0], line, value) 35 | logger().info(f"{var}") 36 | self.vars.append(var) 37 | 38 | 39 | def parse_index(self, var_name): 40 | return int(var_name.split('_')[1]) 41 | 42 | def parse_nondet_call(self, line): 43 | name = line.lstrip("[lamp any]").strip() 44 | parsed = name.split(":") 45 | return parsed 46 | 47 | def parse_term_var(self, line): 48 | line = line.lstrip("[term model]") 49 | parts = line.split(" = ") 50 | return parts[0].strip(), parts[1].strip() 51 | 52 | def parse_value(self, nondet, parsed): 53 | if "pointer" in nondet: 54 | return None # FIXME pointer models 55 | 56 | try: 57 | if "float" in nondet: 58 | val = float(parsed) 59 | return ctypes.c_float(val) 60 | if "double" in nondet: 61 | val = float(parsed) 62 | return ctypes.c_double(val) 63 | except ValueError: 64 | return None 65 | 66 | try: 67 | # integer models: 68 | parsed = parsed.lstrip("#x") 69 | val = int(parsed, 16) 70 | bw = val.bit_length() 71 | if "uint" in nondet and bw <= 32: 72 | return ctypes.c_uint(val) 73 | if "unsigned" in nondet and bw <= 32: 74 | return ctypes.c_uint(val) 75 | if "int" in nondet and bw <= 32: 76 | return ctypes.c_int(val) 77 | if "bool" in nondet and bw <= 8: 78 | return ctypes.c_bool(val) 79 | if "char" in nondet and bw <= 8: 80 | return ctypes.c_byte(val) 81 | if "ushort" in nondet and bw <= 16: 82 | return ctypes.c_ushort(val) 83 | if "short" in nondet and bw <= 16: 84 | return ctypes.c_short(val) 85 | if "ulong" in nondet and bw <= 64: 86 | return ctypes.c_ulong(val) 87 | if "long" in nondet and bw <= 64: 88 | return ctypes.c_long(val) 89 | except ValueError: 90 | return None 91 | return None 92 | 93 | -------------------------------------------------------------------------------- /lartcc/taint.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * (c) 2021 Henrich Lauko 3 | * 4 | * Permission to use, copy, modify, and distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | #include 18 | #include 19 | #include 20 | 21 | #include 22 | 23 | namespace lart::taint 24 | { 25 | namespace detail 26 | { 27 | std::string name( const operation &op ) 28 | { 29 | return "lart.test.taint." + op::name(op) + "." + op::unique_name_suffix(op); 30 | } 31 | 32 | sc::generator< sc::value > arguments( const lart::lifter &lifter ) 33 | { 34 | co_yield lifter.function(); 35 | 36 | for ( auto arg : op::duplicated_arguments(lifter.op, lifter.shadows) ) { 37 | co_yield arg; 38 | } 39 | } 40 | 41 | } // namespace detail 42 | 43 | llvm::CallInst * make_call( const lifter &lift ) 44 | { 45 | std::vector< sc::value > args; 46 | for (auto arg : detail::arguments( lift )) { 47 | args.push_back(arg); 48 | } 49 | return op::make_call( lift.op, args, detail::name( lift.op ), true /* test taint */ ); 50 | } 51 | 52 | sc::generator< ir::argument > paired_view( const ir::intrinsic &intr ) 53 | { 54 | auto call = intr.call; 55 | 56 | auto op = intr.op; 57 | // skip lifter argument 58 | unsigned pos = op::emit_test_taint(op) ? 1 : 0; 59 | 60 | for ( auto arg : op::arguments(op) ) { 61 | switch ( arg.type ) { 62 | case op::argtype::abstract: 63 | co_yield ir::arg::without_taint_abstract{ 64 | call->getOperandUse(pos), 65 | call->getOperandUse(pos + 1) 66 | }; 67 | pos += 2; 68 | break; 69 | case op::argtype::unpack: 70 | case op::argtype::with_taint: 71 | co_yield ir::arg::with_taint{ 72 | call->getOperandUse(pos), 73 | call->getOperandUse(pos + 1), 74 | call->getOperandUse(pos + 2), 75 | }; 76 | pos += 3; 77 | break; 78 | case op::argtype::test: 79 | // TODO ?? 80 | case op::argtype::concrete: 81 | co_yield ir::arg::without_taint_concrete{ 82 | call->getOperandUse(pos), 83 | }; 84 | pos += 1; 85 | break; 86 | } 87 | } 88 | } 89 | 90 | } // namespace lart::taint 91 | -------------------------------------------------------------------------------- /doc/lart-pontos-build.md: -------------------------------------------------------------------------------- 1 | ## Build on pontos 2 | 3 | ### Install LLVM 4 | 5 | ```bash 6 | mkdir -p ~/src/libcxx 7 | cd ~/src/libcxx 8 | git clone https://github.com/llvm/llvm-project.git --depth 1 . 9 | 10 | export LIBCXX_DATAFLOW_DIR=~/opt/libcxx-dataflow/ 11 | 12 | cmake -GNinja \ 13 | -DCMAKE_C_COMPILER=clang-12 \ 14 | -DCMAKE_CXX_COMPILER=clang++-12 \ 15 | -DLLVM_USE_SANITIZER="DataFlow" \ 16 | -DCMAKE_INSTALL_PREFIX=${LIBCXX_DATAFLOW_DIR} \ 17 | -DLLVM_ENABLE_PROJECTS="libcxx;libcxxabi" \ 18 | -S llvm \ 19 | -B build-dataflow 20 | 21 | cmake --build build-dataflow --target cxx cxxabi 22 | cmake --build build-dataflow --target install-cxx install-cxxabi 23 | ``` 24 | 25 | 26 | ### Install SVF 27 | 28 | ```bash 29 | mkdir -p ~/src/svf 30 | cd ~/src/svf 31 | git clone https://github.com/SVF-tools/SVF --depth 1 -b SVF-2.3 . 32 | 33 | export LLVM_INSTALL_DIR=/usr/lib/llvm-12/ 34 | export SVF_INSTALL_DIR=~/opt/svf/ 35 | 36 | cmake -GNinja \ 37 | -DLLVM_DIR="${LLVM_INSTALL_DIR}" \ 38 | -DCMAKE_INSTALL_PREFIX="${SVF_INSTALL_DIR}" \ 39 | -B build \ 40 | -S . 41 | 42 | cmake --build build 43 | cmake --build build --target install 44 | ``` 45 | 46 | 47 | ### Install vcpkg and packages 48 | 49 | ```bash 50 | mkdir -p ~/opt/vcpkg 51 | cd ~/opt/vcpkg 52 | git clone https://github.com/microsoft/vcpkg.git . && ./bootstrap-vcpkg.sh 53 | 54 | export PATH=~/opt/vcpkg:${PATH} 55 | export VCPKG_TOOLCHAIN=~/opt/vcpkg/scripts/buildsystems/vcpkg.cmake 56 | 57 | vcpkg update 58 | vcpkg install spdlog catch2 doctest 59 | ``` 60 | 61 | 62 | ### Build-lart 63 | 64 | ```bash 65 | mkdir -p ~/src/lart 66 | cd ~/src/lart 67 | git clone --recurse-submodules https://github.com/xlauko/lart . 68 | 69 | export LART_INSTALL_DIR=~/opt/lart/ 70 | 71 | cmake -GNinja \ 72 | -DBUILD_LART_CC=ON \ 73 | -DENABLE_TESTING=ON \ 74 | -DCMAKE_BUILD_TYPE=Debug \ 75 | -DLLVM_INSTALL_DIR=${LLVM_INSTALL_DIR}/build/ \ 76 | -DSVF_INSTALL_DIR=${SVF_INSTALL_DIR} \ 77 | -DCMAKE_TOOLCHAIN_FILE=${VCPKG_TOOLCHAIN} \ 78 | -DCMAKE_INSTALL_PREFIX=${LART_INSTALL_DIR} \ 79 | -B build-lart \ 80 | -S . 81 | 82 | cmake --build build-lart 83 | cmake --build build-lart --target install 84 | ``` 85 | 86 | 87 | ### Build-runtime 88 | 89 | ```bash 90 | cd ~/src/lart 91 | 92 | cmake -GNinja \ 93 | -DCMAKE_C_COMPILER=clang-12 \ 94 | -DCMAKE_CXX_COMPILER=clang++-12 \ 95 | -DBUILD_LART_RUNTIME=ON \ 96 | -DLLVM_INSTALL_DIR=${LLVM_INSTALL_DIR} \ 97 | -DLIBCXX_INSTALL_DIR=${LIBCXX_DATAFLOW_DIR} \ 98 | -DCMAKE_TOOLCHAIN_FILE=${VCPKG_TOOLCHAIN} \ 99 | -DCMAKE_INSTALL_PREFIX=${LART_INSTALL_DIR} \ 100 | -B build-runtime \ 101 | -S . 102 | 103 | cmake --build build-runtime 104 | cmake --build build-runtime --target install 105 | ``` 106 | 107 | 108 | ### Add to `.bashrc` 109 | 110 | ```bash 111 | export PATH="${HOME}/opt/lart/bin/lartcc:${PATH}" 112 | ``` 113 | 114 | 115 | ### Example usage 116 | 117 | ```bash 118 | lartcc unit ./test/basic/any-a.c -I./test/include/ -o abstract 119 | ./abstract 120 | ``` 121 | 122 | 123 | ### Install `lit` & run tests 124 | 125 | ```bash 126 | pip install --user lit 127 | export PATH=$PATH:~/.local/bin 128 | 129 | lit -v build-lart/test/ --filter=basic 130 | ``` 131 | -------------------------------------------------------------------------------- /lartcc/include/cc/roots.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * (c) 2021 Henrich Lauko 3 | * 4 | * Permission to use, copy, modify, and distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | #pragma once 18 | 19 | #include 20 | #include 21 | #include 22 | #include 23 | 24 | #include 25 | 26 | #include 27 | 28 | #include 29 | #include 30 | #include 31 | 32 | namespace lart 33 | { 34 | enum class abstract_kind { scalar, pointer }; 35 | 36 | using roots_map = std::map< llvm::CallBase*, abstract_kind >; 37 | 38 | inline std::optional< abstract_kind > get_abstract_kind(sc::function fn) 39 | { 40 | auto scalar = runtime::abstract_scalar_attr(); 41 | if (fn->hasFnAttribute(scalar.getKindAsString())) 42 | return abstract_kind::scalar; 43 | 44 | auto pointer = runtime::abstract_pointer_attr(); 45 | if (fn->hasFnAttribute(pointer.getKindAsString())) 46 | return abstract_kind::pointer; 47 | 48 | return std::nullopt; 49 | } 50 | 51 | using abstract_value_generator = std::pair< sc::function, abstract_kind >; 52 | inline sc::generator< abstract_value_generator > generators(sc::module_ref mod) { 53 | for (auto &fn : mod) { 54 | if (auto kind = get_abstract_kind(&fn)) { 55 | co_yield { &fn, kind.value() }; 56 | } 57 | } 58 | } 59 | 60 | inline roots_map gather_roots(sc::module_ref m) 61 | { 62 | roots_map result; 63 | 64 | for (auto [gen, kind] : generators(m)) 65 | { 66 | std::queue< llvm::Value* > worklist; 67 | auto transitive_users = [&] (auto val) { 68 | for ( auto user : val->users() ) { 69 | worklist.emplace( user ); 70 | } 71 | }; 72 | 73 | auto register_root = [&, kind = kind] (auto root) { 74 | spdlog::debug("[dfa] root: {}", sc::fmt::llvm_to_string(root)); 75 | result[root] = kind; 76 | }; 77 | 78 | transitive_users(gen); 79 | while ( !worklist.empty() ) { 80 | sc::llvmcase( worklist.front(), 81 | [&] ( llvm::CastInst *c ) { transitive_users(c); }, 82 | [&] ( llvm::ConstantExpr *c ) { transitive_users(c); }, 83 | [&] ( llvm::CallInst *c ) { register_root(c); }, 84 | [&] ( llvm::InvokeInst * c) { register_root(c); } 85 | ); 86 | worklist.pop(); 87 | } 88 | } 89 | 90 | return result; 91 | } 92 | 93 | } // namespace lart 94 | 95 | -------------------------------------------------------------------------------- /runtime/include/runtime/lart.h: -------------------------------------------------------------------------------- 1 | /* 2 | * (c) 2020 Henrich Lauko 3 | * 4 | * Permission to use, copy, modify, and distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | #pragma once 18 | 19 | #include 20 | #include 21 | #include 22 | 23 | #define __lart_annotate( x ) __attribute__(( __annotate__( #x ) )) 24 | #define __lart_inline __attribute__(( __always_inline__ )) 25 | #define __lart_noinline __attribute__(( __noinline__ )) 26 | #define __lart_flatten __attribute__(( __flatten__ )) 27 | 28 | #define __lart_ignore_return __lart_annotate( lart.transform.ignore.ret ) 29 | #define __lart_ignore_args __lart_annotate( lart.transform.ignore.arg ) 30 | #define __lart_noalias_return __lart_annotate( lart.noalias.ret ) 31 | #define __lart_noalias_args __lart_annotate( lart.noalias.arg ) 32 | #define __lart_noalias __lart_noalias_return __lart_noalias_args 33 | #define __lart_unused __attribute__((unused)) 34 | #define __lart_used __attribute__((used)) 35 | #define __lart_export 36 | #define __lart_stub { __builtin_unreachable(); } 37 | 38 | #define __lart_ignore_diagnostic \ 39 | _Pragma("GCC diagnostic push") \ 40 | _Pragma("GCC diagnostic ignored \"-Wunused-parameter\"") \ 41 | 42 | #define __lart_pop_diagnostic \ 43 | _Pragma("GCC diagnostic pop") \ 44 | 45 | __lart_ignore_diagnostic 46 | 47 | #ifdef __cplusplus 48 | extern "C" { 49 | #endif 50 | /* Abstract versions of arguments and return values are passed in a 'stash', a 51 | * global (per-thread) location. On 'unstash', we clear the stash for two 52 | * reasons: 1) it flags up otherwise hard-to-pin bugs where mismatched 53 | * stash/unstash reads an old value of the stash, and 2) when verification 54 | * encounters a possible diamond (the explicit content of the state is the 55 | * same, e.g. after an if/else) and we leave old stashes around, it might so 56 | * happen that the stashed values in the candidate states are of different 57 | * types, leading to a type mismatch in the comparison. 58 | * 59 | * TODO The second problem might have to be tackled in the verification 60 | * algorithm anyway, since there might be other ways to trigger the same 61 | * problem. */ 62 | __lart_export void __lart_stash( bool taint, void* abstract ); 63 | 64 | __lart_export void* __lart_unstash(); 65 | 66 | __lart_export bool __lart_unstash_taint(); 67 | 68 | __lart_export int __lart_choose( int count ); 69 | 70 | __lart_export void __lart_cancel(); 71 | 72 | __lart_export bool __lart_test_taint( void* addr, size_t bytes ); 73 | 74 | __lart_export void __lart_entry_frame(); 75 | 76 | __lart_export void __lart_exit_frame(); 77 | 78 | #ifdef __cplusplus 79 | } 80 | #endif 81 | 82 | __lart_pop_diagnostic 83 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # LART: LLVM Abstraction and Refinement Tool 2 | 3 | [![Build Status](https://travis-ci.com/xlauko/lart.svg?branch=master)](https://travis-ci.com/xlauko/lart) 4 | [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) 5 | 6 | LART = LLVM Abstraction & Refinement Tool. The goal of this tool is to provide LLVM-to-LLVM transformations that implement various program abstractions. In terms of the instruction set, the resulting programs are normal, concrete LLVM programs that can be executed and analyzed. Extra information about the abstraction(s) in effect over a (fragment) program is inserted using special LLVM intrinsic functions and LLVM metadata nodes. 7 | LART provides both a standalone tool that processes on-disk bitcode files, as well as a framework that can be integrated into complex LLVM-based tools. The primary motivation behind LART is to provide a "preprocessor" for LLVM-based model checkers and other analysis tools, simplifying their job by reducing the problem size without compromising the soundness of the analyses. 8 | The abstractions implemented by LART can be usually refined based on specific instructions about which "part" of the abstraction is too rough (an abstraction that is too rough will create spurious errors visible to subsequent analyses but not present in the original program). 9 | 10 | ## Abstractions for LLVM Bitcode 11 | 12 | The purpose of the entire exercise is to abstract away information from LLVM bitcode, making subsequent analyses more efficient (at the expense of some precision). To this end, we mainly need to be able to encode non-deterministic choice in LLVM programs, which can be done simply through a special-purpose function (similar to LLVM intrinsics). The function is named `@lart.choice`, takes a pair of bounds as arguments and non-deterministically returns a value that falls between those bounds. 13 | 14 | This extension to LLVM semantics needs to be recognized by the downstream tool. This is also the only crucial deviation from standard LLVM bitcode. Many analysis tools will already implement a similar mechanism, either internally or even with an external interface. Adapting tools without support for `@lart.choice` to work with LART is usually very straightforward. 15 | 16 | There are other special-purpose functions provided by LART, namely the `@lart.meta.*` family, but as far as these instructions are concerned, most tools will be able to safely ignore their existence, just like with existing `@llvm.dbg.*` calls. Program transformations would be expected to retain those calls in case LART is called in to refine an abstraction (each abstraction provided by LART comes with a corresponding refinement procedure, which will often need to find the `@lart.meta` calls inserted by the abstraction). 17 | 18 | While most traditional abstraction engines work as interpreters, abstractions can also be "compiled" into programs. Instead of (re-)interpreting instructions symbolically, the symbolic instructions can be compiled. In case of predicate abstraction, the resulting bitcode will directly manipulate and use predicate valuations instead of concrete variables. As explained above, the important difference is that the bitcode needs to make non-deterministic choices, since some predicates may have indeterminate valuations (are both true and false). Some variables could be even abstracted away entirely, and all tests on such variables will yield both yes and no answers. 19 | 20 | ## Build 21 | 22 | Use or repeat the setup from `./devcontainer/Dockerfile` for the time being. 23 | 24 | Then use: 25 | 26 | ``` 27 | ./scripts/build.sh 28 | ``` 29 | 30 | ## Run Compiler 31 | 32 | ``` 33 | ./build/bin/lartcc in.c 34 | ``` 35 | 36 | ## OPT 37 | 38 | ``` 39 | opt -load build/lib/cc/liblart_module.so -lart < in.bc > out.bc 40 | ``` 41 | 42 | ## Test 43 | 44 | ``` 45 | lit -v build/test 46 | ``` 47 | 48 | Note: `build/lartcc/lartcc` has to have exacutabple permisions. 49 | --------------------------------------------------------------------------------