1// Copyright (c) 2012, Google Inc.
2// All rights reserved.
3//
4// Redistribution and use in source and binary forms, with or without
5// modification, are permitted provided that the following conditions are
6// met:
7//
8//     * Redistributions of source code must retain the above copyright
9// notice, this list of conditions and the following disclaimer.
10//     * Redistributions in binary form must reproduce the above
11// copyright notice, this list of conditions and the following disclaimer
12// in the documentation and/or other materials provided with the
13// distribution.
14//     * Neither the name of Google Inc. nor the names of its
15// contributors may be used to endorse or promote products derived from
16// this software without specific prior written permission.
17//
18// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
30#include "common/mac/arch_utilities.h"
31
32#include <mach-o/arch.h>
33#include <stdio.h>
34#include <string.h>
35
36#ifndef CPU_TYPE_ARM
37#define CPU_TYPE_ARM (static_cast<cpu_type_t>(12))
38#endif  // CPU_TYPE_ARM
39
40#ifndef CPU_SUBTYPE_ARM_V7
41#define CPU_SUBTYPE_ARM_V7 (static_cast<cpu_subtype_t>(9))
42#endif  // CPU_SUBTYPE_ARM_V7
43
44#ifndef CPU_SUBTYPE_ARM_V7S
45#define CPU_SUBTYPE_ARM_V7S (static_cast<cpu_subtype_t>(11))
46#endif  // CPU_SUBTYPE_ARM_V7S
47
48#ifndef CPU_TYPE_ARM64
49#define CPU_TYPE_ARM64 (static_cast<cpu_type_t>(16777228))
50#endif  // CPU_TYPE_ARM64
51
52#ifndef CPU_SUBTYPE_ARM64_ALL
53#define CPU_SUBTYPE_ARM64_ALL (static_cast<cpu_type_t>(0))
54#endif  // CPU_SUBTYPE_ARM64_ALL
55
56namespace {
57
58const NXArchInfo* ArchInfo_arm64() {
59  NXArchInfo* arm64 = new NXArchInfo;
60  *arm64 = *NXGetArchInfoFromCpuType(CPU_TYPE_ARM,
61                                     CPU_SUBTYPE_ARM_V7);
62  arm64->name = "arm64";
63  arm64->cputype = CPU_TYPE_ARM64;
64  arm64->cpusubtype = CPU_SUBTYPE_ARM64_ALL;
65  arm64->description = "arm 64";
66  return arm64;
67}
68
69const NXArchInfo* ArchInfo_armv7s() {
70  NXArchInfo* armv7s = new NXArchInfo;
71  *armv7s = *NXGetArchInfoFromCpuType(CPU_TYPE_ARM,
72                                      CPU_SUBTYPE_ARM_V7);
73  armv7s->name = "armv7s";
74  armv7s->cpusubtype = CPU_SUBTYPE_ARM_V7S;
75  armv7s->description = "arm v7s";
76  return armv7s;
77}
78
79}  // namespace
80
81namespace google_breakpad {
82
83const NXArchInfo* BreakpadGetArchInfoFromName(const char* arch_name) {
84  // TODO: Remove this when the OS knows about arm64.
85  if (!strcmp("arm64", arch_name))
86    return BreakpadGetArchInfoFromCpuType(CPU_TYPE_ARM64,
87                                          CPU_SUBTYPE_ARM64_ALL);
88
89  // TODO: Remove this when the OS knows about armv7s.
90  if (!strcmp("armv7s", arch_name))
91    return BreakpadGetArchInfoFromCpuType(CPU_TYPE_ARM, CPU_SUBTYPE_ARM_V7S);
92
93  return NXGetArchInfoFromName(arch_name);
94}
95
96const NXArchInfo* BreakpadGetArchInfoFromCpuType(cpu_type_t cpu_type,
97                                                 cpu_subtype_t cpu_subtype) {
98  // TODO: Remove this when the OS knows about arm64.
99  if (cpu_type == CPU_TYPE_ARM64 && cpu_subtype == CPU_SUBTYPE_ARM64_ALL) {
100    static const NXArchInfo* arm64 = ArchInfo_arm64();
101    return arm64;
102  }
103
104  // TODO: Remove this when the OS knows about armv7s.
105  if (cpu_type == CPU_TYPE_ARM && cpu_subtype == CPU_SUBTYPE_ARM_V7S) {
106    static const NXArchInfo* armv7s = ArchInfo_armv7s();
107    return armv7s;
108  }
109
110  return NXGetArchInfoFromCpuType(cpu_type, cpu_subtype);
111}
112
113}  // namespace google_breakpad
114