1 /* 2 * Copyright (C) 2017 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #pragma once 18 19 #include <stdint.h> 20 #include <string> 21 22 namespace slicer { 23 24 // Encapsulate the runtime check and error reporting policy. 25 // (currently a simple fail-fast but the the intention is to allow customization) 26 void _checkFailed(const char* expr, int line, const char* file) __attribute__((noreturn)); 27 #define SLICER_CHECK(expr) do { if(!(expr)) slicer::_checkFailed(#expr, __LINE__, __FILE__); } while(false) 28 29 // Helper methods for SLICER_CHECK_OP macro. 30 void _checkFailedOp(const void* lhs, const void* rhs, const char* op, const char* suffix, 31 int line, const char* file) 32 __attribute__((noreturn)); 33 void _checkFailedOp(uint32_t lhs, uint32_t rhs, const char* op, const char* suffix, int line, 34 const char* file) 35 __attribute__((noreturn)); 36 37 #define SLICER_CHECK_OP(lhs, rhs, op, suffix) \ 38 do { \ 39 if (!((lhs) op (rhs))) { \ 40 slicer::_checkFailedOp(lhs, rhs, #op, suffix, __LINE__, __FILE__); \ 41 } \ 42 } while(false) 43 44 // Macros that check the binary relation between two values. If the relation is not true, 45 // the values are logged and the process aborts. 46 #define SLICER_CHECK_EQ(a, b) SLICER_CHECK_OP(a, b, ==, "EQ") 47 #define SLICER_CHECK_NE(a, b) SLICER_CHECK_OP(a, b, !=, "NE") 48 #define SLICER_CHECK_LT(a, b) SLICER_CHECK_OP(a, b, <, "LT") 49 #define SLICER_CHECK_LE(a, b) SLICER_CHECK_OP(a, b, <=, "LE") 50 #define SLICER_CHECK_GT(a, b) SLICER_CHECK_OP(a, b, >, "GT") 51 #define SLICER_CHECK_GE(a, b) SLICER_CHECK_OP(a, b, >=, "GE") 52 53 // A modal check: if the strict mode is enabled, it behaves as a SLICER_CHECK, 54 // otherwise it will only log a warning and continue 55 // 56 // NOTE: we use SLICER_WEAK_CHECK for .dex format validations that are frequently 57 // violated by existing apps. So we need to be able to annotate these common 58 // problems and potentially ignoring them for parity with the Android runtime. 59 // 60 void _weakCheckFailed(const char* expr, int line, const char* file); 61 #define SLICER_WEAK_CHECK(expr) do { if(!(expr)) slicer::_weakCheckFailed(#expr, __LINE__, __FILE__); } while(false) 62 63 // Report a fatal condition with a printf-formatted message 64 void _fatal(const std::string& msg) __attribute__((noreturn)); 65 #define SLICER_FATAL(msg) slicer::_fatal(msg) 66 67 // Annotation customization point for extra validation / state. 68 #ifdef NDEBUG 69 #define SLICER_EXTRA(x) 70 #else 71 #define SLICER_EXTRA(x) x 72 #endif 73 74 #ifndef FALLTHROUGH_INTENDED 75 #ifdef __clang__ 76 #define FALLTHROUGH_INTENDED [[clang::fallthrough]] 77 #else 78 #define FALLTHROUGH_INTENDED 79 #endif // __clang__ 80 #endif // FALLTHROUGH_INTENDED 81 82 typedef void (*logger_type)(const std::string&); 83 84 // By default, slicer prints error messages to stdout. Users can set their own 85 // callback. 86 void set_logger(const logger_type new_logger); 87 88 } // namespace slicer 89 90