• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2020 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 #include "berberis/base/config_globals.h"
18 
19 #include <bitset>
20 #include <cerrno>
21 #include <cstdint>
22 #include <cstdlib>  // strtoull
23 #include <string>
24 
25 #include "berberis/base/logging.h"
26 #include "berberis/base/strings.h"
27 
28 namespace berberis {
29 
30 namespace {
31 
ToString(ConfigFlag flag)32 std::string ToString(ConfigFlag flag) {
33   switch (flag) {
34     case kVerboseTranslation:
35       return "verbose-translation";
36     case kAccurateSigsegv:
37       return "accurate-sigsegv";
38     case kTopByteIgnore:
39       return "top-byte-ignore";
40     case kDisableRegMap:
41       return "disable-reg-map";
42     case kEnableDisjointRegionsTranslation:
43       return "enable-disjoint-regions-translation";
44     case kDisableIntrinsicInlining:
45       return "disable-intrinsic-inlining";
46     case kMergeProfilesForSameModeRegions:
47       return "merge-profiles-for-same-mode-regions";
48     case kPrintTranslatedAddrs:
49       return "print-translated-addrs";
50     case kPrintIRs:
51       return "print-irs";
52     case kPrintCodePoolSize:
53       return "print-code-pool-size";
54     case kLocalExperiment:
55       return "local-experiment";
56     case kPlatformCustomCPUCapability:
57       return "platform-custom-cpu-capability";
58     case kNumConfigFlags:
59       break;
60   }
61   return "<unknown-config-flag>";
62 }
63 
MakeConfigFlagsSet()64 std::bitset<kNumConfigFlags> MakeConfigFlagsSet() {
65   ConfigStr var("BERBERIS_FLAGS", "ro.berberis.flags");
66   std::bitset<kNumConfigFlags> flags_set;
67   if (!var.get()) {
68     return flags_set;
69   }
70   auto token_vector = Split(var.get(), ",");
71   for (const auto& token : token_vector) {
72     bool found = false;
73     for (int flag = 0; flag < kNumConfigFlags; flag++) {
74       if (token == ToString(ConfigFlag(flag))) {
75         flags_set.set(flag);
76         found = true;
77         break;
78       }
79     }
80     if (!found) {
81       ALOGW("Unrecognized config flag '%s' - ignoring", token.c_str());
82     }
83   }
84   return flags_set;
85 }
86 
ParseAddr(const char * addr_cstr)87 uintptr_t ParseAddr(const char* addr_cstr) {
88   if (!addr_cstr) {
89     return 0;
90   }
91   char* end_ptr = nullptr;
92   errno = 0;
93   uintptr_t addr = static_cast<uintptr_t>(strtoull(addr_cstr, &end_ptr, 16));
94 
95   // Warning: setting errno on failure is implementation defined. So we also use extra heuristics.
96   if (errno != 0 || (*end_ptr != '\n' && *end_ptr != '\0')) {
97     ALOGE("Cannot convert \"%s\" to integer: %s\n",
98           addr_cstr,
99           errno != 0 ? strerror(errno) : "unexpected end of string");
100     return 0;
101   }
102   return addr;
103 }
104 
105 }  // namespace
106 
GetTracingConfig()107 const char* GetTracingConfig() {
108   static ConfigStr var("BERBERIS_TRACING", "berberis.tracing");
109   return var.get();
110 }
111 
GetTranslationModeConfig()112 const char* GetTranslationModeConfig() {
113   static ConfigStr var("BERBERIS_MODE", "berberis.mode");
114   return var.get();
115 }
116 
GetProfilingConfig()117 const char* GetProfilingConfig() {
118   static ConfigStr var("BERBERIS_PROFILING", "berberis.profiling");
119   return var.get();
120 }
121 
GetEntryPointOverride()122 uintptr_t GetEntryPointOverride() {
123   static ConfigStr var("BERBERIS_ENTRY_POINT", "berberis.entry_point");
124   static uintptr_t entry_point = ParseAddr(var.get());
125   return entry_point;
126 }
127 
IsConfigFlagSet(ConfigFlag flag)128 bool IsConfigFlagSet(ConfigFlag flag) {
129   static auto flags_set = MakeConfigFlagsSet();
130   return flags_set.test(flag);
131 }
132 
133 }  // namespace berberis
134