From 58ec03e3322edb3952514980424dc37c9661030b Mon Sep 17 00:00:00 2001 From: Julius Hohnerlein Date: Mon, 7 Jun 2021 13:30:41 +0000 Subject: [PATCH 01/32] add new runtime that compiles to static library and contains only common runtime code --- runtime/CMakeLists.txt | 5 +- runtime/RuntimeCommon.cpp | 7 +++ runtime/RuntimeCommon.h | 4 ++ runtime/Shadow.h | 4 +- runtime/common_only/CMakeLists.txt | 25 +++++++++ runtime/common_only/Runtime.cpp | 83 ++++++++++++++++++++++++++++++ runtime/common_only/Runtime.h | 21 ++++++++ 7 files changed, 146 insertions(+), 3 deletions(-) create mode 100644 runtime/common_only/CMakeLists.txt create mode 100644 runtime/common_only/Runtime.cpp create mode 100644 runtime/common_only/Runtime.h diff --git a/runtime/CMakeLists.txt b/runtime/CMakeLists.txt index 637fc1ce..7d3627dc 100644 --- a/runtime/CMakeLists.txt +++ b/runtime/CMakeLists.txt @@ -22,6 +22,7 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17 \ -Wmissing-format-attribute -Wformat-nonliteral") option(QSYM_BACKEND "Use the Qsym backend instead of our own" OFF) +option(COMMON_ONLY "Build just the common backend code as a static archive" OFF) option(Z3_TRUST_SYSTEM_VERSION "Use the system-provided Z3 without a version check" OFF) # Place the final product in the top-level output directory @@ -35,7 +36,9 @@ set(SHARED_RUNTIME_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/Shadow.cpp ${CMAKE_CURRENT_SOURCE_DIR}/GarbageCollection.cpp) -if (${QSYM_BACKEND}) +if (${COMMON_ONLY}) + add_subdirectory(common_only) +elseif (${QSYM_BACKEND}) add_subdirectory(qsym_backend) else() add_subdirectory(simple_backend) diff --git a/runtime/RuntimeCommon.cpp b/runtime/RuntimeCommon.cpp index 32081e3e..26e1f440 100644 --- a/runtime/RuntimeCommon.cpp +++ b/runtime/RuntimeCommon.cpp @@ -134,6 +134,12 @@ void _sym_write_memory(uint8_t *addr, size_t length, SymExpr expr, } } +#ifdef COMMON_ONLY + +// these builders should be implementable by the runtime. + +#else + SymExpr _sym_build_extract(SymExpr expr, uint64_t offset, uint64_t length, bool little_endian) { size_t totalBits = _sym_bits_helper(expr); @@ -192,6 +198,7 @@ SymExpr _sym_build_insert(SymExpr target, SymExpr to_insert, uint64_t offset, return result; } +#endif void _sym_register_expression_region(SymExpr *start, size_t length) { registerExpressionRegion({start, length}); diff --git a/runtime/RuntimeCommon.h b/runtime/RuntimeCommon.h index f00176ea..1f9bb9e8 100644 --- a/runtime/RuntimeCommon.h +++ b/runtime/RuntimeCommon.h @@ -25,6 +25,8 @@ #ifndef RUNTIMECOMMON_H #define RUNTIMECOMMON_H +#include + #ifdef __cplusplus #include extern "C" { @@ -126,7 +128,9 @@ SymExpr _sym_build_bool_to_bits(SymExpr expr, uint8_t bits); */ SymExpr _sym_concat_helper(SymExpr a, SymExpr b); SymExpr _sym_extract_helper(SymExpr expr, size_t first_bit, size_t last_bit); +#ifndef COMMON_ONLY size_t _sym_bits_helper(SymExpr expr); +#endif /* * Function-call helpers diff --git a/runtime/Shadow.h b/runtime/Shadow.h index 967e11ca..160852b8 100644 --- a/runtime/Shadow.h +++ b/runtime/Shadow.h @@ -23,8 +23,6 @@ #include -#include - // // This file is dedicated to the management of shadow memory. // @@ -84,9 +82,11 @@ class ReadShadowIterator } SymExpr operator*() { +#ifndef COMMON_ONLY // _sym_bits_helper may not be implemeted assert((shadow_ == nullptr || *shadow_ == nullptr || _sym_bits_helper(*shadow_) == 8) && "Shadow memory always represents bytes"); +#endif return shadow_ != nullptr ? *shadow_ : nullptr; } diff --git a/runtime/common_only/CMakeLists.txt b/runtime/common_only/CMakeLists.txt new file mode 100644 index 00000000..94df2409 --- /dev/null +++ b/runtime/common_only/CMakeLists.txt @@ -0,0 +1,25 @@ +# This file is part of SymCC. +# +# SymCC is free software: you can redistribute it and/or modify it under the +# terms of the GNU General Public License as published by the Free Software +# Foundation, either version 3 of the License, or (at your option) any later +# version. +# +# SymCC is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +# A PARTICULAR PURPOSE. See the GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along with +# SymCC. If not, see . + +add_library(SymRuntime STATIC + ${SHARED_RUNTIME_SOURCES} + Runtime.cpp) + +target_include_directories(SymRuntime PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/..) + +set_target_properties(SymRuntime PROPERTIES COMPILE_FLAGS "-Werror") + +add_definitions(-DCOMMON_ONLY) \ No newline at end of file diff --git a/runtime/common_only/Runtime.cpp b/runtime/common_only/Runtime.cpp new file mode 100644 index 00000000..d77db991 --- /dev/null +++ b/runtime/common_only/Runtime.cpp @@ -0,0 +1,83 @@ +// This file is part of SymCC. +// +// SymCC is free software: you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the Free Software +// Foundation, either version 3 of the License, or (at your option) any later +// version. +// +// SymCC is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +// A PARTICULAR PURPOSE. See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along with +// SymCC. If not, see . + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "Config.h" +#include "GarbageCollection.h" +#include "LibcWrappers.h" +#include "Shadow.h" + +namespace +{ + + /// Indicate whether the runtime has been initialized. + std::atomic_flag g_initialized = ATOMIC_FLAG_INIT; + + FILE *g_log = stderr; + +} // namespace + +void _sym_initialize(void) +{ + if (g_initialized.test_and_set()) + return; + +#ifndef NDEBUG + std::cerr << "Initializing symbolic runtime" << std::endl; +#endif + + loadConfig(); + initLibcWrappers(); + std::cerr << "This is SymCC running with the common backend" << std::endl + << std::endl; + + if (g_config.logFile.empty()) + { + g_log = stderr; + } + else + { + g_log = fopen(g_config.logFile.c_str(), "w"); + } +} + +/* No call-stack tracing */ +void _sym_notify_call(uintptr_t) {} +void _sym_notify_ret(uintptr_t) {} +void _sym_notify_basic_block(uintptr_t) {} + +/* No debugging */ +const char *_sym_expr_to_string(SymExpr) +{ + return NULL; +} + +bool _sym_feasible(SymExpr) +{ + return false; +} + +/* No garbage collection */ +void _sym_collect_garbage() +{ +} diff --git a/runtime/common_only/Runtime.h b/runtime/common_only/Runtime.h new file mode 100644 index 00000000..901c536a --- /dev/null +++ b/runtime/common_only/Runtime.h @@ -0,0 +1,21 @@ +// This file is part of SymCC. +// +// SymCC is free software: you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the Free Software +// Foundation, either version 3 of the License, or (at your option) any later +// version. +// +// SymCC is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +// A PARTICULAR PURPOSE. See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along with +// SymCC. If not, see . + +#ifndef RUNTIME_H +#define RUNTIME_H + +typedef void* SymExpr; +#include + +#endif From d23f876c40163953e33d632f93e7f92576377e5d Mon Sep 17 00:00:00 2001 From: Julius Hohnerlein Date: Tue, 8 Jun 2021 11:59:31 +0200 Subject: [PATCH 02/32] add the common only runtime library to installation output of cmake --- runtime/common_only/CMakeLists.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/runtime/common_only/CMakeLists.txt b/runtime/common_only/CMakeLists.txt index 94df2409..c7fda703 100644 --- a/runtime/common_only/CMakeLists.txt +++ b/runtime/common_only/CMakeLists.txt @@ -22,4 +22,6 @@ target_include_directories(SymRuntime PRIVATE set_target_properties(SymRuntime PROPERTIES COMPILE_FLAGS "-Werror") -add_definitions(-DCOMMON_ONLY) \ No newline at end of file +add_definitions(-DCOMMON_ONLY) + +install(TARGETS SymRuntime ARCHIVE DESTINATION ${CMAKE_INSTALL_PREFIX}) From 396884152abbc94ac3e49a4075aa87d4f40ee56a Mon Sep 17 00:00:00 2001 From: Julius Hohnerlein Date: Thu, 17 Jun 2021 11:48:18 +0000 Subject: [PATCH 03/32] make cmake call cargo instead of cargo calling cmake this is due to linking issues with rust --- CMakeLists.txt | 2 ++ runtime/CMakeLists.txt | 6 +++--- runtime/{common_only => rust_backend}/CMakeLists.txt | 12 +++++++++--- runtime/{common_only => rust_backend}/Runtime.cpp | 0 runtime/{common_only => rust_backend}/Runtime.h | 0 5 files changed, 14 insertions(+), 6 deletions(-) rename runtime/{common_only => rust_backend}/CMakeLists.txt (80%) rename runtime/{common_only => rust_backend}/Runtime.cpp (100%) rename runtime/{common_only => rust_backend}/Runtime.h (100%) diff --git a/CMakeLists.txt b/CMakeLists.txt index ac18c3bd..6152af45 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -15,6 +15,7 @@ cmake_minimum_required(VERSION 3.5) project(SymbolicCompiler) +option(RUST_BACKEND "Build just the common backend code, linked with the rust runtime" OFF) option(QSYM_BACKEND "Use the Qsym backend instead of our own" OFF) option(TARGET_32BIT "Make the compiler work correctly with -m32" OFF) @@ -29,6 +30,7 @@ set(SYM_RUNTIME_BUILD_ARGS -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER} -DCMAKE_CXX_FLAGS=${CMAKE_CXX_FLAGS} -DCMAKE_SHARED_LINKER_FLAGS=${CMAKE_SHARED_LINKER_FLAGS} + -DRUST_BACKEND=${RUST_BACKEND} -DQSYM_BACKEND=${QSYM_BACKEND} -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} -DZ3_TRUST_SYSTEM_VERSION=${Z3_TRUST_SYSTEM_VERSION}) diff --git a/runtime/CMakeLists.txt b/runtime/CMakeLists.txt index 7d3627dc..1628b59c 100644 --- a/runtime/CMakeLists.txt +++ b/runtime/CMakeLists.txt @@ -22,7 +22,7 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17 \ -Wmissing-format-attribute -Wformat-nonliteral") option(QSYM_BACKEND "Use the Qsym backend instead of our own" OFF) -option(COMMON_ONLY "Build just the common backend code as a static archive" OFF) +option(RUST_BACKEND "Build just the common backend code, linked with the rust runtime" OFF) option(Z3_TRUST_SYSTEM_VERSION "Use the system-provided Z3 without a version check" OFF) # Place the final product in the top-level output directory @@ -36,8 +36,8 @@ set(SHARED_RUNTIME_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/Shadow.cpp ${CMAKE_CURRENT_SOURCE_DIR}/GarbageCollection.cpp) -if (${COMMON_ONLY}) - add_subdirectory(common_only) +if (${RUST_BACKEND}) + add_subdirectory(rust_backend) elseif (${QSYM_BACKEND}) add_subdirectory(qsym_backend) else() diff --git a/runtime/common_only/CMakeLists.txt b/runtime/rust_backend/CMakeLists.txt similarity index 80% rename from runtime/common_only/CMakeLists.txt rename to runtime/rust_backend/CMakeLists.txt index c7fda703..7f7fcc83 100644 --- a/runtime/common_only/CMakeLists.txt +++ b/runtime/rust_backend/CMakeLists.txt @@ -12,7 +12,9 @@ # You should have received a copy of the GNU General Public License along with # SymCC. If not, see . -add_library(SymRuntime STATIC +cmake_minimum_required(VERSION 3.12) + +add_library(SymRuntime SHARED ${SHARED_RUNTIME_SOURCES} Runtime.cpp) @@ -22,6 +24,10 @@ target_include_directories(SymRuntime PRIVATE set_target_properties(SymRuntime PROPERTIES COMPILE_FLAGS "-Werror") -add_definitions(-DCOMMON_ONLY) +find_package(Corrosion REQUIRED) + +corrosion_import_crate(MANIFEST_PATH ../../../runtime/Cargo.toml) -install(TARGETS SymRuntime ARCHIVE DESTINATION ${CMAKE_INSTALL_PREFIX}) +target_link_libraries(SymRuntime PUBLIC runtime) + +add_definitions(-DCOMMON_ONLY) diff --git a/runtime/common_only/Runtime.cpp b/runtime/rust_backend/Runtime.cpp similarity index 100% rename from runtime/common_only/Runtime.cpp rename to runtime/rust_backend/Runtime.cpp diff --git a/runtime/common_only/Runtime.h b/runtime/rust_backend/Runtime.h similarity index 100% rename from runtime/common_only/Runtime.h rename to runtime/rust_backend/Runtime.h From 1613c7853991743960c714007be5a88ea37bc6da Mon Sep 17 00:00:00 2001 From: Julius Hohnerlein Date: Fri, 18 Jun 2021 07:09:45 +0000 Subject: [PATCH 04/32] common backend is now the rust backend --- runtime/rust_backend/Runtime.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime/rust_backend/Runtime.cpp b/runtime/rust_backend/Runtime.cpp index d77db991..103d507b 100644 --- a/runtime/rust_backend/Runtime.cpp +++ b/runtime/rust_backend/Runtime.cpp @@ -48,7 +48,7 @@ void _sym_initialize(void) loadConfig(); initLibcWrappers(); - std::cerr << "This is SymCC running with the common backend" << std::endl + std::cerr << "This is SymCC running with the rust backend" << std::endl << std::endl; if (g_config.logFile.empty()) From b67b70ad37cda7c22859e14b553740b38e062384 Mon Sep 17 00:00:00 2001 From: Julius Hohnerlein Date: Fri, 18 Jun 2021 11:03:44 +0000 Subject: [PATCH 05/32] delegate call stack tracing to rust runtime --- runtime/rust_backend/Runtime.cpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/runtime/rust_backend/Runtime.cpp b/runtime/rust_backend/Runtime.cpp index 103d507b..fd497514 100644 --- a/runtime/rust_backend/Runtime.cpp +++ b/runtime/rust_backend/Runtime.cpp @@ -61,11 +61,6 @@ void _sym_initialize(void) } } -/* No call-stack tracing */ -void _sym_notify_call(uintptr_t) {} -void _sym_notify_ret(uintptr_t) {} -void _sym_notify_basic_block(uintptr_t) {} - /* No debugging */ const char *_sym_expr_to_string(SymExpr) { From f1c6b0e1593e0e86f55736380d6dea53351feb61 Mon Sep 17 00:00:00 2001 From: Julius Hohnerlein Date: Thu, 1 Jul 2021 09:32:24 +0000 Subject: [PATCH 06/32] move panic mode configuration to cmake script --- runtime/rust_backend/CMakeLists.txt | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/runtime/rust_backend/CMakeLists.txt b/runtime/rust_backend/CMakeLists.txt index 7f7fcc83..bef79adb 100644 --- a/runtime/rust_backend/CMakeLists.txt +++ b/runtime/rust_backend/CMakeLists.txt @@ -12,7 +12,7 @@ # You should have received a copy of the GNU General Public License along with # SymCC. If not, see . -cmake_minimum_required(VERSION 3.12) +cmake_minimum_required(VERSION 3.19) add_library(SymRuntime SHARED ${SHARED_RUNTIME_SOURCES} @@ -28,6 +28,20 @@ find_package(Corrosion REQUIRED) corrosion_import_crate(MANIFEST_PATH ../../../runtime/Cargo.toml) +# enfore panic=abort on the rust runtime, as unwinding will never be what we want (and may cause weird behavior) +set_property( + TARGET runtime + APPEND + PROPERTY CORROSION_ENVIRONMENT_VARIABLES + "CARGO_PROFILE_DEV_PANIC=abort" +) +set_property( + TARGET runtime + APPEND + PROPERTY CORROSION_ENVIRONMENT_VARIABLES + "CARGO_PROFILE_RELEASE_PANIC=abort" +) + target_link_libraries(SymRuntime PUBLIC runtime) add_definitions(-DCOMMON_ONLY) From e243f9aad202841c81a4b76bf7cda06caba788c0 Mon Sep 17 00:00:00 2001 From: Julius Hohnerlein Date: Fri, 16 Jul 2021 07:45:23 +0000 Subject: [PATCH 07/32] re-implement rust backend to support GC and _sym_bits_helper --- runtime/RuntimeCommon.cpp | 7 - runtime/RuntimeCommon.h | 2 - runtime/Shadow.h | 2 - runtime/rust_backend/CMakeLists.txt | 2 - runtime/rust_backend/README.md | 24 +++ runtime/rust_backend/Runtime.cpp | 321 +++++++++++++++++++++++++--- runtime/rust_backend/RustRuntime.h | 150 +++++++++++++ 7 files changed, 471 insertions(+), 37 deletions(-) create mode 100644 runtime/rust_backend/README.md create mode 100644 runtime/rust_backend/RustRuntime.h diff --git a/runtime/RuntimeCommon.cpp b/runtime/RuntimeCommon.cpp index 26e1f440..32081e3e 100644 --- a/runtime/RuntimeCommon.cpp +++ b/runtime/RuntimeCommon.cpp @@ -134,12 +134,6 @@ void _sym_write_memory(uint8_t *addr, size_t length, SymExpr expr, } } -#ifdef COMMON_ONLY - -// these builders should be implementable by the runtime. - -#else - SymExpr _sym_build_extract(SymExpr expr, uint64_t offset, uint64_t length, bool little_endian) { size_t totalBits = _sym_bits_helper(expr); @@ -198,7 +192,6 @@ SymExpr _sym_build_insert(SymExpr target, SymExpr to_insert, uint64_t offset, return result; } -#endif void _sym_register_expression_region(SymExpr *start, size_t length) { registerExpressionRegion({start, length}); diff --git a/runtime/RuntimeCommon.h b/runtime/RuntimeCommon.h index 1f9bb9e8..d8da5dc4 100644 --- a/runtime/RuntimeCommon.h +++ b/runtime/RuntimeCommon.h @@ -128,9 +128,7 @@ SymExpr _sym_build_bool_to_bits(SymExpr expr, uint8_t bits); */ SymExpr _sym_concat_helper(SymExpr a, SymExpr b); SymExpr _sym_extract_helper(SymExpr expr, size_t first_bit, size_t last_bit); -#ifndef COMMON_ONLY size_t _sym_bits_helper(SymExpr expr); -#endif /* * Function-call helpers diff --git a/runtime/Shadow.h b/runtime/Shadow.h index 160852b8..ae920600 100644 --- a/runtime/Shadow.h +++ b/runtime/Shadow.h @@ -82,11 +82,9 @@ class ReadShadowIterator } SymExpr operator*() { -#ifndef COMMON_ONLY // _sym_bits_helper may not be implemeted assert((shadow_ == nullptr || *shadow_ == nullptr || _sym_bits_helper(*shadow_) == 8) && "Shadow memory always represents bytes"); -#endif return shadow_ != nullptr ? *shadow_ : nullptr; } diff --git a/runtime/rust_backend/CMakeLists.txt b/runtime/rust_backend/CMakeLists.txt index bef79adb..f5a51a46 100644 --- a/runtime/rust_backend/CMakeLists.txt +++ b/runtime/rust_backend/CMakeLists.txt @@ -43,5 +43,3 @@ set_property( ) target_link_libraries(SymRuntime PUBLIC runtime) - -add_definitions(-DCOMMON_ONLY) diff --git a/runtime/rust_backend/README.md b/runtime/rust_backend/README.md new file mode 100644 index 00000000..a21f9874 --- /dev/null +++ b/runtime/rust_backend/README.md @@ -0,0 +1,24 @@ +# SymCC Rust Runtime + +This runtime is a wrapper around a stripped down runtime which can be implemented in Rust (or any other language). +This wrapper implements Garbage Collection like the the Simple and QSym runtimes and implements the `_sym_bits_helper`. + +The functions that are left to be implemented by the wrapped runtime are defined in `RustRuntime.h` and mirror those which are defined in `RuntimeCommon.h` except for having new name prefixes and missing those which are related to memory management and utilites. + +## GC implementation +The GC implementation works by keeping track of all expressions that the wrapped runtime generates and calling a new method (`_rsym_expression_unreachable(RSymExpr)`) for each expression that became unreachable in terms of the GC. +The details of this implementation are the same as those of the Simple backend (it's a straight copy). + +## Bits Helper +The bits helper is implemented by embedding the number of bits inside the expression pointer. +Specifically, the least significant byte contains the bit width of the expression. +Boolean expressions have a bit width of 0. +The actual expression pointer is shifted towards the MSB to make space for the bit width. +This reduces the amount of available bits in the expression pointer by 8. +The runtime panics if an expression pointer is returned that would not fit, but this is not expected on 64-bit systems. +(On 32-bit systems this may be a problem, but at this point, we don't care about 32-bit.) + +On a high level, this means that there are two `SymExpr` types now: `SymExpr`, which is used by the wrapper, and `RSymExpr`, which is used by the wrapped runtime. +The wrapper takes care of translating between the two representations as necessary. + +The wrapper also takes care of maintaining the correct bit widths by calculating the resulting width when a width-changing instruction is encountered. \ No newline at end of file diff --git a/runtime/rust_backend/Runtime.cpp b/runtime/rust_backend/Runtime.cpp index fd497514..c6f496b8 100644 --- a/runtime/rust_backend/Runtime.cpp +++ b/runtime/rust_backend/Runtime.cpp @@ -13,6 +13,7 @@ // SymCC. If not, see . #include +#include #include #include @@ -22,23 +23,75 @@ #include #include +#ifndef NDEBUG +#include +#endif + #include "Config.h" #include "GarbageCollection.h" #include "LibcWrappers.h" #include "Shadow.h" -namespace -{ +#ifndef NDEBUG +// Helper to print pointers properly. +#define P(ptr) reinterpret_cast(ptr) +#endif + +/* TODO Eventually we'll want to inline as much of this as possible. I'm keeping + it in C for now because that makes it easier to experiment with new features, + but I expect that a lot of the functions will stay so simple that we can + generate the corresponding bitcode directly in the compiler pass. */ + +namespace { - /// Indicate whether the runtime has been initialized. - std::atomic_flag g_initialized = ATOMIC_FLAG_INIT; +/// Indicate whether the runtime has been initialized. +std::atomic_flag g_initialized = ATOMIC_FLAG_INIT; - FILE *g_log = stderr; +FILE *g_log = stderr; + +#ifndef NDEBUG +[[maybe_unused]] void dump_known_regions() { + std::cerr << "Known regions:" << std::endl; + for (const auto &[page, shadow] : g_shadow_pages) { + std::cerr << " " << P(page) << " shadowed by " << P(shadow) << std::endl; + } +} + +#endif +/// The set of all expressions we have ever passed to client code. +std::set allocatedExpressions; + +SymExpr registerExpression(SymExpr expr) { + allocatedExpressions.insert(expr); + return expr; +} + +// To understand why the following functions exist, read the Bits Helper section +// in the README. + +// Get the bit width out of a SymExpr. +uint8_t symexpr_width(SymExpr expr) { + return (uint8_t)((uintptr_t)expr & UINT8_MAX); +} + +// Get the id out of a SymExpr (which is an RSymExpr). +RSymExpr symexpr_id(SymExpr expr) { return (uintptr_t)expr >> 8; } + +// Construct a SymExpr from a RSymExpr and a bit width. +SymExpr symexpr(RSymExpr expr, uint8_t width) { + if (expr == 0) { + // ensure that 0 RSymExpr still maps to 0 in SymExpr, as this is a special + // value for the rest of the backend. + return 0; + } + // ensure that the RSymExpr fits inside the SymExpr. + assert((((expr << 8) >> 8) == expr) && "expr is too large to be stored"); + return (SymExpr)((expr << 8) | width); +} } // namespace -void _sym_initialize(void) -{ +void _sym_initialize(void) { if (g_initialized.test_and_set()) return; @@ -48,31 +101,251 @@ void _sym_initialize(void) loadConfig(); initLibcWrappers(); - std::cerr << "This is SymCC running with the rust backend" << std::endl - << std::endl; + std::cerr << "This is SymCC running with the Rust backend" << std::endl; - if (g_config.logFile.empty()) - { + if (g_config.logFile.empty()) { g_log = stderr; - } - else - { + } else { g_log = fopen(g_config.logFile.c_str(), "w"); } } -/* No debugging */ -const char *_sym_expr_to_string(SymExpr) -{ - return NULL; +SymExpr _sym_build_integer(uint64_t value, uint8_t bits) { + return registerExpression(symexpr(_rsym_build_integer(value, bits), bits)); +} + +SymExpr _sym_build_integer128(uint64_t high, uint64_t low) { + return registerExpression(symexpr(_rsym_build_integer128(high, low), 128)); } -bool _sym_feasible(SymExpr) -{ - return false; +SymExpr _sym_build_float(double value, int is_double) { + return registerExpression( + symexpr(_rsym_build_float(value, is_double), is_double ? 64 : 32)); } -/* No garbage collection */ -void _sym_collect_garbage() -{ +SymExpr _sym_get_input_byte(size_t offset) { + return registerExpression(symexpr(_rsym_get_input_byte(offset), 8)); +} + +SymExpr _sym_build_null_pointer(void) { + return registerExpression( + symexpr(_rsym_build_null_pointer(), sizeof(uintptr_t) * 8)); +} + +SymExpr _sym_build_true(void) { + return registerExpression(symexpr(_rsym_build_true(), 0)); +} + +SymExpr _sym_build_false(void) { + return registerExpression(symexpr(_rsym_build_false(), 0)); +} + +SymExpr _sym_build_bool(bool value) { + return registerExpression(symexpr(_rsym_build_bool(value), 0)); +} + +#define DEF_UNARY_EXPR_BUILDER(name) \ + SymExpr _sym_build_##name(SymExpr expr) { \ + return registerExpression( \ + symexpr(_rsym_build_##name(symexpr_id(expr)), symexpr_width(expr))); \ + } + +DEF_UNARY_EXPR_BUILDER(neg) + +#define DEF_BINARY_BV_EXPR_BUILDER(name) \ + SymExpr _sym_build_##name(SymExpr a, SymExpr b) { \ + return registerExpression(symexpr( \ + _rsym_build_##name(symexpr_id(a), symexpr_id(b)), symexpr_width(a))); \ + } + +DEF_BINARY_BV_EXPR_BUILDER(add) +DEF_BINARY_BV_EXPR_BUILDER(sub) +DEF_BINARY_BV_EXPR_BUILDER(mul) +DEF_BINARY_BV_EXPR_BUILDER(unsigned_div) +DEF_BINARY_BV_EXPR_BUILDER(signed_div) +DEF_BINARY_BV_EXPR_BUILDER(unsigned_rem) +DEF_BINARY_BV_EXPR_BUILDER(signed_rem) +DEF_BINARY_BV_EXPR_BUILDER(shift_left) +DEF_BINARY_BV_EXPR_BUILDER(logical_shift_right) +DEF_BINARY_BV_EXPR_BUILDER(arithmetic_shift_right) + +#define DEF_BINARY_BOOL_EXPR_BUILDER(name) \ + SymExpr _sym_build_##name(SymExpr a, SymExpr b) { \ + return registerExpression( \ + symexpr(_rsym_build_##name(symexpr_id(a), symexpr_id(b)), 0)); \ + } + +DEF_BINARY_BOOL_EXPR_BUILDER(signed_less_than) +DEF_BINARY_BOOL_EXPR_BUILDER(signed_less_equal) +DEF_BINARY_BOOL_EXPR_BUILDER(signed_greater_than) +DEF_BINARY_BOOL_EXPR_BUILDER(signed_greater_equal) +DEF_BINARY_BOOL_EXPR_BUILDER(unsigned_less_than) +DEF_BINARY_BOOL_EXPR_BUILDER(unsigned_less_equal) +DEF_BINARY_BOOL_EXPR_BUILDER(unsigned_greater_than) +DEF_BINARY_BOOL_EXPR_BUILDER(unsigned_greater_equal) +DEF_BINARY_BOOL_EXPR_BUILDER(equal) + +DEF_BINARY_BV_EXPR_BUILDER(and) +DEF_BINARY_BV_EXPR_BUILDER(or) +DEF_BINARY_BV_EXPR_BUILDER(bool_xor) +DEF_BINARY_BV_EXPR_BUILDER(xor) + +DEF_BINARY_BOOL_EXPR_BUILDER(float_ordered_greater_than) +DEF_BINARY_BOOL_EXPR_BUILDER(float_ordered_greater_equal) +DEF_BINARY_BOOL_EXPR_BUILDER(float_ordered_less_than) +DEF_BINARY_BOOL_EXPR_BUILDER(float_ordered_less_equal) +DEF_BINARY_BOOL_EXPR_BUILDER(float_ordered_equal) + +DEF_BINARY_BV_EXPR_BUILDER(fp_add) +DEF_BINARY_BV_EXPR_BUILDER(fp_sub) +DEF_BINARY_BV_EXPR_BUILDER(fp_mul) +DEF_BINARY_BV_EXPR_BUILDER(fp_div) +DEF_BINARY_BV_EXPR_BUILDER(fp_rem) + +#undef DEF_BINARY_BV_EXPR_BUILDER + +DEF_UNARY_EXPR_BUILDER(fp_abs) + +DEF_UNARY_EXPR_BUILDER(not ) +DEF_BINARY_BOOL_EXPR_BUILDER(not_equal) + +#undef DEF_UNARY_EXPR_BUILDER + +DEF_BINARY_BOOL_EXPR_BUILDER(bool_and) +DEF_BINARY_BOOL_EXPR_BUILDER(bool_or) + +DEF_BINARY_BOOL_EXPR_BUILDER(float_ordered_not_equal) +DEF_BINARY_BOOL_EXPR_BUILDER(float_ordered) +DEF_BINARY_BOOL_EXPR_BUILDER(float_unordered) + +DEF_BINARY_BOOL_EXPR_BUILDER(float_unordered_greater_than) +DEF_BINARY_BOOL_EXPR_BUILDER(float_unordered_greater_equal) +DEF_BINARY_BOOL_EXPR_BUILDER(float_unordered_less_than) +DEF_BINARY_BOOL_EXPR_BUILDER(float_unordered_less_equal) +DEF_BINARY_BOOL_EXPR_BUILDER(float_unordered_equal) +DEF_BINARY_BOOL_EXPR_BUILDER(float_unordered_not_equal) + +#undef DEF_BINARY_BOOL_EXPR_BUILDER + +SymExpr _sym_build_sext(SymExpr expr, uint8_t bits) { + return registerExpression(symexpr(_rsym_build_sext(symexpr_id(expr), bits), + symexpr_width(expr) + bits)); +} + +SymExpr _sym_build_zext(SymExpr expr, uint8_t bits) { + return registerExpression(symexpr(_rsym_build_zext(symexpr_id(expr), bits), + symexpr_width(expr) + bits)); +} + +SymExpr _sym_build_trunc(SymExpr expr, uint8_t bits) { + return registerExpression( + symexpr(_rsym_build_zext(symexpr_id(expr), bits), bits)); +} + +SymExpr _sym_build_int_to_float(SymExpr expr, int is_double, int is_signed) { + return registerExpression( + symexpr(_rsym_build_int_to_float(symexpr_id(expr), is_double, is_signed), + is_double ? 64 : 32)); +} + +SymExpr _sym_build_float_to_float(SymExpr expr, int to_double) { + return registerExpression( + symexpr(_rsym_build_float_to_float(symexpr_id(expr), to_double), + to_double ? 64 : 32)); +} + +SymExpr _sym_build_bits_to_float(SymExpr expr, int to_double) { + if (expr == 0) + return 0; + + return registerExpression( + symexpr(_rsym_build_bits_to_float(symexpr_id(expr), to_double), + to_double ? 64 : 32)); +} + +SymExpr _sym_build_float_to_bits(SymExpr expr) { + if (expr == nullptr) + return nullptr; + return registerExpression(symexpr(_rsym_build_float_to_bits(symexpr_id(expr)), + symexpr_width(expr))); +} + +SymExpr _sym_build_float_to_signed_integer(SymExpr expr, uint8_t bits) { + return registerExpression(symexpr( + _rsym_build_float_to_signed_integer(symexpr_id(expr), bits), bits)); +} + +SymExpr _sym_build_float_to_unsigned_integer(SymExpr expr, uint8_t bits) { + return registerExpression(symexpr( + _rsym_build_float_to_unsigned_integer(symexpr_id(expr), bits), bits)); +} + +SymExpr _sym_build_bool_to_bits(SymExpr expr, uint8_t bits) { + return registerExpression( + symexpr(_rsym_build_bool_to_bits(symexpr_id(expr), bits), bits)); +} + +void _sym_push_path_constraint(SymExpr constraint, int taken, + uintptr_t site_id) { + if (constraint == 0) + return; + _rsym_push_path_constraint(symexpr_id(constraint), taken, site_id); +} + +SymExpr _sym_concat_helper(SymExpr a, SymExpr b) { + return registerExpression( + symexpr(_rsym_concat_helper(symexpr_id(a), symexpr_id(b)), + symexpr_width(a) + symexpr_width(b))); +} + +SymExpr _sym_extract_helper(SymExpr expr, size_t first_bit, size_t last_bit) { + return registerExpression( + symexpr(_rsym_extract_helper(symexpr_id(expr), first_bit, last_bit), + first_bit - last_bit + 1)); +} + +size_t _sym_bits_helper(SymExpr expr) { return symexpr_width(expr); } + +void _sym_notify_call(uintptr_t loc) { _rsym_notify_call(loc); } +void _sym_notify_ret(uintptr_t loc) { _rsym_notify_ret(loc); } +void _sym_notify_basic_block(uintptr_t loc) { _rsym_notify_basic_block(loc); } + +/* Debugging */ +const char *_sym_expr_to_string(SymExpr) { return nullptr; } + +bool _sym_feasible(SymExpr) { return false; } + +/* Garbage collection */ +void _sym_collect_garbage() { + if (allocatedExpressions.size() < g_config.garbageCollectionThreshold) + return; + +#ifndef NDEBUG + auto start = std::chrono::high_resolution_clock::now(); + auto startSize = allocatedExpressions.size(); +#endif + + auto reachableExpressions = collectReachableExpressions(); + for (auto expr_it = allocatedExpressions.begin(); + expr_it != allocatedExpressions.end();) { + if (reachableExpressions.count(*expr_it) == 0) { + _rsym_expression_unreachable(symexpr_id(*expr_it)); + expr_it = allocatedExpressions.erase(expr_it); + } else { + ++expr_it; + } + } + +#ifndef NDEBUG + auto end = std::chrono::high_resolution_clock::now(); + auto endSize = allocatedExpressions.size(); + + std::cerr << "After garbage collection: " << endSize + << " expressions remain (before: " << startSize << ")" << std::endl + << "\t(collection took " + << std::chrono::duration_cast(end - + start) + .count() + << " milliseconds)" << std::endl; +#endif } diff --git a/runtime/rust_backend/RustRuntime.h b/runtime/rust_backend/RustRuntime.h new file mode 100644 index 00000000..a90c6426 --- /dev/null +++ b/runtime/rust_backend/RustRuntime.h @@ -0,0 +1,150 @@ +// Rust Run-time library interface -*- C++ -*- +// +// This header is mostly a straight copy of RuntimeCommon.h with different +// function name prefixes, a separate SymExpr type and all functions that are +// implemented by this wrapper removed. This file defines the interface that the +// wrapped runtime should implement. Consult the README for a high-level +// overview. +// +// This file is part of SymCC. +// +// SymCC is free software: you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the Free Software +// Foundation, either version 3 of the License, or (at your option) any later +// version. +// +// SymCC is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +// A PARTICULAR PURPOSE. See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along with +// SymCC. If not, see . + +#ifndef RUSTRUNTIME_H +#define RUSTRUNTIME_H + +typedef uintptr_t RSymExpr; + +#include + +#ifdef __cplusplus +#include +extern "C" { +#else +#include +#endif + +/* + * Construction of simple values + */ +RSymExpr _rsym_build_integer(uint64_t value, uint8_t bits); +RSymExpr _rsym_build_integer128(uint64_t high, uint64_t low); +RSymExpr _rsym_build_float(double value, int is_double); +RSymExpr _rsym_build_null_pointer(void); +RSymExpr _rsym_build_true(void); +RSymExpr _rsym_build_false(void); +RSymExpr _rsym_build_bool(bool value); + +/* + * Arithmetic and shifts + */ +RSymExpr _rsym_build_neg(RSymExpr expr); +RSymExpr _rsym_build_add(RSymExpr a, RSymExpr b); +RSymExpr _rsym_build_sub(RSymExpr a, RSymExpr b); +RSymExpr _rsym_build_mul(RSymExpr a, RSymExpr b); +RSymExpr _rsym_build_unsigned_div(RSymExpr a, RSymExpr b); +RSymExpr _rsym_build_signed_div(RSymExpr a, RSymExpr b); +RSymExpr _rsym_build_unsigned_rem(RSymExpr a, RSymExpr b); +RSymExpr _rsym_build_signed_rem(RSymExpr a, RSymExpr b); +RSymExpr _rsym_build_shift_left(RSymExpr a, RSymExpr b); +RSymExpr _rsym_build_logical_shift_right(RSymExpr a, RSymExpr b); +RSymExpr _rsym_build_arithmetic_shift_right(RSymExpr a, RSymExpr b); + +RSymExpr _rsym_build_fp_add(RSymExpr a, RSymExpr b); +RSymExpr _rsym_build_fp_sub(RSymExpr a, RSymExpr b); +RSymExpr _rsym_build_fp_mul(RSymExpr a, RSymExpr b); +RSymExpr _rsym_build_fp_div(RSymExpr a, RSymExpr b); +RSymExpr _rsym_build_fp_rem(RSymExpr a, RSymExpr b); +RSymExpr _rsym_build_fp_abs(RSymExpr a); + +/* + * Boolean operations + */ +RSymExpr _rsym_build_not(RSymExpr expr); +RSymExpr _rsym_build_signed_less_than(RSymExpr a, RSymExpr b); +RSymExpr _rsym_build_signed_less_equal(RSymExpr a, RSymExpr b); +RSymExpr _rsym_build_signed_greater_than(RSymExpr a, RSymExpr b); +RSymExpr _rsym_build_signed_greater_equal(RSymExpr a, RSymExpr b); +RSymExpr _rsym_build_unsigned_less_than(RSymExpr a, RSymExpr b); +RSymExpr _rsym_build_unsigned_less_equal(RSymExpr a, RSymExpr b); +RSymExpr _rsym_build_unsigned_greater_than(RSymExpr a, RSymExpr b); +RSymExpr _rsym_build_unsigned_greater_equal(RSymExpr a, RSymExpr b); +RSymExpr _rsym_build_equal(RSymExpr a, RSymExpr b); +RSymExpr _rsym_build_not_equal(RSymExpr a, RSymExpr b); +RSymExpr _rsym_build_bool_and(RSymExpr a, RSymExpr b); +RSymExpr _rsym_build_and(RSymExpr a, RSymExpr b); +RSymExpr _rsym_build_bool_or(RSymExpr a, RSymExpr b); +RSymExpr _rsym_build_or(RSymExpr a, RSymExpr b); +RSymExpr _rsym_build_bool_xor(RSymExpr a, RSymExpr b); +RSymExpr _rsym_build_xor(RSymExpr a, RSymExpr b); + +RSymExpr _rsym_build_float_ordered_greater_than(RSymExpr a, RSymExpr b); +RSymExpr _rsym_build_float_ordered_greater_equal(RSymExpr a, RSymExpr b); +RSymExpr _rsym_build_float_ordered_less_than(RSymExpr a, RSymExpr b); +RSymExpr _rsym_build_float_ordered_less_equal(RSymExpr a, RSymExpr b); +RSymExpr _rsym_build_float_ordered_equal(RSymExpr a, RSymExpr b); +RSymExpr _rsym_build_float_ordered_not_equal(RSymExpr a, RSymExpr b); +RSymExpr _rsym_build_float_ordered(RSymExpr a, RSymExpr b); +RSymExpr _rsym_build_float_unordered(RSymExpr a, RSymExpr b); +RSymExpr _rsym_build_float_unordered_greater_than(RSymExpr a, RSymExpr b); +RSymExpr _rsym_build_float_unordered_greater_equal(RSymExpr a, RSymExpr b); +RSymExpr _rsym_build_float_unordered_less_than(RSymExpr a, RSymExpr b); +RSymExpr _rsym_build_float_unordered_less_equal(RSymExpr a, RSymExpr b); +RSymExpr _rsym_build_float_unordered_equal(RSymExpr a, RSymExpr b); +RSymExpr _rsym_build_float_unordered_not_equal(RSymExpr a, RSymExpr b); + +/* + * Casts + */ +RSymExpr _rsym_build_sext(RSymExpr expr, uint8_t bits); +RSymExpr _rsym_build_zext(RSymExpr expr, uint8_t bits); +RSymExpr _rsym_build_trunc(RSymExpr expr, uint8_t bits); +RSymExpr _rsym_build_bswap(RSymExpr expr); +RSymExpr _rsym_build_int_to_float(RSymExpr value, int is_double, int is_signed); +RSymExpr _rsym_build_float_to_float(RSymExpr expr, int to_double); +RSymExpr _rsym_build_bits_to_float(RSymExpr expr, int to_double); +RSymExpr _rsym_build_float_to_bits(RSymExpr expr); +RSymExpr _rsym_build_float_to_signed_integer(RSymExpr expr, uint8_t bits); +RSymExpr _rsym_build_float_to_unsigned_integer(RSymExpr expr, uint8_t bits); +RSymExpr _rsym_build_bool_to_bits(RSymExpr expr, uint8_t bits); + +/* + * Bit-array helpers + */ +RSymExpr _rsym_concat_helper(RSymExpr a, RSymExpr b); +RSymExpr _rsym_extract_helper(RSymExpr expr, size_t first_bit, size_t last_bit); + +/* + * Constraint handling + */ +void _rsym_push_path_constraint(RSymExpr constraint, int taken, + uintptr_t site_id); +RSymExpr _rsym_get_input_byte(size_t offset); + +/* + * Call-stack tracing + */ +void _rsym_notify_call(uintptr_t site_id); +void _rsym_notify_ret(uintptr_t site_id); +void _rsym_notify_basic_block(uintptr_t site_id); + +/* + * Garbage collection + */ +void _rsym_expression_unreachable(RSymExpr expr); + +#ifdef __cplusplus +} +#endif + +#endif From 1346fca3c1447772df0b5168d3a8df954178daf9 Mon Sep 17 00:00:00 2001 From: Julius Hohnerlein Date: Fri, 16 Jul 2021 09:08:02 +0000 Subject: [PATCH 08/32] pass gc information as array instead of of single values --- runtime/rust_backend/Runtime.cpp | 8 +++++++- runtime/rust_backend/RustRuntime.h | 2 +- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/runtime/rust_backend/Runtime.cpp b/runtime/rust_backend/Runtime.cpp index c6f496b8..3a6cc29a 100644 --- a/runtime/rust_backend/Runtime.cpp +++ b/runtime/rust_backend/Runtime.cpp @@ -325,16 +325,22 @@ void _sym_collect_garbage() { auto startSize = allocatedExpressions.size(); #endif + std::vector unreachable_expressions; + auto reachableExpressions = collectReachableExpressions(); for (auto expr_it = allocatedExpressions.begin(); expr_it != allocatedExpressions.end();) { if (reachableExpressions.count(*expr_it) == 0) { - _rsym_expression_unreachable(symexpr_id(*expr_it)); + unreachable_expressions.push_back(symexpr_id(*expr_it)); expr_it = allocatedExpressions.erase(expr_it); } else { ++expr_it; } } + if (unreachable_expressions.size() > 0) { + _rsym_expression_unreachable(unreachable_expressions.data(), + unreachable_expressions.size()); + } #ifndef NDEBUG auto end = std::chrono::high_resolution_clock::now(); diff --git a/runtime/rust_backend/RustRuntime.h b/runtime/rust_backend/RustRuntime.h index a90c6426..e171e2da 100644 --- a/runtime/rust_backend/RustRuntime.h +++ b/runtime/rust_backend/RustRuntime.h @@ -141,7 +141,7 @@ void _rsym_notify_basic_block(uintptr_t site_id); /* * Garbage collection */ -void _rsym_expression_unreachable(RSymExpr expr); +void _rsym_expression_unreachable(RSymExpr *expressions, size_t num_elements); #ifdef __cplusplus } From 2b62059a683628ac74cdd1030a0d5c7d9346ab38 Mon Sep 17 00:00:00 2001 From: Julius Hohnerlein Date: Mon, 26 Jul 2021 10:22:26 +0000 Subject: [PATCH 09/32] fix missing include --- runtime/rust_backend/Runtime.h | 1 + 1 file changed, 1 insertion(+) diff --git a/runtime/rust_backend/Runtime.h b/runtime/rust_backend/Runtime.h index 901c536a..988bac79 100644 --- a/runtime/rust_backend/Runtime.h +++ b/runtime/rust_backend/Runtime.h @@ -14,6 +14,7 @@ #ifndef RUNTIME_H #define RUNTIME_H +#include typedef void* SymExpr; #include From ec053674ba1a09b8b4187a7e4069c40cdf0bc95c Mon Sep 17 00:00:00 2001 From: Julius Hohnerlein Date: Mon, 26 Jul 2021 10:23:07 +0000 Subject: [PATCH 10/32] switch to building the rust backend into a static archive instead of a dynamic library --- runtime/rust_backend/CMakeLists.txt | 24 ++---------------------- 1 file changed, 2 insertions(+), 22 deletions(-) diff --git a/runtime/rust_backend/CMakeLists.txt b/runtime/rust_backend/CMakeLists.txt index f5a51a46..b237c093 100644 --- a/runtime/rust_backend/CMakeLists.txt +++ b/runtime/rust_backend/CMakeLists.txt @@ -12,9 +12,7 @@ # You should have received a copy of the GNU General Public License along with # SymCC. If not, see . -cmake_minimum_required(VERSION 3.19) - -add_library(SymRuntime SHARED +add_library(SymRuntime STATIC ${SHARED_RUNTIME_SOURCES} Runtime.cpp) @@ -24,22 +22,4 @@ target_include_directories(SymRuntime PRIVATE set_target_properties(SymRuntime PROPERTIES COMPILE_FLAGS "-Werror") -find_package(Corrosion REQUIRED) - -corrosion_import_crate(MANIFEST_PATH ../../../runtime/Cargo.toml) - -# enfore panic=abort on the rust runtime, as unwinding will never be what we want (and may cause weird behavior) -set_property( - TARGET runtime - APPEND - PROPERTY CORROSION_ENVIRONMENT_VARIABLES - "CARGO_PROFILE_DEV_PANIC=abort" -) -set_property( - TARGET runtime - APPEND - PROPERTY CORROSION_ENVIRONMENT_VARIABLES - "CARGO_PROFILE_RELEASE_PANIC=abort" -) - -target_link_libraries(SymRuntime PUBLIC runtime) +INSTALL(TARGETS SymRuntime) \ No newline at end of file From ba0aeac613e75f60c633cd17d736352f80e5a67d Mon Sep 17 00:00:00 2001 From: Julius Hohnerlein Date: Wed, 28 Jul 2021 10:33:48 +0000 Subject: [PATCH 11/32] fix rust runtime header --- runtime/rust_backend/RustRuntime.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/runtime/rust_backend/RustRuntime.h b/runtime/rust_backend/RustRuntime.h index e171e2da..e1a5afa5 100644 --- a/runtime/rust_backend/RustRuntime.h +++ b/runtime/rust_backend/RustRuntime.h @@ -23,8 +23,6 @@ #ifndef RUSTRUNTIME_H #define RUSTRUNTIME_H -typedef uintptr_t RSymExpr; - #include #ifdef __cplusplus @@ -34,6 +32,8 @@ extern "C" { #include #endif +typedef uintptr_t RSymExpr; + /* * Construction of simple values */ From 1a1bf95ac52fa3074acfb095ca91c45cfe6c35d4 Mon Sep 17 00:00:00 2001 From: Julius Hohnerlein Date: Wed, 28 Jul 2021 12:54:59 +0000 Subject: [PATCH 12/32] use more convenient types for rust runtime --- runtime/rust_backend/RustRuntime.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/runtime/rust_backend/RustRuntime.h b/runtime/rust_backend/RustRuntime.h index e1a5afa5..53edf6e2 100644 --- a/runtime/rust_backend/RustRuntime.h +++ b/runtime/rust_backend/RustRuntime.h @@ -39,7 +39,7 @@ typedef uintptr_t RSymExpr; */ RSymExpr _rsym_build_integer(uint64_t value, uint8_t bits); RSymExpr _rsym_build_integer128(uint64_t high, uint64_t low); -RSymExpr _rsym_build_float(double value, int is_double); +RSymExpr _rsym_build_float(double value, bool is_double); RSymExpr _rsym_build_null_pointer(void); RSymExpr _rsym_build_true(void); RSymExpr _rsym_build_false(void); @@ -109,10 +109,10 @@ RSymExpr _rsym_build_float_unordered_not_equal(RSymExpr a, RSymExpr b); RSymExpr _rsym_build_sext(RSymExpr expr, uint8_t bits); RSymExpr _rsym_build_zext(RSymExpr expr, uint8_t bits); RSymExpr _rsym_build_trunc(RSymExpr expr, uint8_t bits); -RSymExpr _rsym_build_bswap(RSymExpr expr); -RSymExpr _rsym_build_int_to_float(RSymExpr value, int is_double, int is_signed); -RSymExpr _rsym_build_float_to_float(RSymExpr expr, int to_double); -RSymExpr _rsym_build_bits_to_float(RSymExpr expr, int to_double); +RSymExpr _rsym_build_int_to_float(RSymExpr value, bool is_double, + bool is_signed); +RSymExpr _rsym_build_float_to_float(RSymExpr expr, bool to_double); +RSymExpr _rsym_build_bits_to_float(RSymExpr expr, bool to_double); RSymExpr _rsym_build_float_to_bits(RSymExpr expr); RSymExpr _rsym_build_float_to_signed_integer(RSymExpr expr, uint8_t bits); RSymExpr _rsym_build_float_to_unsigned_integer(RSymExpr expr, uint8_t bits); @@ -127,7 +127,7 @@ RSymExpr _rsym_extract_helper(RSymExpr expr, size_t first_bit, size_t last_bit); /* * Constraint handling */ -void _rsym_push_path_constraint(RSymExpr constraint, int taken, +void _rsym_push_path_constraint(RSymExpr constraint, bool taken, uintptr_t site_id); RSymExpr _rsym_get_input_byte(size_t offset); From 8b35ef859c17f4de2bfbfeb57fd3fcdaedc99d66 Mon Sep 17 00:00:00 2001 From: Julius Hohnerlein Date: Thu, 29 Jul 2021 09:09:55 +0000 Subject: [PATCH 13/32] cleanup --- CMakeLists.txt | 2 +- runtime/CMakeLists.txt | 2 +- runtime/RuntimeCommon.h | 2 -- 3 files changed, 2 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6152af45..d31d053b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -15,8 +15,8 @@ cmake_minimum_required(VERSION 3.5) project(SymbolicCompiler) -option(RUST_BACKEND "Build just the common backend code, linked with the rust runtime" OFF) option(QSYM_BACKEND "Use the Qsym backend instead of our own" OFF) +option(RUST_BACKEND "Build the support code required for a Rust backend as a static archive." OFF) option(TARGET_32BIT "Make the compiler work correctly with -m32" OFF) # We need to build the runtime as an external project because CMake otherwise diff --git a/runtime/CMakeLists.txt b/runtime/CMakeLists.txt index 1628b59c..28ddb303 100644 --- a/runtime/CMakeLists.txt +++ b/runtime/CMakeLists.txt @@ -22,7 +22,7 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17 \ -Wmissing-format-attribute -Wformat-nonliteral") option(QSYM_BACKEND "Use the Qsym backend instead of our own" OFF) -option(RUST_BACKEND "Build just the common backend code, linked with the rust runtime" OFF) +option(RUST_BACKEND "Build the support code required for a Rust backend as a static archive." OFF) option(Z3_TRUST_SYSTEM_VERSION "Use the system-provided Z3 without a version check" OFF) # Place the final product in the top-level output directory diff --git a/runtime/RuntimeCommon.h b/runtime/RuntimeCommon.h index d8da5dc4..f00176ea 100644 --- a/runtime/RuntimeCommon.h +++ b/runtime/RuntimeCommon.h @@ -25,8 +25,6 @@ #ifndef RUNTIMECOMMON_H #define RUNTIMECOMMON_H -#include - #ifdef __cplusplus #include extern "C" { From f44262f9304190a93e85d86530f4ae02ab8f391f Mon Sep 17 00:00:00 2001 From: Julius Hohnerlein Date: Thu, 29 Jul 2021 09:19:52 +0000 Subject: [PATCH 14/32] fix RuntimeCommon.h includes --- runtime/RuntimeCommon.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/runtime/RuntimeCommon.h b/runtime/RuntimeCommon.h index f00176ea..05d8e954 100644 --- a/runtime/RuntimeCommon.h +++ b/runtime/RuntimeCommon.h @@ -26,9 +26,11 @@ #define RUNTIMECOMMON_H #ifdef __cplusplus +#include // for size_t #include extern "C" { #else +#include // for size_t #include #endif From 45cde0269ae22aef4cca2e1fb98c3b24f7bb2984 Mon Sep 17 00:00:00 2001 From: Julius Hohnerlein Date: Mon, 2 Aug 2021 12:10:08 +0000 Subject: [PATCH 15/32] fix c+p bug in rust runtime (inadverntently turgnin trunc in zext) --- runtime/rust_backend/Runtime.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime/rust_backend/Runtime.cpp b/runtime/rust_backend/Runtime.cpp index 3a6cc29a..a8188313 100644 --- a/runtime/rust_backend/Runtime.cpp +++ b/runtime/rust_backend/Runtime.cpp @@ -239,7 +239,7 @@ SymExpr _sym_build_zext(SymExpr expr, uint8_t bits) { SymExpr _sym_build_trunc(SymExpr expr, uint8_t bits) { return registerExpression( - symexpr(_rsym_build_zext(symexpr_id(expr), bits), bits)); + symexpr(_rsym_build_trunc(symexpr_id(expr), bits), bits)); } SymExpr _sym_build_int_to_float(SymExpr expr, int is_double, int is_signed) { From 3133c0b37d3c498db9addf2331378c7c9cadbf10 Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Tue, 4 Jan 2022 14:36:54 +0100 Subject: [PATCH 16/32] Move to clap3 (#2) --- util/symcc_fuzzing_helper/Cargo.toml | 2 +- util/symcc_fuzzing_helper/src/main.rs | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/util/symcc_fuzzing_helper/Cargo.toml b/util/symcc_fuzzing_helper/Cargo.toml index d09d8ae3..f8858d88 100644 --- a/util/symcc_fuzzing_helper/Cargo.toml +++ b/util/symcc_fuzzing_helper/Cargo.toml @@ -20,7 +20,7 @@ edition = "2018" license = "GPL-3.0-or-later" [dependencies] -structopt = "0.3" +clap = { version = "3.0", features = ["derive"]} tempfile = "3.1" anyhow = "1.0" log = "0.4.0" diff --git a/util/symcc_fuzzing_helper/src/main.rs b/util/symcc_fuzzing_helper/src/main.rs index 6d284e1e..a75f9db8 100644 --- a/util/symcc_fuzzing_helper/src/main.rs +++ b/util/symcc_fuzzing_helper/src/main.rs @@ -22,7 +22,7 @@ use std::io::Write; use std::path::{Path, PathBuf}; use std::thread; use std::time::{Duration, Instant}; -use structopt::StructOpt; +use clap::{self, StructOpt}; use symcc::{AflConfig, AflMap, AflShowmapResult, SymCC, TestcaseDir}; use tempfile::tempdir; @@ -32,22 +32,22 @@ const STATS_INTERVAL_SEC: u64 = 60; // inputs. #[derive(Debug, StructOpt)] -#[structopt(about = "Make SymCC collaborate with AFL.", no_version)] -struct CLI { +#[clap(about = "Make SymCC collaborate with AFL.", no_version)] +struct Opt { /// The name of the fuzzer to work with - #[structopt(short = "a")] + #[clap(short = 'a')] fuzzer_name: String, /// The AFL output directory - #[structopt(short = "o")] + #[clap(short = 'o')] output_dir: PathBuf, /// Name to use for SymCC - #[structopt(short = "n")] + #[clap(short = 'n')] name: String, /// Enable verbose logging - #[structopt(short = "v")] + #[clap(short = 'v')] verbose: bool, /// Program under test @@ -264,7 +264,7 @@ impl State { } fn main() -> Result<()> { - let options = CLI::from_args(); + let options = Opt::parse(); env_logger::builder() .filter_level(if options.verbose { log::LevelFilter::Debug From 08c29c5894c8db263232f684243cdbc545866f88 Mon Sep 17 00:00:00 2001 From: WilliamParks Date: Sat, 26 Mar 2022 19:49:16 -0400 Subject: [PATCH 17/32] Adds handling for afl-showmap failures, to avoid crashing the entire symcc fuzzing helper (#1) --- util/symcc_fuzzing_helper/src/main.rs | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/util/symcc_fuzzing_helper/src/main.rs b/util/symcc_fuzzing_helper/src/main.rs index a75f9db8..d2e11b6d 100644 --- a/util/symcc_fuzzing_helper/src/main.rs +++ b/util/symcc_fuzzing_helper/src/main.rs @@ -227,24 +227,35 @@ impl State { let mut num_interesting = 0u64; let mut num_total = 0u64; + let mut num_failed = 0u64; let symcc_result = symcc .run(&input, tmp_dir.path().join("output")) .context("Failed to run SymCC")?; for new_test in symcc_result.test_cases.iter() { - let res = process_new_testcase(&new_test, &input, &tmp_dir, &afl_config, self)?; + let res = process_new_testcase(&new_test, &input, &tmp_dir, &afl_config, self); num_total += 1; - if res == TestcaseResult::New { - log::debug!("Test case is interesting"); - num_interesting += 1; - } + + match res { + Err(e) => { + log::error!("Showmap failed with {}", e); + num_failed += 1; + } + Ok(o) => { + if o == TestcaseResult::New { + log::debug!("Test case is interesting"); + num_interesting += 1; + } + } + }; } log::info!( - "Generated {} test cases ({} new)", + "Generated {} test cases ({} new, {} failed)", num_total, - num_interesting + num_interesting, + num_failed ); if symcc_result.killed { From 5cccc33456c48ad83008eb618e7da5d005c72d89 Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Sun, 27 Mar 2022 00:11:01 +0000 Subject: [PATCH 18/32] more less bugs --- util/symcc_fuzzing_helper/Cargo.lock | 371 ++++++++++++-------------- util/symcc_fuzzing_helper/src/main.rs | 2 +- 2 files changed, 172 insertions(+), 201 deletions(-) diff --git a/util/symcc_fuzzing_helper/Cargo.lock b/util/symcc_fuzzing_helper/Cargo.lock index 5fa913db..417f964f 100644 --- a/util/symcc_fuzzing_helper/Cargo.lock +++ b/util/symcc_fuzzing_helper/Cargo.lock @@ -1,459 +1,430 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. +version = 3 + [[package]] name = "aho-corasick" version = "0.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "743ad5a418686aad3b87fd14c43badd828cf26e214a00f92a384291cf22e1811" dependencies = [ - "memchr 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "ansi_term" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", + "memchr", ] [[package]] name = "anyhow" version = "1.0.26" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7825f6833612eb2414095684fcf6c635becf3ce97fe48cf6421321e93bfbd53c" [[package]] name = "atty" version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" dependencies = [ - "hermit-abi 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", + "hermit-abi", + "libc", + "winapi", ] +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + [[package]] name = "bitflags" version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" [[package]] name = "c2-chacha" version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "214238caa1bf3a496ec3392968969cab8549f96ff30652c9e56885329315f6bb" dependencies = [ - "ppv-lite86 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", + "ppv-lite86", ] [[package]] name = "cfg-if" version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" [[package]] name = "clap" -version = "2.33.0" +version = "3.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8c93436c21e4698bacadf42917db28b23017027a4deccb35dbe47a7e7840123" +dependencies = [ + "atty", + "bitflags", + "clap_derive", + "indexmap", + "lazy_static", + "os_str_bytes", + "strsim", + "termcolor", + "textwrap", +] + +[[package]] +name = "clap_derive" +version = "3.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da95d038ede1a964ce99f49cbe27a7fb538d1da595e4b4f70b8c8f338d17bf16" dependencies = [ - "ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", - "atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", - "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "strsim 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", - "textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", - "unicode-width 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", - "vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", + "heck", + "proc-macro-error", + "proc-macro2", + "quote", + "syn", ] [[package]] name = "env_logger" version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44533bbbb3bb3c1fa17d9f2e4e38bbbaf8396ba82193c4cb1b6445d711445d36" dependencies = [ - "atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", - "humantime 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)", - "termcolor 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "atty", + "humantime", + "log", + "regex", + "termcolor", ] [[package]] name = "getrandom" version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7abc8dd8451921606d809ba32e95b6111925cd2906060d2dcc29c070220503eb" dependencies = [ - "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", - "wasi 0.9.0+wasi-snapshot-preview1 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if", + "libc", + "wasi", ] +[[package]] +name = "hashbrown" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" + [[package]] name = "heck" -version = "0.3.1" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "unicode-segmentation 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)", -] +checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9" [[package]] name = "hermit-abi" version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eff2656d88f158ce120947499e971d743c05dbcbed62e5bd2f38f1698bbc3772" dependencies = [ - "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", + "libc", ] [[package]] name = "humantime" version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df004cfca50ef23c36850aaaa59ad52cc70d0e90243c3c7737a4dd32dc7a3c4f" +dependencies = [ + "quick-error", +] + +[[package]] +name = "indexmap" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282a6247722caba404c065016bbfa522806e51714c34f5dfc3e4a3a46fcb4223" dependencies = [ - "quick-error 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "autocfg", + "hashbrown", ] [[package]] name = "lazy_static" version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" version = "0.2.66" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d515b1f41455adea1313a4a2ac8a8a477634fbae63cc6100e3aebb207ce61558" [[package]] name = "log" version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7" dependencies = [ - "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if", ] [[package]] name = "memchr" -version = "2.3.0" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a" + +[[package]] +name = "os_str_bytes" +version = "6.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e22443d1643a904602595ba1cd8f7d896afe56d26712531c5ff73a15b2fbf64" +dependencies = [ + "memchr", +] [[package]] name = "ppv-lite86" version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74490b50b9fbe561ac330df47c08f3f33073d2d00c150f719147d7c54522fa1b" [[package]] name = "proc-macro-error" -version = "0.4.5" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" dependencies = [ - "proc-macro-error-attr 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro2 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "rustversion 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro-error-attr", + "proc-macro2", + "quote", + "syn", + "version_check", ] [[package]] name = "proc-macro-error-attr" -version = "0.4.5" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" dependencies = [ - "proc-macro2 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "rustversion 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)", - "syn-mid 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2", + "quote", + "version_check", ] [[package]] name = "proc-macro2" -version = "1.0.8" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7342d5883fbccae1cc37a2353b09c87c9b0f3afd73f5fb9bba687a1f733b029" dependencies = [ - "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-xid", ] [[package]] name = "quick-error" version = "1.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" [[package]] name = "quote" -version = "1.0.2" +version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "632d02bff7f874a36f33ea8bb416cd484b90cc66c1194b1a1110d067a7013f58" dependencies = [ - "proc-macro2 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2", ] [[package]] name = "rand" version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" dependencies = [ - "getrandom 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_chacha 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_hc 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "getrandom", + "libc", + "rand_chacha", + "rand_core", + "rand_hc", ] [[package]] name = "rand_chacha" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03a2a90da8c7523f554344f921aa97283eadf6ac484a6d2a7d0212fa7f8d6853" dependencies = [ - "c2-chacha 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "c2-chacha", + "rand_core", ] [[package]] name = "rand_core" version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" dependencies = [ - "getrandom 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)", + "getrandom", ] [[package]] name = "rand_hc" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" dependencies = [ - "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core", ] [[package]] name = "redox_syscall" version = "0.1.56" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84" [[package]] name = "regex" version = "1.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "322cf97724bea3ee221b78fe25ac9c46114ebb51747ad5babd51a2fc6a8235a8" dependencies = [ - "aho-corasick 0.7.8 (registry+https://github.com/rust-lang/crates.io-index)", - "memchr 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "regex-syntax 0.6.14 (registry+https://github.com/rust-lang/crates.io-index)", - "thread_local 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "aho-corasick", + "memchr", + "regex-syntax", + "thread_local", ] [[package]] name = "regex-syntax" version = "0.6.14" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b28dfe3fe9badec5dbf0a79a9cccad2cfc2ab5484bdb3e44cbd1ae8b3ba2be06" [[package]] name = "remove_dir_all" version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a83fa3702a688b9359eccba92d153ac33fd2e8462f9e0e3fdf155239ea7792e" dependencies = [ - "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "rustversion" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "proc-macro2 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi", ] [[package]] name = "strsim" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "structopt" -version = "0.3.8" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "structopt-derive 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "structopt-derive" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro-error 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro2 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)", -] +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" [[package]] name = "symcc_fuzzing_helper" version = "0.1.0" dependencies = [ - "anyhow 1.0.26 (registry+https://github.com/rust-lang/crates.io-index)", - "env_logger 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)", - "structopt 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", - "tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "anyhow", + "clap", + "env_logger", + "log", + "regex", + "tempfile", ] [[package]] name = "syn" -version = "1.0.14" +version = "1.0.89" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea297be220d52398dcc07ce15a209fce436d361735ac1db700cab3b6cdfb9f54" dependencies = [ - "proc-macro2 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "syn-mid" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "proc-macro2 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2", + "quote", + "unicode-xid", ] [[package]] name = "tempfile" version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a6e24d9338a0a5be79593e2fa15a648add6138caa803e2d5bc782c371732ca9" dependencies = [ - "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", - "redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)", - "remove_dir_all 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if", + "libc", + "rand", + "redox_syscall", + "remove_dir_all", + "winapi", ] [[package]] name = "termcolor" -version = "1.1.0" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755" dependencies = [ - "winapi-util 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-util", ] [[package]] name = "textwrap" -version = "0.11.0" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "unicode-width 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", -] +checksum = "b1141d4d61095b28419e22cb0bbf02755f5e54e0526f97f1e3d1d160e60885fb" [[package]] name = "thread_local" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d40c6d1b69745a6ec6fb1ca717914848da4b44ae29d9b3080cbee91d72a69b14" dependencies = [ - "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static", ] -[[package]] -name = "unicode-segmentation" -version = "1.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "unicode-width" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "unicode-xid" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c" [[package]] -name = "vec_map" -version = "0.8.1" +name = "version_check" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" [[package]] name = "wasi" version = "0.9.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" [[package]] name = "winapi" version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8093091eeb260906a183e6ae1abdba2ef5ef2257a21801128899c3fc699229c6" dependencies = [ - "winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", ] [[package]] name = "winapi-i686-pc-windows-gnu" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ccfbf554c6ad11084fb7517daca16cfdcaccbdadba4fc336f032a8b12c2ad80" dependencies = [ - "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi", ] [[package]] name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" - -[metadata] -"checksum aho-corasick 0.7.8 (registry+https://github.com/rust-lang/crates.io-index)" = "743ad5a418686aad3b87fd14c43badd828cf26e214a00f92a384291cf22e1811" -"checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" -"checksum anyhow 1.0.26 (registry+https://github.com/rust-lang/crates.io-index)" = "7825f6833612eb2414095684fcf6c635becf3ce97fe48cf6421321e93bfbd53c" -"checksum atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" -"checksum bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" -"checksum c2-chacha 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "214238caa1bf3a496ec3392968969cab8549f96ff30652c9e56885329315f6bb" -"checksum cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" -"checksum clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5067f5bb2d80ef5d68b4c87db81601f0b75bca627bc2ef76b141d7b846a3c6d9" -"checksum env_logger 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "44533bbbb3bb3c1fa17d9f2e4e38bbbaf8396ba82193c4cb1b6445d711445d36" -"checksum getrandom 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "7abc8dd8451921606d809ba32e95b6111925cd2906060d2dcc29c070220503eb" -"checksum heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "20564e78d53d2bb135c343b3f47714a56af2061f1c928fdb541dc7b9fdd94205" -"checksum hermit-abi 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "eff2656d88f158ce120947499e971d743c05dbcbed62e5bd2f38f1698bbc3772" -"checksum humantime 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "df004cfca50ef23c36850aaaa59ad52cc70d0e90243c3c7737a4dd32dc7a3c4f" -"checksum lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" -"checksum libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)" = "d515b1f41455adea1313a4a2ac8a8a477634fbae63cc6100e3aebb207ce61558" -"checksum log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7" -"checksum memchr 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3197e20c7edb283f87c071ddfc7a2cca8f8e0b888c242959846a6fce03c72223" -"checksum ppv-lite86 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "74490b50b9fbe561ac330df47c08f3f33073d2d00c150f719147d7c54522fa1b" -"checksum proc-macro-error 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "1b79a464461615532fcc8a6ed8296fa66cc12350c18460ab3f4594a6cee0fcb6" -"checksum proc-macro-error-attr 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "23832e5eae6bac56bbac190500eef1aaede63776b5cd131eaa4ee7fe120cd892" -"checksum proc-macro2 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)" = "3acb317c6ff86a4e579dfa00fc5e6cca91ecbb4e7eb2df0468805b674eb88548" -"checksum quick-error 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" -"checksum quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "053a8c8bcc71fcce321828dc897a98ab9760bef03a4fc36693c231e5b3216cfe" -"checksum rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" -"checksum rand_chacha 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "03a2a90da8c7523f554344f921aa97283eadf6ac484a6d2a7d0212fa7f8d6853" -"checksum rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" -"checksum rand_hc 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" -"checksum redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)" = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84" -"checksum regex 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "322cf97724bea3ee221b78fe25ac9c46114ebb51747ad5babd51a2fc6a8235a8" -"checksum regex-syntax 0.6.14 (registry+https://github.com/rust-lang/crates.io-index)" = "b28dfe3fe9badec5dbf0a79a9cccad2cfc2ab5484bdb3e44cbd1ae8b3ba2be06" -"checksum remove_dir_all 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4a83fa3702a688b9359eccba92d153ac33fd2e8462f9e0e3fdf155239ea7792e" -"checksum rustversion 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b3bba175698996010c4f6dce5e7f173b6eb781fce25d2cfc45e27091ce0b79f6" -"checksum strsim 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" -"checksum structopt 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "df136b42d76b1fbea72e2ab3057343977b04b4a2e00836c3c7c0673829572713" -"checksum structopt-derive 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fd50a87d2f7b8958055f3e73a963d78feaccca3836767a9069844e34b5b03c0a" -"checksum syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)" = "af6f3550d8dff9ef7dc34d384ac6f107e5d31c8f57d9f28e0081503f547ac8f5" -"checksum syn-mid 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9fd3937748a7eccff61ba5b90af1a20dbf610858923a9192ea0ecb0cb77db1d0" -"checksum tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e24d9338a0a5be79593e2fa15a648add6138caa803e2d5bc782c371732ca9" -"checksum termcolor 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bb6bfa289a4d7c5766392812c0a1f4c1ba45afa1ad47803c11e1f407d846d75f" -"checksum textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" -"checksum thread_local 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d40c6d1b69745a6ec6fb1ca717914848da4b44ae29d9b3080cbee91d72a69b14" -"checksum unicode-segmentation 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e83e153d1053cbb5a118eeff7fd5be06ed99153f00dbcd8ae310c5fb2b22edc0" -"checksum unicode-width 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "caaa9d531767d1ff2150b9332433f32a24622147e5ebb1f26409d5da67afd479" -"checksum unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c" -"checksum vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a" -"checksum wasi 0.9.0+wasi-snapshot-preview1 (registry+https://github.com/rust-lang/crates.io-index)" = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" -"checksum winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "8093091eeb260906a183e6ae1abdba2ef5ef2257a21801128899c3fc699229c6" -"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" -"checksum winapi-util 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4ccfbf554c6ad11084fb7517daca16cfdcaccbdadba4fc336f032a8b12c2ad80" -"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" diff --git a/util/symcc_fuzzing_helper/src/main.rs b/util/symcc_fuzzing_helper/src/main.rs index d2e11b6d..6b2105e3 100644 --- a/util/symcc_fuzzing_helper/src/main.rs +++ b/util/symcc_fuzzing_helper/src/main.rs @@ -32,7 +32,7 @@ const STATS_INTERVAL_SEC: u64 = 60; // inputs. #[derive(Debug, StructOpt)] -#[clap(about = "Make SymCC collaborate with AFL.", no_version)] +#[clap(about = "Make SymCC collaborate with AFL.")] struct Opt { /// The name of the fuzzer to work with #[clap(short = 'a')] From b103c54a3d0a944e0f7166a6208af1f3a1858738 Mon Sep 17 00:00:00 2001 From: julihoh Date: Sat, 19 Nov 2022 15:30:11 +0100 Subject: [PATCH 19/32] Merge upstream (#3) * This is a temporary fix due to std::iterator depercation. This commit needs to be reverted once a proper fix is in place. * symcc_fuzzing_helper: Move to clap3 (#94) * Revert "symcc_fuzzing_helper: Move to clap3 (#94)" (#101) This reverts commit 88b464c290786b58e5883f5aa1d08e2a3d5de0fb. * Add some FAQs to the Readme * changed from structopt to clap 3 (#103) * fix for issue #108 * fix for issue #108 * LLVM 12 works without changes * Add a clang-format configuration This is just the output of "clang-format -style=llvm -dump-config". * Add support for LLVM 13 Clang now uses the new pass manager for the optimization pipeline, so we have to do the same to make Clang use our pass. Moreover, FileCheck now complains if a configured prefix doesn't appear in the checked file; added "ANY" in three tests where it was missing. Finally, printing arbitrary-precision integers in QSYM needed some changes. * Add support for LLVM 14 * LLVM 15 works without changes * fix issue #109 * Run clang-format We should really automate this... * Add a GitHub action that checks LLVM compatibility * Prevent test failures in case of reordered solver output Z3 doesn't always output model constants in the same order; make sure that our tests don't depend on it. * Accept symbolic input from memory This commit adds the option to mark symbolic input by calling symcc_make_symbolic from the program under test. The refactoring that was required to add the new feature has had the pleasant side effect that the QSYM backend now doesn't require the entire input upfront anymore, making it much more convenient to feed symbolic data through stdin. * Run GitHub actions for pull requests only No need for "push": the "pull_request" event already triggers when new commits are pushed to the PR branch, and we expect all changes to go through a PR. Co-authored-by: Aurelien Francillon Co-authored-by: Dominik Maier Co-authored-by: aurelf Co-authored-by: Dominik Maier Co-authored-by: Emilio Coppa Co-authored-by: Sebastian Poeplau --- .clang-format | 192 ++++++++++++++++++++++++++ .github/workflows/run_tests.yml | 28 +++- CMakeLists.txt | 12 +- README.md | 61 +++++++- compiler/Main.cpp | 64 +++++++-- compiler/Pass.cpp | 36 ++++- compiler/Pass.h | 24 +++- compiler/Runtime.cpp | 2 +- compiler/Runtime.h | 2 +- compiler/Symbolizer.cpp | 51 ++++--- compiler/sym++.in | 2 +- compiler/symcc.in | 2 +- docs/Configuration.txt | 7 +- runtime/Config.cpp | 23 ++- runtime/Config.h | 25 +++- runtime/LibcWrappers.cpp | 83 +++++------ runtime/RuntimeCommon.cpp | 23 +++ runtime/RuntimeCommon.h | 15 +- runtime/qsym_backend/Runtime.cpp | 81 +++++------ runtime/qsym_backend/qsym | 2 +- runtime/simple_backend/CMakeLists.txt | 2 +- runtime/simple_backend/Runtime.cpp | 8 +- test/bool_cast.c | 42 ++++++ test/if.c | 1 + test/loop.c | 1 + test/memory_input.c | 51 +++++++ test/propagation_select.c | 47 +++++++ util/symcc_fuzzing_helper/Cargo.lock | 56 ++++---- util/symcc_fuzzing_helper/Cargo.toml | 2 +- util/symcc_fuzzing_helper/src/main.rs | 6 +- 30 files changed, 762 insertions(+), 189 deletions(-) create mode 100644 .clang-format create mode 100644 test/bool_cast.c create mode 100644 test/memory_input.c create mode 100644 test/propagation_select.c diff --git a/.clang-format b/.clang-format new file mode 100644 index 00000000..48b2c678 --- /dev/null +++ b/.clang-format @@ -0,0 +1,192 @@ +--- +Language: Cpp +# BasedOnStyle: LLVM +AccessModifierOffset: -2 +AlignAfterOpenBracket: Align +AlignArrayOfStructures: None +AlignConsecutiveMacros: None +AlignConsecutiveAssignments: None +AlignConsecutiveBitFields: None +AlignConsecutiveDeclarations: None +AlignEscapedNewlines: Right +AlignOperands: Align +AlignTrailingComments: true +AllowAllArgumentsOnNextLine: true +AllowAllParametersOfDeclarationOnNextLine: true +AllowShortEnumsOnASingleLine: true +AllowShortBlocksOnASingleLine: Never +AllowShortCaseLabelsOnASingleLine: false +AllowShortFunctionsOnASingleLine: All +AllowShortLambdasOnASingleLine: All +AllowShortIfStatementsOnASingleLine: Never +AllowShortLoopsOnASingleLine: false +AlwaysBreakAfterDefinitionReturnType: None +AlwaysBreakAfterReturnType: None +AlwaysBreakBeforeMultilineStrings: false +AlwaysBreakTemplateDeclarations: MultiLine +AttributeMacros: + - __capability +BinPackArguments: true +BinPackParameters: true +BraceWrapping: + AfterCaseLabel: false + AfterClass: false + AfterControlStatement: Never + AfterEnum: false + AfterFunction: false + AfterNamespace: false + AfterObjCDeclaration: false + AfterStruct: false + AfterUnion: false + AfterExternBlock: false + BeforeCatch: false + BeforeElse: false + BeforeLambdaBody: false + BeforeWhile: false + IndentBraces: false + SplitEmptyFunction: true + SplitEmptyRecord: true + SplitEmptyNamespace: true +BreakBeforeBinaryOperators: None +BreakBeforeConceptDeclarations: true +BreakBeforeBraces: Attach +BreakBeforeInheritanceComma: false +BreakInheritanceList: BeforeColon +BreakBeforeTernaryOperators: true +BreakConstructorInitializersBeforeComma: false +BreakConstructorInitializers: BeforeColon +BreakAfterJavaFieldAnnotations: false +BreakStringLiterals: true +ColumnLimit: 80 +CommentPragmas: '^ IWYU pragma:' +QualifierAlignment: Leave +CompactNamespaces: false +ConstructorInitializerIndentWidth: 4 +ContinuationIndentWidth: 4 +Cpp11BracedListStyle: true +DeriveLineEnding: true +DerivePointerAlignment: false +DisableFormat: false +EmptyLineAfterAccessModifier: Never +EmptyLineBeforeAccessModifier: LogicalBlock +ExperimentalAutoDetectBinPacking: false +PackConstructorInitializers: BinPack +BasedOnStyle: '' +ConstructorInitializerAllOnOneLineOrOnePerLine: false +AllowAllConstructorInitializersOnNextLine: true +FixNamespaceComments: true +ForEachMacros: + - foreach + - Q_FOREACH + - BOOST_FOREACH +IfMacros: + - KJ_IF_MAYBE +IncludeBlocks: Preserve +IncludeCategories: + - Regex: '^"(llvm|llvm-c|clang|clang-c)/' + Priority: 2 + SortPriority: 0 + CaseSensitive: false + - Regex: '^(<|"(gtest|gmock|isl|json)/)' + Priority: 3 + SortPriority: 0 + CaseSensitive: false + - Regex: '.*' + Priority: 1 + SortPriority: 0 + CaseSensitive: false +IncludeIsMainRegex: '(Test)?$' +IncludeIsMainSourceRegex: '' +IndentAccessModifiers: false +IndentCaseLabels: false +IndentCaseBlocks: false +IndentGotoLabels: true +IndentPPDirectives: None +IndentExternBlock: AfterExternBlock +IndentRequires: false +IndentWidth: 2 +IndentWrappedFunctionNames: false +InsertTrailingCommas: None +JavaScriptQuotes: Leave +JavaScriptWrapImports: true +KeepEmptyLinesAtTheStartOfBlocks: true +LambdaBodyIndentation: Signature +MacroBlockBegin: '' +MacroBlockEnd: '' +MaxEmptyLinesToKeep: 1 +NamespaceIndentation: None +ObjCBinPackProtocolList: Auto +ObjCBlockIndentWidth: 2 +ObjCBreakBeforeNestedBlockParam: true +ObjCSpaceAfterProperty: false +ObjCSpaceBeforeProtocolList: true +PenaltyBreakAssignment: 2 +PenaltyBreakBeforeFirstCallParameter: 19 +PenaltyBreakComment: 300 +PenaltyBreakFirstLessLess: 120 +PenaltyBreakOpenParenthesis: 0 +PenaltyBreakString: 1000 +PenaltyBreakTemplateDeclaration: 10 +PenaltyExcessCharacter: 1000000 +PenaltyReturnTypeOnItsOwnLine: 60 +PenaltyIndentedWhitespace: 0 +PointerAlignment: Right +PPIndentWidth: -1 +ReferenceAlignment: Pointer +ReflowComments: true +RemoveBracesLLVM: false +SeparateDefinitionBlocks: Leave +ShortNamespaceLines: 1 +SortIncludes: CaseSensitive +SortJavaStaticImport: Before +SortUsingDeclarations: true +SpaceAfterCStyleCast: false +SpaceAfterLogicalNot: false +SpaceAfterTemplateKeyword: true +SpaceBeforeAssignmentOperators: true +SpaceBeforeCaseColon: false +SpaceBeforeCpp11BracedList: false +SpaceBeforeCtorInitializerColon: true +SpaceBeforeInheritanceColon: true +SpaceBeforeParens: ControlStatements +SpaceBeforeParensOptions: + AfterControlStatements: true + AfterForeachMacros: true + AfterFunctionDefinitionName: false + AfterFunctionDeclarationName: false + AfterIfMacros: true + AfterOverloadedOperator: false + BeforeNonEmptyParentheses: false +SpaceAroundPointerQualifiers: Default +SpaceBeforeRangeBasedForLoopColon: true +SpaceInEmptyBlock: false +SpaceInEmptyParentheses: false +SpacesBeforeTrailingComments: 1 +SpacesInAngles: Never +SpacesInConditionalStatement: false +SpacesInContainerLiterals: true +SpacesInCStyleCastParentheses: false +SpacesInLineCommentPrefix: + Minimum: 1 + Maximum: -1 +SpacesInParentheses: false +SpacesInSquareBrackets: false +SpaceBeforeSquareBrackets: false +BitFieldColonSpacing: Both +Standard: Latest +StatementAttributeLikeMacros: + - Q_EMIT +StatementMacros: + - Q_UNUSED + - QT_REQUIRE_VERSION +TabWidth: 8 +UseCRLF: false +UseTab: Never +WhitespaceSensitiveMacros: + - STRINGIZE + - PP_STRINGIZE + - BOOST_PP_STRINGIZE + - NS_SWIFT_NAME + - CF_SWIFT_NAME +... + diff --git a/.github/workflows/run_tests.yml b/.github/workflows/run_tests.yml index fe2c0f82..eb5ae3ca 100644 --- a/.github/workflows/run_tests.yml +++ b/.github/workflows/run_tests.yml @@ -1,5 +1,5 @@ name: Compile and test SymCC -on: [push, pull_request] +on: [pull_request] jobs: build_and_test_symcc: runs-on: ubuntu-20.04 @@ -15,3 +15,29 @@ jobs: run: docker build --target builder_qsym -t symcc . - name: Creation of the final SymCC docker image with Qsym backend and libcxx run: docker build -t symcc . + llvm_compatibility: + runs-on: ubuntu-22.04 + strategy: + matrix: + llvm_version: [11, 12, 13, 14] + steps: + - uses: actions/checkout@v3 + with: + submodules: true + - name: Install dependencies + run: | + sudo apt-get install -y \ + llvm-${{ matrix.llvm_version }}-dev \ + libz3-dev \ + python2 + - name: Build SymCC with the QSYM backend + run: | + mkdir build + cd build + cmake \ + -DCMAKE_BUILD_TYPE=Release \ + -DZ3_TRUST_SYSTEM_VERSION=ON \ + -DQSYM_BACKEND=ON \ + -DLLVM_DIR=/usr/lib/llvm-${{ matrix.llvm_version }}/cmake \ + .. + make diff --git a/CMakeLists.txt b/CMakeLists.txt index 07335ea3..d0601bf1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -79,8 +79,8 @@ find_package(LLVM REQUIRED CONFIG) message(STATUS "Found LLVM ${LLVM_PACKAGE_VERSION}") message(STATUS "Using LLVMConfig.cmake from ${LLVM_DIR}") -if (${LLVM_VERSION_MAJOR} LESS 8 OR ${LLVM_VERSION_MAJOR} GREATER 11) - message(WARNING "The software has been developed for LLVM 8 through 11; \ +if (${LLVM_VERSION_MAJOR} LESS 8 OR ${LLVM_VERSION_MAJOR} GREATER 15) + message(WARNING "The software has been developed for LLVM 8 through 15; \ it is unlikely to work with other versions!") endif() @@ -90,7 +90,7 @@ include_directories(SYSTEM ${LLVM_INCLUDE_DIRS}) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17 \ -Wredundant-decls -Wcast-align -Wmissing-include-dirs -Wswitch-default \ -Wextra -Wall -Winvalid-pch -Wredundant-decls -Wformat=2 \ --Wmissing-format-attribute -Wformat-nonliteral -Werror") +-Wmissing-format-attribute -Wformat-nonliteral -Werror -Wno-error=deprecated-declarations") # Mark nodelete to work around unload bug in upstream LLVM 5.0+ set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} -Wl,-z,nodelete") @@ -117,6 +117,12 @@ if (NOT CLANG_BINARY) message(FATAL_ERROR "Clang not found; please make sure that the version corresponding to your LLVM installation is available.") endif() +if (${LLVM_VERSION_MAJOR} LESS 13) + set(CLANG_LOAD_PASS "-Xclang -load -Xclang ") +else() + set(CLANG_LOAD_PASS "-fpass-plugin=") +endif() + configure_file("compiler/symcc.in" "symcc" @ONLY) configure_file("compiler/sym++.in" "sym++" @ONLY) diff --git a/README.md b/README.md index 4d59677f..0bb20644 100644 --- a/README.md +++ b/README.md @@ -15,16 +15,18 @@ compiler inserts code that computes symbolic expressions for each value in the program. The actual computation happens through calls to the support library at run time. -To build the pass and the support library, make sure that LLVM 8, 9, 10 or 11 -and Z3 version 4.5 or later, as well as a C++ compiler with support for C++17 -are installed. "lit" is also needed which is not always packaged with LLVM. +To build the pass and the support library, install LLVM (any version between 8 +and 15) and Z3 (version 4.5 or later), as well as a C++ compiler with support +for C++17. LLVM lit is only needed to run the tests; if it's not packaged with +your LLVM, you can get it with `pip install lit`. -Under Ubuntu groovy the following one liner should install all required +Under Ubuntu Groovy the following one liner should install all required packages: ``` sudo apt install -y git cargo clang-10 cmake g++ git libz3-dev llvm-10-dev llvm-10-tools ninja-build python2 python3-pip zlib1g-dev && sudo pip3 install lit ``` + Alternatively, see below for using the provided Dockerfile, or the file `util/quicktest.sh` for exact steps to perform under Ubuntu (or use with the provided Vagrant file). @@ -180,6 +182,57 @@ every change to SymCC (which is, in principle the right thing to do), whereas in many cases it is sufficient to let the build system figure out what to rebuild (and recompile, e.g., libc++ only when necessary). +## FAQ / BUGS / TODOs + +### Why is SymCC only exploring one path and not all paths? + +SymCC is currently a concolic executor it follows the concrete +path. In theory, it would be possible to make it a forking executor +see [issue #14](https://github.com/eurecom-s3/symcc/issues/14) + +### Why does SymCC not generate some test cases? + +There are multiple possible reasons: + +#### QSym backend performs pruning + +When built with the QSym backend exploration (e.g., loops) symcc is +subject to path pruning, this is part of the optimizations that makes +SymCC/QSym fast, it isn't sound. This is not a problem for using in +hybrid fuzzing, but this may be a problem for other uses. See for +example [issue #88](https://github.com/eurecom-s3/symcc/issues/88). + +When building with the simple backend the paths should be found. If +the paths are not found with the simple backend this may be a bug (or +possibly a limitation of the simple backend). + +#### Incomplete symbolic handing of functions, systems interactions. + +The current symbolic understanding of libc is incomplete. So when an +unsupported libc function is called SymCC can't trace the computations +that happen in the function. + +1. Adding the function to the [collection of wrapped libc + functions](https://github.com/eurecom-s3/symcc/blob/master/runtime/LibcWrappers.cpp) + and [register the + wrapper](https://github.com/eurecom-s3/symcc/blob/b29dc4db2803830ebf50798e72b336473a567655/compiler/Runtime.cpp#L159) + in the compiler. +2. Build a fully instrumented libc. +3. Cherry-pick individual libc functions from a libc implementation (e.g., musl) + +See [issue #23](https://github.com/eurecom-s3/symcc/issues/23) for more details. + + +### Rust support ? + +This would be possible to support RUST, see [issue +#1](https://github.com/eurecom-s3/symcc/issues/1) for tracking this. + +### Bug reporting + +We appreciate bugs with test cases and steps to reproduce, PR with +corresponding test cases. SymCC is currently understaffed, we hope to +catch up and get back to active development at some point. ## Contact diff --git a/compiler/Main.cpp b/compiler/Main.cpp index 9be71ff6..f915d5d4 100644 --- a/compiler/Main.cpp +++ b/compiler/Main.cpp @@ -15,17 +15,65 @@ #include #include +#if LLVM_VERSION_MAJOR >= 13 +#include +#include + +#if LLVM_VERSION_MAJOR >= 14 +#include +#else +using OptimizationLevel = llvm::PassBuilder::OptimizationLevel; +#endif +#endif + #include "Pass.h" -void addSymbolizePass(const llvm::PassManagerBuilder & /* unused */, - llvm::legacy::PassManagerBase &PM) { - PM.add(new SymbolizePass()); +using namespace llvm; + +// +// Legacy pass registration (up to LLVM 13) +// + +void addSymbolizeLegacyPass(const PassManagerBuilder & /* unused */, + legacy::PassManagerBase &PM) { + PM.add(new SymbolizeLegacyPass()); } // Make the pass known to opt. -static llvm::RegisterPass X("symbolize", "Symbolization Pass"); +static RegisterPass X("symbolize", "Symbolization Pass"); // Tell frontends to run the pass automatically. -static struct llvm::RegisterStandardPasses - Y(llvm::PassManagerBuilder::EP_VectorizerStart, addSymbolizePass); -static struct llvm::RegisterStandardPasses - Z(llvm::PassManagerBuilder::EP_EnabledOnOptLevel0, addSymbolizePass); +static struct RegisterStandardPasses Y(PassManagerBuilder::EP_VectorizerStart, + addSymbolizeLegacyPass); +static struct RegisterStandardPasses + Z(PassManagerBuilder::EP_EnabledOnOptLevel0, addSymbolizeLegacyPass); + +// +// New pass registration (LLVM 13 and above) +// + +#if LLVM_VERSION_MAJOR >= 13 + +PassPluginLibraryInfo getSymbolizePluginInfo() { + return {LLVM_PLUGIN_API_VERSION, "Symbolization Pass", LLVM_VERSION_STRING, + [](PassBuilder &PB) { + // We need to act on the entire module as well as on each function. + // Those actions are independent from each other, so we register a + // module pass at the start of the pipeline and a function pass just + // before the vectorizer. (There doesn't seem to be a way to run + // module passes at the start of the vectorizer, hence the split.) + PB.registerPipelineStartEPCallback( + [](ModulePassManager &PM, OptimizationLevel) { + PM.addPass(SymbolizePass()); + }); + PB.registerVectorizerStartEPCallback( + [](FunctionPassManager &PM, OptimizationLevel) { + PM.addPass(SymbolizePass()); + }); + }}; +} + +extern "C" LLVM_ATTRIBUTE_WEAK PassPluginLibraryInfo llvmGetPassPluginInfo() { + return getSymbolizePluginInfo(); +} + +#endif diff --git a/compiler/Pass.cpp b/compiler/Pass.cpp index 122fd571..f17fd7e5 100644 --- a/compiler/Pass.cpp +++ b/compiler/Pass.cpp @@ -34,10 +34,14 @@ using namespace llvm; #define DEBUG(X) ((void)0) #endif -char SymbolizePass::ID = 0; +char SymbolizeLegacyPass::ID = 0; -bool SymbolizePass::doInitialization(Module &M) { - DEBUG(errs() << "Symbolizer module init\n"); +namespace { + +static constexpr char kSymCtorName[] = "__sym_ctor"; + +bool instrumentModule(Module &M) { + DEBUG(errs() << "Symbolizer module instrumentation\n"); // Redirect calls to external functions to the corresponding wrappers and // rename internal functions. @@ -56,7 +60,7 @@ bool SymbolizePass::doInitialization(Module &M) { return true; } -bool SymbolizePass::runOnFunction(Function &F) { +bool instrumentFunction(Function &F) { auto functionName = F.getName(); if (functionName == kSymCtorName) return false; @@ -87,3 +91,27 @@ bool SymbolizePass::runOnFunction(Function &F) { return true; } + +} // namespace + +bool SymbolizeLegacyPass::doInitialization(Module &M) { + return instrumentModule(M); +} + +bool SymbolizeLegacyPass::runOnFunction(Function &F) { + return instrumentFunction(F); +} + +#if LLVM_VERSION_MAJOR >= 13 + +PreservedAnalyses SymbolizePass::run(Function &F, FunctionAnalysisManager &) { + return instrumentFunction(F) ? PreservedAnalyses::none() + : PreservedAnalyses::all(); +} + +PreservedAnalyses SymbolizePass::run(Module &M, ModuleAnalysisManager &) { + return instrumentModule(M) ? PreservedAnalyses::none() + : PreservedAnalyses::all(); +} + +#endif diff --git a/compiler/Pass.h b/compiler/Pass.h index 53764931..cf0676aa 100644 --- a/compiler/Pass.h +++ b/compiler/Pass.h @@ -19,21 +19,31 @@ #include #include -class SymbolizePass : public llvm::FunctionPass { +#if LLVM_VERSION_MAJOR >= 13 +#include +#endif + +class SymbolizeLegacyPass : public llvm::FunctionPass { public: static char ID; - SymbolizePass() : FunctionPass(ID) {} + SymbolizeLegacyPass() : FunctionPass(ID) {} bool doInitialization(llvm::Module &M) override; bool runOnFunction(llvm::Function &F) override; +}; -private: - static constexpr char kSymCtorName[] = "__sym_ctor"; +#if LLVM_VERSION_MAJOR >= 13 - /// Mapping from global variables to their corresponding symbolic expressions. - llvm::ValueMap - globalExpressions; +class SymbolizePass : public llvm::PassInfoMixin { +public: + llvm::PreservedAnalyses run(llvm::Function &F, + llvm::FunctionAnalysisManager &); + llvm::PreservedAnalyses run(llvm::Module &M, llvm::ModuleAnalysisManager &); + + static bool isRequired() { return true; } }; #endif + +#endif diff --git a/compiler/Runtime.cpp b/compiler/Runtime.cpp index 81768841..ba0f3d83 100644 --- a/compiler/Runtime.cpp +++ b/compiler/Runtime.cpp @@ -69,7 +69,7 @@ Runtime::Runtime(Module &M) { buildBoolAnd = import(M, "_sym_build_bool_and", ptrT, ptrT, ptrT); buildBoolOr = import(M, "_sym_build_bool_or", ptrT, ptrT, ptrT); buildBoolXor = import(M, "_sym_build_bool_xor", ptrT, ptrT, ptrT); - buildBoolToBits = import(M, "_sym_build_bool_to_bits", ptrT, ptrT, int8T); + buildBoolToBit = import(M, "_sym_build_bool_to_bit", ptrT, ptrT); pushPathConstraint = import(M, "_sym_push_path_constraint", voidT, ptrT, IRB.getInt1Ty(), intPtrType); diff --git a/compiler/Runtime.h b/compiler/Runtime.h index 7bf4a769..519f9f00 100644 --- a/compiler/Runtime.h +++ b/compiler/Runtime.h @@ -49,7 +49,7 @@ struct Runtime { SymFnT buildBoolAnd{}; SymFnT buildBoolOr{}; SymFnT buildBoolXor{}; - SymFnT buildBoolToBits{}; + SymFnT buildBoolToBit{}; SymFnT pushPathConstraint{}; SymFnT getParameterExpression{}; SymFnT setParameterExpression{}; diff --git a/compiler/Symbolizer.cpp b/compiler/Symbolizer.cpp index a6206823..05f5a6b5 100644 --- a/compiler/Symbolizer.cpp +++ b/compiler/Symbolizer.cpp @@ -380,6 +380,13 @@ void Symbolizer::visitSelectInst(SelectInst &I) { {I.getCondition(), false}, {getTargetPreferredInt(&I), false}}); registerSymbolicComputation(runtimeCall); + if (getSymbolicExpression(I.getTrueValue()) || + getSymbolicExpression(I.getFalseValue())) { + auto *data = IRB.CreateSelect( + I.getCondition(), getSymbolicExpressionOrNull(I.getTrueValue()), + getSymbolicExpressionOrNull(I.getFalseValue())); + symbolicExpressions[&I] = data; + } } void Symbolizer::visitCmpInst(CmpInst &I) { @@ -696,30 +703,36 @@ void Symbolizer::visitCastInst(CastInst &I) { IRBuilder<> IRB(&I); + SymFnT target; + + switch (I.getOpcode()) { + case Instruction::SExt: + target = runtime.buildSExt; + break; + case Instruction::ZExt: + target = runtime.buildZExt; + break; + default: + llvm_unreachable("Unknown cast opcode"); + } + // LLVM bitcode represents Boolean values as i1. In Z3, those are a not a // bit-vector sort, so trying to cast one into a bit vector of any length // raises an error. The run-time library provides a dedicated conversion // function for this case. if (I.getSrcTy()->getIntegerBitWidth() == 1) { - auto boolToBitConversion = buildRuntimeCall( - IRB, runtime.buildBoolToBits, - {{I.getOperand(0), true}, - {IRB.getInt8(I.getDestTy()->getIntegerBitWidth()), false}}); - registerSymbolicComputation(boolToBitConversion, &I); - } else { - SymFnT target; - switch (I.getOpcode()) { - case Instruction::SExt: - target = runtime.buildSExt; - break; - case Instruction::ZExt: - target = runtime.buildZExt; - break; - default: - llvm_unreachable("Unknown cast opcode"); - } + SymbolicComputation symbolicComputation; + symbolicComputation.merge(forceBuildRuntimeCall(IRB, runtime.buildBoolToBit, + {{I.getOperand(0), true}})); + symbolicComputation.merge(forceBuildRuntimeCall( + IRB, target, + {{symbolicComputation.lastInstruction, false}, + {IRB.getInt8(I.getDestTy()->getIntegerBitWidth() - 1), false}})); + registerSymbolicComputation(symbolicComputation, &I); + + } else { auto symbolicCast = buildRuntimeCall(IRB, target, {{I.getOperand(0), true}, @@ -758,7 +771,9 @@ void Symbolizer::visitInsertValueInst(InsertValueInst &I) { {IRB.getInt64(aggregateMemberOffset(I.getAggregateOperand()->getType(), I.getIndices())), false}, - {IRB.getInt8(isLittleEndian(I.getInsertedValueOperand()->getType()) ? 1 : 0), false}}); + {IRB.getInt8(isLittleEndian(I.getInsertedValueOperand()->getType()) ? 1 + : 0), + false}}); registerSymbolicComputation(insert, &I); } diff --git a/compiler/sym++.in b/compiler/sym++.in index 82221945..2b775739 100755 --- a/compiler/sym++.in +++ b/compiler/sym++.in @@ -55,7 +55,7 @@ if [ $# -eq 0 ]; then fi exec $compiler \ - -Xclang -load -Xclang "$pass" \ + @CLANG_LOAD_PASS@"$pass" \ $stdlib_cflags \ "$@" \ $stdlib_ldflags \ diff --git a/compiler/symcc.in b/compiler/symcc.in index a0694c06..4e0ad37e 100755 --- a/compiler/symcc.in +++ b/compiler/symcc.in @@ -39,7 +39,7 @@ if [ $# -eq 0 ]; then fi exec $compiler \ - -Xclang -load -Xclang "$pass" \ + @CLANG_LOAD_PASS@"$pass" \ "$@" \ -L"$runtime_dir" \ -lSymRuntime \ diff --git a/docs/Configuration.txt b/docs/Configuration.txt index 123aec34..4e743aa8 100644 --- a/docs/Configuration.txt +++ b/docs/Configuration.txt @@ -60,7 +60,12 @@ environment variables. - SYMCC_INPUT_FILE (default empty): When empty, SymCC treats data read from standard input as symbolic; when set to a file name, any data read from that - file is considered symbolic. + file is considered symbolic. Ignored if SYMCC_NO_SYMBOLIC_INPUT is set to 1. + +- SYMCC_MEMORY_INPUT=0/1 (default 0): When set to 1, expect the program under + test to communicate symbolic inputs with one or more calls to + symcc_make_symbolic. Can't be combined with SYMCC_INPUT_FILE. Ignored if + SYMCC_NO_SYMBOLIC_INPUT is set to 1. - SYMCC_LOG_FILE (default empty): When set to a file name, SymCC creates the file (or overwrites any existing file!) and uses it to log backend activity diff --git a/runtime/Config.cpp b/runtime/Config.cpp index c7d45ee0..0088a4d1 100644 --- a/runtime/Config.cpp +++ b/runtime/Config.cpp @@ -19,6 +19,7 @@ #include #include #include +#include namespace { @@ -41,17 +42,26 @@ bool checkFlagString(std::string value) { Config g_config; void loadConfig() { - auto *fullyConcrete = getenv("SYMCC_NO_SYMBOLIC_INPUT"); - if (fullyConcrete != nullptr) - g_config.fullyConcrete = checkFlagString(fullyConcrete); - auto *outputDir = getenv("SYMCC_OUTPUT_DIR"); if (outputDir != nullptr) g_config.outputDir = outputDir; auto *inputFile = getenv("SYMCC_INPUT_FILE"); if (inputFile != nullptr) - g_config.inputFile = inputFile; + g_config.input = FileInput{inputFile}; + + auto *memoryInput = getenv("SYMCC_MEMORY_INPUT"); + if (memoryInput != nullptr && checkFlagString(memoryInput)) { + if (std::holds_alternative(g_config.input)) + throw std::runtime_error{ + "Can't enable file and memory input at the same time"}; + + g_config.input = MemoryInput{}; + } + + auto *fullyConcrete = getenv("SYMCC_NO_SYMBOLIC_INPUT"); + if (fullyConcrete != nullptr && checkFlagString(fullyConcrete)) + g_config.input = NoInput{}; auto *logFile = getenv("SYMCC_LOG_FILE"); if (logFile != nullptr) @@ -76,7 +86,8 @@ void loadConfig() { throw std::runtime_error(msg.str()); } catch (std::out_of_range &) { std::stringstream msg; - msg << "The GC threshold must be between 0 and " << std::numeric_limits::max(); + msg << "The GC threshold must be between 0 and " + << std::numeric_limits::max(); throw std::runtime_error(msg.str()); } } diff --git a/runtime/Config.h b/runtime/Config.h index 450344eb..4ed8f806 100644 --- a/runtime/Config.h +++ b/runtime/Config.h @@ -16,17 +16,32 @@ #define CONFIG_H #include +#include + +/// Marker struct for fully concrete execution. +struct NoInput {}; + +/// Marker struct for symbolic input from stdin. +struct StdinInput {}; + +/// Marker struct for symbolic input via _sym_make_symbolic. +struct MemoryInput {}; + +/// Configuration for symbolic input from a file. +struct FileInput { + /// The name of input file. + std::string fileName; +}; struct Config { - /// Should we allow symbolic data in the program? - bool fullyConcrete = false; + using InputConfig = std::variant; + + /// The configuration for our symbolic input. + InputConfig input = StdinInput{}; /// The directory for storing new outputs. std::string outputDir = "/tmp/output"; - /// The input file, if any. - std::string inputFile; - /// The file to log constraint solving information to. std::string logFile = ""; diff --git a/runtime/LibcWrappers.cpp b/runtime/LibcWrappers.cpp index 319ae9f5..6e9c6c90 100644 --- a/runtime/LibcWrappers.cpp +++ b/runtime/LibcWrappers.cpp @@ -18,6 +18,7 @@ #include #include #include +#include #include #include @@ -56,13 +57,28 @@ template void tryAlternative(E *value, SymExpr valueExpr, F caller) { tryAlternative(reinterpret_cast(value), valueExpr, caller); } -} // namespace -void initLibcWrappers() { - if (g_config.fullyConcrete) +void maybeSetInputFile(const char *path, int fd) { + auto *fileInput = std::get_if(&g_config.input); + if (fileInput == nullptr) return; - if (g_config.inputFile.empty()) { + if (strstr(path, fileInput->fileName.c_str()) == nullptr) + return; + + if (inputFileDescriptor != -1) + std::cerr << "Warning: input file opened multiple times; this is not yet " + "supported" + << std::endl; + + inputFileDescriptor = fd; + inputOffset = 0; +} + +} // namespace + +void initLibcWrappers() { + if (std::holds_alternative(g_config.input)) { // Symbolic data comes from standard input. inputFileDescriptor = 0; } @@ -111,15 +127,8 @@ int SYM(open)(const char *path, int oflag, mode_t mode) { auto result = open(path, oflag, mode); _sym_set_return_expression(nullptr); - if (result >= 0 && !g_config.fullyConcrete && !g_config.inputFile.empty() && - strstr(path, g_config.inputFile.c_str()) != nullptr) { - if (inputFileDescriptor != -1) - std::cerr << "Warning: input file opened multiple times; this is not yet " - "supported" - << std::endl; - inputFileDescriptor = result; - inputOffset = 0; - } + if (result >= 0) + maybeSetInputFile(path, result); return result; } @@ -136,9 +145,8 @@ ssize_t SYM(read)(int fildes, void *buf, size_t nbyte) { if (fildes == inputFileDescriptor) { // Reading symbolic input. - ReadWriteShadow shadow(buf, result); - std::generate(shadow.begin(), shadow.end(), - []() { return _sym_get_input_byte(inputOffset++); }); + _sym_make_symbolic(buf, result, inputOffset); + inputOffset += result; } else if (!isConcrete(buf, result)) { ReadWriteShadow shadow(buf, result); std::fill(shadow.begin(), shadow.end(), nullptr); @@ -193,16 +201,8 @@ FILE *SYM(fopen)(const char *pathname, const char *mode) { auto *result = fopen(pathname, mode); _sym_set_return_expression(nullptr); - if (result != nullptr && !g_config.fullyConcrete && - !g_config.inputFile.empty() && - strstr(pathname, g_config.inputFile.c_str()) != nullptr) { - if (inputFileDescriptor != -1) - std::cerr << "Warning: input file opened multiple times; this is not yet " - "supported" - << std::endl; - inputFileDescriptor = fileno(result); - inputOffset = 0; - } + if (result != nullptr) + maybeSetInputFile(pathname, fileno(result)); return result; } @@ -211,16 +211,8 @@ FILE *SYM(fopen64)(const char *pathname, const char *mode) { auto *result = fopen64(pathname, mode); _sym_set_return_expression(nullptr); - if (result != nullptr && !g_config.fullyConcrete && - !g_config.inputFile.empty() && - strstr(pathname, g_config.inputFile.c_str()) != nullptr) { - if (inputFileDescriptor != -1) - std::cerr << "Warning: input file opened multiple times; this is not yet " - "supported" - << std::endl; - inputFileDescriptor = fileno(result); - inputOffset = 0; - } + if (result != nullptr) + maybeSetInputFile(pathname, fileno(result)); return result; } @@ -235,9 +227,8 @@ size_t SYM(fread)(void *ptr, size_t size, size_t nmemb, FILE *stream) { if (fileno(stream) == inputFileDescriptor) { // Reading symbolic input. - ReadWriteShadow shadow(ptr, result * size); - std::generate(shadow.begin(), shadow.end(), - []() { return _sym_get_input_byte(inputOffset++); }); + _sym_make_symbolic(ptr, result * size, inputOffset); + inputOffset += result * size; } else if (!isConcrete(ptr, result * size)) { ReadWriteShadow shadow(ptr, result * size); std::fill(shadow.begin(), shadow.end(), nullptr); @@ -255,9 +246,9 @@ char *SYM(fgets)(char *str, int n, FILE *stream) { if (fileno(stream) == inputFileDescriptor) { // Reading symbolic input. - ReadWriteShadow shadow(str, sizeof(char) * strlen(str)); - std::generate(shadow.begin(), shadow.end(), - []() { return _sym_get_input_byte(inputOffset++); }); + const auto length = sizeof(char) * strlen(str); + _sym_make_symbolic(str, length, inputOffset); + inputOffset += length; } else if (!isConcrete(str, sizeof(char) * strlen(str))) { ReadWriteShadow shadow(str, sizeof(char) * strlen(str)); std::fill(shadow.begin(), shadow.end(), nullptr); @@ -338,7 +329,7 @@ int SYM(getc)(FILE *stream) { if (fileno(stream) == inputFileDescriptor) _sym_set_return_expression(_sym_build_zext( - _sym_get_input_byte(inputOffset++), sizeof(int) * 8 - 8)); + _sym_get_input_byte(inputOffset++, result), sizeof(int) * 8 - 8)); else _sym_set_return_expression(nullptr); @@ -354,16 +345,14 @@ int SYM(fgetc)(FILE *stream) { if (fileno(stream) == inputFileDescriptor) _sym_set_return_expression(_sym_build_zext( - _sym_get_input_byte(inputOffset++), sizeof(int) * 8 - 8)); + _sym_get_input_byte(inputOffset++, result), sizeof(int) * 8 - 8)); else _sym_set_return_expression(nullptr); return result; } -int SYM(getchar)(void) { - return SYM(getc)(stdin); -} +int SYM(getchar)(void) { return SYM(getc)(stdin); } int SYM(ungetc)(int c, FILE *stream) { auto result = ungetc(c, stream); diff --git a/runtime/RuntimeCommon.cpp b/runtime/RuntimeCommon.cpp index 32081e3e..eddd93d0 100644 --- a/runtime/RuntimeCommon.cpp +++ b/runtime/RuntimeCommon.cpp @@ -14,10 +14,15 @@ #include +#include #include #include +#include #include +#include +#include +#include "Config.h" #include "GarbageCollection.h" #include "RuntimeCommon.h" #include "Shadow.h" @@ -196,3 +201,21 @@ SymExpr _sym_build_insert(SymExpr target, SymExpr to_insert, uint64_t offset, void _sym_register_expression_region(SymExpr *start, size_t length) { registerExpressionRegion({start, length}); } + +void _sym_make_symbolic(void *data, size_t byte_length, size_t input_offset) { + ReadWriteShadow shadow(data, byte_length); + uint8_t *data_bytes = reinterpret_cast(data); + std::generate(shadow.begin(), shadow.end(), [&, i = 0]() mutable { + return _sym_get_input_byte(input_offset++, data_bytes[i++]); + }); +} + +void symcc_make_symbolic(void *start, size_t byte_length) { + if (!std::holds_alternative(g_config.input)) + throw std::runtime_error{"Calls to symcc_make_symbolic aren't allowed when " + "SYMCC_MEMORY_INPUT isn't set"}; + + static size_t inputOffset = 0; // track the offset across calls + _sym_make_symbolic(start, byte_length, inputOffset); + inputOffset += byte_length; +} diff --git a/runtime/RuntimeCommon.h b/runtime/RuntimeCommon.h index 05d8e954..bd86a6ed 100644 --- a/runtime/RuntimeCommon.h +++ b/runtime/RuntimeCommon.h @@ -27,10 +27,12 @@ #ifdef __cplusplus #include // for size_t +#include #include extern "C" { #else #include // for size_t +#include #include #endif @@ -121,7 +123,7 @@ SymExpr _sym_build_bits_to_float(SymExpr expr, int to_double); SymExpr _sym_build_float_to_bits(SymExpr expr); SymExpr _sym_build_float_to_signed_integer(SymExpr expr, uint8_t bits); SymExpr _sym_build_float_to_unsigned_integer(SymExpr expr, uint8_t bits); -SymExpr _sym_build_bool_to_bits(SymExpr expr, uint8_t bits); +SymExpr _sym_build_bool_to_bit(SymExpr expr); /* * Bit-array helpers @@ -143,7 +145,8 @@ SymExpr _sym_get_return_expression(void); */ void _sym_push_path_constraint(SymExpr constraint, int taken, uintptr_t site_id); -SymExpr _sym_get_input_byte(size_t offset); +SymExpr _sym_get_input_byte(size_t offset, uint8_t concrete_value); +void _sym_make_symbolic(void *data, size_t byte_length, size_t input_offset); /* * Memory management @@ -178,6 +181,14 @@ bool _sym_feasible(SymExpr expr); void _sym_register_expression_region(SymExpr *start, size_t length); void _sym_collect_garbage(void); +/* + * Symbolic input from memory + * + * This is the only function in the interface that we expect to be called by + * users (i.e., calls to it aren't auto-generated by our compiler pass). + */ +void symcc_make_symbolic(void *start, size_t byte_length); + #ifdef __cplusplus } #endif diff --git a/runtime/qsym_backend/Runtime.cpp b/runtime/qsym_backend/Runtime.cpp index 68b093bd..b4558a43 100644 --- a/runtime/qsym_backend/Runtime.cpp +++ b/runtime/qsym_backend/Runtime.cpp @@ -34,6 +34,7 @@ #include #include #include +#include #if HAVE_FILESYSTEM #include @@ -46,6 +47,7 @@ #endif // C +#include #include // Qsym @@ -77,11 +79,6 @@ namespace { /// Indicate whether the runtime has been initialized. std::atomic_flag g_initialized = ATOMIC_FLAG_INIT; -/// The file that contains out input. -std::string inputFileName; - -void deleteInputFile() { std::remove(inputFileName.c_str()); } - /// A mapping of all expressions that we have ever received from Qsym to the /// corresponding shared pointers on the heap. /// @@ -105,6 +102,34 @@ SymExpr registerExpression(const qsym::ExprRef &expr) { return rawExpr; } +/// A Qsym solver that doesn't require the entire input on initialization. +class EnhancedQsymSolver : public qsym::Solver { + // Warning! + // + // We can't override methods of qsym::Solver. None of them are declared + // virtual, and the Qsym code refers to the solver with a pointer of type + // qsym::Solver*, so it will always choose the implementation of the base + // class. What we can do, though, is add new functions that access the data + // members of the base class. + // + // Subclassing the Qsym solver is ugly but helps us to avoid making too many + // changes in the Qsym codebase. + +public: + EnhancedQsymSolver() + : qsym::Solver("/dev/null", g_config.outputDir, g_config.aflCoverageMap) { + } + + void pushInputByte(size_t offset, uint8_t value) { + if (inputs_.size() <= offset) + inputs_.resize(offset + 1); + + inputs_[offset] = value; + } +}; + +EnhancedQsymSolver *g_enhanced_solver; + } // namespace using namespace qsym; @@ -122,7 +147,7 @@ void _sym_initialize(void) { loadConfig(); initLibcWrappers(); std::cerr << "This is SymCC running with the QSYM backend" << std::endl; - if (g_config.fullyConcrete) { + if (std::holds_alternative(g_config.input)) { std::cerr << "Performing fully concrete execution (i.e., without symbolic input)" << std::endl; @@ -138,42 +163,9 @@ void _sym_initialize(void) { exit(-1); } - // Qsym requires the full input in a file - if (g_config.inputFile.empty()) { - std::cerr << "Reading program input until EOF (use Ctrl+D in a terminal)..." - << std::endl; - std::istreambuf_iterator in_begin(std::cin), in_end; - std::vector inputData(in_begin, in_end); - inputFileName = std::tmpnam(nullptr); - std::ofstream inputFile(inputFileName, std::ios::trunc); - std::copy(inputData.begin(), inputData.end(), - std::ostreambuf_iterator(inputFile)); - inputFile.close(); - -#ifdef DEBUG_RUNTIME - std::cerr << "Loaded input:" << std::endl; - std::copy(inputData.begin(), inputData.end(), - std::ostreambuf_iterator(std::cerr)); - std::cerr << std::endl; -#endif - - atexit(deleteInputFile); - - // Restore some semblance of standard input - auto *newStdin = freopen(inputFileName.c_str(), "r", stdin); - if (newStdin == nullptr) { - perror("Failed to reopen stdin"); - exit(-1); - } - } else { - inputFileName = g_config.inputFile; - std::cerr << "Making data read from " << inputFileName << " as symbolic" - << std::endl; - } - g_z3_context = new z3::context{}; - g_solver = - new Solver(inputFileName, g_config.outputDir, g_config.aflCoverageMap); + g_enhanced_solver = new EnhancedQsymSolver{}; + g_solver = g_enhanced_solver; // for Qsym-internal use g_expr_builder = g_config.pruning ? PruneExprBuilder::create() : SymbolicExprBuilder::create(); } @@ -289,7 +281,8 @@ void _sym_push_path_constraint(SymExpr constraint, int taken, g_solver->addJcc(allocatedExpressions.at(constraint), taken != 0, site_id); } -SymExpr _sym_get_input_byte(size_t offset) { +SymExpr _sym_get_input_byte(size_t offset, uint8_t value) { + g_enhanced_solver->pushInputByte(offset, value); return registerExpression(g_expr_builder->createRead(offset)); } @@ -305,9 +298,9 @@ SymExpr _sym_extract_helper(SymExpr expr, size_t first_bit, size_t last_bit) { size_t _sym_bits_helper(SymExpr expr) { return expr->bits(); } -SymExpr _sym_build_bool_to_bits(SymExpr expr, uint8_t bits) { +SymExpr _sym_build_bool_to_bit(SymExpr expr) { return registerExpression( - g_expr_builder->boolToBit(allocatedExpressions.at(expr), bits)); + g_expr_builder->boolToBit(allocatedExpressions.at(expr), 1)); } // diff --git a/runtime/qsym_backend/qsym b/runtime/qsym_backend/qsym index d17a39d4..6cba7f99 160000 --- a/runtime/qsym_backend/qsym +++ b/runtime/qsym_backend/qsym @@ -1 +1 @@ -Subproject commit d17a39d40dc3ea1d17262dd52607f8a6527dde10 +Subproject commit 6cba7f996fa2568dcc02e632a72d9931fdf30f70 diff --git a/runtime/simple_backend/CMakeLists.txt b/runtime/simple_backend/CMakeLists.txt index a8fef903..baaff20b 100644 --- a/runtime/simple_backend/CMakeLists.txt +++ b/runtime/simple_backend/CMakeLists.txt @@ -39,4 +39,4 @@ target_include_directories(SymRuntime PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/.. ${Z3_C_INCLUDE_DIRS}) -set_target_properties(SymRuntime PROPERTIES COMPILE_FLAGS "-Werror") +set_target_properties(SymRuntime PROPERTIES COMPILE_FLAGS "-Werror -Wno-error=deprecated-declarations") diff --git a/runtime/simple_backend/Runtime.cpp b/runtime/simple_backend/Runtime.cpp index d7ef5f20..50dbc8df 100644 --- a/runtime/simple_backend/Runtime.cpp +++ b/runtime/simple_backend/Runtime.cpp @@ -178,7 +178,7 @@ Z3_ast _sym_build_float(double value, int is_double) { return result; } -Z3_ast _sym_get_input_byte(size_t offset) { +Z3_ast _sym_get_input_byte(size_t offset, uint8_t) { static std::vector stdinBytes; if (offset < stdinBytes.size()) @@ -407,10 +407,10 @@ Z3_ast _sym_build_float_to_unsigned_integer(Z3_ast expr, uint8_t bits) { g_context, Z3_mk_fpa_round_toward_zero(g_context), expr, bits)); } -Z3_ast _sym_build_bool_to_bits(Z3_ast expr, uint8_t bits) { +Z3_ast _sym_build_bool_to_bit(Z3_ast expr) { return registerExpression(Z3_mk_ite(g_context, expr, - _sym_build_integer(1, bits), - _sym_build_integer(0, bits))); + _sym_build_integer(1, 1), + _sym_build_integer(0, 1))); } void _sym_push_path_constraint(Z3_ast constraint, int taken, diff --git a/test/bool_cast.c b/test/bool_cast.c new file mode 100644 index 00000000..0d3764a0 --- /dev/null +++ b/test/bool_cast.c @@ -0,0 +1,42 @@ +// This file is part of SymCC. +// +// SymCC is free software: you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the Free Software +// Foundation, either version 3 of the License, or (at your option) any later +// version. +// +// SymCC is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +// A PARTICULAR PURPOSE. See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along with +// SymCC. If not, see . + +// RUN: %symcc -O1 %s -o %t +// RUN: echo b | %t 2>&1 | %filecheck %s +// +// Check that bool cast is handled correctly (Issue #108) + +#include +#include +#include + +int bar(unsigned char a) { + if (a == 0xCA) return -1; + else return 0; +} + +int main() { + unsigned char input = 0; + read(0, &input, sizeof(input)); + int r = bar(input); + // SIMPLE: Trying to solve + // SIMPLE: Found diverging input + // SIMPLE: stdin0 -> #xca + // QSYM-COUNT-2: SMT + // QSYM: New testcase + if (r == -1) printf("Bingo!\n"); + else printf("Ok\n"); + // ANY: Ok + return r; +} diff --git a/test/if.c b/test/if.c index 036c4402..dda1d13a 100644 --- a/test/if.c +++ b/test/if.c @@ -51,5 +51,6 @@ int main(int argc, char* argv[]) { } fprintf(stderr, "%d\n", x); fprintf(stderr, "%d\n", foo(x, 7)); + // ANY: 7 return 0; } diff --git a/test/loop.c b/test/loop.c index d411e180..5d90eb9d 100644 --- a/test/loop.c +++ b/test/loop.c @@ -50,5 +50,6 @@ int main(int argc, char* argv[]) { } x = ntohl(x); fprintf(stderr, "%d\n", fac(x)); + // ANY: 120 return 0; } diff --git a/test/memory_input.c b/test/memory_input.c new file mode 100644 index 00000000..58f55702 --- /dev/null +++ b/test/memory_input.c @@ -0,0 +1,51 @@ +// This file is part of SymCC. +// +// SymCC is free software: you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the Free Software +// Foundation, either version 3 of the License, or (at your option) any later +// version. +// +// SymCC is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +// A PARTICULAR PURPOSE. See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along with +// SymCC. If not, see . + +// RUN: %symcc -O2 %s -o %t +// RUN: env SYMCC_MEMORY_INPUT=1 %t 2>&1 | %filecheck %s +#include +#include +#include + +void symcc_make_symbolic(void *start, size_t byte_length); + +uint64_t g_value = 0xaaaabbbbccccdddd; + +int main(int argc, char *argv[]) { + uint64_t x = 10; + uint8_t y = 0; + + symcc_make_symbolic(&x, sizeof(x)); + symcc_make_symbolic(&y, sizeof(y)); + + fprintf(stderr, "%s\n", (x == g_value) ? "yes" : "no"); + // SIMPLE: Trying to solve + // SIMPLE: Found diverging input + // SIMPLE-DAG: #xaa + // SIMPLE-DAG: #xbb + // SIMPLE-DAG: #xcc + // SIMPLE-DAG: #xdd + // QSYM-COUNT-2: SMT + // ANY: no + + fprintf(stderr, "%s\n", (y == 10) ? "yes" : "no"); + // SIMPLE: Trying to solve + // SIMPLE: Found diverging input + // y should be part of the input, just after x + // SIMPLE: stdin8 -> #x0a + // QSYM-COUNT-2: SMT + // ANY: no + + return 0; +} diff --git a/test/propagation_select.c b/test/propagation_select.c new file mode 100644 index 00000000..a04af9e0 --- /dev/null +++ b/test/propagation_select.c @@ -0,0 +1,47 @@ +// This file is part of SymCC. +// +// SymCC is free software: you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the Free Software +// Foundation, either version 3 of the License, or (at your option) any later +// version. +// +// SymCC is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +// A PARTICULAR PURPOSE. See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along with +// SymCC. If not, see . + +// RUN: %symcc -O1 %s -o %t +// RUN: echo xxx | %t 2>&1 | %filecheck %s +// +// Check that select instruction is propagating the symbolic value (issue #109) + +#include +#include +#include + +char bar(char a, char b, char c) { return (a == 0xA) ? b : c; } + +int main() { + char input[3] = {0}; + read(0, &input, sizeof(input)); + // SIMPLE: Trying to solve + // SIMPLE: Found diverging input + // SIMPLE: stdin0 -> #x0a + // QSYM-COUNT-2: SMT + // QSYM: New testcase + char r = bar(input[0], input[1], input[2]); + // SIMPLE: Trying to solve + // SIMPLE: Found diverging input + // SIMPLE-DAG: stdin2 -> #x0b + // SIMPLE-DAG: stdin0 -> #x00 + // QSYM-COUNT-2: SMT + // QSYM: New testcase + // ANY: KO + if (r == 0xB) + printf("OK!\n"); + else + printf("KO\n"); + return 0; +} diff --git a/util/symcc_fuzzing_helper/Cargo.lock b/util/symcc_fuzzing_helper/Cargo.lock index 417f964f..9f8b5069 100644 --- a/util/symcc_fuzzing_helper/Cargo.lock +++ b/util/symcc_fuzzing_helper/Cargo.lock @@ -57,16 +57,16 @@ checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" [[package]] name = "clap" -version = "3.1.6" +version = "3.1.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8c93436c21e4698bacadf42917db28b23017027a4deccb35dbe47a7e7840123" +checksum = "d2dbdf4bdacb33466e854ce889eee8dfd5729abf7ccd7664d0a2d60cd384440b" dependencies = [ "atty", "bitflags", "clap_derive", + "clap_lex", "indexmap", "lazy_static", - "os_str_bytes", "strsim", "termcolor", "textwrap", @@ -74,9 +74,9 @@ dependencies = [ [[package]] name = "clap_derive" -version = "3.1.4" +version = "3.1.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da95d038ede1a964ce99f49cbe27a7fb538d1da595e4b4f70b8c8f338d17bf16" +checksum = "25320346e922cffe59c0bbc5410c8d8784509efb321488971081313cb1e1a33c" dependencies = [ "heck", "proc-macro-error", @@ -85,6 +85,15 @@ dependencies = [ "syn", ] +[[package]] +name = "clap_lex" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a37c35f1112dad5e6e0b1adaff798507497a18fceeb30cceb3bae7d1427b9213" +dependencies = [ + "os_str_bytes", +] + [[package]] name = "env_logger" version = "0.7.1" @@ -141,9 +150,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "1.8.0" +version = "1.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "282a6247722caba404c065016bbfa522806e51714c34f5dfc3e4a3a46fcb4223" +checksum = "e6012d540c5baa3589337a98ce73408de9b5a25ec9fc2c6fd6be8f0d39e0ca5a" dependencies = [ "autocfg", "hashbrown", @@ -172,18 +181,15 @@ dependencies = [ [[package]] name = "memchr" -version = "2.4.1" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a" +checksum = "3197e20c7edb283f87c071ddfc7a2cca8f8e0b888c242959846a6fce03c72223" [[package]] name = "os_str_bytes" -version = "6.0.0" +version = "6.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e22443d1643a904602595ba1cd8f7d896afe56d26712531c5ff73a15b2fbf64" -dependencies = [ - "memchr", -] +checksum = "21326818e99cfe6ce1e524c2a805c189a99b5ae555a35d19f9a284b427d86afa" [[package]] name = "ppv-lite86" @@ -217,11 +223,11 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.36" +version = "1.0.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7342d5883fbccae1cc37a2353b09c87c9b0f3afd73f5fb9bba687a1f733b029" +checksum = "c54b25569025b7fc9651de43004ae593a75ad88543b17178aa5e1b9c4f15f56f" dependencies = [ - "unicode-xid", + "unicode-ident", ] [[package]] @@ -232,9 +238,9 @@ checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" [[package]] name = "quote" -version = "1.0.17" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "632d02bff7f874a36f33ea8bb416cd484b90cc66c1194b1a1110d067a7013f58" +checksum = "a1feb54ed693b93a84e14094943b84b7c4eae204c512b7ccb95ab0c66d278ad1" dependencies = [ "proc-macro2", ] @@ -333,13 +339,13 @@ dependencies = [ [[package]] name = "syn" -version = "1.0.89" +version = "1.0.96" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea297be220d52398dcc07ce15a209fce436d361735ac1db700cab3b6cdfb9f54" +checksum = "0748dd251e24453cb8717f0354206b91557e4ec8703673a4b30208f2abaf1ebf" dependencies = [ "proc-macro2", "quote", - "unicode-xid", + "unicode-ident", ] [[package]] @@ -381,10 +387,10 @@ dependencies = [ ] [[package]] -name = "unicode-xid" -version = "0.2.0" +name = "unicode-ident" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c" +checksum = "d22af068fba1eb5edcb4aea19d382b2a3deb4c8f9d475c589b6ada9e0fd493ee" [[package]] name = "version_check" diff --git a/util/symcc_fuzzing_helper/Cargo.toml b/util/symcc_fuzzing_helper/Cargo.toml index f8858d88..d884dce1 100644 --- a/util/symcc_fuzzing_helper/Cargo.toml +++ b/util/symcc_fuzzing_helper/Cargo.toml @@ -20,7 +20,7 @@ edition = "2018" license = "GPL-3.0-or-later" [dependencies] -clap = { version = "3.0", features = ["derive"]} +clap = { version = "3", features = ["derive"] } tempfile = "3.1" anyhow = "1.0" log = "0.4.0" diff --git a/util/symcc_fuzzing_helper/src/main.rs b/util/symcc_fuzzing_helper/src/main.rs index 6b2105e3..f9b0a870 100644 --- a/util/symcc_fuzzing_helper/src/main.rs +++ b/util/symcc_fuzzing_helper/src/main.rs @@ -15,6 +15,7 @@ mod symcc; use anyhow::{Context, Result}; +use clap::{self, StructOpt}; use std::collections::HashSet; use std::fs; use std::fs::File; @@ -22,7 +23,6 @@ use std::io::Write; use std::path::{Path, PathBuf}; use std::thread; use std::time::{Duration, Instant}; -use clap::{self, StructOpt}; use symcc::{AflConfig, AflMap, AflShowmapResult, SymCC, TestcaseDir}; use tempfile::tempdir; @@ -33,7 +33,7 @@ const STATS_INTERVAL_SEC: u64 = 60; #[derive(Debug, StructOpt)] #[clap(about = "Make SymCC collaborate with AFL.")] -struct Opt { +struct CLI { /// The name of the fuzzer to work with #[clap(short = 'a')] fuzzer_name: String, @@ -275,7 +275,7 @@ impl State { } fn main() -> Result<()> { - let options = Opt::parse(); + let options = CLI::parse(); env_logger::builder() .filter_level(if options.verbose { log::LevelFilter::Debug From 76d4e26c58d3f62c9e47c16c8a79088be3f8cf40 Mon Sep 17 00:00:00 2001 From: julihoh Date: Sat, 19 Nov 2022 18:27:33 +0100 Subject: [PATCH 20/32] adapt rust runtime to api changes from upstream (#4) --- runtime/rust_backend/Runtime.cpp | 8 ++++---- runtime/rust_backend/RustRuntime.h | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/runtime/rust_backend/Runtime.cpp b/runtime/rust_backend/Runtime.cpp index a8188313..a2c33f5a 100644 --- a/runtime/rust_backend/Runtime.cpp +++ b/runtime/rust_backend/Runtime.cpp @@ -123,8 +123,8 @@ SymExpr _sym_build_float(double value, int is_double) { symexpr(_rsym_build_float(value, is_double), is_double ? 64 : 32)); } -SymExpr _sym_get_input_byte(size_t offset) { - return registerExpression(symexpr(_rsym_get_input_byte(offset), 8)); +SymExpr _sym_get_input_byte(size_t offset, uint8_t value) { + return registerExpression(symexpr(_rsym_get_input_byte(offset, value), 8)); } SymExpr _sym_build_null_pointer(void) { @@ -280,9 +280,9 @@ SymExpr _sym_build_float_to_unsigned_integer(SymExpr expr, uint8_t bits) { _rsym_build_float_to_unsigned_integer(symexpr_id(expr), bits), bits)); } -SymExpr _sym_build_bool_to_bits(SymExpr expr, uint8_t bits) { +SymExpr _sym_build_bool_to_bit(SymExpr expr, uint8_t bits) { return registerExpression( - symexpr(_rsym_build_bool_to_bits(symexpr_id(expr), bits), bits)); + symexpr(_rsym_build_bool_to_bit(symexpr_id(expr), bits), bits)); } void _sym_push_path_constraint(SymExpr constraint, int taken, diff --git a/runtime/rust_backend/RustRuntime.h b/runtime/rust_backend/RustRuntime.h index 53edf6e2..b53d6d2a 100644 --- a/runtime/rust_backend/RustRuntime.h +++ b/runtime/rust_backend/RustRuntime.h @@ -116,7 +116,7 @@ RSymExpr _rsym_build_bits_to_float(RSymExpr expr, bool to_double); RSymExpr _rsym_build_float_to_bits(RSymExpr expr); RSymExpr _rsym_build_float_to_signed_integer(RSymExpr expr, uint8_t bits); RSymExpr _rsym_build_float_to_unsigned_integer(RSymExpr expr, uint8_t bits); -RSymExpr _rsym_build_bool_to_bits(RSymExpr expr, uint8_t bits); +RSymExpr _rsym_build_bool_to_bit(RSymExpr expr, uint8_t bits); /* * Bit-array helpers @@ -129,7 +129,7 @@ RSymExpr _rsym_extract_helper(RSymExpr expr, size_t first_bit, size_t last_bit); */ void _rsym_push_path_constraint(RSymExpr constraint, bool taken, uintptr_t site_id); -RSymExpr _rsym_get_input_byte(size_t offset); +RSymExpr _rsym_get_input_byte(size_t offset, uint8_t value); /* * Call-stack tracing From 2a3229da6101596af220f20fef5085e59537abcb Mon Sep 17 00:00:00 2001 From: julihoh Date: Sat, 19 Nov 2022 19:04:57 +0100 Subject: [PATCH 21/32] Follow up #4 (#5) * actually fix interface * more fixes --- runtime/rust_backend/Runtime.cpp | 4 ++-- runtime/rust_backend/RustRuntime.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/runtime/rust_backend/Runtime.cpp b/runtime/rust_backend/Runtime.cpp index a2c33f5a..91adf9e9 100644 --- a/runtime/rust_backend/Runtime.cpp +++ b/runtime/rust_backend/Runtime.cpp @@ -280,9 +280,9 @@ SymExpr _sym_build_float_to_unsigned_integer(SymExpr expr, uint8_t bits) { _rsym_build_float_to_unsigned_integer(symexpr_id(expr), bits), bits)); } -SymExpr _sym_build_bool_to_bit(SymExpr expr, uint8_t bits) { +SymExpr _sym_build_bool_to_bit(SymExpr expr) { return registerExpression( - symexpr(_rsym_build_bool_to_bit(symexpr_id(expr), bits), bits)); + symexpr(_rsym_build_bool_to_bit(symexpr_id(expr)), 1)); } void _sym_push_path_constraint(SymExpr constraint, int taken, diff --git a/runtime/rust_backend/RustRuntime.h b/runtime/rust_backend/RustRuntime.h index b53d6d2a..7789a86f 100644 --- a/runtime/rust_backend/RustRuntime.h +++ b/runtime/rust_backend/RustRuntime.h @@ -116,7 +116,7 @@ RSymExpr _rsym_build_bits_to_float(RSymExpr expr, bool to_double); RSymExpr _rsym_build_float_to_bits(RSymExpr expr); RSymExpr _rsym_build_float_to_signed_integer(RSymExpr expr, uint8_t bits); RSymExpr _rsym_build_float_to_unsigned_integer(RSymExpr expr, uint8_t bits); -RSymExpr _rsym_build_bool_to_bit(RSymExpr expr, uint8_t bits); +RSymExpr _rsym_build_bool_to_bit(RSymExpr expr); /* * Bit-array helpers From a42e95e754f7d8645957ab399d3eb346d2303b5a Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Wed, 4 Jan 2023 15:19:58 +0100 Subject: [PATCH 22/32] Fix naming for afl++ --- docs/Experiments.txt | 4 ++-- docs/Fuzzing.txt | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/docs/Experiments.txt b/docs/Experiments.txt index 81751a4a..a59a5232 100644 --- a/docs/Experiments.txt +++ b/docs/Experiments.txt @@ -40,7 +40,7 @@ you have exported CC=symcc, CXX=sym++ and SYMCC_NO_SYMBOLIC_INPUT=1, first download the code, then build it using its own build system, finally unset SYMCC_NO_SYMBOLIC_INPUT and analyze the program in concert with AFL (which requires building a second time for AFL, see docs/Fuzzing.txt). We used AFL -2.56b and built the targets with AFL_USE_ASAN=1. Note that the fuzzing helper is +2.56b and built the targets with AFL_USE_ASan=1. Note that the fuzzing helper is already installed in the Docker container. OpenJPEG [4]: we used revision 1f1e9682, built with CMake as described in the @@ -61,7 +61,7 @@ tcpdump: we built both tcpdump [7] and libpcap [8]; in order to make the former and analyzed "tcpdump/tcpdump -e -r @@"; the corpus consisted of just a single dummy file containing the character "A". -All experiments used one AFL master process, one secondary AFL process, and one +All experiments used one AFL main process, one secondary AFL process, and one SymCC process. We let them run for 24 hours and repeated each of them 30 times to create the graphs in the paper; AFL map density was extracted from the secondary AFL process' "plot_data" file, column "map_size". diff --git a/docs/Fuzzing.txt b/docs/Fuzzing.txt index ecbda392..074ff289 100644 --- a/docs/Fuzzing.txt +++ b/docs/Fuzzing.txt @@ -50,7 +50,7 @@ $ tcpdump -e -r Compile tcpdump and libpcap, the library it uses for pcap reading, once with SymCC and once with one of AFL's compiler wrappers (e.g., afl-clang). In order to detect memory corruptions, enable address sanitizer in the AFL-instrumented -version by exporting AFL_USE_ASAN=1 before compiling: +version by exporting AFL_USE_ASan=1 before compiling: $ git clone https://github.com/the-tcpdump-group/libpcap.git $ git clone https://github.com/the-tcpdump-group/tcpdump.git @@ -66,7 +66,7 @@ $ make $ cd .. $ mkdir afl_build; cd afl_build -$ export AFL_USE_ASAN=1 +$ export AFL_USE_ASan=1 $ cp -r ../{libpcap,tcpdump} . $ cd libpcap $ CC=/path/to/afl-clang ./configure @@ -88,10 +88,10 @@ AFL: $ mkdir corpus $ echo A > corpus/dummy -Then launch one AFL master and one AFL secondary instance, both writing their +Then launch one AFL main and one AFL secondary instance, both writing their outputs to the arbitrarily named directory "afl_out": -$ afl-fuzz -M afl-master -i corpus -o afl_out -m none -- afl_build/tcpdump/tcpdump -e -r @@ +$ afl-fuzz -M afl-main -i corpus -o afl_out -m none -- afl_build/tcpdump/tcpdump -e -r @@ $ afl-fuzz -S afl-secondary -i corpus -o afl_out -m none -- afl_build/tcpdump/tcpdump -e -r @@ For simplicity, we disable memory limits (with "-m none"); be sure to read AFL's @@ -109,7 +109,7 @@ you should see the counter "imported" in the "path geometry" section increase after a short time - this means that the fuzzer instances and SymCC are exchanging inputs. Crashes will be stored in afl_out/*/crashes as usual. -It is possible to run SymCC with only an AFL master or only a secondary AFL +It is possible to run SymCC with only an AFL main or only a secondary AFL instance; see the AFL docs for the implications. Moreover, the number of fuzzer and SymCC instances can be increased - just make sure that each has a unique name. From bee13dadc0c8bf5a2daa4a295456b20393718161 Mon Sep 17 00:00:00 2001 From: toka Date: Fri, 20 Oct 2023 16:19:50 +0200 Subject: [PATCH 23/32] Update: qsym_backend --- runtime/qsym_backend/qsym | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime/qsym_backend/qsym b/runtime/qsym_backend/qsym index 6cba7f99..300300e8 160000 --- a/runtime/qsym_backend/qsym +++ b/runtime/qsym_backend/qsym @@ -1 +1 @@ -Subproject commit 6cba7f996fa2568dcc02e632a72d9931fdf30f70 +Subproject commit 300300e8f417e057f918eb8fd696290aec3e1a69 From 5cb76f1491eb298b604b66db4207e0588c945798 Mon Sep 17 00:00:00 2001 From: toka Date: Fri, 20 Oct 2023 17:42:25 +0200 Subject: [PATCH 24/32] add --- runtime/rust_backend/Runtime.cpp | 6 ++++++ runtime/rust_backend/RustRuntime.h | 2 ++ 2 files changed, 8 insertions(+) diff --git a/runtime/rust_backend/Runtime.cpp b/runtime/rust_backend/Runtime.cpp index 91adf9e9..a00ff4f9 100644 --- a/runtime/rust_backend/Runtime.cpp +++ b/runtime/rust_backend/Runtime.cpp @@ -205,6 +205,7 @@ DEF_BINARY_BV_EXPR_BUILDER(fp_rem) #undef DEF_BINARY_BV_EXPR_BUILDER DEF_UNARY_EXPR_BUILDER(fp_abs) +DEF_UNARY_EXPR_BUILDER(fp_neg) DEF_UNARY_EXPR_BUILDER(not ) DEF_BINARY_BOOL_EXPR_BUILDER(not_equal) @@ -227,6 +228,11 @@ DEF_BINARY_BOOL_EXPR_BUILDER(float_unordered_not_equal) #undef DEF_BINARY_BOOL_EXPR_BUILDER +SymExpr _sym_build_ite(SymExpr cond, SymExpr a, SymExpr b) { + return registerExpression(symexpr( + _rsym_build_ite(symexpr_id(cond), symexpr_id(a), symexpr_id(b)), 0)); +} + SymExpr _sym_build_sext(SymExpr expr, uint8_t bits) { return registerExpression(symexpr(_rsym_build_sext(symexpr_id(expr), bits), symexpr_width(expr) + bits)); diff --git a/runtime/rust_backend/RustRuntime.h b/runtime/rust_backend/RustRuntime.h index 7789a86f..766faa41 100644 --- a/runtime/rust_backend/RustRuntime.h +++ b/runtime/rust_backend/RustRuntime.h @@ -66,6 +66,7 @@ RSymExpr _rsym_build_fp_mul(RSymExpr a, RSymExpr b); RSymExpr _rsym_build_fp_div(RSymExpr a, RSymExpr b); RSymExpr _rsym_build_fp_rem(RSymExpr a, RSymExpr b); RSymExpr _rsym_build_fp_abs(RSymExpr a); +RSymExpr _rsym_build_fp_neg(RSymExpr a); /* * Boolean operations @@ -87,6 +88,7 @@ RSymExpr _rsym_build_bool_or(RSymExpr a, RSymExpr b); RSymExpr _rsym_build_or(RSymExpr a, RSymExpr b); RSymExpr _rsym_build_bool_xor(RSymExpr a, RSymExpr b); RSymExpr _rsym_build_xor(RSymExpr a, RSymExpr b); +RSymExpr _rsym_build_ite(RSymExpr cond, RSymExpr a, RSymExpr b); RSymExpr _rsym_build_float_ordered_greater_than(RSymExpr a, RSymExpr b); RSymExpr _rsym_build_float_ordered_greater_equal(RSymExpr a, RSymExpr b); From fa54463ee52179bb646a0f02c55b21003ba6ee51 Mon Sep 17 00:00:00 2001 From: toka Date: Thu, 4 Jan 2024 14:04:05 +0100 Subject: [PATCH 25/32] remove extern block --- runtime/rust_backend/RustRuntime.h | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/runtime/rust_backend/RustRuntime.h b/runtime/rust_backend/RustRuntime.h index 766faa41..506ff543 100644 --- a/runtime/rust_backend/RustRuntime.h +++ b/runtime/rust_backend/RustRuntime.h @@ -24,13 +24,7 @@ #define RUSTRUNTIME_H #include - -#ifdef __cplusplus #include -extern "C" { -#else -#include -#endif typedef uintptr_t RSymExpr; @@ -144,9 +138,3 @@ void _rsym_notify_basic_block(uintptr_t site_id); * Garbage collection */ void _rsym_expression_unreachable(RSymExpr *expressions, size_t num_elements); - -#ifdef __cplusplus -} -#endif - -#endif From 7caf6aa052365f78f8eb9d133526d8cad5fe7397 Mon Sep 17 00:00:00 2001 From: toka Date: Thu, 4 Jan 2024 14:09:32 +0100 Subject: [PATCH 26/32] endif --- runtime/rust_backend/RustRuntime.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/runtime/rust_backend/RustRuntime.h b/runtime/rust_backend/RustRuntime.h index 506ff543..f446b789 100644 --- a/runtime/rust_backend/RustRuntime.h +++ b/runtime/rust_backend/RustRuntime.h @@ -138,3 +138,5 @@ void _rsym_notify_basic_block(uintptr_t site_id); * Garbage collection */ void _rsym_expression_unreachable(RSymExpr *expressions, size_t num_elements); + +#endif \ No newline at end of file From 27734ff7e98f3f84cd581c8baa8a9166a8ee058c Mon Sep 17 00:00:00 2001 From: toka Date: Thu, 4 Jan 2024 14:15:01 +0100 Subject: [PATCH 27/32] FMT --- runtime/rust_backend/RustRuntime.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime/rust_backend/RustRuntime.h b/runtime/rust_backend/RustRuntime.h index f446b789..ca265a9e 100644 --- a/runtime/rust_backend/RustRuntime.h +++ b/runtime/rust_backend/RustRuntime.h @@ -23,8 +23,8 @@ #ifndef RUSTRUNTIME_H #define RUSTRUNTIME_H -#include #include +#include typedef uintptr_t RSymExpr; From 5db9e6bd11e7e84bce41d72531c01877837fc150 Mon Sep 17 00:00:00 2001 From: toka Date: Thu, 4 Jan 2024 14:48:12 +0100 Subject: [PATCH 28/32] include --- runtime/rust_backend/RustRuntime.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime/rust_backend/RustRuntime.h b/runtime/rust_backend/RustRuntime.h index ca265a9e..7f839678 100644 --- a/runtime/rust_backend/RustRuntime.h +++ b/runtime/rust_backend/RustRuntime.h @@ -23,7 +23,7 @@ #ifndef RUSTRUNTIME_H #define RUSTRUNTIME_H -#include +#include #include typedef uintptr_t RSymExpr; From 1e8f02bfc10e029a1e7b42003a7e4df8f7409a46 Mon Sep 17 00:00:00 2001 From: toka Date: Thu, 4 Jan 2024 14:51:37 +0100 Subject: [PATCH 29/32] boolean? --- runtime/rust_backend/RustRuntime.h | 1 + 1 file changed, 1 insertion(+) diff --git a/runtime/rust_backend/RustRuntime.h b/runtime/rust_backend/RustRuntime.h index 7f839678..67996500 100644 --- a/runtime/rust_backend/RustRuntime.h +++ b/runtime/rust_backend/RustRuntime.h @@ -23,6 +23,7 @@ #ifndef RUSTRUNTIME_H #define RUSTRUNTIME_H +#include #include #include From 950ab01bc51616377e4c894aec20d761fdf722bb Mon Sep 17 00:00:00 2001 From: toka Date: Thu, 4 Jan 2024 14:55:22 +0100 Subject: [PATCH 30/32] fmt --- runtime/rust_backend/RustRuntime.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime/rust_backend/RustRuntime.h b/runtime/rust_backend/RustRuntime.h index 67996500..b3c9eb88 100644 --- a/runtime/rust_backend/RustRuntime.h +++ b/runtime/rust_backend/RustRuntime.h @@ -24,8 +24,8 @@ #define RUSTRUNTIME_H #include -#include #include +#include typedef uintptr_t RSymExpr; From 4898f5b275b520620cfa247ed885a3418bb05141 Mon Sep 17 00:00:00 2001 From: toka Date: Thu, 4 Jan 2024 16:24:25 +0100 Subject: [PATCH 31/32] revert --- runtime/rust_backend/RustRuntime.h | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/runtime/rust_backend/RustRuntime.h b/runtime/rust_backend/RustRuntime.h index b3c9eb88..766faa41 100644 --- a/runtime/rust_backend/RustRuntime.h +++ b/runtime/rust_backend/RustRuntime.h @@ -23,9 +23,14 @@ #ifndef RUSTRUNTIME_H #define RUSTRUNTIME_H -#include #include + +#ifdef __cplusplus +#include +extern "C" { +#else #include +#endif typedef uintptr_t RSymExpr; @@ -140,4 +145,8 @@ void _rsym_notify_basic_block(uintptr_t site_id); */ void _rsym_expression_unreachable(RSymExpr *expressions, size_t num_elements); -#endif \ No newline at end of file +#ifdef __cplusplus +} +#endif + +#endif From 1330e29d28bce706d9f7c0864da3b0a5ae218e03 Mon Sep 17 00:00:00 2001 From: "Dongjia \"toka\" Zhang" Date: Sat, 13 Apr 2024 23:53:04 +0200 Subject: [PATCH 32/32] Update rust backend (#13) * push * add * FMT * f * bits --- runtime/rust_backend/Runtime.cpp | 5 +++++ runtime/rust_backend/RustRuntime.h | 1 + 2 files changed, 6 insertions(+) diff --git a/runtime/rust_backend/Runtime.cpp b/runtime/rust_backend/Runtime.cpp index a00ff4f9..2f11cbe3 100644 --- a/runtime/rust_backend/Runtime.cpp +++ b/runtime/rust_backend/Runtime.cpp @@ -118,6 +118,11 @@ SymExpr _sym_build_integer128(uint64_t high, uint64_t low) { return registerExpression(symexpr(_rsym_build_integer128(high, low), 128)); } +SymExpr _sym_build_integer_from_buffer(void *buffer, unsigned num_bits) { + return registerExpression( + symexpr(_rsym_build_integer_from_buffer(buffer, num_bits), num_bits)); +} + SymExpr _sym_build_float(double value, int is_double) { return registerExpression( symexpr(_rsym_build_float(value, is_double), is_double ? 64 : 32)); diff --git a/runtime/rust_backend/RustRuntime.h b/runtime/rust_backend/RustRuntime.h index 766faa41..ebc28eb3 100644 --- a/runtime/rust_backend/RustRuntime.h +++ b/runtime/rust_backend/RustRuntime.h @@ -39,6 +39,7 @@ typedef uintptr_t RSymExpr; */ RSymExpr _rsym_build_integer(uint64_t value, uint8_t bits); RSymExpr _rsym_build_integer128(uint64_t high, uint64_t low); +RSymExpr _rsym_build_integer_from_buffer(void *buffer, unsigned num_bits); RSymExpr _rsym_build_float(double value, bool is_double); RSymExpr _rsym_build_null_pointer(void); RSymExpr _rsym_build_true(void);