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 #pragma once
18 
19 // The `annotate` attribute always pulls the annotated (inline) function into the object files, thus
20 // we should only annotate headers when we are running versioner.
21 #if defined(__BIONIC_VERSIONER)
22 
23 #define __INTRODUCED_IN(api_level) __attribute__((annotate("introduced_in=" #api_level)))
24 #define __INTRODUCED_IN_NO_GUARD_FOR_NDK(api_level) __attribute__((annotate("introduced_in=" #api_level))) __VERSIONER_NO_GUARD
25 #define __DEPRECATED_IN(api_level) __attribute__((annotate("deprecated_in=" #api_level)))
26 #define __REMOVED_IN(api_level) __attribute__((annotate("obsoleted_in=" #api_level)))
27 #define __INTRODUCED_IN_32(api_level) __attribute__((annotate("introduced_in_32=" #api_level)))
28 #define __INTRODUCED_IN_64(api_level) __attribute__((annotate("introduced_in_64=" #api_level)))
29 #define __INTRODUCED_IN_ARM(api_level) __attribute__((annotate("introduced_in_arm=" #api_level)))
30 #define __INTRODUCED_IN_X86(api_level) __attribute__((annotate("introduced_in_x86=" #api_level)))
31 #define __INTRODUCED_IN_X86_NO_GUARD_FOR_NDK(api_level) __attribute__((annotate("introduced_in_x86=" #api_level))) __VERSIONER_NO_GUARD
32 
33 #define __VERSIONER_NO_GUARD __attribute__((annotate("versioner_no_guard")))
34 #define __VERSIONER_FORTIFY_INLINE __attribute__((annotate("versioner_fortify_inline")))
35 
36 #else
37 
38 // When headers are not processed by the versioner (i.e. compiled into object files),
39 // the availability attributed is emitted instead. The clang compiler will make the symbol weak
40 // when targeting old api_level and enforce the reference to the symbol to be guarded with
41 // __builtin_available(android api_level, *).
42 
43 // The 'strict' flag is required for NDK clients where the use of "-Wunguarded-availability" cannot
44 // be enforced. In the case, the absence of 'strict' makes it possible to call an unavailable API
45 // without the __builtin_available check, which will cause a link error at runtime.
46 // Android platform build system defines this macro along with -Wunguarded-availability
47 //
48 // The _NO_GUARD_FOR_NDK variants keep the __VERSIONER_NO_GUARD behavior working for the NDK. This
49 // allows libc++ to refer to these functions in inlines without needing to guard them, needed since
50 // libc++ doesn't currently guard these calls. There's no risk to the apps though because using
51 // those APIs will still cause a link error.
52 #if defined(__ANDROID_UNAVAILABLE_SYMBOLS_ARE_WEAK__)
53 #define __BIONIC_AVAILABILITY(__what) __attribute__((__availability__(android,__what)))
54 #define __INTRODUCED_IN_NO_GUARD_FOR_NDK(api_level) __INTRODUCED_IN_X86(api_level)
55 #define __INTRODUCED_IN_X86_NO_GUARD_FOR_NDK(api_level) __INTRODUCED_IN_X86(api_level)
56 #else
57 #define __BIONIC_AVAILABILITY(__what) __attribute__((__availability__(android,strict,__what)))
58 #define __INTRODUCED_IN_NO_GUARD_FOR_NDK(api_level)
59 #define __INTRODUCED_IN_X86_NO_GUARD_FOR_NDK(api_level)
60 #endif
61 
62 #define __INTRODUCED_IN(api_level) __BIONIC_AVAILABILITY(introduced=api_level)
63 #define __DEPRECATED_IN(api_level) __BIONIC_AVAILABILITY(deprecated=api_level)
64 #define __REMOVED_IN(api_level) __BIONIC_AVAILABILITY(obsoleted=api_level)
65 
66 // The same availability attribute can't be annotated multiple times. Therefore, the macros are
67 // defined for the configuration that it is valid for so that declarations like the below doesn't
68 // cause inconsistent availability values which is an error with -Wavailability:
69 //
70 // void foo() __INTRODUCED_IN_32(30) __INTRODUCED_IN_64(31);
71 //
72 // This also takes the advantage of the fact that we never use bitness-specific macro with
73 // arch-specific macro. In other words,
74 //
75 // void foo() __INTRODUCED_IN_ARM(30) __INTRODUCED_IN_64(31);
76 //
77 // hasn't been supported and won't be.
78 #if !defined(__LP64__)
79 #define __INTRODUCED_IN_32(api_level) __BIONIC_AVAILABILITY(introduced=api_level)
80 #define __INTRODUCED_IN_64(api_level)
81 #else
82 #define __INTRODUCED_IN_32(api_level)
83 #define __INTRODUCED_IN_64(api_level) __BIONIC_AVAILABILITY(introduced=api_level)
84 #endif
85 
86 #if defined(__arm__) || defined(__aarch64__)
87 #define __INTRODUCED_IN_ARM(api_level) __BIONIC_AVAILABILITY(introduced=api_level)
88 #define __INTRODUCED_IN_X86(api_level)
89 #elif defined(__i386__) || defined(__x86_64__)
90 #define __INTRODUCED_IN_ARM(api_level)
91 #define __INTRODUCED_IN_X86(api_level) __BIONIC_AVAILABILITY(introduced=api_level)
92 #else
93 #define __INTRODUCED_IN_ARM(api_level)
94 #define __INTRODUCED_IN_X86(api_level)
95 #endif
96 
97 #define __VERSIONER_NO_GUARD
98 #define __VERSIONER_FORTIFY_INLINE
99 
100 #endif  // defined(__BIONIC_VERSIONER)
101