blob: 8f64dcd30653396abf166945faebfb9f25a834da [file] [log] [blame]
Ian Rogersd582fa42014-11-05 23:46:43 -08001/*
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
Andreas Gampe6f611412015-01-21 22:25:24 -080019// Explicitly include our own elf.h to avoid Linux and other dependencies.
20#include "../elf.h"
Andreas Gamped1262282016-08-11 18:35:58 -070021#include "base/bit_utils.h"
Andreas Gampebda1d602016-08-29 17:43:45 -070022#include "base/logging.h"
Ian Rogersd582fa42014-11-05 23:46:43 -080023#include "globals.h"
24
25namespace art {
26
Andreas Gampebda1d602016-08-29 17:43:45 -070027void 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 default:
41 LOG(FATAL) << "Unknown ISA " << isa;
42 UNREACHABLE();
43 }
44}
45
46const char* GetInstructionSetString(InstructionSet isa) {
Ian Rogersd582fa42014-11-05 23:46:43 -080047 switch (isa) {
48 case kArm:
49 case kThumb2:
50 return "arm";
51 case kArm64:
52 return "arm64";
53 case kX86:
54 return "x86";
55 case kX86_64:
56 return "x86_64";
57 case kMips:
58 return "mips";
59 case kMips64:
60 return "mips64";
61 case kNone:
62 return "none";
63 default:
64 LOG(FATAL) << "Unknown ISA " << isa;
65 UNREACHABLE();
66 }
67}
68
69InstructionSet GetInstructionSetFromString(const char* isa_str) {
70 CHECK(isa_str != nullptr);
71
72 if (strcmp("arm", isa_str) == 0) {
73 return kArm;
74 } else if (strcmp("arm64", isa_str) == 0) {
75 return kArm64;
76 } else if (strcmp("x86", isa_str) == 0) {
77 return kX86;
78 } else if (strcmp("x86_64", isa_str) == 0) {
79 return kX86_64;
80 } else if (strcmp("mips", isa_str) == 0) {
81 return kMips;
82 } else if (strcmp("mips64", isa_str) == 0) {
Andreas Gampe57b34292015-01-14 15:45:59 -080083 return kMips64;
Ian Rogersd582fa42014-11-05 23:46:43 -080084 }
85
86 return kNone;
87}
88
Andreas Gampe6f611412015-01-21 22:25:24 -080089InstructionSet GetInstructionSetFromELF(uint16_t e_machine, uint32_t e_flags) {
90 switch (e_machine) {
91 case EM_ARM:
92 return kArm;
93 case EM_AARCH64:
94 return kArm64;
95 case EM_386:
96 return kX86;
97 case EM_X86_64:
98 return kX86_64;
99 case EM_MIPS: {
100 if ((e_flags & EF_MIPS_ARCH) == EF_MIPS_ARCH_32R2 ||
101 (e_flags & EF_MIPS_ARCH) == EF_MIPS_ARCH_32R6) {
102 return kMips;
103 } else if ((e_flags & EF_MIPS_ARCH) == EF_MIPS_ARCH_64R6) {
104 return kMips64;
105 }
106 break;
107 }
108 }
109 return kNone;
110}
111
Ian Rogersd582fa42014-11-05 23:46:43 -0800112size_t GetInstructionSetAlignment(InstructionSet isa) {
113 switch (isa) {
114 case kArm:
115 // Fall-through.
116 case kThumb2:
117 return kArmAlignment;
118 case kArm64:
119 return kArm64Alignment;
120 case kX86:
121 // Fall-through.
122 case kX86_64:
123 return kX86Alignment;
124 case kMips:
Andreas Gampe57b34292015-01-14 15:45:59 -0800125 // Fall-through.
126 case kMips64:
Ian Rogersd582fa42014-11-05 23:46:43 -0800127 return kMipsAlignment;
128 case kNone:
129 LOG(FATAL) << "ISA kNone does not have alignment.";
130 UNREACHABLE();
131 default:
132 LOG(FATAL) << "Unknown ISA " << isa;
133 UNREACHABLE();
134 }
135}
136
Andreas Gamped1262282016-08-11 18:35:58 -0700137#if !defined(ART_STACK_OVERFLOW_GAP_arm) || !defined(ART_STACK_OVERFLOW_GAP_arm64) || \
138 !defined(ART_STACK_OVERFLOW_GAP_mips) || !defined(ART_STACK_OVERFLOW_GAP_mips64) || \
139 !defined(ART_STACK_OVERFLOW_GAP_x86) || !defined(ART_STACK_OVERFLOW_GAP_x86_64)
140#error "Missing defines for stack overflow gap"
141#endif
Ian Rogersd582fa42014-11-05 23:46:43 -0800142
Andreas Gamped1262282016-08-11 18:35:58 -0700143static constexpr size_t kArmStackOverflowReservedBytes = ART_STACK_OVERFLOW_GAP_arm;
144static constexpr size_t kArm64StackOverflowReservedBytes = ART_STACK_OVERFLOW_GAP_arm64;
145static constexpr size_t kMipsStackOverflowReservedBytes = ART_STACK_OVERFLOW_GAP_mips;
146static constexpr size_t kMips64StackOverflowReservedBytes = ART_STACK_OVERFLOW_GAP_mips64;
147static constexpr size_t kX86StackOverflowReservedBytes = ART_STACK_OVERFLOW_GAP_x86;
148static constexpr size_t kX86_64StackOverflowReservedBytes = ART_STACK_OVERFLOW_GAP_x86_64;
149
150static_assert(IsAligned<kPageSize>(kArmStackOverflowReservedBytes), "ARM gap not page aligned");
151static_assert(IsAligned<kPageSize>(kArm64StackOverflowReservedBytes), "ARM64 gap not page aligned");
152static_assert(IsAligned<kPageSize>(kMipsStackOverflowReservedBytes), "Mips gap not page aligned");
153static_assert(IsAligned<kPageSize>(kMips64StackOverflowReservedBytes),
154 "Mips64 gap not page aligned");
155static_assert(IsAligned<kPageSize>(kX86StackOverflowReservedBytes), "X86 gap not page aligned");
156static_assert(IsAligned<kPageSize>(kX86_64StackOverflowReservedBytes),
157 "X86_64 gap not page aligned");
158
159#if !defined(ART_FRAME_SIZE_LIMIT)
160#error "ART frame size limit missing"
161#endif
162
163// TODO: Should we require an extra page (RoundUp(SIZE) + kPageSize)?
164static_assert(ART_FRAME_SIZE_LIMIT < kArmStackOverflowReservedBytes, "Frame size limit too large");
165static_assert(ART_FRAME_SIZE_LIMIT < kArm64StackOverflowReservedBytes,
166 "Frame size limit too large");
167static_assert(ART_FRAME_SIZE_LIMIT < kMipsStackOverflowReservedBytes,
168 "Frame size limit too large");
169static_assert(ART_FRAME_SIZE_LIMIT < kMips64StackOverflowReservedBytes,
170 "Frame size limit too large");
171static_assert(ART_FRAME_SIZE_LIMIT < kX86StackOverflowReservedBytes,
172 "Frame size limit too large");
173static_assert(ART_FRAME_SIZE_LIMIT < kX86_64StackOverflowReservedBytes,
174 "Frame size limit too large");
Ian Rogersd582fa42014-11-05 23:46:43 -0800175
176size_t GetStackOverflowReservedBytes(InstructionSet isa) {
177 switch (isa) {
178 case kArm: // Intentional fall-through.
179 case kThumb2:
180 return kArmStackOverflowReservedBytes;
181
182 case kArm64:
183 return kArm64StackOverflowReservedBytes;
184
185 case kMips:
186 return kMipsStackOverflowReservedBytes;
187
Andreas Gampe57b34292015-01-14 15:45:59 -0800188 case kMips64:
189 return kMips64StackOverflowReservedBytes;
190
Ian Rogersd582fa42014-11-05 23:46:43 -0800191 case kX86:
192 return kX86StackOverflowReservedBytes;
193
194 case kX86_64:
195 return kX86_64StackOverflowReservedBytes;
196
197 case kNone:
198 LOG(FATAL) << "kNone has no stack overflow size";
199 UNREACHABLE();
200
201 default:
202 LOG(FATAL) << "Unknown instruction set" << isa;
203 UNREACHABLE();
204 }
205}
206
207} // namespace art