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