1*e582193eSAndroid Build Coastguard Worker /*
2*e582193eSAndroid Build Coastguard Worker * Copyright 2015 The Android Open Source Project
3*e582193eSAndroid Build Coastguard Worker *
4*e582193eSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*e582193eSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*e582193eSAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*e582193eSAndroid Build Coastguard Worker *
8*e582193eSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
9*e582193eSAndroid Build Coastguard Worker *
10*e582193eSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*e582193eSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*e582193eSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*e582193eSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*e582193eSAndroid Build Coastguard Worker * limitations under the License.
15*e582193eSAndroid Build Coastguard Worker *
16*e582193eSAndroid Build Coastguard Worker */
17*e582193eSAndroid Build Coastguard Worker #ifndef GOOGLE_GATEKEEPER_UTILS_H_
18*e582193eSAndroid Build Coastguard Worker #define GOOGLE_GATEKEEPER_UTILS_H_
19*e582193eSAndroid Build Coastguard Worker
20*e582193eSAndroid Build Coastguard Worker #include <string.h>
21*e582193eSAndroid Build Coastguard Worker
22*e582193eSAndroid Build Coastguard Worker namespace gatekeeper {
23*e582193eSAndroid Build Coastguard Worker /**
24*e582193eSAndroid Build Coastguard Worker * Variant of memset() that uses GCC-specific pragmas to disable optimizations, so effect is not
25*e582193eSAndroid Build Coastguard Worker * optimized away. This is important because we often need to wipe blocks of sensitive data from
26*e582193eSAndroid Build Coastguard Worker * memory. As an additional convenience, this implementation avoids writing to NULL pointers.
27*e582193eSAndroid Build Coastguard Worker */
28*e582193eSAndroid Build Coastguard Worker #ifdef __clang__
29*e582193eSAndroid Build Coastguard Worker #define OPTNONE __attribute__((optnone))
30*e582193eSAndroid Build Coastguard Worker #else // not __clang__
31*e582193eSAndroid Build Coastguard Worker #define OPTNONE __attribute__((optimize("O0")))
32*e582193eSAndroid Build Coastguard Worker #endif // not __clang__
memset_s(void * s,int c,size_t n)33*e582193eSAndroid Build Coastguard Worker inline OPTNONE void* memset_s(void* s, int c, size_t n) {
34*e582193eSAndroid Build Coastguard Worker if (!s)
35*e582193eSAndroid Build Coastguard Worker return s;
36*e582193eSAndroid Build Coastguard Worker return memset(s, c, n);
37*e582193eSAndroid Build Coastguard Worker }
38*e582193eSAndroid Build Coastguard Worker #undef OPTNONE
39*e582193eSAndroid Build Coastguard Worker
40*e582193eSAndroid Build Coastguard Worker /**
41*e582193eSAndroid Build Coastguard Worker * Return the number of elements in array \p a.
42*e582193eSAndroid Build Coastguard Worker */
array_length(const T (&)[N])43*e582193eSAndroid Build Coastguard Worker template <typename T, size_t N> inline size_t array_length(const T (&)[N]) {
44*e582193eSAndroid Build Coastguard Worker return N;
45*e582193eSAndroid Build Coastguard Worker }
46*e582193eSAndroid Build Coastguard Worker
memcmp_s(const void * p1,const void * p2,size_t length)47*e582193eSAndroid Build Coastguard Worker static inline int memcmp_s(const void* p1, const void* p2, size_t length) {
48*e582193eSAndroid Build Coastguard Worker const uint8_t* s1 = static_cast<const uint8_t*>(p1);
49*e582193eSAndroid Build Coastguard Worker const uint8_t* s2 = static_cast<const uint8_t*>(p2);
50*e582193eSAndroid Build Coastguard Worker uint8_t result = 0;
51*e582193eSAndroid Build Coastguard Worker for (; length > 0; length--)
52*e582193eSAndroid Build Coastguard Worker result |= *s1++ ^ *s2++;
53*e582193eSAndroid Build Coastguard Worker return result == 0 ? 0 : 1;
54*e582193eSAndroid Build Coastguard Worker }
55*e582193eSAndroid Build Coastguard Worker
56*e582193eSAndroid Build Coastguard Worker template<typename T> struct remove_reference {typedef T type;};
57*e582193eSAndroid Build Coastguard Worker template<typename T> struct remove_reference<T&> {typedef T type;};
58*e582193eSAndroid Build Coastguard Worker template<typename T> struct remove_reference<T&&> {typedef T type;};
59*e582193eSAndroid Build Coastguard Worker template<typename T>
60*e582193eSAndroid Build Coastguard Worker using remove_reference_t = typename remove_reference<T>::type;
61*e582193eSAndroid Build Coastguard Worker template<typename T>
62*e582193eSAndroid Build Coastguard Worker remove_reference_t<T>&& move(T&& x) {
63*e582193eSAndroid Build Coastguard Worker return static_cast<remove_reference_t<T>&&>(x);
64*e582193eSAndroid Build Coastguard Worker }
65*e582193eSAndroid Build Coastguard Worker
66*e582193eSAndroid Build Coastguard Worker template<typename T>
67*e582193eSAndroid Build Coastguard Worker constexpr T&& forward(remove_reference_t<T>& x) {
68*e582193eSAndroid Build Coastguard Worker return static_cast<T&&>(x);
69*e582193eSAndroid Build Coastguard Worker }
70*e582193eSAndroid Build Coastguard Worker template<typename T>
71*e582193eSAndroid Build Coastguard Worker constexpr T&& forward(remove_reference_t<T>&& x) {
72*e582193eSAndroid Build Coastguard Worker return static_cast<T&&>(x);
73*e582193eSAndroid Build Coastguard Worker }
74*e582193eSAndroid Build Coastguard Worker
75*e582193eSAndroid Build Coastguard Worker
76*e582193eSAndroid Build Coastguard Worker };
77*e582193eSAndroid Build Coastguard Worker #endif //GOOGLE_GATEKEEPER_UTILS_H_
78