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 #include <stdlib.h>
20 
21 #include <array>
22 #include <initializer_list>
23 #include <optional>
24 #include <set>
25 #include <string>
26 #include <unordered_map>
27 
28 enum class Arch : size_t {
29   arm = 0,
30   arm64,
31   riscv64,
32   x86,
33   x86_64,
34 };
35 
36 std::string to_string(const Arch& arch);
37 std::optional<Arch> arch_from_string(const std::string& name);
38 
39 template <typename T>
40 class ArchMapIterator;
41 
42 template <typename T>
43 class ArchMap {
44  public:
ArchMap()45   ArchMap() {
46   }
47 
ArchMap(std::initializer_list<std::pair<Arch,T>> initializer)48   ArchMap(std::initializer_list<std::pair<Arch, T>> initializer) {
49     for (auto& pair : initializer) {
50       this->operator[](pair.first) = pair.second;
51     }
52   }
53 
54   T& operator[](Arch arch) {
55     return data_[size_t(arch)];
56   }
57 
58   const T& operator[](Arch arch) const {
59     return data_[size_t(arch)];
60   }
61 
62   bool operator==(const ArchMap& other) const {
63     for (size_t i = 0; i < data_.size(); ++i) {
64       if (data_[i] != other.data_[i]) {
65         return false;
66       }
67     }
68     return true;
69   }
70 
begin()71   ArchMapIterator<T> begin() const {
72     return ArchMapIterator<T>(*this, Arch::arm);
73   }
74 
end()75   ArchMapIterator<T> end() const {
76     return ArchMapIterator<T>(*this, Arch(size_t(Arch::x86_64) + 1));
77   }
78 
79  private:
80   std::array<T, size_t(Arch::x86_64) + 1> data_ = {};
81 };
82 
83 template <typename T>
84 class ArchMapIterator {
85   const ArchMap<T>& map_;
86   Arch arch_ = Arch::arm;
87 
88  public:
89   ArchMapIterator() = delete;
90 
ArchMapIterator(const ArchMap<T> & map,Arch arch)91   ArchMapIterator(const ArchMap<T>& map, Arch arch) : map_(map), arch_(arch) {
92   }
93 
94   bool operator==(const ArchMapIterator<T>& rhs) const {
95     return map_ == rhs.map_ && arch_ == rhs.arch_;
96   }
97 
98   bool operator!=(const ArchMapIterator<T>& rhs) const {
99     return !(*this == rhs);
100   }
101 
102   ArchMapIterator& operator++() {
103     arch_ = Arch(size_t(arch_) + 1);
104     return *this;
105   }
106 
107   ArchMapIterator operator++(int) {
108     ArchMapIterator result = *this;
109     ++*this;
110     return result;
111   }
112 
113   std::pair<const Arch&, const T&> operator*() const {
114     return std::tie(arch_, map_[arch_]);
115   }
116 
117   std::pair<const Arch&, const T&> operator->() const {
118     return std::tie(arch_, map_[arch_]);
119   }
120 };
121 
122 static const std::set<Arch> supported_archs = {
123   Arch::arm,
124   Arch::arm64,
125   Arch::riscv64,
126   Arch::x86,
127   Arch::x86_64,
128 };
129 
130 static ArchMap<std::string> arch_targets = {
131   { Arch::arm, "arm-linux-androideabi" },
132   { Arch::arm64, "aarch64-linux-android" },
133   { Arch::riscv64, "riscv64-linux-android" },
134   { Arch::x86, "i686-linux-android" },
135   { Arch::x86_64, "x86_64-linux-android" },
136 };
137 
138 static const std::set<int> default_levels = {
139   14, 15, 16, 17, 18, 19, 21, 23, 24, 25, 26, 27, 28, 29, 30, 31, 33, 34,
140 };
141 
142 static const ArchMap<int> arch_min_api = {
143   { Arch::arm, 9 },
144   { Arch::arm64, 21 },
145   { Arch::riscv64, 10000 },
146   { Arch::x86, 9 },
147   { Arch::x86_64, 21 },
148 };
149 
150 static const std::unordered_map<std::string, int> api_codename_map{
151   {"G", 9},
152   {"I", 14},
153   {"J", 16},
154   {"J-MR1", 17},
155   {"J-MR2", 18},
156   {"K", 19},
157   {"L", 21},
158   {"L-MR1", 22},
159   {"M", 23},
160   {"N", 24},
161   {"N-MR1", 25},
162   {"O", 26},
163   {"O-MR1", 27},
164   {"P", 28},
165   {"Q", 29},
166   {"R", 30},
167   {"S", 31},
168   {"T", 33},
169   {"U", 34},
170 };
171