macros.h revision 5fdfec1dbfefa9ac64e464fcd43038bceed6544b
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_ATTRIBUTE_1(value) __attribute__(value)
92#else
93#define CONSCRYPT_ATTRIBUTE_1(value)
94#endif
95
96#define CONSCRYPT_NATIVE_METHOD(className, functionName, signature) \
97    {                                                               \
98        (char*)#functionName, (char*)(signature),                   \
99                reinterpret_cast<void*>(className##_##functionName) \
100    }
101
102#ifndef NELEM
103#define NELEM(x) ((int)(sizeof(x) / sizeof((x)[0])))
104#endif
105
106/**
107 * Many OpenSSL APIs take ownership of an argument on success but don't free the argument
108 * on failure. This means we need to tell our scoped pointers when we've transferred ownership,
109 * without triggering a warning by not using the result of release().
110 */
111#define OWNERSHIP_TRANSFERRED(obj)                                                          \
112    do {                                                                                    \
113        decltype((obj).release()) _dummy CONSCRYPT_ATTRIBUTE_1((unused)) = (obj).release(); \
114    } while (0)
115
116/**
117 * UNUSED_ARGUMENT can be used to mark an, otherwise unused, argument as "used"
118 * for the purposes of -Werror=unused-parameter. This can be needed when an
119 * argument's use is based on an #ifdef.
120 */
121#define UNUSED_ARGUMENT(x) ((void)(x));
122
123/**
124 * Check array bounds for arguments when an array and offset are given.
125 */
126#define ARRAY_OFFSET_INVALID(array, offset) \
127    ((offset) < 0 || (offset) > static_cast<ssize_t>((array).size()))
128
129/**
130 * Check array bounds for arguments when an array, offset, and length are given.
131 */
132#define ARRAY_OFFSET_LENGTH_INVALID(array, offset, len)                              \
133    ((offset) < 0 || (offset) > static_cast<ssize_t>((array).size()) || (len) < 0 || \
134     (len) > static_cast<ssize_t>((array).size()) - (offset))
135
136/**
137 * Check array bounds for arguments when an array length, chunk offset, and chunk length are given.
138 */
139#define ARRAY_CHUNK_INVALID(array_len, chunk_offset, chunk_len)                                   \
140    ((chunk_offset) < 0 || (chunk_offset) > static_cast<ssize_t>(array_len) || (chunk_len) < 0 || \
141     (chunk_len) > static_cast<ssize_t>(array_len) - (chunk_offset))
142
143// Define logging macros...
144
145#define LOG_TAG "NativeCrypto"
146
147#ifndef CONSCRYPT_UNBUNDLED
148
149#include <log/log.h>
150
151#elif defined(ANDROID) && !defined(CONSCRYPT_OPENJDK)
152
153#include <android/log.h>
154#ifndef ALOG
155#define ALOG(priority, tag, ...) __android_log_print(ANDROID_##priority, tag, __VA_ARGS__)
156#endif
157#ifndef ALOGD
158#define ALOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)
159#endif
160#ifndef ALOGE
161#define ALOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)
162#endif
163
164#ifndef __ALOGV
165#define __ALOGV(...) __android_log_print(ANDROID_LOG_VERBOSE, LOG_TAG, __VA_ARGS__)
166#endif
167#ifndef ALOGV
168#if LOG_NDEBUG
169#define ALOGV(...)                \
170    do {                          \
171        if (0) {                  \
172            __ALOGV(__VA_ARGS__); \
173        }                         \
174    } while (0)
175#else
176#define ALOGV(...) __ALOGV(__VA_ARGS__)
177#endif
178#endif
179
180#else  // !ANDROID
181
182#define LOG_INFO ((void)0)
183
184#define ALOG(...) VA_ARGS_UNUSED(__VA_ARGS__)
185#define ALOGD(...) VA_ARGS_UNUSED(__VA_ARGS__)
186#define ALOGE(...) VA_ARGS_UNUSED(__VA_ARGS__)
187#define ALOGV(...) VA_ARGS_UNUSED(__VA_ARGS__)
188
189#define UNUSED_1(a) ((void)(a))
190#define UNUSED_2(a, b) ((void)(a)), UNUSED_1(b)
191#define UNUSED_3(a, b, c) ((void)(a)), UNUSED_2(b, c)
192#define UNUSED_4(a, b, c, d) ((void)(a)), UNUSED_3(b, c, d)
193#define UNUSED_5(a, b, c, d, e) ((void)(a)), UNUSED_4(b, c, d, e)
194#define UNUSED_6(a, b, c, d, e, f) ((void)(a)), UNUSED_5(b, c, d, e, f)
195#define UNUSED_7(a, b, c, d, e, f, g) ((void)(a)), UNUSED_6(b, c, d, e, f, g)
196#define UNUSED_8(a, b, c, d, e, f, g, h) ((void)(a)), UNUSED_7(b, c, d, e, f, g, h)
197#define UNUSED_9(a, b, c, d, e, f, g, h, i) ((void)(a)), UNUSED_8(b, c, d, e, f, g, h, i)
198#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)
199#define UNUSED_11(a, b, c, d, e, f, g, h, i, j, k) \
200    ((void)(a)), UNUSED_10(b, c, d, e, f, g, h, i, j, k)
201#define UNUSED_12(a, b, c, d, e, f, g, h, i, j, k, l) \
202    ((void)(a)), UNUSED_11(b, c, d, e, f, g, h, i, j, k, l)
203#define UNUSED_13(a, b, c, d, e, f, g, h, i, j, k, l, m) \
204    ((void)(a)), UNUSED_12(b, c, d, e, f, g, h, i, j, k, l, m)
205#define UNUSED_14(a, b, c, d, e, f, g, h, i, j, k, l, m, n) \
206    ((void)(a)), UNUSED_13(b, c, d, e, f, g, h, i, j, k, l, m, n)
207
208#define VA_ARGS_UNUSED_IMPL_(num) UNUSED_##num
209#define VA_ARGS_UNUSED_IMPL(num) VA_ARGS_UNUSED_IMPL_(num)
210
211#define VA_NARGS_IMPL(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, N, ...) N
212#define VA_NARGS(...) VA_NARGS_IMPL(__VA_ARGS__, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1)
213
214#define VA_ARGS_UNUSED(...) VA_ARGS_UNUSED_IMPL(VA_NARGS(__VA_ARGS__))(__VA_ARGS__)
215
216#endif  // !ANDROID
217
218#endif  // CONSCRYPT_SRC_MAIN_NATIVE_MACROS_H_
219