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 // Explicitly include our own elf.h to avoid Linux and other dependencies.
20 #include "../elf.h"
21 #include "globals.h"
22
23 namespace art {
24
GetInstructionSetString(const InstructionSet isa)25 const char* GetInstructionSetString(const InstructionSet isa) {
26 switch (isa) {
27 case kArm:
28 case kThumb2:
29 return "arm";
30 case kArm64:
31 return "arm64";
32 case kX86:
33 return "x86";
34 case kX86_64:
35 return "x86_64";
36 case kMips:
37 return "mips";
38 case kMips64:
39 return "mips64";
40 case kNone:
41 return "none";
42 default:
43 LOG(FATAL) << "Unknown ISA " << isa;
44 UNREACHABLE();
45 }
46 }
47
GetInstructionSetFromString(const char * isa_str)48 InstructionSet GetInstructionSetFromString(const char* isa_str) {
49 CHECK(isa_str != nullptr);
50
51 if (strcmp("arm", isa_str) == 0) {
52 return kArm;
53 } else if (strcmp("arm64", isa_str) == 0) {
54 return kArm64;
55 } else if (strcmp("x86", isa_str) == 0) {
56 return kX86;
57 } else if (strcmp("x86_64", isa_str) == 0) {
58 return kX86_64;
59 } else if (strcmp("mips", isa_str) == 0) {
60 return kMips;
61 } else if (strcmp("mips64", isa_str) == 0) {
62 return kMips64;
63 }
64
65 return kNone;
66 }
67
GetInstructionSetFromELF(uint16_t e_machine,uint32_t e_flags)68 InstructionSet GetInstructionSetFromELF(uint16_t e_machine, uint32_t e_flags) {
69 switch (e_machine) {
70 case EM_ARM:
71 return kArm;
72 case EM_AARCH64:
73 return kArm64;
74 case EM_386:
75 return kX86;
76 case EM_X86_64:
77 return kX86_64;
78 case EM_MIPS: {
79 if ((e_flags & EF_MIPS_ARCH) == EF_MIPS_ARCH_32R2 ||
80 (e_flags & EF_MIPS_ARCH) == EF_MIPS_ARCH_32R6) {
81 return kMips;
82 } else if ((e_flags & EF_MIPS_ARCH) == EF_MIPS_ARCH_64R6) {
83 return kMips64;
84 }
85 break;
86 }
87 }
88 return kNone;
89 }
90
GetInstructionSetAlignment(InstructionSet isa)91 size_t GetInstructionSetAlignment(InstructionSet isa) {
92 switch (isa) {
93 case kArm:
94 // Fall-through.
95 case kThumb2:
96 return kArmAlignment;
97 case kArm64:
98 return kArm64Alignment;
99 case kX86:
100 // Fall-through.
101 case kX86_64:
102 return kX86Alignment;
103 case kMips:
104 // Fall-through.
105 case kMips64:
106 return kMipsAlignment;
107 case kNone:
108 LOG(FATAL) << "ISA kNone does not have alignment.";
109 UNREACHABLE();
110 default:
111 LOG(FATAL) << "Unknown ISA " << isa;
112 UNREACHABLE();
113 }
114 }
115
116 static constexpr size_t kDefaultStackOverflowReservedBytes = 16 * KB;
117 static constexpr size_t kMipsStackOverflowReservedBytes = kDefaultStackOverflowReservedBytes;
118 static constexpr size_t kMips64StackOverflowReservedBytes = kDefaultStackOverflowReservedBytes;
119
120 static constexpr size_t kArmStackOverflowReservedBytes = 8 * KB;
121 static constexpr size_t kArm64StackOverflowReservedBytes = 8 * KB;
122 static constexpr size_t kX86StackOverflowReservedBytes = 8 * KB;
123 static constexpr size_t kX86_64StackOverflowReservedBytes = 8 * KB;
124
GetStackOverflowReservedBytes(InstructionSet isa)125 size_t GetStackOverflowReservedBytes(InstructionSet isa) {
126 switch (isa) {
127 case kArm: // Intentional fall-through.
128 case kThumb2:
129 return kArmStackOverflowReservedBytes;
130
131 case kArm64:
132 return kArm64StackOverflowReservedBytes;
133
134 case kMips:
135 return kMipsStackOverflowReservedBytes;
136
137 case kMips64:
138 return kMips64StackOverflowReservedBytes;
139
140 case kX86:
141 return kX86StackOverflowReservedBytes;
142
143 case kX86_64:
144 return kX86_64StackOverflowReservedBytes;
145
146 case kNone:
147 LOG(FATAL) << "kNone has no stack overflow size";
148 UNREACHABLE();
149
150 default:
151 LOG(FATAL) << "Unknown instruction set" << isa;
152 UNREACHABLE();
153 }
154 }
155
156 } // namespace art
157