• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //===-- ArchSpec.cpp --------------------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #include "lldb/Core/ArchSpec.h"
11 
12 #include <stdio.h>
13 #include <errno.h>
14 
15 #include <string>
16 
17 #include "llvm/Support/ELF.h"
18 #include "llvm/Support/Host.h"
19 #include "llvm/Support/MachO.h"
20 #include "lldb/Core/RegularExpression.h"
21 #include "lldb/Host/Endian.h"
22 #include "lldb/Host/Host.h"
23 #include "lldb/Target/Platform.h"
24 
25 using namespace lldb;
26 using namespace lldb_private;
27 
28 #define ARCH_SPEC_SEPARATOR_CHAR '-'
29 
30 
31 static bool cores_match (const ArchSpec::Core core1, const ArchSpec::Core core2, bool try_inverse, bool enforce_exact_match);
32 
33 namespace lldb_private {
34 
35     struct CoreDefinition
36     {
37         ByteOrder default_byte_order;
38         uint32_t addr_byte_size;
39         uint32_t min_opcode_byte_size;
40         uint32_t max_opcode_byte_size;
41         llvm::Triple::ArchType machine;
42         ArchSpec::Core core;
43         const char *name;
44     };
45 
46 }
47 
48 // This core information can be looked using the ArchSpec::Core as the index
49 static const CoreDefinition g_core_definitions[ArchSpec::kNumCores] =
50 {
51     { eByteOrderLittle, 4, 2, 4, llvm::Triple::arm    , ArchSpec::eCore_arm_generic     , "arm"       },
52     { eByteOrderLittle, 4, 2, 4, llvm::Triple::arm    , ArchSpec::eCore_arm_armv4       , "armv4"     },
53     { eByteOrderLittle, 4, 2, 4, llvm::Triple::arm    , ArchSpec::eCore_arm_armv4t      , "armv4t"    },
54     { eByteOrderLittle, 4, 2, 4, llvm::Triple::arm    , ArchSpec::eCore_arm_armv5       , "armv5"     },
55     { eByteOrderLittle, 4, 2, 4, llvm::Triple::arm    , ArchSpec::eCore_arm_armv5e      , "armv5e"    },
56     { eByteOrderLittle, 4, 2, 4, llvm::Triple::arm    , ArchSpec::eCore_arm_armv5t      , "armv5t"    },
57     { eByteOrderLittle, 4, 2, 4, llvm::Triple::arm    , ArchSpec::eCore_arm_armv6       , "armv6"     },
58     { eByteOrderLittle, 4, 2, 4, llvm::Triple::arm    , ArchSpec::eCore_arm_armv7       , "armv7"     },
59     { eByteOrderLittle, 4, 2, 4, llvm::Triple::arm    , ArchSpec::eCore_arm_armv7f      , "armv7f"    },
60     { eByteOrderLittle, 4, 2, 4, llvm::Triple::arm    , ArchSpec::eCore_arm_armv7s      , "armv7s"    },
61     { eByteOrderLittle, 4, 2, 4, llvm::Triple::arm    , ArchSpec::eCore_arm_armv7k      , "armv7k"    },
62     { eByteOrderLittle, 4, 2, 4, llvm::Triple::arm    , ArchSpec::eCore_arm_armv7m      , "armv7m"    },
63     { eByteOrderLittle, 4, 2, 4, llvm::Triple::arm    , ArchSpec::eCore_arm_armv7em     , "armv7em"   },
64     { eByteOrderLittle, 4, 2, 4, llvm::Triple::arm    , ArchSpec::eCore_arm_xscale      , "xscale"    },
65     { eByteOrderLittle, 4, 2, 4, llvm::Triple::thumb  , ArchSpec::eCore_thumb           , "thumb"     },
66     { eByteOrderLittle, 4, 2, 4, llvm::Triple::thumb  , ArchSpec::eCore_thumbv4t        , "thumbv4t"  },
67     { eByteOrderLittle, 4, 2, 4, llvm::Triple::thumb  , ArchSpec::eCore_thumbv5         , "thumbv5"   },
68     { eByteOrderLittle, 4, 2, 4, llvm::Triple::thumb  , ArchSpec::eCore_thumbv5e        , "thumbv5e"  },
69     { eByteOrderLittle, 4, 2, 4, llvm::Triple::thumb  , ArchSpec::eCore_thumbv6         , "thumbv6"   },
70     { eByteOrderLittle, 4, 2, 4, llvm::Triple::thumb  , ArchSpec::eCore_thumbv7         , "thumbv7"   },
71     { eByteOrderLittle, 4, 2, 4, llvm::Triple::thumb  , ArchSpec::eCore_thumbv7f        , "thumbv7f"  },
72     { eByteOrderLittle, 4, 2, 4, llvm::Triple::thumb  , ArchSpec::eCore_thumbv7s        , "thumbv7s"  },
73     { eByteOrderLittle, 4, 2, 4, llvm::Triple::thumb  , ArchSpec::eCore_thumbv7k        , "thumbv7k"  },
74     { eByteOrderLittle, 4, 2, 4, llvm::Triple::thumb  , ArchSpec::eCore_thumbv7m        , "thumbv7m"  },
75     { eByteOrderLittle, 4, 2, 4, llvm::Triple::thumb  , ArchSpec::eCore_thumbv7em       , "thumbv7em" },
76 
77 
78     { eByteOrderLittle, 4, 4, 4, llvm::Triple::ppc    , ArchSpec::eCore_ppc_generic     , "ppc"       },
79     { eByteOrderLittle, 4, 4, 4, llvm::Triple::ppc    , ArchSpec::eCore_ppc_ppc601      , "ppc601"    },
80     { eByteOrderLittle, 4, 4, 4, llvm::Triple::ppc    , ArchSpec::eCore_ppc_ppc602      , "ppc602"    },
81     { eByteOrderLittle, 4, 4, 4, llvm::Triple::ppc    , ArchSpec::eCore_ppc_ppc603      , "ppc603"    },
82     { eByteOrderLittle, 4, 4, 4, llvm::Triple::ppc    , ArchSpec::eCore_ppc_ppc603e     , "ppc603e"   },
83     { eByteOrderLittle, 4, 4, 4, llvm::Triple::ppc    , ArchSpec::eCore_ppc_ppc603ev    , "ppc603ev"  },
84     { eByteOrderLittle, 4, 4, 4, llvm::Triple::ppc    , ArchSpec::eCore_ppc_ppc604      , "ppc604"    },
85     { eByteOrderLittle, 4, 4, 4, llvm::Triple::ppc    , ArchSpec::eCore_ppc_ppc604e     , "ppc604e"   },
86     { eByteOrderLittle, 4, 4, 4, llvm::Triple::ppc    , ArchSpec::eCore_ppc_ppc620      , "ppc620"    },
87     { eByteOrderLittle, 4, 4, 4, llvm::Triple::ppc    , ArchSpec::eCore_ppc_ppc750      , "ppc750"    },
88     { eByteOrderLittle, 4, 4, 4, llvm::Triple::ppc    , ArchSpec::eCore_ppc_ppc7400     , "ppc7400"   },
89     { eByteOrderLittle, 4, 4, 4, llvm::Triple::ppc    , ArchSpec::eCore_ppc_ppc7450     , "ppc7450"   },
90     { eByteOrderLittle, 4, 4, 4, llvm::Triple::ppc    , ArchSpec::eCore_ppc_ppc970      , "ppc970"    },
91 
92     { eByteOrderLittle, 8, 4, 4, llvm::Triple::ppc64  , ArchSpec::eCore_ppc64_generic   , "ppc64"     },
93     { eByteOrderLittle, 8, 4, 4, llvm::Triple::ppc64  , ArchSpec::eCore_ppc64_ppc970_64 , "ppc970-64" },
94 
95     { eByteOrderLittle, 4, 4, 4, llvm::Triple::sparc  , ArchSpec::eCore_sparc_generic   , "sparc"     },
96     { eByteOrderLittle, 8, 4, 4, llvm::Triple::sparcv9, ArchSpec::eCore_sparc9_generic  , "sparcv9"   },
97 
98     { eByteOrderLittle, 4, 1, 15, llvm::Triple::x86    , ArchSpec::eCore_x86_32_i386    , "i386"      },
99     { eByteOrderLittle, 4, 1, 15, llvm::Triple::x86    , ArchSpec::eCore_x86_32_i486    , "i486"      },
100     { eByteOrderLittle, 4, 1, 15, llvm::Triple::x86    , ArchSpec::eCore_x86_32_i486sx  , "i486sx"    },
101 
102     { eByteOrderLittle, 8, 1, 15, llvm::Triple::x86_64 , ArchSpec::eCore_x86_64_x86_64  , "x86_64"    },
103     { eByteOrderLittle, 4, 4, 4 , llvm::Triple::UnknownArch , ArchSpec::eCore_uknownMach32  , "unknown-mach-32" },
104     { eByteOrderLittle, 8, 4, 4 , llvm::Triple::UnknownArch , ArchSpec::eCore_uknownMach64  , "unknown-mach-64" }
105 };
106 
107 struct ArchDefinitionEntry
108 {
109     ArchSpec::Core core;
110     uint32_t cpu;
111     uint32_t sub;
112     uint32_t cpu_mask;
113     uint32_t sub_mask;
114 };
115 
116 struct ArchDefinition
117 {
118     ArchitectureType type;
119     size_t num_entries;
120     const ArchDefinitionEntry *entries;
121     const char *name;
122 };
123 
124 
125 size_t
AutoComplete(const char * name,StringList & matches)126 ArchSpec::AutoComplete (const char *name, StringList &matches)
127 {
128     uint32_t i;
129     if (name && name[0])
130     {
131         for (i = 0; i < ArchSpec::kNumCores; ++i)
132         {
133             if (NameMatches(g_core_definitions[i].name, eNameMatchStartsWith, name))
134                 matches.AppendString (g_core_definitions[i].name);
135         }
136     }
137     else
138     {
139         for (i = 0; i < ArchSpec::kNumCores; ++i)
140             matches.AppendString (g_core_definitions[i].name);
141     }
142     return matches.GetSize();
143 }
144 
145 
146 
147 #define CPU_ANY (UINT32_MAX)
148 
149 //===----------------------------------------------------------------------===//
150 // A table that gets searched linearly for matches. This table is used to
151 // convert cpu type and subtypes to architecture names, and to convert
152 // architecture names to cpu types and subtypes. The ordering is important and
153 // allows the precedence to be set when the table is built.
154 #define SUBTYPE_MASK 0x00FFFFFFu
155 static const ArchDefinitionEntry g_macho_arch_entries[] =
156 {
157     { ArchSpec::eCore_arm_generic     , llvm::MachO::CPUTypeARM       , CPU_ANY, UINT32_MAX , UINT32_MAX  },
158     { ArchSpec::eCore_arm_generic     , llvm::MachO::CPUTypeARM       , 0      , UINT32_MAX , SUBTYPE_MASK },
159     { ArchSpec::eCore_arm_armv4       , llvm::MachO::CPUTypeARM       , 5      , UINT32_MAX , SUBTYPE_MASK },
160     { ArchSpec::eCore_arm_armv4t      , llvm::MachO::CPUTypeARM       , 5      , UINT32_MAX , SUBTYPE_MASK },
161     { ArchSpec::eCore_arm_armv6       , llvm::MachO::CPUTypeARM       , 6      , UINT32_MAX , SUBTYPE_MASK },
162     { ArchSpec::eCore_arm_armv5       , llvm::MachO::CPUTypeARM       , 7      , UINT32_MAX , SUBTYPE_MASK },
163     { ArchSpec::eCore_arm_armv5e      , llvm::MachO::CPUTypeARM       , 7      , UINT32_MAX , SUBTYPE_MASK },
164     { ArchSpec::eCore_arm_armv5t      , llvm::MachO::CPUTypeARM       , 7      , UINT32_MAX , SUBTYPE_MASK },
165     { ArchSpec::eCore_arm_xscale      , llvm::MachO::CPUTypeARM       , 8      , UINT32_MAX , SUBTYPE_MASK },
166     { ArchSpec::eCore_arm_armv7       , llvm::MachO::CPUTypeARM       , 9      , UINT32_MAX , SUBTYPE_MASK },
167     { ArchSpec::eCore_arm_armv7f      , llvm::MachO::CPUTypeARM       , 10     , UINT32_MAX , SUBTYPE_MASK },
168     { ArchSpec::eCore_arm_armv7s      , llvm::MachO::CPUTypeARM       , 11     , UINT32_MAX , SUBTYPE_MASK },
169     { ArchSpec::eCore_arm_armv7k      , llvm::MachO::CPUTypeARM       , 12     , UINT32_MAX , SUBTYPE_MASK },
170     { ArchSpec::eCore_arm_armv7m      , llvm::MachO::CPUTypeARM       , 15     , UINT32_MAX , SUBTYPE_MASK },
171     { ArchSpec::eCore_arm_armv7em     , llvm::MachO::CPUTypeARM       , 16     , UINT32_MAX , SUBTYPE_MASK },
172     { ArchSpec::eCore_thumb           , llvm::MachO::CPUTypeARM       , 0      , UINT32_MAX , SUBTYPE_MASK },
173     { ArchSpec::eCore_thumbv4t        , llvm::MachO::CPUTypeARM       , 5      , UINT32_MAX , SUBTYPE_MASK },
174     { ArchSpec::eCore_thumbv5         , llvm::MachO::CPUTypeARM       , 7      , UINT32_MAX , SUBTYPE_MASK },
175     { ArchSpec::eCore_thumbv5e        , llvm::MachO::CPUTypeARM       , 7      , UINT32_MAX , SUBTYPE_MASK },
176     { ArchSpec::eCore_thumbv6         , llvm::MachO::CPUTypeARM       , 6      , UINT32_MAX , SUBTYPE_MASK },
177     { ArchSpec::eCore_thumbv7         , llvm::MachO::CPUTypeARM       , 9      , UINT32_MAX , SUBTYPE_MASK },
178     { ArchSpec::eCore_thumbv7f        , llvm::MachO::CPUTypeARM       , 10     , UINT32_MAX , SUBTYPE_MASK },
179     { ArchSpec::eCore_thumbv7s        , llvm::MachO::CPUTypeARM       , 11     , UINT32_MAX , SUBTYPE_MASK },
180     { ArchSpec::eCore_thumbv7k        , llvm::MachO::CPUTypeARM       , 12     , UINT32_MAX , SUBTYPE_MASK },
181     { ArchSpec::eCore_thumbv7m        , llvm::MachO::CPUTypeARM       , 15     , UINT32_MAX , SUBTYPE_MASK },
182     { ArchSpec::eCore_thumbv7em       , llvm::MachO::CPUTypeARM       , 16     , UINT32_MAX , SUBTYPE_MASK },
183     { ArchSpec::eCore_ppc_generic     , llvm::MachO::CPUTypePowerPC   , CPU_ANY, UINT32_MAX , UINT32_MAX  },
184     { ArchSpec::eCore_ppc_generic     , llvm::MachO::CPUTypePowerPC   , 0      , UINT32_MAX , SUBTYPE_MASK },
185     { ArchSpec::eCore_ppc_ppc601      , llvm::MachO::CPUTypePowerPC   , 1      , UINT32_MAX , SUBTYPE_MASK },
186     { ArchSpec::eCore_ppc_ppc602      , llvm::MachO::CPUTypePowerPC   , 2      , UINT32_MAX , SUBTYPE_MASK },
187     { ArchSpec::eCore_ppc_ppc603      , llvm::MachO::CPUTypePowerPC   , 3      , UINT32_MAX , SUBTYPE_MASK },
188     { ArchSpec::eCore_ppc_ppc603e     , llvm::MachO::CPUTypePowerPC   , 4      , UINT32_MAX , SUBTYPE_MASK },
189     { ArchSpec::eCore_ppc_ppc603ev    , llvm::MachO::CPUTypePowerPC   , 5      , UINT32_MAX , SUBTYPE_MASK },
190     { ArchSpec::eCore_ppc_ppc604      , llvm::MachO::CPUTypePowerPC   , 6      , UINT32_MAX , SUBTYPE_MASK },
191     { ArchSpec::eCore_ppc_ppc604e     , llvm::MachO::CPUTypePowerPC   , 7      , UINT32_MAX , SUBTYPE_MASK },
192     { ArchSpec::eCore_ppc_ppc620      , llvm::MachO::CPUTypePowerPC   , 8      , UINT32_MAX , SUBTYPE_MASK },
193     { ArchSpec::eCore_ppc_ppc750      , llvm::MachO::CPUTypePowerPC   , 9      , UINT32_MAX , SUBTYPE_MASK },
194     { ArchSpec::eCore_ppc_ppc7400     , llvm::MachO::CPUTypePowerPC   , 10     , UINT32_MAX , SUBTYPE_MASK },
195     { ArchSpec::eCore_ppc_ppc7450     , llvm::MachO::CPUTypePowerPC   , 11     , UINT32_MAX , SUBTYPE_MASK },
196     { ArchSpec::eCore_ppc_ppc970      , llvm::MachO::CPUTypePowerPC   , 100    , UINT32_MAX , SUBTYPE_MASK },
197     { ArchSpec::eCore_ppc64_generic   , llvm::MachO::CPUTypePowerPC64 , 0      , UINT32_MAX , SUBTYPE_MASK },
198     { ArchSpec::eCore_ppc64_ppc970_64 , llvm::MachO::CPUTypePowerPC64 , 100    , UINT32_MAX , SUBTYPE_MASK },
199     { ArchSpec::eCore_x86_32_i386     , llvm::MachO::CPUTypeI386      , 3      , UINT32_MAX , SUBTYPE_MASK },
200     { ArchSpec::eCore_x86_32_i486     , llvm::MachO::CPUTypeI386      , 4      , UINT32_MAX , SUBTYPE_MASK },
201     { ArchSpec::eCore_x86_32_i486sx   , llvm::MachO::CPUTypeI386      , 0x84   , UINT32_MAX , SUBTYPE_MASK },
202     { ArchSpec::eCore_x86_32_i386     , llvm::MachO::CPUTypeI386      , CPU_ANY, UINT32_MAX , UINT32_MAX  },
203     { ArchSpec::eCore_x86_64_x86_64   , llvm::MachO::CPUTypeX86_64    , 3      , UINT32_MAX , SUBTYPE_MASK },
204     { ArchSpec::eCore_x86_64_x86_64   , llvm::MachO::CPUTypeX86_64    , 4      , UINT32_MAX , SUBTYPE_MASK },
205     { ArchSpec::eCore_x86_64_x86_64   , llvm::MachO::CPUTypeX86_64    , CPU_ANY, UINT32_MAX , UINT32_MAX  },
206     // Catch any unknown mach architectures so we can always use the object and symbol mach-o files
207     { ArchSpec::eCore_uknownMach32    , 0                             , 0      , 0xFF000000u, 0x00000000u },
208     { ArchSpec::eCore_uknownMach64    , llvm::MachO::CPUArchABI64     , 0      , 0xFF000000u, 0x00000000u }
209 };
210 static const ArchDefinition g_macho_arch_def = {
211     eArchTypeMachO,
212     sizeof(g_macho_arch_entries)/sizeof(g_macho_arch_entries[0]),
213     g_macho_arch_entries,
214     "mach-o"
215 };
216 
217 //===----------------------------------------------------------------------===//
218 // A table that gets searched linearly for matches. This table is used to
219 // convert cpu type and subtypes to architecture names, and to convert
220 // architecture names to cpu types and subtypes. The ordering is important and
221 // allows the precedence to be set when the table is built.
222 static const ArchDefinitionEntry g_elf_arch_entries[] =
223 {
224     { ArchSpec::eCore_sparc_generic   , llvm::ELF::EM_SPARC  , LLDB_INVALID_CPUTYPE, 0xFFFFFFFFu, 0xFFFFFFFFu }, // Sparc
225     { ArchSpec::eCore_x86_32_i386     , llvm::ELF::EM_386    , LLDB_INVALID_CPUTYPE, 0xFFFFFFFFu, 0xFFFFFFFFu }, // Intel 80386
226     { ArchSpec::eCore_x86_32_i486     , llvm::ELF::EM_486    , LLDB_INVALID_CPUTYPE, 0xFFFFFFFFu, 0xFFFFFFFFu }, // Intel 486 (deprecated)
227     { ArchSpec::eCore_ppc_generic     , llvm::ELF::EM_PPC    , LLDB_INVALID_CPUTYPE, 0xFFFFFFFFu, 0xFFFFFFFFu }, // PowerPC
228     { ArchSpec::eCore_ppc64_generic   , llvm::ELF::EM_PPC64  , LLDB_INVALID_CPUTYPE, 0xFFFFFFFFu, 0xFFFFFFFFu }, // PowerPC64
229     { ArchSpec::eCore_arm_generic     , llvm::ELF::EM_ARM    , LLDB_INVALID_CPUTYPE, 0xFFFFFFFFu, 0xFFFFFFFFu }, // ARM
230     { ArchSpec::eCore_sparc9_generic  , llvm::ELF::EM_SPARCV9, LLDB_INVALID_CPUTYPE, 0xFFFFFFFFu, 0xFFFFFFFFu }, // SPARC V9
231     { ArchSpec::eCore_x86_64_x86_64   , llvm::ELF::EM_X86_64 , LLDB_INVALID_CPUTYPE, 0xFFFFFFFFu, 0xFFFFFFFFu }  // AMD64
232 };
233 
234 static const ArchDefinition g_elf_arch_def = {
235     eArchTypeELF,
236     sizeof(g_elf_arch_entries)/sizeof(g_elf_arch_entries[0]),
237     g_elf_arch_entries,
238     "elf",
239 };
240 
241 //===----------------------------------------------------------------------===//
242 // Table of all ArchDefinitions
243 static const ArchDefinition *g_arch_definitions[] = {
244     &g_macho_arch_def,
245     &g_elf_arch_def
246 };
247 
248 static const size_t k_num_arch_definitions =
249     sizeof(g_arch_definitions) / sizeof(g_arch_definitions[0]);
250 
251 //===----------------------------------------------------------------------===//
252 // Static helper functions.
253 
254 
255 // Get the architecture definition for a given object type.
256 static const ArchDefinition *
FindArchDefinition(ArchitectureType arch_type)257 FindArchDefinition (ArchitectureType arch_type)
258 {
259     for (unsigned int i = 0; i < k_num_arch_definitions; ++i)
260     {
261         const ArchDefinition *def = g_arch_definitions[i];
262         if (def->type == arch_type)
263             return def;
264     }
265     return NULL;
266 }
267 
268 // Get an architecture definition by name.
269 static const CoreDefinition *
FindCoreDefinition(llvm::StringRef name)270 FindCoreDefinition (llvm::StringRef name)
271 {
272     for (unsigned int i = 0; i < ArchSpec::kNumCores; ++i)
273     {
274         if (name.equals_lower(g_core_definitions[i].name))
275             return &g_core_definitions[i];
276     }
277     return NULL;
278 }
279 
280 static inline const CoreDefinition *
FindCoreDefinition(ArchSpec::Core core)281 FindCoreDefinition (ArchSpec::Core core)
282 {
283     if (core >= 0 && core < ArchSpec::kNumCores)
284         return &g_core_definitions[core];
285     return NULL;
286 }
287 
288 // Get a definition entry by cpu type and subtype.
289 static const ArchDefinitionEntry *
FindArchDefinitionEntry(const ArchDefinition * def,uint32_t cpu,uint32_t sub)290 FindArchDefinitionEntry (const ArchDefinition *def, uint32_t cpu, uint32_t sub)
291 {
292     if (def == NULL)
293         return NULL;
294 
295     const ArchDefinitionEntry *entries = def->entries;
296     for (size_t i = 0; i < def->num_entries; ++i)
297     {
298         if (entries[i].cpu == (cpu & entries[i].cpu_mask))
299             if (entries[i].sub == (sub & entries[i].sub_mask))
300                 return &entries[i];
301     }
302     return NULL;
303 }
304 
305 static const ArchDefinitionEntry *
FindArchDefinitionEntry(const ArchDefinition * def,ArchSpec::Core core)306 FindArchDefinitionEntry (const ArchDefinition *def, ArchSpec::Core core)
307 {
308     if (def == NULL)
309         return NULL;
310 
311     const ArchDefinitionEntry *entries = def->entries;
312     for (size_t i = 0; i < def->num_entries; ++i)
313     {
314         if (entries[i].core == core)
315             return &entries[i];
316     }
317     return NULL;
318 }
319 
320 //===----------------------------------------------------------------------===//
321 // Constructors and destructors.
322 
ArchSpec()323 ArchSpec::ArchSpec() :
324     m_triple (),
325     m_core (kCore_invalid),
326     m_byte_order (eByteOrderInvalid)
327 {
328 }
329 
ArchSpec(const char * triple_cstr,Platform * platform)330 ArchSpec::ArchSpec (const char *triple_cstr, Platform *platform) :
331     m_triple (),
332     m_core (kCore_invalid),
333     m_byte_order (eByteOrderInvalid)
334 {
335     if (triple_cstr)
336         SetTriple(triple_cstr, platform);
337 }
338 
339 
ArchSpec(const char * triple_cstr)340 ArchSpec::ArchSpec (const char *triple_cstr) :
341     m_triple (),
342     m_core (kCore_invalid),
343     m_byte_order (eByteOrderInvalid)
344 {
345     if (triple_cstr)
346         SetTriple(triple_cstr);
347 }
348 
ArchSpec(const llvm::Triple & triple)349 ArchSpec::ArchSpec(const llvm::Triple &triple) :
350     m_triple (),
351     m_core (kCore_invalid),
352     m_byte_order (eByteOrderInvalid)
353 {
354     SetTriple(triple);
355 }
356 
ArchSpec(ArchitectureType arch_type,uint32_t cpu,uint32_t subtype)357 ArchSpec::ArchSpec (ArchitectureType arch_type, uint32_t cpu, uint32_t subtype) :
358     m_triple (),
359     m_core (kCore_invalid),
360     m_byte_order (eByteOrderInvalid)
361 {
362     SetArchitecture (arch_type, cpu, subtype);
363 }
364 
~ArchSpec()365 ArchSpec::~ArchSpec()
366 {
367 }
368 
369 //===----------------------------------------------------------------------===//
370 // Assignment and initialization.
371 
372 const ArchSpec&
operator =(const ArchSpec & rhs)373 ArchSpec::operator= (const ArchSpec& rhs)
374 {
375     if (this != &rhs)
376     {
377         m_triple = rhs.m_triple;
378         m_core = rhs.m_core;
379         m_byte_order = rhs.m_byte_order;
380     }
381     return *this;
382 }
383 
384 void
Clear()385 ArchSpec::Clear()
386 {
387     m_triple = llvm::Triple();
388     m_core = kCore_invalid;
389     m_byte_order = eByteOrderInvalid;
390 }
391 
392 //===----------------------------------------------------------------------===//
393 // Predicates.
394 
395 
396 const char *
GetArchitectureName() const397 ArchSpec::GetArchitectureName () const
398 {
399     const CoreDefinition *core_def = FindCoreDefinition (m_core);
400     if (core_def)
401         return core_def->name;
402     return "unknown";
403 }
404 
405 uint32_t
GetMachOCPUType() const406 ArchSpec::GetMachOCPUType () const
407 {
408     const CoreDefinition *core_def = FindCoreDefinition (m_core);
409     if (core_def)
410     {
411         const ArchDefinitionEntry *arch_def = FindArchDefinitionEntry (&g_macho_arch_def, core_def->core);
412         if (arch_def)
413         {
414             return arch_def->cpu;
415         }
416     }
417     return LLDB_INVALID_CPUTYPE;
418 }
419 
420 uint32_t
GetMachOCPUSubType() const421 ArchSpec::GetMachOCPUSubType () const
422 {
423     const CoreDefinition *core_def = FindCoreDefinition (m_core);
424     if (core_def)
425     {
426         const ArchDefinitionEntry *arch_def = FindArchDefinitionEntry (&g_macho_arch_def, core_def->core);
427         if (arch_def)
428         {
429             return arch_def->sub;
430         }
431     }
432     return LLDB_INVALID_CPUTYPE;
433 }
434 
435 llvm::Triple::ArchType
GetMachine() const436 ArchSpec::GetMachine () const
437 {
438     const CoreDefinition *core_def = FindCoreDefinition (m_core);
439     if (core_def)
440         return core_def->machine;
441 
442     return llvm::Triple::UnknownArch;
443 }
444 
445 uint32_t
GetAddressByteSize() const446 ArchSpec::GetAddressByteSize() const
447 {
448     const CoreDefinition *core_def = FindCoreDefinition (m_core);
449     if (core_def)
450         return core_def->addr_byte_size;
451     return 0;
452 }
453 
454 ByteOrder
GetDefaultEndian() const455 ArchSpec::GetDefaultEndian () const
456 {
457     const CoreDefinition *core_def = FindCoreDefinition (m_core);
458     if (core_def)
459         return core_def->default_byte_order;
460     return eByteOrderInvalid;
461 }
462 
463 lldb::ByteOrder
GetByteOrder() const464 ArchSpec::GetByteOrder () const
465 {
466     if (m_byte_order == eByteOrderInvalid)
467         return GetDefaultEndian();
468     return m_byte_order;
469 }
470 
471 //===----------------------------------------------------------------------===//
472 // Mutators.
473 
474 bool
SetTriple(const llvm::Triple & triple)475 ArchSpec::SetTriple (const llvm::Triple &triple)
476 {
477     m_triple = triple;
478 
479     llvm::StringRef arch_name (m_triple.getArchName());
480     const CoreDefinition *core_def = FindCoreDefinition (arch_name);
481     if (core_def)
482     {
483         m_core = core_def->core;
484         // Set the byte order to the default byte order for an architecture.
485         // This can be modified if needed for cases when cores handle both
486         // big and little endian
487         m_byte_order = core_def->default_byte_order;
488     }
489     else
490     {
491         Clear();
492     }
493 
494 
495     return IsValid();
496 }
497 
498 static bool
ParseMachCPUDashSubtypeTriple(const char * triple_cstr,ArchSpec & arch)499 ParseMachCPUDashSubtypeTriple (const char *triple_cstr, ArchSpec &arch)
500 {
501     // Accept "12-10" or "12.10" as cpu type/subtype
502     if (isdigit(triple_cstr[0]))
503     {
504         char *end = NULL;
505         errno = 0;
506         uint32_t cpu = (uint32_t)::strtoul (triple_cstr, &end, 0);
507         if (errno == 0 && cpu != 0 && end && ((*end == '-') || (*end == '.')))
508         {
509             errno = 0;
510             uint32_t sub = (uint32_t)::strtoul (end + 1, &end, 0);
511             if (errno == 0 && end && ((*end == '-') || (*end == '.') || (*end == '\0')))
512             {
513                 if (arch.SetArchitecture (eArchTypeMachO, cpu, sub))
514                 {
515                     if (*end == '-')
516                     {
517                         llvm::StringRef vendor_os (end + 1);
518                         size_t dash_pos = vendor_os.find('-');
519                         if (dash_pos != llvm::StringRef::npos)
520                         {
521                             llvm::StringRef vendor_str(vendor_os.substr(0, dash_pos));
522                             arch.GetTriple().setVendorName(vendor_str);
523                             const size_t vendor_start_pos = dash_pos+1;
524                             dash_pos = vendor_os.find('-', vendor_start_pos);
525                             if (dash_pos == llvm::StringRef::npos)
526                             {
527                                 if (vendor_start_pos < vendor_os.size())
528                                     arch.GetTriple().setOSName(vendor_os.substr(vendor_start_pos));
529                             }
530                             else
531                             {
532                                 arch.GetTriple().setOSName(vendor_os.substr(vendor_start_pos, dash_pos - vendor_start_pos));
533                             }
534                         }
535                     }
536                     return true;
537                 }
538             }
539         }
540     }
541     return false;
542 }
543 bool
SetTriple(const char * triple_cstr)544 ArchSpec::SetTriple (const char *triple_cstr)
545 {
546     if (triple_cstr && triple_cstr[0])
547     {
548         if (ParseMachCPUDashSubtypeTriple (triple_cstr, *this))
549             return true;
550 
551         llvm::StringRef triple_stref (triple_cstr);
552         if (triple_stref.startswith (LLDB_ARCH_DEFAULT))
553         {
554             // Special case for the current host default architectures...
555             if (triple_stref.equals (LLDB_ARCH_DEFAULT_32BIT))
556                 *this = Host::GetArchitecture (Host::eSystemDefaultArchitecture32);
557             else if (triple_stref.equals (LLDB_ARCH_DEFAULT_64BIT))
558                 *this = Host::GetArchitecture (Host::eSystemDefaultArchitecture64);
559             else if (triple_stref.equals (LLDB_ARCH_DEFAULT))
560                 *this = Host::GetArchitecture (Host::eSystemDefaultArchitecture);
561         }
562         else
563         {
564             std::string normalized_triple_sstr (llvm::Triple::normalize(triple_stref));
565             triple_stref = normalized_triple_sstr;
566             SetTriple (llvm::Triple (triple_stref));
567         }
568     }
569     else
570         Clear();
571     return IsValid();
572 }
573 
574 bool
SetTriple(const char * triple_cstr,Platform * platform)575 ArchSpec::SetTriple (const char *triple_cstr, Platform *platform)
576 {
577     if (triple_cstr && triple_cstr[0])
578     {
579         if (ParseMachCPUDashSubtypeTriple (triple_cstr, *this))
580             return true;
581 
582         llvm::StringRef triple_stref (triple_cstr);
583         if (triple_stref.startswith (LLDB_ARCH_DEFAULT))
584         {
585             // Special case for the current host default architectures...
586             if (triple_stref.equals (LLDB_ARCH_DEFAULT_32BIT))
587                 *this = Host::GetArchitecture (Host::eSystemDefaultArchitecture32);
588             else if (triple_stref.equals (LLDB_ARCH_DEFAULT_64BIT))
589                 *this = Host::GetArchitecture (Host::eSystemDefaultArchitecture64);
590             else if (triple_stref.equals (LLDB_ARCH_DEFAULT))
591                 *this = Host::GetArchitecture (Host::eSystemDefaultArchitecture);
592         }
593         else
594         {
595             ArchSpec raw_arch (triple_cstr);
596 
597             std::string normalized_triple_sstr (llvm::Triple::normalize(triple_stref));
598             triple_stref = normalized_triple_sstr;
599             llvm::Triple normalized_triple (triple_stref);
600 
601             const bool os_specified = normalized_triple.getOSName().size() > 0;
602             const bool vendor_specified = normalized_triple.getVendorName().size() > 0;
603             const bool env_specified = normalized_triple.getEnvironmentName().size() > 0;
604 
605             // If we got an arch only, then default the vendor, os, environment
606             // to match the platform if one is supplied
607             if (!(os_specified || vendor_specified || env_specified))
608             {
609                 if (platform)
610                 {
611                     // If we were given a platform, use the platform's system
612                     // architecture. If this is not available (might not be
613                     // connected) use the first supported architecture.
614                     ArchSpec compatible_arch;
615                     if (platform->IsCompatibleArchitecture (raw_arch, false, &compatible_arch))
616                     {
617                         if (compatible_arch.IsValid())
618                         {
619                             const llvm::Triple &compatible_triple = compatible_arch.GetTriple();
620                             if (!vendor_specified)
621                                 normalized_triple.setVendor(compatible_triple.getVendor());
622                             if (!os_specified)
623                                 normalized_triple.setOS(compatible_triple.getOS());
624                             if (!env_specified && compatible_triple.getEnvironmentName().size())
625                                 normalized_triple.setEnvironment(compatible_triple.getEnvironment());
626                         }
627                     }
628                     else
629                     {
630                         *this = raw_arch;
631                         return IsValid();
632                     }
633                 }
634                 else
635                 {
636                     // No platform specified, fall back to the host system for
637                     // the default vendor, os, and environment.
638                     llvm::Triple host_triple(llvm::sys::getDefaultTargetTriple());
639                     if (!vendor_specified)
640                         normalized_triple.setVendor(host_triple.getVendor());
641                     if (!vendor_specified)
642                         normalized_triple.setOS(host_triple.getOS());
643                     if (!env_specified && host_triple.getEnvironmentName().size())
644                         normalized_triple.setEnvironment(host_triple.getEnvironment());
645                 }
646             }
647             SetTriple (normalized_triple);
648         }
649     }
650     else
651         Clear();
652     return IsValid();
653 }
654 
655 bool
SetArchitecture(ArchitectureType arch_type,uint32_t cpu,uint32_t sub)656 ArchSpec::SetArchitecture (ArchitectureType arch_type, uint32_t cpu, uint32_t sub)
657 {
658     m_core = kCore_invalid;
659     bool update_triple = true;
660     const ArchDefinition *arch_def = FindArchDefinition(arch_type);
661     if (arch_def)
662     {
663         const ArchDefinitionEntry *arch_def_entry = FindArchDefinitionEntry (arch_def, cpu, sub);
664         if (arch_def_entry)
665         {
666             const CoreDefinition *core_def = FindCoreDefinition (arch_def_entry->core);
667             if (core_def)
668             {
669                 m_core = core_def->core;
670                 update_triple = false;
671                 // Always use the architecture name because it might be more descriptive
672                 // than the architecture enum ("armv7" -> llvm::Triple::arm).
673                 m_triple.setArchName(llvm::StringRef(core_def->name));
674                 if (arch_type == eArchTypeMachO)
675                 {
676                     m_triple.setVendor (llvm::Triple::Apple);
677 
678                     switch (core_def->machine)
679                     {
680                         case llvm::Triple::arm:
681                         case llvm::Triple::thumb:
682                             m_triple.setOS (llvm::Triple::IOS);
683                             break;
684 
685                         case llvm::Triple::x86:
686                         case llvm::Triple::x86_64:
687                         default:
688                             m_triple.setOS (llvm::Triple::MacOSX);
689                             break;
690                     }
691                 }
692                 else
693                 {
694                     m_triple.setVendor (llvm::Triple::UnknownVendor);
695                     m_triple.setOS (llvm::Triple::UnknownOS);
696                 }
697                 // Fall back onto setting the machine type if the arch by name failed...
698                 if (m_triple.getArch () == llvm::Triple::UnknownArch)
699                     m_triple.setArch (core_def->machine);
700             }
701         }
702     }
703     CoreUpdated(update_triple);
704     return IsValid();
705 }
706 
707 uint32_t
GetMinimumOpcodeByteSize() const708 ArchSpec::GetMinimumOpcodeByteSize() const
709 {
710     const CoreDefinition *core_def = FindCoreDefinition (m_core);
711     if (core_def)
712         return core_def->min_opcode_byte_size;
713     return 0;
714 }
715 
716 uint32_t
GetMaximumOpcodeByteSize() const717 ArchSpec::GetMaximumOpcodeByteSize() const
718 {
719     const CoreDefinition *core_def = FindCoreDefinition (m_core);
720     if (core_def)
721         return core_def->max_opcode_byte_size;
722     return 0;
723 }
724 
725 bool
IsExactMatch(const ArchSpec & rhs) const726 ArchSpec::IsExactMatch (const ArchSpec& rhs) const
727 {
728     return IsEqualTo (rhs, true);
729 }
730 
731 bool
IsCompatibleMatch(const ArchSpec & rhs) const732 ArchSpec::IsCompatibleMatch (const ArchSpec& rhs) const
733 {
734     return IsEqualTo (rhs, false);
735 }
736 
737 bool
IsEqualTo(const ArchSpec & rhs,bool exact_match) const738 ArchSpec::IsEqualTo (const ArchSpec& rhs, bool exact_match) const
739 {
740     if (GetByteOrder() != rhs.GetByteOrder())
741         return false;
742 
743     const ArchSpec::Core lhs_core = GetCore ();
744     const ArchSpec::Core rhs_core = rhs.GetCore ();
745 
746     const bool core_match = cores_match (lhs_core, rhs_core, true, exact_match);
747 
748     if (core_match)
749     {
750         const llvm::Triple &lhs_triple = GetTriple();
751         const llvm::Triple &rhs_triple = rhs.GetTriple();
752 
753         const llvm::Triple::VendorType lhs_triple_vendor = lhs_triple.getVendor();
754         const llvm::Triple::VendorType rhs_triple_vendor = rhs_triple.getVendor();
755         if (lhs_triple_vendor != rhs_triple_vendor)
756         {
757             if (exact_match)
758             {
759                 const bool rhs_vendor_specified = rhs.TripleVendorWasSpecified();
760                 const bool lhs_vendor_specified = TripleVendorWasSpecified();
761                 // Both architectures had the vendor specified, so if they aren't
762                 // equal then we return false
763                 if (rhs_vendor_specified && lhs_vendor_specified)
764                     return false;
765             }
766 
767             // Only fail if both vendor types are not unknown
768             if (lhs_triple_vendor != llvm::Triple::UnknownVendor &&
769                 rhs_triple_vendor != llvm::Triple::UnknownVendor)
770                 return false;
771         }
772 
773         const llvm::Triple::OSType lhs_triple_os = lhs_triple.getOS();
774         const llvm::Triple::OSType rhs_triple_os = rhs_triple.getOS();
775         if (lhs_triple_os != rhs_triple_os)
776         {
777             if (exact_match)
778             {
779                 const bool rhs_os_specified = rhs.TripleOSWasSpecified();
780                 const bool lhs_os_specified = TripleOSWasSpecified();
781                 // Both architectures had the OS specified, so if they aren't
782                 // equal then we return false
783                 if (rhs_os_specified && lhs_os_specified)
784                     return false;
785             }
786             // Only fail if both os types are not unknown
787             if (lhs_triple_os != llvm::Triple::UnknownOS &&
788                 rhs_triple_os != llvm::Triple::UnknownOS)
789                 return false;
790         }
791 
792         const llvm::Triple::EnvironmentType lhs_triple_env = lhs_triple.getEnvironment();
793         const llvm::Triple::EnvironmentType rhs_triple_env = rhs_triple.getEnvironment();
794 
795         if (lhs_triple_env != rhs_triple_env)
796         {
797             // Only fail if both environment types are not unknown
798             if (lhs_triple_env != llvm::Triple::UnknownEnvironment &&
799                 rhs_triple_env != llvm::Triple::UnknownEnvironment)
800                 return false;
801         }
802         return true;
803     }
804     return false;
805 }
806 
807 //===----------------------------------------------------------------------===//
808 // Helper methods.
809 
810 void
CoreUpdated(bool update_triple)811 ArchSpec::CoreUpdated (bool update_triple)
812 {
813     const CoreDefinition *core_def = FindCoreDefinition (m_core);
814     if (core_def)
815     {
816         if (update_triple)
817             m_triple = llvm::Triple(core_def->name, "unknown", "unknown");
818         m_byte_order = core_def->default_byte_order;
819     }
820     else
821     {
822         if (update_triple)
823             m_triple = llvm::Triple();
824         m_byte_order = eByteOrderInvalid;
825     }
826 }
827 
828 //===----------------------------------------------------------------------===//
829 // Operators.
830 
831 static bool
cores_match(const ArchSpec::Core core1,const ArchSpec::Core core2,bool try_inverse,bool enforce_exact_match)832 cores_match (const ArchSpec::Core core1, const ArchSpec::Core core2, bool try_inverse, bool enforce_exact_match)
833 {
834     if (core1 == core2)
835         return true;
836 
837     switch (core1)
838     {
839     case ArchSpec::kCore_any:
840         return true;
841 
842     case ArchSpec::kCore_arm_any:
843         if (core2 >= ArchSpec::kCore_arm_first && core2 <= ArchSpec::kCore_arm_last)
844             return true;
845         if (core2 >= ArchSpec::kCore_thumb_first && core2 <= ArchSpec::kCore_thumb_last)
846             return true;
847         if (core2 == ArchSpec::kCore_arm_any)
848             return true;
849         break;
850 
851     case ArchSpec::kCore_x86_32_any:
852         if ((core2 >= ArchSpec::kCore_x86_32_first && core2 <= ArchSpec::kCore_x86_32_last) || (core2 == ArchSpec::kCore_x86_32_any))
853             return true;
854         break;
855 
856     case ArchSpec::kCore_ppc_any:
857         if ((core2 >= ArchSpec::kCore_ppc_first && core2 <= ArchSpec::kCore_ppc_last) || (core2 == ArchSpec::kCore_ppc_any))
858             return true;
859         break;
860 
861     case ArchSpec::kCore_ppc64_any:
862         if ((core2 >= ArchSpec::kCore_ppc64_first && core2 <= ArchSpec::kCore_ppc64_last) || (core2 == ArchSpec::kCore_ppc64_any))
863             return true;
864         break;
865 
866     case ArchSpec::eCore_arm_armv7m:
867     case ArchSpec::eCore_arm_armv7em:
868     case ArchSpec::eCore_arm_armv7f:
869     case ArchSpec::eCore_arm_armv7k:
870     case ArchSpec::eCore_arm_armv7s:
871         if (!enforce_exact_match)
872         {
873             try_inverse = false;
874             if (core2 == ArchSpec::eCore_arm_armv7)
875                 return true;
876         }
877         break;
878 
879     default:
880         break;
881     }
882     if (try_inverse)
883         return cores_match (core2, core1, false, enforce_exact_match);
884     return false;
885 }
886 
887 bool
operator <(const ArchSpec & lhs,const ArchSpec & rhs)888 lldb_private::operator<(const ArchSpec& lhs, const ArchSpec& rhs)
889 {
890     const ArchSpec::Core lhs_core = lhs.GetCore ();
891     const ArchSpec::Core rhs_core = rhs.GetCore ();
892     return lhs_core < rhs_core;
893 }
894