Coverage Report

Created: 2025-12-31 06:16

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/botan/src/lib/utils/cpuid/cpuid.cpp
Line
Count
Source
1
/*
2
* Runtime CPU detection
3
* (C) 2009,2010,2013,2017,2023 Jack Lloyd
4
*
5
* Botan is released under the Simplified BSD License (see license.txt)
6
*/
7
8
#include <botan/internal/cpuid.h>
9
10
#include <botan/exceptn.h>
11
#include <botan/internal/parsing.h>
12
13
#if defined(BOTAN_HAS_OS_UTILS)
14
   #include <botan/internal/os_utils.h>
15
#endif
16
17
namespace Botan {
18
19
#if !defined(BOTAN_HAS_CPUID_DETECTION)
20
uint32_t CPUFeature::as_u32() const {
21
   throw Invalid_State("CPUFeature invalid bit");
22
}
23
24
std::optional<CPUFeature> CPUFeature::from_string(std::string_view) {
25
   return {};
26
}
27
28
std::string CPUFeature::to_string() const {
29
   throw Invalid_State("CPUFeature invalid bit");
30
}
31
#endif
32
33
//static
34
0
std::string CPUID::to_string() {
35
0
   std::vector<std::string> flags;
36
37
0
   const uint32_t bitset = state().bitset();
38
39
0
   for(size_t i = 0; i != 32; ++i) {
40
0
      const uint32_t b = static_cast<uint32_t>(1) << i;
41
0
      if((bitset & b) == b) {
42
         // NOLINTNEXTLINE(clang-analyzer-optin.core.EnumCastOutOfRange)
43
0
         flags.push_back(CPUFeature(static_cast<CPUFeature::Bit>(b)).to_string());
44
0
      }
45
0
   }
46
47
0
   return string_join(flags, ' ');
48
0
}
49
50
//static
51
0
void CPUID::initialize() {
52
0
   state() = CPUID_Data();
53
0
}
54
55
#if defined(BOTAN_HAS_CPUID_DETECTION)
56
57
namespace {
58
59
0
uint32_t cleared_cpuid_bits() {
60
0
   uint32_t cleared = 0;
61
62
0
   #if defined(BOTAN_HAS_OS_UTILS)
63
0
   std::string clear_cpuid_env;
64
0
   if(OS::read_env_variable(clear_cpuid_env, "BOTAN_CLEAR_CPUID")) {
65
0
      for(const auto& cpuid : split_on(clear_cpuid_env, ',')) {
66
0
         if(auto bit = CPUID::bit_from_string(cpuid)) {
67
0
            cleared |= bit->as_u32();
68
0
         }
69
0
      }
70
0
   }
71
0
   #endif
72
73
0
   return cleared;
74
0
}
75
76
}  // namespace
77
78
#endif
79
80
0
CPUID::CPUID_Data::CPUID_Data() {
81
   // NOLINTBEGIN(*-prefer-member-initializer)
82
0
#if defined(BOTAN_HAS_CPUID_DETECTION)
83
0
   m_processor_features = detect_cpu_features(~cleared_cpuid_bits());
84
#else
85
   m_processor_features = 0;
86
#endif
87
   // NOLINTEND(*-prefer-member-initializer)
88
0
}
89
90
0
std::optional<CPUFeature> CPUID::bit_from_string(std::string_view tok) {
91
0
   return CPUFeature::from_string(tok);
92
0
}
93
94
}  // namespace Botan