1 /*
2 * Copyright (C) 2011 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 "instruction_set.h"
18
19 #include "android-base/logging.h"
20 #include "android-base/properties.h"
21 #include "android-base/stringprintf.h"
22 #include "base/bit_utils.h"
23 #include "base/globals.h"
24
25 namespace art {
26
InstructionSetAbort(InstructionSet isa)27 void InstructionSetAbort(InstructionSet isa) {
28 switch (isa) {
29 case InstructionSet::kArm:
30 case InstructionSet::kThumb2:
31 case InstructionSet::kArm64:
32 case InstructionSet::kRiscv64:
33 case InstructionSet::kX86:
34 case InstructionSet::kX86_64:
35 case InstructionSet::kNone:
36 LOG(FATAL) << "Unsupported instruction set " << isa;
37 UNREACHABLE();
38 }
39 }
40
GetInstructionSetString(InstructionSet isa)41 const char* GetInstructionSetString(InstructionSet isa) {
42 switch (isa) {
43 case InstructionSet::kArm:
44 case InstructionSet::kThumb2:
45 return "arm";
46 case InstructionSet::kArm64:
47 return "arm64";
48 case InstructionSet::kRiscv64:
49 return "riscv64";
50 case InstructionSet::kX86:
51 return "x86";
52 case InstructionSet::kX86_64:
53 return "x86_64";
54 case InstructionSet::kNone:
55 return "none";
56 }
57 }
58
GetInstructionSetFromString(const char * isa_str)59 InstructionSet GetInstructionSetFromString(const char* isa_str) {
60 CHECK(isa_str != nullptr);
61
62 if (strcmp("arm", isa_str) == 0) {
63 return InstructionSet::kArm;
64 } else if (strcmp("arm64", isa_str) == 0) {
65 return InstructionSet::kArm64;
66 } else if (strcmp("riscv64", isa_str) == 0) {
67 return InstructionSet::kRiscv64;
68 } else if (strcmp("x86", isa_str) == 0) {
69 return InstructionSet::kX86;
70 } else if (strcmp("x86_64", isa_str) == 0) {
71 return InstructionSet::kX86_64;
72 }
73
74 return InstructionSet::kNone;
75 }
76
GetSupportedInstructionSets(std::string * error_msg)77 std::vector<InstructionSet> GetSupportedInstructionSets(std::string* error_msg) {
78 std::string zygote_kinds = android::base::GetProperty("ro.zygote", {});
79 if (zygote_kinds.empty()) {
80 *error_msg = "Unable to get Zygote kinds";
81 return {};
82 }
83
84 switch (kRuntimeISA) {
85 case InstructionSet::kArm:
86 case InstructionSet::kArm64:
87 if (zygote_kinds == "zygote64_32" || zygote_kinds == "zygote32_64") {
88 return {InstructionSet::kArm64, InstructionSet::kArm};
89 } else if (zygote_kinds == "zygote64") {
90 return {InstructionSet::kArm64};
91 } else if (zygote_kinds == "zygote32") {
92 return {InstructionSet::kArm};
93 } else {
94 *error_msg = android::base::StringPrintf("Unknown Zygote kinds '%s'", zygote_kinds.c_str());
95 return {};
96 }
97 case InstructionSet::kRiscv64:
98 return {InstructionSet::kRiscv64};
99 case InstructionSet::kX86:
100 case InstructionSet::kX86_64:
101 if (zygote_kinds == "zygote64_32" || zygote_kinds == "zygote32_64") {
102 return {InstructionSet::kX86_64, InstructionSet::kX86};
103 } else if (zygote_kinds == "zygote64") {
104 return {InstructionSet::kX86_64};
105 } else if (zygote_kinds == "zygote32") {
106 return {InstructionSet::kX86};
107 } else {
108 *error_msg = android::base::StringPrintf("Unknown Zygote kinds '%s'", zygote_kinds.c_str());
109 return {};
110 }
111 default:
112 *error_msg = android::base::StringPrintf("Unknown runtime ISA '%s'",
113 GetInstructionSetString(kRuntimeISA));
114 return {};
115 }
116 }
117
118 namespace instruction_set_details {
119
120 #if !defined(ART_FRAME_SIZE_LIMIT)
121 #error "ART frame size limit missing"
122 #endif
123
124 // TODO: Should we require an extra page (RoundUp(SIZE) + gPageSize)?
125 static_assert(ART_FRAME_SIZE_LIMIT < kArmStackOverflowReservedBytes, "Frame size limit too large");
126 static_assert(ART_FRAME_SIZE_LIMIT < kArm64StackOverflowReservedBytes,
127 "Frame size limit too large");
128 static_assert(ART_FRAME_SIZE_LIMIT < kRiscv64StackOverflowReservedBytes,
129 "Frame size limit too large");
130 static_assert(ART_FRAME_SIZE_LIMIT < kX86StackOverflowReservedBytes,
131 "Frame size limit too large");
132 static_assert(ART_FRAME_SIZE_LIMIT < kX86_64StackOverflowReservedBytes,
133 "Frame size limit too large");
134
GetStackOverflowReservedBytesFailure(const char * error_msg)135 NO_RETURN void GetStackOverflowReservedBytesFailure(const char* error_msg) {
136 LOG(FATAL) << error_msg;
137 UNREACHABLE();
138 }
139
140 } // namespace instruction_set_details
141
142 } // namespace art
143