1/* 2 * Copyright (C) 2016 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#ifndef CONSCRYPT_SRC_MAIN_NATIVE_MACROS_H_ 18#define CONSCRYPT_SRC_MAIN_NATIVE_MACROS_H_ 19 20#define TO_STRING1(x) #x 21#define TO_STRING(x) TO_STRING1(x) 22#ifndef JNI_JARJAR_PREFIX 23#ifndef CONSCRYPT_NOT_UNBUNDLED 24#define CONSCRYPT_UNBUNDLED 25#endif 26#define JNI_JARJAR_PREFIX 27#endif 28 29// The FALLTHROUGH_INTENDED macro can be used to annotate implicit fall-through 30// between switch labels: 31// switch (x) { 32// case 40: 33// case 41: 34// if (truth_is_out_there) { 35// ++x; 36// FALLTHROUGH_INTENDED; // Use instead of/along with annotations in 37// // comments. 38// } else { 39// return x; 40// } 41// case 42: 42// ... 43// 44// As shown in the example above, the FALLTHROUGH_INTENDED macro should be 45// followed by a semicolon. It is designed to mimic control-flow statements 46// like 'break;', so it can be placed in most places where 'break;' can, but 47// only if there are no statements on the execution path between it and the 48// next switch label. 49// 50// When compiled with clang in C++11 mode, the FALLTHROUGH_INTENDED macro is 51// expanded to [[clang::fallthrough]] attribute, which is analysed when 52// performing switch labels fall-through diagnostic ('-Wimplicit-fallthrough'). 53// See clang documentation on language extensions for details: 54// http://clang.llvm.org/docs/LanguageExtensions.html#clang__fallthrough 55// 56// When used with unsupported compilers, the FALLTHROUGH_INTENDED macro has no 57// effect on diagnostics. 58// 59// In either case this macro has no effect on runtime behavior and performance 60// of code. 61#if defined(__clang__) && __cplusplus >= 201103L && defined(__has_warning) 62#if __has_feature(cxx_attributes) && __has_warning("-Wimplicit-fallthrough") 63#define FALLTHROUGH_INTENDED [[clang::fallthrough]] // NOLINT 64#endif 65#endif 66 67#ifndef FALLTHROUGH_INTENDED 68#define FALLTHROUGH_INTENDED \ 69 do { \ 70 } while (0) 71#endif 72 73#if defined _WIN32 || defined __CYGWIN__ 74#ifdef __GNUC__ 75#define CONSCRYPT_PUBLIC __attribute__((dllexport)) 76#else 77#define CONSCRYPT_PUBLIC __declspec(dllexport) 78#endif 79#define CONSCRYPT_LOCAL 80#else 81#if __GNUC__ >= 4 82#define CONSCRYPT_PUBLIC __attribute__((visibility("default"))) 83#define CONSCRYPT_LOCAL __attribute__((visibility("hidden"))) 84#else 85#define CONSCRYPT_PUBLIC 86#define CONSCRYPT_LOCAL 87#endif 88#endif 89 90#ifdef __GNUC__ 91#define CONSCRYPT_UNUSED __attribute__((unused)) 92#define CONSCRYPT_WARN_UNUSED __attribute__((warn_unused_result)) 93#elif defined(_WIN32) 94#define CONSCRYPT_UNUSED __pragma(warning(suppress : 4100)) 95#define CONSCRYPT_WARN_UNUSED _Check_return_ 96#else 97#define CONSCRYPT_UNUSED 98#define CONSCRYPT_WARN_UNUSED 99#endif 100 101#ifndef NELEM 102#define NELEM(x) ((int)(sizeof(x) / sizeof((x)[0]))) 103#endif 104 105/** 106 * Many OpenSSL APIs take ownership of an argument on success but don't free the argument 107 * on failure. This means we need to tell our scoped pointers when we've transferred ownership, 108 * without triggering a warning by not using the result of release(). 109 */ 110#define OWNERSHIP_TRANSFERRED(obj) \ 111 do { \ 112 decltype((obj).release()) CONSCRYPT_UNUSED _dummy = (obj).release(); \ 113 } while (0) 114 115/** 116 * UNUSED_ARGUMENT can be used to mark an, otherwise unused, argument as "used" 117 * for the purposes of -Werror=unused-parameter. This can be needed when an 118 * argument's use is based on an #ifdef. 119 */ 120#define UNUSED_ARGUMENT(x) ((void)(x)); 121 122/** 123 * Check array bounds for arguments when an array and offset are given. 124 */ 125#define ARRAY_OFFSET_INVALID(array, offset) \ 126 ((offset) < 0 || (offset) > static_cast<ssize_t>((array).size())) 127 128/** 129 * Check array bounds for arguments when an array, offset, and length are given. 130 */ 131#define ARRAY_OFFSET_LENGTH_INVALID(array, offset, len) \ 132 ((offset) < 0 || (offset) > static_cast<ssize_t>((array).size()) || (len) < 0 || \ 133 (len) > static_cast<ssize_t>((array).size()) - (offset)) 134 135/** 136 * Check array bounds for arguments when an array length, chunk offset, and chunk length are given. 137 */ 138#define ARRAY_CHUNK_INVALID(array_len, chunk_offset, chunk_len) \ 139 ((chunk_offset) < 0 || (chunk_offset) > static_cast<ssize_t>(array_len) || (chunk_len) < 0 || \ 140 (chunk_len) > static_cast<ssize_t>(array_len) - (chunk_offset)) 141 142// Define logging macros... 143 144#define LOG_TAG "NativeCrypto" 145 146#ifndef CONSCRYPT_UNBUNDLED 147 148#include <log/log.h> 149 150#elif defined(ANDROID) && !defined(CONSCRYPT_OPENJDK) 151 152#include <android/log.h> 153#ifndef ALOG 154#define ALOG(priority, tag, ...) __android_log_print(ANDROID_##priority, tag, __VA_ARGS__) 155#endif 156#ifndef ALOGD 157#define ALOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__) 158#endif 159#ifndef ALOGE 160#define ALOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__) 161#endif 162 163#ifndef __ALOGV 164#define __ALOGV(...) __android_log_print(ANDROID_LOG_VERBOSE, LOG_TAG, __VA_ARGS__) 165#endif 166#ifndef ALOGV 167#if LOG_NDEBUG 168#define ALOGV(...) \ 169 do { \ 170 if (0) { \ 171 __ALOGV(__VA_ARGS__); \ 172 } \ 173 } while (0) 174#else 175#define ALOGV(...) __ALOGV(__VA_ARGS__) 176#endif 177#endif 178 179#else // !ANDROID 180 181#define LOG_INFO ((void)0) 182 183#define ALOG(...) VA_ARGS_UNUSED(__VA_ARGS__) 184#define ALOGD(...) VA_ARGS_UNUSED(__VA_ARGS__) 185#define ALOGE(...) VA_ARGS_UNUSED(__VA_ARGS__) 186#define ALOGV(...) VA_ARGS_UNUSED(__VA_ARGS__) 187 188#define UNUSED_1(a) ((void)(a)) 189#define UNUSED_2(a, b) ((void)(a)), UNUSED_1(b) 190#define UNUSED_3(a, b, c) ((void)(a)), UNUSED_2(b, c) 191#define UNUSED_4(a, b, c, d) ((void)(a)), UNUSED_3(b, c, d) 192#define UNUSED_5(a, b, c, d, e) ((void)(a)), UNUSED_4(b, c, d, e) 193#define UNUSED_6(a, b, c, d, e, f) ((void)(a)), UNUSED_5(b, c, d, e, f) 194#define UNUSED_7(a, b, c, d, e, f, g) ((void)(a)), UNUSED_6(b, c, d, e, f, g) 195#define UNUSED_8(a, b, c, d, e, f, g, h) ((void)(a)), UNUSED_7(b, c, d, e, f, g, h) 196#define UNUSED_9(a, b, c, d, e, f, g, h, i) ((void)(a)), UNUSED_8(b, c, d, e, f, g, h, i) 197#define UNUSED_10(a, b, c, d, e, f, g, h, i, j) ((void)(a)), UNUSED_9(b, c, d, e, f, g, h, i, j) 198#define UNUSED_11(a, b, c, d, e, f, g, h, i, j, k) \ 199 ((void)(a)), UNUSED_10(b, c, d, e, f, g, h, i, j, k) 200#define UNUSED_12(a, b, c, d, e, f, g, h, i, j, k, l) \ 201 ((void)(a)), UNUSED_11(b, c, d, e, f, g, h, i, j, k, l) 202#define UNUSED_13(a, b, c, d, e, f, g, h, i, j, k, l, m) \ 203 ((void)(a)), UNUSED_12(b, c, d, e, f, g, h, i, j, k, l, m) 204#define UNUSED_14(a, b, c, d, e, f, g, h, i, j, k, l, m, n) \ 205 ((void)(a)), UNUSED_13(b, c, d, e, f, g, h, i, j, k, l, m, n) 206 207#define VA_ARGS_UNUSED_IMPL_(num) UNUSED_##num 208#define VA_ARGS_UNUSED_IMPL(num) VA_ARGS_UNUSED_IMPL_(num) 209 210#define VA_NARGS_IMPL(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, N, ...) N 211#define VA_NARGS(...) VA_NARGS_IMPL(__VA_ARGS__, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1) 212 213#define VA_ARGS_UNUSED(...) VA_ARGS_UNUSED_IMPL(VA_NARGS(__VA_ARGS__))(__VA_ARGS__) 214 215#endif // !ANDROID 216 217#endif // CONSCRYPT_SRC_MAIN_NATIVE_MACROS_H_ 218