1 | //===-- ArchSpec.h ----------------------------------------------*- C++ -*-===// |
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | |
9 | #ifndef LLDB_UTILITY_ARCHSPEC_H |
10 | #define LLDB_UTILITY_ARCHSPEC_H |
11 | |
12 | #include "lldb/Utility/CompletionRequest.h" |
13 | #include "lldb/lldb-enumerations.h" |
14 | #include "lldb/lldb-forward.h" |
15 | #include "lldb/lldb-private-enumerations.h" |
16 | #include "llvm/ADT/StringRef.h" |
17 | #include "llvm/TargetParser/Triple.h" |
18 | #include <cstddef> |
19 | #include <cstdint> |
20 | #include <string> |
21 | |
22 | namespace lldb_private { |
23 | |
24 | /// \class ArchSpec ArchSpec.h "lldb/Utility/ArchSpec.h" An architecture |
25 | /// specification class. |
26 | /// |
27 | /// A class designed to be created from a cpu type and subtype, a |
28 | /// string representation, or an llvm::Triple. Keeping all of the conversions |
29 | /// of strings to architecture enumeration values confined to this class |
30 | /// allows new architecture support to be added easily. |
31 | class ArchSpec { |
32 | public: |
33 | enum MIPSSubType { |
34 | eMIPSSubType_unknown, |
35 | eMIPSSubType_mips32, |
36 | eMIPSSubType_mips32r2, |
37 | eMIPSSubType_mips32r6, |
38 | eMIPSSubType_mips32el, |
39 | eMIPSSubType_mips32r2el, |
40 | eMIPSSubType_mips32r6el, |
41 | eMIPSSubType_mips64, |
42 | eMIPSSubType_mips64r2, |
43 | eMIPSSubType_mips64r6, |
44 | eMIPSSubType_mips64el, |
45 | eMIPSSubType_mips64r2el, |
46 | eMIPSSubType_mips64r6el, |
47 | }; |
48 | |
49 | // Masks for the ases word of an ABI flags structure. |
50 | enum MIPSASE { |
51 | eMIPSAse_dsp = 0x00000001, // DSP ASE |
52 | eMIPSAse_dspr2 = 0x00000002, // DSP R2 ASE |
53 | eMIPSAse_eva = 0x00000004, // Enhanced VA Scheme |
54 | eMIPSAse_mcu = 0x00000008, // MCU (MicroController) ASE |
55 | eMIPSAse_mdmx = 0x00000010, // MDMX ASE |
56 | eMIPSAse_mips3d = 0x00000020, // MIPS-3D ASE |
57 | eMIPSAse_mt = 0x00000040, // MT ASE |
58 | eMIPSAse_smartmips = 0x00000080, // SmartMIPS ASE |
59 | eMIPSAse_virt = 0x00000100, // VZ ASE |
60 | eMIPSAse_msa = 0x00000200, // MSA ASE |
61 | eMIPSAse_mips16 = 0x00000400, // MIPS16 ASE |
62 | eMIPSAse_micromips = 0x00000800, // MICROMIPS ASE |
63 | eMIPSAse_xpa = 0x00001000, // XPA ASE |
64 | eMIPSAse_mask = 0x00001fff, |
65 | eMIPSABI_O32 = 0x00002000, |
66 | eMIPSABI_N32 = 0x00004000, |
67 | eMIPSABI_N64 = 0x00008000, |
68 | eMIPSABI_O64 = 0x00020000, |
69 | eMIPSABI_EABI32 = 0x00040000, |
70 | eMIPSABI_EABI64 = 0x00080000, |
71 | eMIPSABI_mask = 0x000ff000 |
72 | }; |
73 | |
74 | // MIPS Floating point ABI Values |
75 | enum MIPS_ABI_FP { |
76 | eMIPS_ABI_FP_ANY = 0x00000000, |
77 | eMIPS_ABI_FP_DOUBLE = 0x00100000, // hard float / -mdouble-float |
78 | eMIPS_ABI_FP_SINGLE = 0x00200000, // hard float / -msingle-float |
79 | eMIPS_ABI_FP_SOFT = 0x00300000, // soft float |
80 | eMIPS_ABI_FP_OLD_64 = 0x00400000, // -mips32r2 -mfp64 |
81 | eMIPS_ABI_FP_XX = 0x00500000, // -mfpxx |
82 | eMIPS_ABI_FP_64 = 0x00600000, // -mips32r2 -mfp64 |
83 | eMIPS_ABI_FP_64A = 0x00700000, // -mips32r2 -mfp64 -mno-odd-spreg |
84 | eMIPS_ABI_FP_mask = 0x00700000 |
85 | }; |
86 | |
87 | // ARM specific e_flags |
88 | enum ARMeflags { |
89 | eARM_abi_soft_float = 0x00000200, |
90 | eARM_abi_hard_float = 0x00000400 |
91 | }; |
92 | |
93 | enum RISCVeflags { |
94 | eRISCV_rvc = 0x00000001, /// RVC, +c |
95 | eRISCV_float_abi_soft = 0x00000000, /// soft float |
96 | eRISCV_float_abi_single = 0x00000002, /// single precision floating point, +f |
97 | eRISCV_float_abi_double = 0x00000004, /// double precision floating point, +d |
98 | eRISCV_float_abi_quad = 0x00000006, /// quad precision floating point, +q |
99 | eRISCV_float_abi_mask = 0x00000006, |
100 | eRISCV_rve = 0x00000008, /// RVE, +e |
101 | eRISCV_tso = 0x00000010, /// RVTSO (total store ordering) |
102 | }; |
103 | |
104 | enum RISCVSubType { |
105 | eRISCVSubType_unknown, |
106 | eRISCVSubType_riscv32, |
107 | eRISCVSubType_riscv64, |
108 | }; |
109 | |
110 | enum LoongArchSubType { |
111 | eLoongArchSubType_unknown, |
112 | eLoongArchSubType_loongarch32, |
113 | eLoongArchSubType_loongarch64, |
114 | }; |
115 | |
116 | enum Core { |
117 | eCore_arm_generic, |
118 | eCore_arm_armv4, |
119 | eCore_arm_armv4t, |
120 | eCore_arm_armv5, |
121 | eCore_arm_armv5e, |
122 | eCore_arm_armv5t, |
123 | eCore_arm_armv6, |
124 | eCore_arm_armv6m, |
125 | eCore_arm_armv7, |
126 | eCore_arm_armv7l, |
127 | eCore_arm_armv7f, |
128 | eCore_arm_armv7s, |
129 | eCore_arm_armv7k, |
130 | eCore_arm_armv7m, |
131 | eCore_arm_armv7em, |
132 | eCore_arm_xscale, |
133 | |
134 | eCore_thumb, |
135 | eCore_thumbv4t, |
136 | eCore_thumbv5, |
137 | eCore_thumbv5e, |
138 | eCore_thumbv6, |
139 | eCore_thumbv6m, |
140 | eCore_thumbv7, |
141 | eCore_thumbv7s, |
142 | eCore_thumbv7k, |
143 | eCore_thumbv7f, |
144 | eCore_thumbv7m, |
145 | eCore_thumbv7em, |
146 | eCore_arm_arm64, |
147 | eCore_arm_armv8, |
148 | eCore_arm_armv8l, |
149 | eCore_arm_arm64e, |
150 | eCore_arm_arm64_32, |
151 | eCore_arm_aarch64, |
152 | |
153 | eCore_mips32, |
154 | eCore_mips32r2, |
155 | eCore_mips32r3, |
156 | eCore_mips32r5, |
157 | eCore_mips32r6, |
158 | eCore_mips32el, |
159 | eCore_mips32r2el, |
160 | eCore_mips32r3el, |
161 | eCore_mips32r5el, |
162 | eCore_mips32r6el, |
163 | eCore_mips64, |
164 | eCore_mips64r2, |
165 | eCore_mips64r3, |
166 | eCore_mips64r5, |
167 | eCore_mips64r6, |
168 | eCore_mips64el, |
169 | eCore_mips64r2el, |
170 | eCore_mips64r3el, |
171 | eCore_mips64r5el, |
172 | eCore_mips64r6el, |
173 | |
174 | eCore_msp430, |
175 | |
176 | eCore_ppc_generic, |
177 | eCore_ppc_ppc601, |
178 | eCore_ppc_ppc602, |
179 | eCore_ppc_ppc603, |
180 | eCore_ppc_ppc603e, |
181 | eCore_ppc_ppc603ev, |
182 | eCore_ppc_ppc604, |
183 | eCore_ppc_ppc604e, |
184 | eCore_ppc_ppc620, |
185 | eCore_ppc_ppc750, |
186 | eCore_ppc_ppc7400, |
187 | eCore_ppc_ppc7450, |
188 | eCore_ppc_ppc970, |
189 | |
190 | eCore_ppc64le_generic, |
191 | eCore_ppc64_generic, |
192 | eCore_ppc64_ppc970_64, |
193 | |
194 | eCore_s390x_generic, |
195 | |
196 | eCore_sparc_generic, |
197 | |
198 | eCore_sparc9_generic, |
199 | |
200 | eCore_x86_32_i386, |
201 | eCore_x86_32_i486, |
202 | eCore_x86_32_i486sx, |
203 | eCore_x86_32_i686, |
204 | |
205 | eCore_x86_64_x86_64, |
206 | eCore_x86_64_x86_64h, // Haswell enabled x86_64 |
207 | eCore_hexagon_generic, |
208 | eCore_hexagon_hexagonv4, |
209 | eCore_hexagon_hexagonv5, |
210 | |
211 | eCore_riscv32, |
212 | eCore_riscv64, |
213 | |
214 | eCore_loongarch32, |
215 | eCore_loongarch64, |
216 | |
217 | eCore_uknownMach32, |
218 | eCore_uknownMach64, |
219 | |
220 | eCore_arc, // little endian ARC |
221 | |
222 | eCore_avr, |
223 | |
224 | eCore_wasm32, |
225 | |
226 | kNumCores, |
227 | |
228 | kCore_invalid, |
229 | // The following constants are used for wildcard matching only |
230 | kCore_any, |
231 | kCore_arm_any, |
232 | kCore_ppc_any, |
233 | kCore_ppc64_any, |
234 | kCore_x86_32_any, |
235 | kCore_x86_64_any, |
236 | kCore_hexagon_any, |
237 | |
238 | kCore_arm_first = eCore_arm_generic, |
239 | kCore_arm_last = eCore_arm_xscale, |
240 | |
241 | kCore_thumb_first = eCore_thumb, |
242 | kCore_thumb_last = eCore_thumbv7em, |
243 | |
244 | kCore_ppc_first = eCore_ppc_generic, |
245 | kCore_ppc_last = eCore_ppc_ppc970, |
246 | |
247 | kCore_ppc64_first = eCore_ppc64_generic, |
248 | kCore_ppc64_last = eCore_ppc64_ppc970_64, |
249 | |
250 | kCore_x86_32_first = eCore_x86_32_i386, |
251 | kCore_x86_32_last = eCore_x86_32_i686, |
252 | |
253 | kCore_x86_64_first = eCore_x86_64_x86_64, |
254 | kCore_x86_64_last = eCore_x86_64_x86_64h, |
255 | |
256 | kCore_hexagon_first = eCore_hexagon_generic, |
257 | kCore_hexagon_last = eCore_hexagon_hexagonv5, |
258 | |
259 | kCore_mips32_first = eCore_mips32, |
260 | kCore_mips32_last = eCore_mips32r6, |
261 | |
262 | kCore_mips32el_first = eCore_mips32el, |
263 | kCore_mips32el_last = eCore_mips32r6el, |
264 | |
265 | kCore_mips64_first = eCore_mips64, |
266 | kCore_mips64_last = eCore_mips64r6, |
267 | |
268 | kCore_mips64el_first = eCore_mips64el, |
269 | kCore_mips64el_last = eCore_mips64r6el, |
270 | |
271 | kCore_mips_first = eCore_mips32, |
272 | kCore_mips_last = eCore_mips64r6el |
273 | |
274 | }; |
275 | |
276 | /// Default constructor. |
277 | /// |
278 | /// Default constructor that initializes the object with invalid cpu type |
279 | /// and subtype values. |
280 | ArchSpec(); |
281 | |
282 | /// Constructor over triple. |
283 | /// |
284 | /// Constructs an ArchSpec with properties consistent with the given Triple. |
285 | explicit ArchSpec(const llvm::Triple &triple); |
286 | explicit ArchSpec(const char *triple_cstr); |
287 | explicit ArchSpec(llvm::StringRef triple_str); |
288 | /// Constructor over architecture name. |
289 | /// |
290 | /// Constructs an ArchSpec with properties consistent with the given object |
291 | /// type and architecture name. |
292 | explicit ArchSpec(ArchitectureType arch_type, uint32_t cpu_type, |
293 | uint32_t cpu_subtype); |
294 | |
295 | /// Destructor. |
296 | ~ArchSpec(); |
297 | |
298 | /// Returns true if the OS, vendor and environment fields of the triple are |
299 | /// unset. The triple is expected to be normalized |
300 | /// (llvm::Triple::normalize). |
301 | static bool ContainsOnlyArch(const llvm::Triple &normalized_triple); |
302 | |
303 | static void ListSupportedArchNames(StringList &list); |
304 | static void AutoComplete(CompletionRequest &request); |
305 | |
306 | /// Returns a static string representing the current architecture. |
307 | /// |
308 | /// \return A static string corresponding to the current |
309 | /// architecture. |
310 | const char *GetArchitectureName() const; |
311 | |
312 | /// if MIPS architecture return true. |
313 | /// |
314 | /// \return a boolean value. |
315 | bool IsMIPS() const; |
316 | |
317 | /// Returns a string representing current architecture as a target CPU for |
318 | /// tools like compiler, disassembler etc. |
319 | /// |
320 | /// \return A string representing target CPU for the current |
321 | /// architecture. |
322 | std::string GetClangTargetCPU() const; |
323 | |
324 | /// Return a string representing target application ABI. |
325 | /// |
326 | /// \return A string representing target application ABI. |
327 | std::string GetTargetABI() const; |
328 | |
329 | /// Clears the object state. |
330 | /// |
331 | /// Clears the object state back to a default invalid state. |
332 | void Clear(); |
333 | |
334 | /// Returns the size in bytes of an address of the current architecture. |
335 | /// |
336 | /// \return The byte size of an address of the current architecture. |
337 | uint32_t GetAddressByteSize() const; |
338 | |
339 | /// Returns a machine family for the current architecture. |
340 | /// |
341 | /// \return An LLVM arch type. |
342 | llvm::Triple::ArchType GetMachine() const; |
343 | |
344 | /// Tests if this ArchSpec is valid. |
345 | /// |
346 | /// \return True if the current architecture is valid, false |
347 | /// otherwise. |
348 | bool IsValid() const { |
349 | return m_core >= eCore_arm_generic && m_core < kNumCores; |
350 | } |
351 | explicit operator bool() const { return IsValid(); } |
352 | |
353 | bool TripleVendorWasSpecified() const { |
354 | return !m_triple.getVendorName().empty(); |
355 | } |
356 | |
357 | bool TripleOSWasSpecified() const { return !m_triple.getOSName().empty(); } |
358 | |
359 | bool TripleEnvironmentWasSpecified() const { |
360 | return m_triple.hasEnvironment(); |
361 | } |
362 | |
363 | /// Merges fields from another ArchSpec into this ArchSpec. |
364 | /// |
365 | /// This will use the supplied ArchSpec to fill in any fields of the triple |
366 | /// in this ArchSpec which were unspecified. This can be used to refine a |
367 | /// generic ArchSpec with a more specific one. For example, if this |
368 | /// ArchSpec's triple is something like i386-unknown-unknown-unknown, and we |
369 | /// have a triple which is x64-pc-windows-msvc, then merging that triple |
370 | /// into this one will result in the triple i386-pc-windows-msvc. |
371 | /// |
372 | void MergeFrom(const ArchSpec &other); |
373 | |
374 | /// Change the architecture object type, CPU type and OS type. |
375 | /// |
376 | /// \param[in] arch_type The object type of this ArchSpec. |
377 | /// |
378 | /// \param[in] cpu The required CPU type. |
379 | /// |
380 | /// \param[in] os The optional OS type |
381 | /// The default value of 0 was chosen to from the ELF spec value |
382 | /// ELFOSABI_NONE. ELF is the only one using this parameter. If another |
383 | /// format uses this parameter and 0 does not work, use a value over |
384 | /// 255 because in the ELF header this is value is only a byte. |
385 | /// |
386 | /// \return True if the object, and CPU were successfully set. |
387 | /// |
388 | /// As a side effect, the vendor value is usually set to unknown. The |
389 | /// exceptions are |
390 | /// aarch64-apple-ios |
391 | /// arm-apple-ios |
392 | /// thumb-apple-ios |
393 | /// x86-apple- |
394 | /// x86_64-apple- |
395 | /// |
396 | /// As a side effect, the os value is usually set to unknown The exceptions |
397 | /// are |
398 | /// *-*-aix |
399 | /// aarch64-apple-ios |
400 | /// arm-apple-ios |
401 | /// thumb-apple-ios |
402 | /// powerpc-apple-darwin |
403 | /// *-*-freebsd |
404 | /// *-*-linux |
405 | /// *-*-netbsd |
406 | /// *-*-openbsd |
407 | /// *-*-solaris |
408 | bool SetArchitecture(ArchitectureType arch_type, uint32_t cpu, uint32_t sub, |
409 | uint32_t os = 0); |
410 | |
411 | /// Returns the byte order for the architecture specification. |
412 | /// |
413 | /// \return The endian enumeration for the current endianness of |
414 | /// the architecture specification |
415 | lldb::ByteOrder GetByteOrder() const; |
416 | |
417 | /// Sets this ArchSpec's byte order. |
418 | /// |
419 | /// In the common case there is no need to call this method as the byte |
420 | /// order can almost always be determined by the architecture. However, many |
421 | /// CPU's are bi-endian (ARM, Alpha, PowerPC, etc) and the default/assumed |
422 | /// byte order may be incorrect. |
423 | void SetByteOrder(lldb::ByteOrder byte_order) { m_byte_order = byte_order; } |
424 | |
425 | uint32_t GetMinimumOpcodeByteSize() const; |
426 | |
427 | uint32_t GetMaximumOpcodeByteSize() const; |
428 | |
429 | Core GetCore() const { return m_core; } |
430 | |
431 | uint32_t GetMachOCPUType() const; |
432 | |
433 | uint32_t GetMachOCPUSubType() const; |
434 | |
435 | /// Architecture data byte width accessor |
436 | /// |
437 | /// \return the size in 8-bit (host) bytes of a minimum addressable unit |
438 | /// from the Architecture's data bus |
439 | uint32_t GetDataByteSize() const; |
440 | |
441 | /// Architecture code byte width accessor |
442 | /// |
443 | /// \return the size in 8-bit (host) bytes of a minimum addressable unit |
444 | /// from the Architecture's code bus |
445 | uint32_t GetCodeByteSize() const; |
446 | |
447 | /// Architecture triple accessor. |
448 | /// |
449 | /// \return A triple describing this ArchSpec. |
450 | llvm::Triple &GetTriple() { return m_triple; } |
451 | |
452 | /// Architecture triple accessor. |
453 | /// |
454 | /// \return A triple describing this ArchSpec. |
455 | const llvm::Triple &GetTriple() const { return m_triple; } |
456 | |
457 | void DumpTriple(llvm::raw_ostream &s) const; |
458 | |
459 | /// Architecture triple setter. |
460 | /// |
461 | /// Configures this ArchSpec according to the given triple. If the triple |
462 | /// has unknown components in all of the vendor, OS, and the optional |
463 | /// environment field (i.e. "i386-unknown-unknown") then default values are |
464 | /// taken from the host. Architecture and environment components are used |
465 | /// to further resolve the CPU type and subtype, endian characteristics, |
466 | /// etc. |
467 | /// |
468 | /// \return A triple describing this ArchSpec. |
469 | bool SetTriple(const llvm::Triple &triple); |
470 | |
471 | bool SetTriple(llvm::StringRef triple_str); |
472 | |
473 | /// Returns the default endianness of the architecture. |
474 | /// |
475 | /// \return The endian enumeration for the default endianness of |
476 | /// the architecture. |
477 | lldb::ByteOrder GetDefaultEndian() const; |
478 | |
479 | /// Returns true if 'char' is a signed type by default in the architecture |
480 | /// false otherwise |
481 | /// |
482 | /// \return True if 'char' is a signed type by default on the |
483 | /// architecture and false otherwise. |
484 | bool CharIsSignedByDefault() const; |
485 | |
486 | enum MatchType : bool { CompatibleMatch, ExactMatch }; |
487 | |
488 | /// Compare this ArchSpec to another ArchSpec. \a match specifies the kind of |
489 | /// matching that is to be done. CompatibleMatch requires only a compatible |
490 | /// cpu type (e.g., armv7s is compatible with armv7). ExactMatch requires an |
491 | /// exact match (armv7s is not an exact match with armv7). |
492 | /// |
493 | /// \return true if the two ArchSpecs match. |
494 | bool IsMatch(const ArchSpec &rhs, MatchType match) const; |
495 | |
496 | /// Shorthand for IsMatch(rhs, ExactMatch). |
497 | bool IsExactMatch(const ArchSpec &rhs) const { |
498 | return IsMatch(rhs, match: ExactMatch); |
499 | } |
500 | |
501 | /// Shorthand for IsMatch(rhs, CompatibleMatch). |
502 | bool IsCompatibleMatch(const ArchSpec &rhs) const { |
503 | return IsMatch(rhs, match: CompatibleMatch); |
504 | } |
505 | |
506 | bool IsFullySpecifiedTriple() const; |
507 | |
508 | void PiecewiseTripleCompare(const ArchSpec &other, bool &arch_different, |
509 | bool &vendor_different, bool &os_different, |
510 | bool &os_version_different, |
511 | bool &env_different) const; |
512 | |
513 | /// Detect whether this architecture uses thumb code exclusively |
514 | /// |
515 | /// Some embedded ARM chips (e.g. the ARM Cortex M0-7 line) can only execute |
516 | /// the Thumb instructions, never Arm. We should normally pick up |
517 | /// arm/thumbness from their the processor status bits (cpsr/xpsr) or hints |
518 | /// on each function - but when doing bare-boards low level debugging |
519 | /// (especially common with these embedded processors), we may not have |
520 | /// those things easily accessible. |
521 | /// |
522 | /// \return true if this is an arm ArchSpec which can only execute Thumb |
523 | /// instructions |
524 | bool IsAlwaysThumbInstructions() const; |
525 | |
526 | uint32_t GetFlags() const { return m_flags; } |
527 | |
528 | void SetFlags(uint32_t flags) { m_flags = flags; } |
529 | |
530 | void SetFlags(const std::string &elf_abi); |
531 | |
532 | protected: |
533 | void UpdateCore(); |
534 | |
535 | llvm::Triple m_triple; |
536 | Core m_core = kCore_invalid; |
537 | lldb::ByteOrder m_byte_order = lldb::eByteOrderInvalid; |
538 | |
539 | // Additional arch flags which we cannot get from triple and core For MIPS |
540 | // these are application specific extensions like micromips, mips16 etc. |
541 | uint32_t m_flags = 0; |
542 | |
543 | // Called when m_def or m_entry are changed. Fills in all remaining members |
544 | // with default values. |
545 | void CoreUpdated(bool update_triple); |
546 | }; |
547 | |
548 | /// \fn bool operator< (const ArchSpec& lhs, const ArchSpec& rhs) Less than |
549 | /// operator. |
550 | /// |
551 | /// Tests two ArchSpec objects to see if \a lhs is less than \a rhs. |
552 | /// |
553 | /// \param[in] lhs The Left Hand Side ArchSpec object to compare. \param[in] |
554 | /// rhs The Left Hand Side ArchSpec object to compare. |
555 | /// |
556 | /// \return true if \a lhs is less than \a rhs |
557 | bool operator<(const ArchSpec &lhs, const ArchSpec &rhs); |
558 | bool operator==(const ArchSpec &lhs, const ArchSpec &rhs); |
559 | |
560 | bool ParseMachCPUDashSubtypeTriple(llvm::StringRef triple_str, ArchSpec &arch); |
561 | |
562 | } // namespace lldb_private |
563 | |
564 | #endif // LLDB_UTILITY_ARCHSPEC_H |
565 | |