• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "android-base/logging.h"
22 #include "base/bit_utils.h"
23 #include "globals.h"
24 
25 namespace art {
26 
InstructionSetAbort(InstructionSet isa)27 void InstructionSetAbort(InstructionSet isa) {
28   switch (isa) {
29     case kArm:
30     case kThumb2:
31     case kArm64:
32     case kX86:
33     case kX86_64:
34     case kMips:
35     case kMips64:
36     case kNone:
37       LOG(FATAL) << "Unsupported instruction set " << isa;
38       UNREACHABLE();
39   }
40   LOG(FATAL) << "Unknown ISA " << isa;
41   UNREACHABLE();
42 }
43 
GetInstructionSetString(InstructionSet isa)44 const char* GetInstructionSetString(InstructionSet isa) {
45   switch (isa) {
46     case kArm:
47     case kThumb2:
48       return "arm";
49     case kArm64:
50       return "arm64";
51     case kX86:
52       return "x86";
53     case kX86_64:
54       return "x86_64";
55     case kMips:
56       return "mips";
57     case kMips64:
58       return "mips64";
59     case kNone:
60       return "none";
61   }
62   LOG(FATAL) << "Unknown ISA " << isa;
63   UNREACHABLE();
64 }
65 
GetInstructionSetFromString(const char * isa_str)66 InstructionSet GetInstructionSetFromString(const char* isa_str) {
67   CHECK(isa_str != nullptr);
68 
69   if (strcmp("arm", isa_str) == 0) {
70     return kArm;
71   } else if (strcmp("arm64", isa_str) == 0) {
72     return kArm64;
73   } else if (strcmp("x86", isa_str) == 0) {
74     return kX86;
75   } else if (strcmp("x86_64", isa_str) == 0) {
76     return kX86_64;
77   } else if (strcmp("mips", isa_str) == 0) {
78     return kMips;
79   } else if (strcmp("mips64", isa_str) == 0) {
80     return kMips64;
81   }
82 
83   return kNone;
84 }
85 
GetInstructionSetFromELF(uint16_t e_machine,uint32_t e_flags)86 InstructionSet GetInstructionSetFromELF(uint16_t e_machine, uint32_t e_flags) {
87   switch (e_machine) {
88     case EM_ARM:
89       return kArm;
90     case EM_AARCH64:
91       return kArm64;
92     case EM_386:
93       return kX86;
94     case EM_X86_64:
95       return kX86_64;
96     case EM_MIPS: {
97       if ((e_flags & EF_MIPS_ARCH) == EF_MIPS_ARCH_32R2 ||
98           (e_flags & EF_MIPS_ARCH) == EF_MIPS_ARCH_32R6) {
99         return kMips;
100       } else if ((e_flags & EF_MIPS_ARCH) == EF_MIPS_ARCH_64R6) {
101         return kMips64;
102       }
103       break;
104     }
105   }
106   return kNone;
107 }
108 
GetInstructionSetAlignment(InstructionSet isa)109 size_t GetInstructionSetAlignment(InstructionSet isa) {
110   switch (isa) {
111     case kArm:
112       // Fall-through.
113     case kThumb2:
114       return kArmAlignment;
115     case kArm64:
116       return kArm64Alignment;
117     case kX86:
118       // Fall-through.
119     case kX86_64:
120       return kX86Alignment;
121     case kMips:
122       // Fall-through.
123     case kMips64:
124       return kMipsAlignment;
125     case kNone:
126       LOG(FATAL) << "ISA kNone does not have alignment.";
127       UNREACHABLE();
128   }
129   LOG(FATAL) << "Unknown ISA " << isa;
130   UNREACHABLE();
131 }
132 
133 #if !defined(ART_STACK_OVERFLOW_GAP_arm) || !defined(ART_STACK_OVERFLOW_GAP_arm64) || \
134     !defined(ART_STACK_OVERFLOW_GAP_mips) || !defined(ART_STACK_OVERFLOW_GAP_mips64) || \
135     !defined(ART_STACK_OVERFLOW_GAP_x86) || !defined(ART_STACK_OVERFLOW_GAP_x86_64)
136 #error "Missing defines for stack overflow gap"
137 #endif
138 
139 static constexpr size_t kArmStackOverflowReservedBytes    = ART_STACK_OVERFLOW_GAP_arm;
140 static constexpr size_t kArm64StackOverflowReservedBytes  = ART_STACK_OVERFLOW_GAP_arm64;
141 static constexpr size_t kMipsStackOverflowReservedBytes   = ART_STACK_OVERFLOW_GAP_mips;
142 static constexpr size_t kMips64StackOverflowReservedBytes = ART_STACK_OVERFLOW_GAP_mips64;
143 static constexpr size_t kX86StackOverflowReservedBytes    = ART_STACK_OVERFLOW_GAP_x86;
144 static constexpr size_t kX86_64StackOverflowReservedBytes = ART_STACK_OVERFLOW_GAP_x86_64;
145 
146 static_assert(IsAligned<kPageSize>(kArmStackOverflowReservedBytes), "ARM gap not page aligned");
147 static_assert(IsAligned<kPageSize>(kArm64StackOverflowReservedBytes), "ARM64 gap not page aligned");
148 static_assert(IsAligned<kPageSize>(kMipsStackOverflowReservedBytes), "Mips gap not page aligned");
149 static_assert(IsAligned<kPageSize>(kMips64StackOverflowReservedBytes),
150               "Mips64 gap not page aligned");
151 static_assert(IsAligned<kPageSize>(kX86StackOverflowReservedBytes), "X86 gap not page aligned");
152 static_assert(IsAligned<kPageSize>(kX86_64StackOverflowReservedBytes),
153               "X86_64 gap not page aligned");
154 
155 #if !defined(ART_FRAME_SIZE_LIMIT)
156 #error "ART frame size limit missing"
157 #endif
158 
159 // TODO: Should we require an extra page (RoundUp(SIZE) + kPageSize)?
160 static_assert(ART_FRAME_SIZE_LIMIT < kArmStackOverflowReservedBytes, "Frame size limit too large");
161 static_assert(ART_FRAME_SIZE_LIMIT < kArm64StackOverflowReservedBytes,
162               "Frame size limit too large");
163 static_assert(ART_FRAME_SIZE_LIMIT < kMipsStackOverflowReservedBytes,
164               "Frame size limit too large");
165 static_assert(ART_FRAME_SIZE_LIMIT < kMips64StackOverflowReservedBytes,
166               "Frame size limit too large");
167 static_assert(ART_FRAME_SIZE_LIMIT < kX86StackOverflowReservedBytes,
168               "Frame size limit too large");
169 static_assert(ART_FRAME_SIZE_LIMIT < kX86_64StackOverflowReservedBytes,
170               "Frame size limit too large");
171 
GetStackOverflowReservedBytes(InstructionSet isa)172 size_t GetStackOverflowReservedBytes(InstructionSet isa) {
173   switch (isa) {
174     case kArm:      // Intentional fall-through.
175     case kThumb2:
176       return kArmStackOverflowReservedBytes;
177 
178     case kArm64:
179       return kArm64StackOverflowReservedBytes;
180 
181     case kMips:
182       return kMipsStackOverflowReservedBytes;
183 
184     case kMips64:
185       return kMips64StackOverflowReservedBytes;
186 
187     case kX86:
188       return kX86StackOverflowReservedBytes;
189 
190     case kX86_64:
191       return kX86_64StackOverflowReservedBytes;
192 
193     case kNone:
194       LOG(FATAL) << "kNone has no stack overflow size";
195       UNREACHABLE();
196   }
197   LOG(FATAL) << "Unknown instruction set" << isa;
198   UNREACHABLE();
199 }
200 
201 }  // namespace art
202