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