Home | History | Annotate | Download | only in arch
      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 
     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 
     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 
     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 
     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 
    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