• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2017 Google LLC
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //    http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include "cpu_features_macros.h"
16 
17 #ifdef CPU_FEATURES_ARCH_AARCH64
18 #if defined(CPU_FEATURES_OS_LINUX) || defined(CPU_FEATURES_OS_ANDROID)
19 
20 #include "impl_aarch64__base_implementation.inl"
21 
HandleAarch64Line(const LineResult result,Aarch64Info * const info)22 static bool HandleAarch64Line(const LineResult result,
23                               Aarch64Info* const info) {
24   StringView line = result.line;
25   StringView key, value;
26   if (CpuFeatures_StringView_GetAttributeKeyValue(line, &key, &value)) {
27     if (CpuFeatures_StringView_IsEquals(key, str("Features"))) {
28       for (size_t i = 0; i < AARCH64_LAST_; ++i) {
29         kSetters[i](&info->features, CpuFeatures_StringView_HasWord(
30                                          value, kCpuInfoFlags[i], ' '));
31       }
32     } else if (CpuFeatures_StringView_IsEquals(key, str("CPU implementer"))) {
33       info->implementer = CpuFeatures_StringView_ParsePositiveNumber(value);
34     } else if (CpuFeatures_StringView_IsEquals(key, str("CPU variant"))) {
35       info->variant = CpuFeatures_StringView_ParsePositiveNumber(value);
36     } else if (CpuFeatures_StringView_IsEquals(key, str("CPU part"))) {
37       info->part = CpuFeatures_StringView_ParsePositiveNumber(value);
38     } else if (CpuFeatures_StringView_IsEquals(key, str("CPU revision"))) {
39       info->revision = CpuFeatures_StringView_ParsePositiveNumber(value);
40     }
41   }
42   return !result.eof;
43 }
44 
FillProcCpuInfoData(Aarch64Info * const info)45 static void FillProcCpuInfoData(Aarch64Info* const info) {
46   const int fd = CpuFeatures_OpenFile("/proc/cpuinfo");
47   if (fd >= 0) {
48     StackLineReader reader;
49     StackLineReader_Initialize(&reader, fd);
50     for (;;) {
51       if (!HandleAarch64Line(StackLineReader_NextLine(&reader), info)) {
52         break;
53       }
54     }
55     CpuFeatures_CloseFile(fd);
56   }
57 }
58 
59 static const Aarch64Info kEmptyAarch64Info;
60 
GetAarch64Info(void)61 Aarch64Info GetAarch64Info(void) {
62   // capabilities are fetched from both getauxval and /proc/cpuinfo so we can
63   // have some information if the executable is sandboxed (aka no access to
64   // /proc/cpuinfo).
65   Aarch64Info info = kEmptyAarch64Info;
66 
67   FillProcCpuInfoData(&info);
68   const HardwareCapabilities hwcaps = CpuFeatures_GetHardwareCapabilities();
69   for (size_t i = 0; i < AARCH64_LAST_; ++i) {
70     if (CpuFeatures_IsHwCapsSet(kHardwareCapabilities[i], hwcaps)) {
71       kSetters[i](&info.features, true);
72     }
73   }
74 
75   return info;
76 }
77 
78 #endif  // defined(CPU_FEATURES_OS_LINUX) || defined(CPU_FEATURES_OS_ANDROID)
79 #endif  // CPU_FEATURES_ARCH_AARCH64
80