• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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