| 1 | // This file defines all the identifier enums and target-aware logic. |
| 2 | |
| 3 | use crate::triple::{Endianness, PointerWidth, Triple}; |
| 4 | use alloc::borrow::Cow; |
| 5 | use alloc::boxed::Box; |
| 6 | use alloc::format; |
| 7 | use alloc::string::String; |
| 8 | use core::fmt; |
| 9 | use core::hash::{Hash, Hasher}; |
| 10 | use core::str::FromStr; |
| 11 | |
| 12 | /// The "architecture" field, which in some cases also specifies a specific |
| 13 | /// subarchitecture. |
| 14 | #[cfg_attr (feature = "rust_1_40" , non_exhaustive)] |
| 15 | #[derive (Copy, Clone, Debug, PartialEq, Eq, Hash)] |
| 16 | #[allow (missing_docs)] |
| 17 | pub enum Architecture { |
| 18 | Unknown, |
| 19 | Arm(ArmArchitecture), |
| 20 | AmdGcn, |
| 21 | Aarch64(Aarch64Architecture), |
| 22 | Asmjs, |
| 23 | Avr, |
| 24 | Bpfeb, |
| 25 | Bpfel, |
| 26 | Hexagon, |
| 27 | X86_32(X86_32Architecture), |
| 28 | M68k, |
| 29 | LoongArch64, |
| 30 | Mips32(Mips32Architecture), |
| 31 | Mips64(Mips64Architecture), |
| 32 | Msp430, |
| 33 | Nvptx64, |
| 34 | Pulley32, |
| 35 | Pulley64, |
| 36 | Pulley32be, |
| 37 | Pulley64be, |
| 38 | Powerpc, |
| 39 | Powerpc64, |
| 40 | Powerpc64le, |
| 41 | Riscv32(Riscv32Architecture), |
| 42 | Riscv64(Riscv64Architecture), |
| 43 | S390x, |
| 44 | Sparc, |
| 45 | Sparc64, |
| 46 | Sparcv9, |
| 47 | Wasm32, |
| 48 | Wasm64, |
| 49 | X86_64, |
| 50 | /// x86_64 target that only supports Haswell-compatible Intel chips. |
| 51 | X86_64h, |
| 52 | XTensa, |
| 53 | Clever(CleverArchitecture), |
| 54 | /// A software machine that produces zero-knowledge proofs of the execution. |
| 55 | /// |
| 56 | /// See https://wiki.polygon.technology/docs/category/zk-assembly/ |
| 57 | #[cfg (feature = "arch_zkasm" )] |
| 58 | ZkAsm, |
| 59 | } |
| 60 | |
| 61 | #[cfg_attr (feature = "rust_1_40" , non_exhaustive)] |
| 62 | #[derive (Copy, Clone, Debug, PartialEq, Eq, Hash)] |
| 63 | #[allow (missing_docs)] |
| 64 | pub enum ArmArchitecture { |
| 65 | Arm, // Generic arm |
| 66 | Armeb, |
| 67 | Armv4, |
| 68 | Armv4t, |
| 69 | Armv5t, |
| 70 | Armv5te, |
| 71 | Armv5tej, |
| 72 | Armv6, |
| 73 | Armv6j, |
| 74 | Armv6k, |
| 75 | Armv6z, |
| 76 | Armv6kz, |
| 77 | Armv6t2, |
| 78 | Armv6m, |
| 79 | Armv7, |
| 80 | Armv7a, |
| 81 | Armv7k, |
| 82 | Armv7ve, |
| 83 | Armv7m, |
| 84 | Armv7r, |
| 85 | Armv7s, |
| 86 | Armv8, |
| 87 | Armv8a, |
| 88 | Armv8_1a, |
| 89 | Armv8_2a, |
| 90 | Armv8_3a, |
| 91 | Armv8_4a, |
| 92 | Armv8_5a, |
| 93 | Armv8mBase, |
| 94 | Armv8mMain, |
| 95 | Armv8r, |
| 96 | |
| 97 | Armebv7r, |
| 98 | |
| 99 | Thumbeb, |
| 100 | Thumbv4t, |
| 101 | Thumbv5te, |
| 102 | Thumbv6m, |
| 103 | Thumbv7a, |
| 104 | Thumbv7em, |
| 105 | Thumbv7m, |
| 106 | Thumbv7neon, |
| 107 | Thumbv8mBase, |
| 108 | Thumbv8mMain, |
| 109 | } |
| 110 | |
| 111 | #[cfg_attr (feature = "rust_1_40" , non_exhaustive)] |
| 112 | #[derive (Copy, Clone, Debug, PartialEq, Eq, Hash)] |
| 113 | #[allow (missing_docs)] |
| 114 | pub enum Aarch64Architecture { |
| 115 | Aarch64, |
| 116 | Aarch64be, |
| 117 | } |
| 118 | |
| 119 | // #[cfg_attr(feature = "rust_1_40", non_exhaustive)] |
| 120 | // #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] |
| 121 | // #[allow(missing_docs)] |
| 122 | // pub enum ArmFpu { |
| 123 | // Vfp, |
| 124 | // Vfpv2, |
| 125 | // Vfpv3, |
| 126 | // Vfpv3Fp16, |
| 127 | // Vfpv3Xd, |
| 128 | // Vfpv3XdFp16, |
| 129 | // Neon, |
| 130 | // NeonVfpv3, |
| 131 | // NeonVfpv4, |
| 132 | // Vfpv4, |
| 133 | // Vfpv4D16, |
| 134 | // Fpv4SpD16, |
| 135 | // Fpv5SpD16, |
| 136 | // Fpv5D16, |
| 137 | // FpArmv8, |
| 138 | // NeonFpArmv8, |
| 139 | // CryptoNeonFpArmv8, |
| 140 | // } |
| 141 | |
| 142 | impl ArmArchitecture { |
| 143 | /// Test if this architecture uses the Thumb instruction set. |
| 144 | #[rustfmt::skip] |
| 145 | pub fn is_thumb(self) -> bool { |
| 146 | use ArmArchitecture::*; |
| 147 | |
| 148 | match self { |
| 149 | Arm |
| 150 | | Armeb |
| 151 | | Armv4 |
| 152 | | Armv4t |
| 153 | | Armv5t |
| 154 | | Armv5te |
| 155 | | Armv5tej |
| 156 | | Armv6 |
| 157 | | Armv6j |
| 158 | | Armv6k |
| 159 | | Armv6z |
| 160 | | Armv6kz |
| 161 | | Armv6t2 |
| 162 | | Armv6m |
| 163 | | Armv7 |
| 164 | | Armv7a |
| 165 | | Armv7k |
| 166 | | Armv7ve |
| 167 | | Armv7m |
| 168 | | Armv7r |
| 169 | | Armv7s |
| 170 | | Armv8 |
| 171 | | Armv8a |
| 172 | | Armv8_1a |
| 173 | | Armv8_2a |
| 174 | | Armv8_3a |
| 175 | | Armv8_4a |
| 176 | | Armv8_5a |
| 177 | | Armv8mBase |
| 178 | | Armv8mMain |
| 179 | | Armv8r |
| 180 | | Armebv7r => false, |
| 181 | Thumbeb |
| 182 | | Thumbv4t |
| 183 | | Thumbv5te |
| 184 | | Thumbv6m |
| 185 | | Thumbv7a |
| 186 | | Thumbv7em |
| 187 | | Thumbv7m |
| 188 | | Thumbv7neon |
| 189 | | Thumbv8mBase |
| 190 | | Thumbv8mMain => true, |
| 191 | } |
| 192 | } |
| 193 | |
| 194 | // pub fn has_fpu(self) -> Result<&'static [ArmFpu], ()> { |
| 195 | |
| 196 | // } |
| 197 | |
| 198 | /// Return the pointer bit width of this target's architecture. |
| 199 | #[rustfmt::skip] |
| 200 | pub fn pointer_width(self) -> PointerWidth { |
| 201 | use ArmArchitecture::*; |
| 202 | |
| 203 | match self { |
| 204 | Arm |
| 205 | | Armeb |
| 206 | | Armv4 |
| 207 | | Armv4t |
| 208 | | Armv5t |
| 209 | | Armv5te |
| 210 | | Armv5tej |
| 211 | | Armv6 |
| 212 | | Armv6j |
| 213 | | Armv6k |
| 214 | | Armv6z |
| 215 | | Armv6kz |
| 216 | | Armv6t2 |
| 217 | | Armv6m |
| 218 | | Armv7 |
| 219 | | Armv7a |
| 220 | | Armv7k |
| 221 | | Armv7ve |
| 222 | | Armv7m |
| 223 | | Armv7r |
| 224 | | Armv7s |
| 225 | | Armv8 |
| 226 | | Armv8a |
| 227 | | Armv8_1a |
| 228 | | Armv8_2a |
| 229 | | Armv8_3a |
| 230 | | Armv8_4a |
| 231 | | Armv8_5a |
| 232 | | Armv8mBase |
| 233 | | Armv8mMain |
| 234 | | Armv8r |
| 235 | | Armebv7r |
| 236 | | Thumbeb |
| 237 | | Thumbv4t |
| 238 | | Thumbv5te |
| 239 | | Thumbv6m |
| 240 | | Thumbv7a |
| 241 | | Thumbv7em |
| 242 | | Thumbv7m |
| 243 | | Thumbv7neon |
| 244 | | Thumbv8mBase |
| 245 | | Thumbv8mMain => PointerWidth::U32, |
| 246 | } |
| 247 | } |
| 248 | |
| 249 | /// Return the endianness of this architecture. |
| 250 | #[rustfmt::skip] |
| 251 | pub fn endianness(self) -> Endianness { |
| 252 | use ArmArchitecture::*; |
| 253 | |
| 254 | match self { |
| 255 | Arm |
| 256 | | Armv4 |
| 257 | | Armv4t |
| 258 | | Armv5t |
| 259 | | Armv5te |
| 260 | | Armv5tej |
| 261 | | Armv6 |
| 262 | | Armv6j |
| 263 | | Armv6k |
| 264 | | Armv6z |
| 265 | | Armv6kz |
| 266 | | Armv6t2 |
| 267 | | Armv6m |
| 268 | | Armv7 |
| 269 | | Armv7a |
| 270 | | Armv7k |
| 271 | | Armv7ve |
| 272 | | Armv7m |
| 273 | | Armv7r |
| 274 | | Armv7s |
| 275 | | Armv8 |
| 276 | | Armv8a |
| 277 | | Armv8_1a |
| 278 | | Armv8_2a |
| 279 | | Armv8_3a |
| 280 | | Armv8_4a |
| 281 | | Armv8_5a |
| 282 | | Armv8mBase |
| 283 | | Armv8mMain |
| 284 | | Armv8r |
| 285 | | Thumbv4t |
| 286 | | Thumbv5te |
| 287 | | Thumbv6m |
| 288 | | Thumbv7a |
| 289 | | Thumbv7em |
| 290 | | Thumbv7m |
| 291 | | Thumbv7neon |
| 292 | | Thumbv8mBase |
| 293 | | Thumbv8mMain => Endianness::Little, |
| 294 | Armeb | Armebv7r | Thumbeb => Endianness::Big, |
| 295 | } |
| 296 | } |
| 297 | |
| 298 | /// Convert into a string |
| 299 | pub fn into_str(self) -> Cow<'static, str> { |
| 300 | use ArmArchitecture::*; |
| 301 | |
| 302 | match self { |
| 303 | Arm => Cow::Borrowed("arm" ), |
| 304 | Armeb => Cow::Borrowed("armeb" ), |
| 305 | Armv4 => Cow::Borrowed("armv4" ), |
| 306 | Armv4t => Cow::Borrowed("armv4t" ), |
| 307 | Armv5t => Cow::Borrowed("armv5t" ), |
| 308 | Armv5te => Cow::Borrowed("armv5te" ), |
| 309 | Armv5tej => Cow::Borrowed("armv5tej" ), |
| 310 | Armv6 => Cow::Borrowed("armv6" ), |
| 311 | Armv6j => Cow::Borrowed("armv6j" ), |
| 312 | Armv6k => Cow::Borrowed("armv6k" ), |
| 313 | Armv6z => Cow::Borrowed("armv6z" ), |
| 314 | Armv6kz => Cow::Borrowed("armv6kz" ), |
| 315 | Armv6t2 => Cow::Borrowed("armv6t2" ), |
| 316 | Armv6m => Cow::Borrowed("armv6m" ), |
| 317 | Armv7 => Cow::Borrowed("armv7" ), |
| 318 | Armv7a => Cow::Borrowed("armv7a" ), |
| 319 | Armv7k => Cow::Borrowed("armv7k" ), |
| 320 | Armv7ve => Cow::Borrowed("armv7ve" ), |
| 321 | Armv7m => Cow::Borrowed("armv7m" ), |
| 322 | Armv7r => Cow::Borrowed("armv7r" ), |
| 323 | Armv7s => Cow::Borrowed("armv7s" ), |
| 324 | Armv8 => Cow::Borrowed("armv8" ), |
| 325 | Armv8a => Cow::Borrowed("armv8a" ), |
| 326 | Armv8_1a => Cow::Borrowed("armv8.1a" ), |
| 327 | Armv8_2a => Cow::Borrowed("armv8.2a" ), |
| 328 | Armv8_3a => Cow::Borrowed("armv8.3a" ), |
| 329 | Armv8_4a => Cow::Borrowed("armv8.4a" ), |
| 330 | Armv8_5a => Cow::Borrowed("armv8.5a" ), |
| 331 | Armv8mBase => Cow::Borrowed("armv8m.base" ), |
| 332 | Armv8mMain => Cow::Borrowed("armv8m.main" ), |
| 333 | Armv8r => Cow::Borrowed("armv8r" ), |
| 334 | Thumbeb => Cow::Borrowed("thumbeb" ), |
| 335 | Thumbv4t => Cow::Borrowed("thumbv4t" ), |
| 336 | Thumbv5te => Cow::Borrowed("thumbv5te" ), |
| 337 | Thumbv6m => Cow::Borrowed("thumbv6m" ), |
| 338 | Thumbv7a => Cow::Borrowed("thumbv7a" ), |
| 339 | Thumbv7em => Cow::Borrowed("thumbv7em" ), |
| 340 | Thumbv7m => Cow::Borrowed("thumbv7m" ), |
| 341 | Thumbv7neon => Cow::Borrowed("thumbv7neon" ), |
| 342 | Thumbv8mBase => Cow::Borrowed("thumbv8m.base" ), |
| 343 | Thumbv8mMain => Cow::Borrowed("thumbv8m.main" ), |
| 344 | Armebv7r => Cow::Borrowed("armebv7r" ), |
| 345 | } |
| 346 | } |
| 347 | } |
| 348 | |
| 349 | impl Aarch64Architecture { |
| 350 | /// Test if this architecture uses the Thumb instruction set. |
| 351 | pub fn is_thumb(self) -> bool { |
| 352 | match self { |
| 353 | Aarch64Architecture::Aarch64 | Aarch64Architecture::Aarch64be => false, |
| 354 | } |
| 355 | } |
| 356 | |
| 357 | // pub fn has_fpu(self) -> Result<&'static [ArmFpu], ()> { |
| 358 | |
| 359 | // } |
| 360 | |
| 361 | /// Return the pointer bit width of this target's architecture. |
| 362 | /// |
| 363 | /// This function is only aware of the CPU architecture so it is not aware |
| 364 | /// of ilp32 ABIs. |
| 365 | pub fn pointer_width(self) -> PointerWidth { |
| 366 | match self { |
| 367 | Aarch64Architecture::Aarch64 | Aarch64Architecture::Aarch64be => PointerWidth::U64, |
| 368 | } |
| 369 | } |
| 370 | |
| 371 | /// Return the endianness of this architecture. |
| 372 | pub fn endianness(self) -> Endianness { |
| 373 | match self { |
| 374 | Aarch64Architecture::Aarch64 => Endianness::Little, |
| 375 | Aarch64Architecture::Aarch64be => Endianness::Big, |
| 376 | } |
| 377 | } |
| 378 | |
| 379 | /// Convert into a string |
| 380 | pub fn into_str(self) -> Cow<'static, str> { |
| 381 | use Aarch64Architecture::*; |
| 382 | |
| 383 | match self { |
| 384 | Aarch64 => Cow::Borrowed("aarch64" ), |
| 385 | Aarch64be => Cow::Borrowed("aarch64_be" ), |
| 386 | } |
| 387 | } |
| 388 | } |
| 389 | |
| 390 | #[cfg_attr (feature = "rust_1_40" , non_exhaustive)] |
| 391 | #[derive (Copy, Clone, Debug, PartialEq, Eq, Hash)] |
| 392 | #[allow (missing_docs)] |
| 393 | pub enum CleverArchitecture { |
| 394 | Clever, |
| 395 | Clever1_0, |
| 396 | } |
| 397 | |
| 398 | impl CleverArchitecture { |
| 399 | /// Convert into a string |
| 400 | pub fn into_str(self) -> Cow<'static, str> { |
| 401 | use CleverArchitecture::*; |
| 402 | |
| 403 | match self { |
| 404 | Clever => Cow::Borrowed("clever" ), |
| 405 | Clever1_0 => Cow::Borrowed("clever1.0" ), |
| 406 | } |
| 407 | } |
| 408 | } |
| 409 | |
| 410 | /// An enum for all 32-bit RISC-V architectures. |
| 411 | #[cfg_attr (feature = "rust_1_40" , non_exhaustive)] |
| 412 | #[derive (Copy, Clone, Debug, PartialEq, Eq, Hash)] |
| 413 | #[allow (missing_docs)] |
| 414 | pub enum Riscv32Architecture { |
| 415 | Riscv32, |
| 416 | Riscv32gc, |
| 417 | Riscv32i, |
| 418 | Riscv32im, |
| 419 | Riscv32ima, |
| 420 | Riscv32imac, |
| 421 | Riscv32imafc, |
| 422 | Riscv32imc, |
| 423 | } |
| 424 | |
| 425 | impl Riscv32Architecture { |
| 426 | /// Convert into a string |
| 427 | pub fn into_str(self) -> Cow<'static, str> { |
| 428 | use Riscv32Architecture::*; |
| 429 | |
| 430 | match self { |
| 431 | Riscv32 => Cow::Borrowed("riscv32" ), |
| 432 | Riscv32gc => Cow::Borrowed("riscv32gc" ), |
| 433 | Riscv32i => Cow::Borrowed("riscv32i" ), |
| 434 | Riscv32im => Cow::Borrowed("riscv32im" ), |
| 435 | Riscv32ima => Cow::Borrowed("riscv32ima" ), |
| 436 | Riscv32imac => Cow::Borrowed("riscv32imac" ), |
| 437 | Riscv32imafc => Cow::Borrowed("riscv32imafc" ), |
| 438 | Riscv32imc => Cow::Borrowed("riscv32imc" ), |
| 439 | } |
| 440 | } |
| 441 | } |
| 442 | |
| 443 | /// An enum for all 64-bit RISC-V architectures. |
| 444 | #[cfg_attr (feature = "rust_1_40" , non_exhaustive)] |
| 445 | #[derive (Copy, Clone, Debug, PartialEq, Eq, Hash)] |
| 446 | #[allow (missing_docs)] |
| 447 | pub enum Riscv64Architecture { |
| 448 | Riscv64, |
| 449 | Riscv64gc, |
| 450 | Riscv64imac, |
| 451 | } |
| 452 | |
| 453 | impl Riscv64Architecture { |
| 454 | /// Convert into a string |
| 455 | pub fn into_str(self) -> Cow<'static, str> { |
| 456 | use Riscv64Architecture::*; |
| 457 | |
| 458 | match self { |
| 459 | Riscv64 => Cow::Borrowed("riscv64" ), |
| 460 | Riscv64gc => Cow::Borrowed("riscv64gc" ), |
| 461 | Riscv64imac => Cow::Borrowed("riscv64imac" ), |
| 462 | } |
| 463 | } |
| 464 | } |
| 465 | |
| 466 | /// An enum for all 32-bit x86 architectures. |
| 467 | #[cfg_attr (feature = "rust_1_40" , non_exhaustive)] |
| 468 | #[derive (Copy, Clone, Debug, PartialEq, Eq, Hash)] |
| 469 | #[allow (missing_docs)] |
| 470 | pub enum X86_32Architecture { |
| 471 | I386, |
| 472 | I586, |
| 473 | I686, |
| 474 | } |
| 475 | |
| 476 | impl X86_32Architecture { |
| 477 | /// Convert into a string |
| 478 | pub fn into_str(self) -> Cow<'static, str> { |
| 479 | use X86_32Architecture::*; |
| 480 | |
| 481 | match self { |
| 482 | I386 => Cow::Borrowed("i386" ), |
| 483 | I586 => Cow::Borrowed("i586" ), |
| 484 | I686 => Cow::Borrowed("i686" ), |
| 485 | } |
| 486 | } |
| 487 | } |
| 488 | |
| 489 | /// An enum for all 32-bit MIPS architectures (not just "MIPS32"). |
| 490 | #[cfg_attr (feature = "rust_1_40" , non_exhaustive)] |
| 491 | #[derive (Copy, Clone, Debug, PartialEq, Eq, Hash)] |
| 492 | #[allow (missing_docs)] |
| 493 | pub enum Mips32Architecture { |
| 494 | Mips, |
| 495 | Mipsel, |
| 496 | Mipsisa32r6, |
| 497 | Mipsisa32r6el, |
| 498 | } |
| 499 | |
| 500 | impl Mips32Architecture { |
| 501 | /// Convert into a string |
| 502 | pub fn into_str(self) -> Cow<'static, str> { |
| 503 | use Mips32Architecture::*; |
| 504 | |
| 505 | match self { |
| 506 | Mips => Cow::Borrowed("mips" ), |
| 507 | Mipsel => Cow::Borrowed("mipsel" ), |
| 508 | Mipsisa32r6 => Cow::Borrowed("mipsisa32r6" ), |
| 509 | Mipsisa32r6el => Cow::Borrowed("mipsisa32r6el" ), |
| 510 | } |
| 511 | } |
| 512 | } |
| 513 | |
| 514 | /// An enum for all 64-bit MIPS architectures (not just "MIPS64"). |
| 515 | #[cfg_attr (feature = "rust_1_40" , non_exhaustive)] |
| 516 | #[derive (Copy, Clone, Debug, PartialEq, Eq, Hash)] |
| 517 | #[allow (missing_docs)] |
| 518 | pub enum Mips64Architecture { |
| 519 | Mips64, |
| 520 | Mips64el, |
| 521 | Mipsisa64r6, |
| 522 | Mipsisa64r6el, |
| 523 | } |
| 524 | |
| 525 | impl Mips64Architecture { |
| 526 | /// Convert into a string |
| 527 | pub fn into_str(self) -> Cow<'static, str> { |
| 528 | use Mips64Architecture::*; |
| 529 | |
| 530 | match self { |
| 531 | Mips64 => Cow::Borrowed("mips64" ), |
| 532 | Mips64el => Cow::Borrowed("mips64el" ), |
| 533 | Mipsisa64r6 => Cow::Borrowed("mipsisa64r6" ), |
| 534 | Mipsisa64r6el => Cow::Borrowed("mipsisa64r6el" ), |
| 535 | } |
| 536 | } |
| 537 | } |
| 538 | |
| 539 | /// A string for a `Vendor::Custom` that can either be used in `const` |
| 540 | /// contexts or hold dynamic strings. |
| 541 | #[derive (Clone, Debug, Eq)] |
| 542 | pub enum CustomVendor { |
| 543 | /// An owned `String`. This supports the general case. |
| 544 | Owned(Box<String>), |
| 545 | /// A static `str`, so that `CustomVendor` can be constructed in `const` |
| 546 | /// contexts. |
| 547 | Static(&'static str), |
| 548 | } |
| 549 | |
| 550 | impl CustomVendor { |
| 551 | /// Extracts a string slice. |
| 552 | pub fn as_str(&self) -> &str { |
| 553 | match self { |
| 554 | CustomVendor::Owned(s: &Box) => s, |
| 555 | CustomVendor::Static(s: &&'static str) => s, |
| 556 | } |
| 557 | } |
| 558 | } |
| 559 | |
| 560 | impl PartialEq for CustomVendor { |
| 561 | fn eq(&self, other: &Self) -> bool { |
| 562 | self.as_str() == other.as_str() |
| 563 | } |
| 564 | } |
| 565 | |
| 566 | impl Hash for CustomVendor { |
| 567 | fn hash<H: Hasher>(&self, state: &mut H) { |
| 568 | self.as_str().hash(state) |
| 569 | } |
| 570 | } |
| 571 | |
| 572 | /// The "vendor" field, which in practice is little more than an arbitrary |
| 573 | /// modifier. |
| 574 | #[cfg_attr (feature = "rust_1_40" , non_exhaustive)] |
| 575 | #[derive (Clone, Debug, PartialEq, Eq, Hash)] |
| 576 | #[allow (missing_docs)] |
| 577 | pub enum Vendor { |
| 578 | Unknown, |
| 579 | Amd, |
| 580 | Apple, |
| 581 | Espressif, |
| 582 | Experimental, |
| 583 | Fortanix, |
| 584 | Ibm, |
| 585 | Kmc, |
| 586 | Nintendo, |
| 587 | Nvidia, |
| 588 | Pc, |
| 589 | Rumprun, |
| 590 | Sun, |
| 591 | Uwp, |
| 592 | Wrs, |
| 593 | |
| 594 | /// A custom vendor. "Custom" in this context means that the vendor is |
| 595 | /// not specifically recognized by upstream Autotools, LLVM, Rust, or other |
| 596 | /// relevant authorities on triple naming. It's useful for people building |
| 597 | /// and using locally patched toolchains. |
| 598 | /// |
| 599 | /// Outside of such patched environments, users of `target-lexicon` should |
| 600 | /// treat `Custom` the same as `Unknown` and ignore the string. |
| 601 | Custom(CustomVendor), |
| 602 | } |
| 603 | |
| 604 | impl Vendor { |
| 605 | /// Extracts a string slice. |
| 606 | pub fn as_str(&self) -> &str { |
| 607 | use Vendor::*; |
| 608 | |
| 609 | match self { |
| 610 | Unknown => "unknown" , |
| 611 | Amd => "amd" , |
| 612 | Apple => "apple" , |
| 613 | Espressif => "espressif" , |
| 614 | Experimental => "experimental" , |
| 615 | Fortanix => "fortanix" , |
| 616 | Ibm => "ibm" , |
| 617 | Kmc => "kmc" , |
| 618 | Nintendo => "nintendo" , |
| 619 | Nvidia => "nvidia" , |
| 620 | Pc => "pc" , |
| 621 | Rumprun => "rumprun" , |
| 622 | Sun => "sun" , |
| 623 | Uwp => "uwp" , |
| 624 | Wrs => "wrs" , |
| 625 | Custom(name) => name.as_str(), |
| 626 | } |
| 627 | } |
| 628 | } |
| 629 | |
| 630 | /// The minimum OS version that we're compiling for. |
| 631 | /// |
| 632 | /// This is formatted as `"major.minor.patch"`. |
| 633 | /// |
| 634 | /// The size of the parts here are limited by Mach-O's `LC_BUILD_VERSION`. |
| 635 | #[derive (Copy, Clone, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] |
| 636 | #[allow (missing_docs)] |
| 637 | pub struct DeploymentTarget { |
| 638 | pub major: u16, |
| 639 | pub minor: u8, |
| 640 | pub patch: u8, |
| 641 | } |
| 642 | |
| 643 | /// The "operating system" field, which sometimes implies an environment, and |
| 644 | /// sometimes isn't an actual operating system. |
| 645 | /// |
| 646 | /// LLVM's Apple triples may optionally include the [deployment target]. |
| 647 | /// |
| 648 | /// [deployment target]: DeploymentTarget |
| 649 | #[cfg_attr (feature = "rust_1_40" , non_exhaustive)] |
| 650 | #[derive (Copy, Clone, Debug, PartialEq, Eq, Hash)] |
| 651 | #[allow (missing_docs)] |
| 652 | pub enum OperatingSystem { |
| 653 | Unknown, |
| 654 | Aix, |
| 655 | AmdHsa, |
| 656 | Bitrig, |
| 657 | Cloudabi, |
| 658 | Cuda, |
| 659 | /// The general [Darwin][darwin-wiki] core OS. |
| 660 | /// |
| 661 | /// Generally, `-mmacosx-version-min=...` or similar flags are required by |
| 662 | /// Clang to determine the actual OS (either macOS, iOS, tvOS, watchOS or |
| 663 | /// visionOS). |
| 664 | /// |
| 665 | /// WARNING: When parsing `rustc` target triples, this matches the macOS |
| 666 | /// target triples as well. |
| 667 | /// |
| 668 | /// [darwin-wiki]: https://en.wikipedia.org/wiki/Darwin_(operating_system) |
| 669 | Darwin(Option<DeploymentTarget>), |
| 670 | Dragonfly, |
| 671 | Emscripten, |
| 672 | Espidf, |
| 673 | Freebsd, |
| 674 | Fuchsia, |
| 675 | Haiku, |
| 676 | Hermit, |
| 677 | Horizon, |
| 678 | Hurd, |
| 679 | Illumos, |
| 680 | IOS(Option<DeploymentTarget>), |
| 681 | L4re, |
| 682 | Linux, |
| 683 | /// macOS. |
| 684 | /// |
| 685 | /// WARNING: This does _not_ match the macOS triples when parsing `rustc` |
| 686 | /// target triples, for that see the [`darwin`](Self::Darwin) OS name. |
| 687 | MacOSX(Option<DeploymentTarget>), |
| 688 | Nebulet, |
| 689 | Netbsd, |
| 690 | None_, |
| 691 | Openbsd, |
| 692 | Psp, |
| 693 | Redox, |
| 694 | Solaris, |
| 695 | SolidAsp3, |
| 696 | TvOS(Option<DeploymentTarget>), |
| 697 | Uefi, |
| 698 | VisionOS(Option<DeploymentTarget>), |
| 699 | VxWorks, |
| 700 | Wasi, |
| 701 | WasiP1, |
| 702 | WasiP2, |
| 703 | WatchOS(Option<DeploymentTarget>), |
| 704 | Windows, |
| 705 | /// An alternate name for [visionOS][Self::VisionOS]. |
| 706 | XROS(Option<DeploymentTarget>), |
| 707 | } |
| 708 | |
| 709 | impl OperatingSystem { |
| 710 | /// Convert into a string |
| 711 | pub fn into_str(self) -> Cow<'static, str> { |
| 712 | use OperatingSystem::*; |
| 713 | |
| 714 | let darwin_version = |name, deployment_target| { |
| 715 | if let Some(DeploymentTarget { |
| 716 | major, |
| 717 | minor, |
| 718 | patch, |
| 719 | }) = deployment_target |
| 720 | { |
| 721 | Cow::Owned(format!(" {}{}. {}. {}" , name, major, minor, patch)) |
| 722 | } else { |
| 723 | Cow::Borrowed(name) |
| 724 | } |
| 725 | }; |
| 726 | |
| 727 | match self { |
| 728 | Unknown => Cow::Borrowed("unknown" ), |
| 729 | Aix => Cow::Borrowed("aix" ), |
| 730 | AmdHsa => Cow::Borrowed("amdhsa" ), |
| 731 | Bitrig => Cow::Borrowed("bitrig" ), |
| 732 | Cloudabi => Cow::Borrowed("cloudabi" ), |
| 733 | Cuda => Cow::Borrowed("cuda" ), |
| 734 | Darwin(deployment_target) => darwin_version("darwin" , deployment_target), |
| 735 | Dragonfly => Cow::Borrowed("dragonfly" ), |
| 736 | Emscripten => Cow::Borrowed("emscripten" ), |
| 737 | Espidf => Cow::Borrowed("espidf" ), |
| 738 | Freebsd => Cow::Borrowed("freebsd" ), |
| 739 | Fuchsia => Cow::Borrowed("fuchsia" ), |
| 740 | Haiku => Cow::Borrowed("haiku" ), |
| 741 | Hermit => Cow::Borrowed("hermit" ), |
| 742 | Horizon => Cow::Borrowed("horizon" ), |
| 743 | Hurd => Cow::Borrowed("hurd" ), |
| 744 | Illumos => Cow::Borrowed("illumos" ), |
| 745 | IOS(deployment_target) => darwin_version("ios" , deployment_target), |
| 746 | L4re => Cow::Borrowed("l4re" ), |
| 747 | Linux => Cow::Borrowed("linux" ), |
| 748 | MacOSX(deployment_target) => darwin_version("macosx" , deployment_target), |
| 749 | Nebulet => Cow::Borrowed("nebulet" ), |
| 750 | Netbsd => Cow::Borrowed("netbsd" ), |
| 751 | None_ => Cow::Borrowed("none" ), |
| 752 | Openbsd => Cow::Borrowed("openbsd" ), |
| 753 | Psp => Cow::Borrowed("psp" ), |
| 754 | Redox => Cow::Borrowed("redox" ), |
| 755 | Solaris => Cow::Borrowed("solaris" ), |
| 756 | SolidAsp3 => Cow::Borrowed("solid_asp3" ), |
| 757 | TvOS(deployment_target) => darwin_version("tvos" , deployment_target), |
| 758 | Uefi => Cow::Borrowed("uefi" ), |
| 759 | VxWorks => Cow::Borrowed("vxworks" ), |
| 760 | VisionOS(deployment_target) => darwin_version("visionos" , deployment_target), |
| 761 | Wasi => Cow::Borrowed("wasi" ), |
| 762 | WasiP1 => Cow::Borrowed("wasip1" ), |
| 763 | WasiP2 => Cow::Borrowed("wasip2" ), |
| 764 | WatchOS(deployment_target) => darwin_version("watchos" , deployment_target), |
| 765 | Windows => Cow::Borrowed("windows" ), |
| 766 | XROS(deployment_target) => darwin_version("xros" , deployment_target), |
| 767 | } |
| 768 | } |
| 769 | |
| 770 | /// Whether the OS is similar to Darwin. |
| 771 | /// |
| 772 | /// This matches on any of: |
| 773 | /// - [Darwin](Self::Darwin) |
| 774 | /// - [iOS](Self::IOS) |
| 775 | /// - [macOS](Self::MacOSX) |
| 776 | /// - [tvOS](Self::TvOS) |
| 777 | /// - [visionOS](Self::VisionOS) |
| 778 | /// - [watchOS](Self::WatchOS) |
| 779 | /// - [xrOS](Self::XROS) |
| 780 | pub fn is_like_darwin(&self) -> bool { |
| 781 | use OperatingSystem::*; |
| 782 | |
| 783 | match self { |
| 784 | Darwin(_) | IOS(_) | MacOSX(_) | TvOS(_) | VisionOS(_) | WatchOS(_) | XROS(_) => true, |
| 785 | _ => false, |
| 786 | } |
| 787 | } |
| 788 | } |
| 789 | |
| 790 | /// The "environment" field, which specifies an ABI environment on top of the |
| 791 | /// operating system. In many configurations, this field is omitted, and the |
| 792 | /// environment is implied by the operating system. |
| 793 | #[cfg_attr (feature = "rust_1_40" , non_exhaustive)] |
| 794 | #[derive (Copy, Clone, Debug, PartialEq, Eq, Hash)] |
| 795 | #[allow (missing_docs)] |
| 796 | pub enum Environment { |
| 797 | Unknown, |
| 798 | AmdGiz, |
| 799 | Android, |
| 800 | Androideabi, |
| 801 | Eabi, |
| 802 | Eabihf, |
| 803 | Gnu, |
| 804 | Gnuabi64, |
| 805 | Gnueabi, |
| 806 | Gnueabihf, |
| 807 | Gnuspe, |
| 808 | Gnux32, |
| 809 | GnuIlp32, |
| 810 | GnuLlvm, |
| 811 | HermitKernel, |
| 812 | HurdKernel, |
| 813 | LinuxKernel, |
| 814 | Macabi, |
| 815 | Musl, |
| 816 | Musleabi, |
| 817 | Musleabihf, |
| 818 | Muslabi64, |
| 819 | Msvc, |
| 820 | Newlib, |
| 821 | None, |
| 822 | Kernel, |
| 823 | Uclibc, |
| 824 | Uclibceabi, |
| 825 | Uclibceabihf, |
| 826 | Sgx, |
| 827 | Sim, |
| 828 | Softfloat, |
| 829 | Spe, |
| 830 | Threads, |
| 831 | Ohos, |
| 832 | } |
| 833 | |
| 834 | impl Environment { |
| 835 | /// Convert into a string |
| 836 | pub fn into_str(self) -> Cow<'static, str> { |
| 837 | use Environment::*; |
| 838 | |
| 839 | match self { |
| 840 | Unknown => Cow::Borrowed("unknown" ), |
| 841 | AmdGiz => Cow::Borrowed("amdgiz" ), |
| 842 | Android => Cow::Borrowed("android" ), |
| 843 | Androideabi => Cow::Borrowed("androideabi" ), |
| 844 | Eabi => Cow::Borrowed("eabi" ), |
| 845 | Eabihf => Cow::Borrowed("eabihf" ), |
| 846 | Gnu => Cow::Borrowed("gnu" ), |
| 847 | Gnuabi64 => Cow::Borrowed("gnuabi64" ), |
| 848 | Gnueabi => Cow::Borrowed("gnueabi" ), |
| 849 | Gnueabihf => Cow::Borrowed("gnueabihf" ), |
| 850 | Gnuspe => Cow::Borrowed("gnuspe" ), |
| 851 | Gnux32 => Cow::Borrowed("gnux32" ), |
| 852 | GnuIlp32 => Cow::Borrowed("gnu_ilp32" ), |
| 853 | GnuLlvm => Cow::Borrowed("gnullvm" ), |
| 854 | HermitKernel => Cow::Borrowed("hermitkernel" ), |
| 855 | HurdKernel => Cow::Borrowed("hurdkernel" ), |
| 856 | LinuxKernel => Cow::Borrowed("linuxkernel" ), |
| 857 | Macabi => Cow::Borrowed("macabi" ), |
| 858 | Musl => Cow::Borrowed("musl" ), |
| 859 | Musleabi => Cow::Borrowed("musleabi" ), |
| 860 | Musleabihf => Cow::Borrowed("musleabihf" ), |
| 861 | Muslabi64 => Cow::Borrowed("muslabi64" ), |
| 862 | Msvc => Cow::Borrowed("msvc" ), |
| 863 | Newlib => Cow::Borrowed("newlib" ), |
| 864 | None => Cow::Borrowed("none" ), |
| 865 | Kernel => Cow::Borrowed("kernel" ), |
| 866 | Uclibc => Cow::Borrowed("uclibc" ), |
| 867 | Uclibceabi => Cow::Borrowed("uclibceabi" ), |
| 868 | Uclibceabihf => Cow::Borrowed("uclibceabihf" ), |
| 869 | Sgx => Cow::Borrowed("sgx" ), |
| 870 | Sim => Cow::Borrowed("sim" ), |
| 871 | Softfloat => Cow::Borrowed("softfloat" ), |
| 872 | Spe => Cow::Borrowed("spe" ), |
| 873 | Threads => Cow::Borrowed("threads" ), |
| 874 | Ohos => Cow::Borrowed("ohos" ), |
| 875 | } |
| 876 | } |
| 877 | } |
| 878 | |
| 879 | /// The "binary format" field, which is usually omitted, and the binary format |
| 880 | /// is implied by the other fields. |
| 881 | #[cfg_attr (feature = "rust_1_40" , non_exhaustive)] |
| 882 | #[derive (Copy, Clone, Debug, PartialEq, Eq, Hash)] |
| 883 | #[allow (missing_docs)] |
| 884 | pub enum BinaryFormat { |
| 885 | Unknown, |
| 886 | Elf, |
| 887 | Coff, |
| 888 | Macho, |
| 889 | Wasm, |
| 890 | Xcoff, |
| 891 | } |
| 892 | |
| 893 | impl BinaryFormat { |
| 894 | /// Convert into a string |
| 895 | pub fn into_str(self) -> Cow<'static, str> { |
| 896 | use BinaryFormat::*; |
| 897 | |
| 898 | match self { |
| 899 | Unknown => Cow::Borrowed("unknown" ), |
| 900 | Elf => Cow::Borrowed("elf" ), |
| 901 | Coff => Cow::Borrowed("coff" ), |
| 902 | Macho => Cow::Borrowed("macho" ), |
| 903 | Wasm => Cow::Borrowed("wasm" ), |
| 904 | Xcoff => Cow::Borrowed("xcoff" ), |
| 905 | } |
| 906 | } |
| 907 | } |
| 908 | |
| 909 | impl Architecture { |
| 910 | /// Return the endianness of this architecture. |
| 911 | #[rustfmt::skip] |
| 912 | pub fn endianness(self) -> Result<Endianness, ()> { |
| 913 | use Architecture::*; |
| 914 | |
| 915 | match self { |
| 916 | Unknown => Err(()), |
| 917 | Arm(arm) => Ok(arm.endianness()), |
| 918 | Aarch64(aarch) => Ok(aarch.endianness()), |
| 919 | AmdGcn |
| 920 | | Asmjs |
| 921 | | Avr |
| 922 | | Bpfel |
| 923 | | Hexagon |
| 924 | | X86_32(_) |
| 925 | | LoongArch64 |
| 926 | | Mips64(Mips64Architecture::Mips64el) |
| 927 | | Mips32(Mips32Architecture::Mipsel) |
| 928 | | Mips32(Mips32Architecture::Mipsisa32r6el) |
| 929 | | Mips64(Mips64Architecture::Mipsisa64r6el) |
| 930 | | Msp430 |
| 931 | | Nvptx64 |
| 932 | | Pulley32 |
| 933 | | Pulley64 |
| 934 | | Powerpc64le |
| 935 | | Riscv32(_) |
| 936 | | Riscv64(_) |
| 937 | | Wasm32 |
| 938 | | Wasm64 |
| 939 | | X86_64 |
| 940 | | X86_64h |
| 941 | | XTensa |
| 942 | | Clever(_) => Ok(Endianness::Little), |
| 943 | Bpfeb |
| 944 | | M68k |
| 945 | | Mips32(Mips32Architecture::Mips) |
| 946 | | Mips64(Mips64Architecture::Mips64) |
| 947 | | Mips32(Mips32Architecture::Mipsisa32r6) |
| 948 | | Mips64(Mips64Architecture::Mipsisa64r6) |
| 949 | | Powerpc |
| 950 | | Powerpc64 |
| 951 | | Pulley32be |
| 952 | | Pulley64be |
| 953 | | S390x |
| 954 | | Sparc |
| 955 | | Sparc64 |
| 956 | | Sparcv9 => Ok(Endianness::Big), |
| 957 | #[cfg (feature="arch_zkasm" )] |
| 958 | ZkAsm => Ok(Endianness::Big), |
| 959 | } |
| 960 | } |
| 961 | |
| 962 | /// Return the pointer bit width of this target's architecture. |
| 963 | /// |
| 964 | /// This function is only aware of the CPU architecture so it is not aware |
| 965 | /// of ilp32 and x32 ABIs. |
| 966 | #[rustfmt::skip] |
| 967 | pub fn pointer_width(self) -> Result<PointerWidth, ()> { |
| 968 | use Architecture::*; |
| 969 | |
| 970 | match self { |
| 971 | Unknown => Err(()), |
| 972 | Avr | Msp430 => Ok(PointerWidth::U16), |
| 973 | Arm(arm) => Ok(arm.pointer_width()), |
| 974 | Aarch64(aarch) => Ok(aarch.pointer_width()), |
| 975 | Asmjs |
| 976 | | Hexagon |
| 977 | | X86_32(_) |
| 978 | | Riscv32(_) |
| 979 | | Sparc |
| 980 | | Wasm32 |
| 981 | | M68k |
| 982 | | Mips32(_) |
| 983 | | Pulley32 |
| 984 | | Pulley32be |
| 985 | | Powerpc |
| 986 | | XTensa => Ok(PointerWidth::U32), |
| 987 | AmdGcn |
| 988 | | Bpfeb |
| 989 | | Bpfel |
| 990 | | Powerpc64le |
| 991 | | Riscv64(_) |
| 992 | | X86_64 |
| 993 | | X86_64h |
| 994 | | Mips64(_) |
| 995 | | Nvptx64 |
| 996 | | Pulley64 |
| 997 | | Pulley64be |
| 998 | | Powerpc64 |
| 999 | | S390x |
| 1000 | | Sparc64 |
| 1001 | | Sparcv9 |
| 1002 | | LoongArch64 |
| 1003 | | Wasm64 |
| 1004 | | Clever(_) => Ok(PointerWidth::U64), |
| 1005 | #[cfg (feature="arch_zkasm" )] |
| 1006 | ZkAsm => Ok(PointerWidth::U64), |
| 1007 | } |
| 1008 | } |
| 1009 | |
| 1010 | /// Checks if this Architecture is some variant of Clever-ISA |
| 1011 | pub fn is_clever(&self) -> bool { |
| 1012 | match self { |
| 1013 | Architecture::Clever(_) => true, |
| 1014 | _ => false, |
| 1015 | } |
| 1016 | } |
| 1017 | |
| 1018 | /// Convert into a string |
| 1019 | pub fn into_str(self) -> Cow<'static, str> { |
| 1020 | use Architecture::*; |
| 1021 | |
| 1022 | match self { |
| 1023 | Arm(arm) => arm.into_str(), |
| 1024 | Aarch64(aarch) => aarch.into_str(), |
| 1025 | Unknown => Cow::Borrowed("unknown" ), |
| 1026 | AmdGcn => Cow::Borrowed("amdgcn" ), |
| 1027 | Asmjs => Cow::Borrowed("asmjs" ), |
| 1028 | Avr => Cow::Borrowed("avr" ), |
| 1029 | Bpfeb => Cow::Borrowed("bpfeb" ), |
| 1030 | Bpfel => Cow::Borrowed("bpfel" ), |
| 1031 | Hexagon => Cow::Borrowed("hexagon" ), |
| 1032 | X86_32(x86_32) => x86_32.into_str(), |
| 1033 | LoongArch64 => Cow::Borrowed("loongarch64" ), |
| 1034 | M68k => Cow::Borrowed("m68k" ), |
| 1035 | Mips32(mips32) => mips32.into_str(), |
| 1036 | Mips64(mips64) => mips64.into_str(), |
| 1037 | Msp430 => Cow::Borrowed("msp430" ), |
| 1038 | Nvptx64 => Cow::Borrowed("nvptx64" ), |
| 1039 | Pulley32 => Cow::Borrowed("pulley32" ), |
| 1040 | Pulley64 => Cow::Borrowed("pulley64" ), |
| 1041 | Pulley32be => Cow::Borrowed("pulley32be" ), |
| 1042 | Pulley64be => Cow::Borrowed("pulley64be" ), |
| 1043 | Powerpc => Cow::Borrowed("powerpc" ), |
| 1044 | Powerpc64 => Cow::Borrowed("powerpc64" ), |
| 1045 | Powerpc64le => Cow::Borrowed("powerpc64le" ), |
| 1046 | Riscv32(riscv32) => riscv32.into_str(), |
| 1047 | Riscv64(riscv64) => riscv64.into_str(), |
| 1048 | S390x => Cow::Borrowed("s390x" ), |
| 1049 | Sparc => Cow::Borrowed("sparc" ), |
| 1050 | Sparc64 => Cow::Borrowed("sparc64" ), |
| 1051 | Sparcv9 => Cow::Borrowed("sparcv9" ), |
| 1052 | Wasm32 => Cow::Borrowed("wasm32" ), |
| 1053 | Wasm64 => Cow::Borrowed("wasm64" ), |
| 1054 | X86_64 => Cow::Borrowed("x86_64" ), |
| 1055 | X86_64h => Cow::Borrowed("x86_64h" ), |
| 1056 | XTensa => Cow::Borrowed("xtensa" ), |
| 1057 | Clever(ver) => ver.into_str(), |
| 1058 | #[cfg (feature = "arch_zkasm" )] |
| 1059 | ZkAsm => Cow::Borrowed("zkasm" ), |
| 1060 | } |
| 1061 | } |
| 1062 | } |
| 1063 | |
| 1064 | /// Return the binary format implied by this target triple, ignoring its |
| 1065 | /// `binary_format` field. |
| 1066 | pub(crate) fn default_binary_format(triple: &Triple) -> BinaryFormat { |
| 1067 | match triple.operating_system { |
| 1068 | OperatingSystem::None_ => match triple.environment { |
| 1069 | Environment::Eabi | Environment::Eabihf => BinaryFormat::Elf, |
| 1070 | _ => BinaryFormat::Unknown, |
| 1071 | }, |
| 1072 | OperatingSystem::Aix => BinaryFormat::Xcoff, |
| 1073 | os: OperatingSystem if os.is_like_darwin() => BinaryFormat::Macho, |
| 1074 | OperatingSystem::Windows => BinaryFormat::Coff, |
| 1075 | OperatingSystem::Nebulet |
| 1076 | | OperatingSystem::Emscripten |
| 1077 | | OperatingSystem::VxWorks |
| 1078 | | OperatingSystem::Wasi |
| 1079 | | OperatingSystem::Unknown => match triple.architecture { |
| 1080 | Architecture::Wasm32 | Architecture::Wasm64 => BinaryFormat::Wasm, |
| 1081 | Architecture::Unknown => BinaryFormat::Unknown, |
| 1082 | // Default to ELF, following `getDefaultFormat` in LLVM. |
| 1083 | _ => BinaryFormat::Elf, |
| 1084 | }, |
| 1085 | _ => BinaryFormat::Elf, |
| 1086 | } |
| 1087 | } |
| 1088 | |
| 1089 | impl fmt::Display for ArmArchitecture { |
| 1090 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
| 1091 | f.write_str(&self.into_str()) |
| 1092 | } |
| 1093 | } |
| 1094 | |
| 1095 | impl fmt::Display for Aarch64Architecture { |
| 1096 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
| 1097 | f.write_str(&self.into_str()) |
| 1098 | } |
| 1099 | } |
| 1100 | |
| 1101 | impl fmt::Display for CleverArchitecture { |
| 1102 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
| 1103 | f.write_str(&self.into_str()) |
| 1104 | } |
| 1105 | } |
| 1106 | |
| 1107 | impl fmt::Display for Riscv32Architecture { |
| 1108 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
| 1109 | f.write_str(&self.into_str()) |
| 1110 | } |
| 1111 | } |
| 1112 | |
| 1113 | impl fmt::Display for Riscv64Architecture { |
| 1114 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
| 1115 | f.write_str(&self.into_str()) |
| 1116 | } |
| 1117 | } |
| 1118 | |
| 1119 | impl fmt::Display for X86_32Architecture { |
| 1120 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
| 1121 | f.write_str(&self.into_str()) |
| 1122 | } |
| 1123 | } |
| 1124 | |
| 1125 | impl fmt::Display for Mips32Architecture { |
| 1126 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
| 1127 | f.write_str(&self.into_str()) |
| 1128 | } |
| 1129 | } |
| 1130 | |
| 1131 | impl fmt::Display for Mips64Architecture { |
| 1132 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
| 1133 | f.write_str(&self.into_str()) |
| 1134 | } |
| 1135 | } |
| 1136 | |
| 1137 | impl fmt::Display for Architecture { |
| 1138 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
| 1139 | f.write_str(&self.into_str()) |
| 1140 | } |
| 1141 | } |
| 1142 | |
| 1143 | impl FromStr for ArmArchitecture { |
| 1144 | type Err = (); |
| 1145 | |
| 1146 | fn from_str(s: &str) -> Result<Self, ()> { |
| 1147 | use ArmArchitecture::*; |
| 1148 | |
| 1149 | Ok(match s { |
| 1150 | "arm" => Arm, |
| 1151 | "armeb" => Armeb, |
| 1152 | "armv4" => Armv4, |
| 1153 | "armv4t" => Armv4t, |
| 1154 | "armv5t" => Armv5t, |
| 1155 | "armv5te" => Armv5te, |
| 1156 | "armv5tej" => Armv5tej, |
| 1157 | "armv6" => Armv6, |
| 1158 | "armv6j" => Armv6j, |
| 1159 | "armv6k" => Armv6k, |
| 1160 | "armv6z" => Armv6z, |
| 1161 | "armv6kz" => Armv6kz, |
| 1162 | "armv6t2" => Armv6t2, |
| 1163 | "armv6m" => Armv6m, |
| 1164 | "armv7" => Armv7, |
| 1165 | "armv7a" => Armv7a, |
| 1166 | "armv7k" => Armv7k, |
| 1167 | "armv7ve" => Armv7ve, |
| 1168 | "armv7m" => Armv7m, |
| 1169 | "armv7r" => Armv7r, |
| 1170 | "armv7s" => Armv7s, |
| 1171 | "armv8" => Armv8, |
| 1172 | "armv8a" => Armv8a, |
| 1173 | "armv8.1a" => Armv8_1a, |
| 1174 | "armv8.2a" => Armv8_2a, |
| 1175 | "armv8.3a" => Armv8_3a, |
| 1176 | "armv8.4a" => Armv8_4a, |
| 1177 | "armv8.5a" => Armv8_5a, |
| 1178 | "armv8m.base" => Armv8mBase, |
| 1179 | "armv8m.main" => Armv8mMain, |
| 1180 | "armv8r" => Armv8r, |
| 1181 | "thumbeb" => Thumbeb, |
| 1182 | "thumbv4t" => Thumbv4t, |
| 1183 | "thumbv5te" => Thumbv5te, |
| 1184 | "thumbv6m" => Thumbv6m, |
| 1185 | "thumbv7a" => Thumbv7a, |
| 1186 | "thumbv7em" => Thumbv7em, |
| 1187 | "thumbv7m" => Thumbv7m, |
| 1188 | "thumbv7neon" => Thumbv7neon, |
| 1189 | "thumbv8m.base" => Thumbv8mBase, |
| 1190 | "thumbv8m.main" => Thumbv8mMain, |
| 1191 | "armebv7r" => Armebv7r, |
| 1192 | _ => return Err(()), |
| 1193 | }) |
| 1194 | } |
| 1195 | } |
| 1196 | |
| 1197 | impl FromStr for Aarch64Architecture { |
| 1198 | type Err = (); |
| 1199 | |
| 1200 | fn from_str(s: &str) -> Result<Self, ()> { |
| 1201 | use Aarch64Architecture::*; |
| 1202 | |
| 1203 | Ok(match s { |
| 1204 | "aarch64" => Aarch64, |
| 1205 | "arm64" => Aarch64, |
| 1206 | "aarch64_be" => Aarch64be, |
| 1207 | _ => return Err(()), |
| 1208 | }) |
| 1209 | } |
| 1210 | } |
| 1211 | |
| 1212 | impl FromStr for CleverArchitecture { |
| 1213 | type Err = (); |
| 1214 | fn from_str(s: &str) -> Result<Self, ()> { |
| 1215 | match s { |
| 1216 | "clever" => Ok(CleverArchitecture::Clever), |
| 1217 | "clever1.0" => Ok(CleverArchitecture::Clever1_0), |
| 1218 | _ => Err(()), |
| 1219 | } |
| 1220 | } |
| 1221 | } |
| 1222 | |
| 1223 | impl FromStr for Riscv32Architecture { |
| 1224 | type Err = (); |
| 1225 | |
| 1226 | fn from_str(s: &str) -> Result<Self, ()> { |
| 1227 | use Riscv32Architecture::*; |
| 1228 | |
| 1229 | Ok(match s { |
| 1230 | "riscv32" => Riscv32, |
| 1231 | "riscv32gc" => Riscv32gc, |
| 1232 | "riscv32i" => Riscv32i, |
| 1233 | "riscv32im" => Riscv32im, |
| 1234 | "riscv32ima" => Riscv32ima, |
| 1235 | "riscv32imac" => Riscv32imac, |
| 1236 | "riscv32imafc" => Riscv32imafc, |
| 1237 | "riscv32imc" => Riscv32imc, |
| 1238 | _ => return Err(()), |
| 1239 | }) |
| 1240 | } |
| 1241 | } |
| 1242 | |
| 1243 | impl FromStr for Riscv64Architecture { |
| 1244 | type Err = (); |
| 1245 | |
| 1246 | fn from_str(s: &str) -> Result<Self, ()> { |
| 1247 | use Riscv64Architecture::*; |
| 1248 | |
| 1249 | Ok(match s { |
| 1250 | "riscv64" => Riscv64, |
| 1251 | "riscv64gc" => Riscv64gc, |
| 1252 | "riscv64imac" => Riscv64imac, |
| 1253 | _ => return Err(()), |
| 1254 | }) |
| 1255 | } |
| 1256 | } |
| 1257 | |
| 1258 | impl FromStr for X86_32Architecture { |
| 1259 | type Err = (); |
| 1260 | |
| 1261 | fn from_str(s: &str) -> Result<Self, ()> { |
| 1262 | use X86_32Architecture::*; |
| 1263 | |
| 1264 | Ok(match s { |
| 1265 | "i386" => I386, |
| 1266 | "i586" => I586, |
| 1267 | "i686" => I686, |
| 1268 | _ => return Err(()), |
| 1269 | }) |
| 1270 | } |
| 1271 | } |
| 1272 | |
| 1273 | impl FromStr for Mips32Architecture { |
| 1274 | type Err = (); |
| 1275 | |
| 1276 | fn from_str(s: &str) -> Result<Self, ()> { |
| 1277 | use Mips32Architecture::*; |
| 1278 | |
| 1279 | Ok(match s { |
| 1280 | "mips" => Mips, |
| 1281 | "mipsel" => Mipsel, |
| 1282 | "mipsisa32r6" => Mipsisa32r6, |
| 1283 | "mipsisa32r6el" => Mipsisa32r6el, |
| 1284 | _ => return Err(()), |
| 1285 | }) |
| 1286 | } |
| 1287 | } |
| 1288 | |
| 1289 | impl FromStr for Mips64Architecture { |
| 1290 | type Err = (); |
| 1291 | |
| 1292 | fn from_str(s: &str) -> Result<Self, ()> { |
| 1293 | use Mips64Architecture::*; |
| 1294 | |
| 1295 | Ok(match s { |
| 1296 | "mips64" => Mips64, |
| 1297 | "mips64el" => Mips64el, |
| 1298 | "mipsisa64r6" => Mipsisa64r6, |
| 1299 | "mipsisa64r6el" => Mipsisa64r6el, |
| 1300 | _ => return Err(()), |
| 1301 | }) |
| 1302 | } |
| 1303 | } |
| 1304 | |
| 1305 | impl FromStr for Architecture { |
| 1306 | type Err = (); |
| 1307 | |
| 1308 | fn from_str(s: &str) -> Result<Self, ()> { |
| 1309 | use Architecture::*; |
| 1310 | |
| 1311 | Ok(match s { |
| 1312 | "unknown" => Unknown, |
| 1313 | "amdgcn" => AmdGcn, |
| 1314 | "asmjs" => Asmjs, |
| 1315 | "avr" => Avr, |
| 1316 | "bpfeb" => Bpfeb, |
| 1317 | "bpfel" => Bpfel, |
| 1318 | "hexagon" => Hexagon, |
| 1319 | "loongarch64" => LoongArch64, |
| 1320 | "m68k" => M68k, |
| 1321 | "msp430" => Msp430, |
| 1322 | "nvptx64" => Nvptx64, |
| 1323 | "pulley32" => Pulley32, |
| 1324 | "pulley64" => Pulley64, |
| 1325 | "pulley32be" => Pulley32be, |
| 1326 | "pulley64be" => Pulley64be, |
| 1327 | "powerpc" => Powerpc, |
| 1328 | "powerpc64" => Powerpc64, |
| 1329 | "powerpc64le" => Powerpc64le, |
| 1330 | "s390x" => S390x, |
| 1331 | "sparc" => Sparc, |
| 1332 | "sparc64" => Sparc64, |
| 1333 | "sparcv9" => Sparcv9, |
| 1334 | "wasm32" => Wasm32, |
| 1335 | "wasm64" => Wasm64, |
| 1336 | "x86_64" => X86_64, |
| 1337 | "x86_64h" => X86_64h, |
| 1338 | "xtensa" => XTensa, |
| 1339 | #[cfg (feature = "arch_zkasm" )] |
| 1340 | "zkasm" => ZkAsm, |
| 1341 | _ => { |
| 1342 | if let Ok(arm) = ArmArchitecture::from_str(s) { |
| 1343 | Arm(arm) |
| 1344 | } else if let Ok(aarch64) = Aarch64Architecture::from_str(s) { |
| 1345 | Aarch64(aarch64) |
| 1346 | } else if let Ok(riscv32) = Riscv32Architecture::from_str(s) { |
| 1347 | Riscv32(riscv32) |
| 1348 | } else if let Ok(riscv64) = Riscv64Architecture::from_str(s) { |
| 1349 | Riscv64(riscv64) |
| 1350 | } else if let Ok(x86_32) = X86_32Architecture::from_str(s) { |
| 1351 | X86_32(x86_32) |
| 1352 | } else if let Ok(mips32) = Mips32Architecture::from_str(s) { |
| 1353 | Mips32(mips32) |
| 1354 | } else if let Ok(mips64) = Mips64Architecture::from_str(s) { |
| 1355 | Mips64(mips64) |
| 1356 | } else if let Ok(clever) = CleverArchitecture::from_str(s) { |
| 1357 | Clever(clever) |
| 1358 | } else { |
| 1359 | return Err(()); |
| 1360 | } |
| 1361 | } |
| 1362 | }) |
| 1363 | } |
| 1364 | } |
| 1365 | |
| 1366 | impl fmt::Display for Vendor { |
| 1367 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
| 1368 | f.write_str(self.as_str()) |
| 1369 | } |
| 1370 | } |
| 1371 | |
| 1372 | impl FromStr for Vendor { |
| 1373 | type Err = (); |
| 1374 | |
| 1375 | fn from_str(s: &str) -> Result<Self, ()> { |
| 1376 | use Vendor::*; |
| 1377 | |
| 1378 | Ok(match s { |
| 1379 | "unknown" => Unknown, |
| 1380 | "amd" => Amd, |
| 1381 | "apple" => Apple, |
| 1382 | "espressif" => Espressif, |
| 1383 | "experimental" => Experimental, |
| 1384 | "fortanix" => Fortanix, |
| 1385 | "ibm" => Ibm, |
| 1386 | "kmc" => Kmc, |
| 1387 | "nintendo" => Nintendo, |
| 1388 | "nvidia" => Nvidia, |
| 1389 | "pc" => Pc, |
| 1390 | "rumprun" => Rumprun, |
| 1391 | "sun" => Sun, |
| 1392 | "uwp" => Uwp, |
| 1393 | "wrs" => Wrs, |
| 1394 | custom => { |
| 1395 | #[cfg (not(feature = "std" ))] |
| 1396 | use alloc::borrow::ToOwned; |
| 1397 | |
| 1398 | // A custom vendor. Since triple syntax is so loosely defined, |
| 1399 | // be as conservative as we can to avoid potential ambiguities. |
| 1400 | // We err on the side of being too strict here, as we can |
| 1401 | // always relax it if needed. |
| 1402 | |
| 1403 | // Don't allow empty string names. |
| 1404 | if custom.is_empty() { |
| 1405 | return Err(()); |
| 1406 | } |
| 1407 | |
| 1408 | // Don't allow any other recognized name as a custom vendor, |
| 1409 | // since vendors can be omitted in some contexts. |
| 1410 | if Architecture::from_str(custom).is_ok() |
| 1411 | || OperatingSystem::from_str(custom).is_ok() |
| 1412 | || Environment::from_str(custom).is_ok() |
| 1413 | || BinaryFormat::from_str(custom).is_ok() |
| 1414 | { |
| 1415 | return Err(()); |
| 1416 | } |
| 1417 | |
| 1418 | // Require the first character to be an ascii lowercase. |
| 1419 | if !custom.chars().next().unwrap().is_ascii_lowercase() { |
| 1420 | return Err(()); |
| 1421 | } |
| 1422 | |
| 1423 | // Restrict the set of characters permitted in a custom vendor. |
| 1424 | let has_restricted = custom.chars().any(|c: char| { |
| 1425 | !(c.is_ascii_lowercase() || c.is_ascii_digit() || c == '_' || c == '.' ) |
| 1426 | }); |
| 1427 | |
| 1428 | if has_restricted { |
| 1429 | return Err(()); |
| 1430 | } |
| 1431 | |
| 1432 | Custom(CustomVendor::Owned(Box::new(custom.to_owned()))) |
| 1433 | } |
| 1434 | }) |
| 1435 | } |
| 1436 | } |
| 1437 | |
| 1438 | impl fmt::Display for OperatingSystem { |
| 1439 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
| 1440 | use OperatingSystem::*; |
| 1441 | |
| 1442 | let mut with_version = |name, deployment_target| { |
| 1443 | if let Some(DeploymentTarget { |
| 1444 | major, |
| 1445 | minor, |
| 1446 | patch, |
| 1447 | }) = deployment_target |
| 1448 | { |
| 1449 | write!(f, " {}{}. {}. {}" , name, major, minor, patch) |
| 1450 | } else { |
| 1451 | write!(f, " {}" , name) |
| 1452 | } |
| 1453 | }; |
| 1454 | |
| 1455 | match *self { |
| 1456 | Darwin(deployment_target) => with_version("darwin" , deployment_target), |
| 1457 | IOS(deployment_target) => with_version("ios" , deployment_target), |
| 1458 | MacOSX(deployment_target) => with_version("macosx" , deployment_target), |
| 1459 | TvOS(deployment_target) => with_version("tvos" , deployment_target), |
| 1460 | VisionOS(deployment_target) => with_version("visionos" , deployment_target), |
| 1461 | WatchOS(deployment_target) => with_version("watchos" , deployment_target), |
| 1462 | XROS(deployment_target) => with_version("xros" , deployment_target), |
| 1463 | os => f.write_str(&os.into_str()), |
| 1464 | } |
| 1465 | } |
| 1466 | } |
| 1467 | |
| 1468 | impl FromStr for OperatingSystem { |
| 1469 | type Err = (); |
| 1470 | |
| 1471 | fn from_str(s: &str) -> Result<Self, ()> { |
| 1472 | use OperatingSystem::*; |
| 1473 | |
| 1474 | let parse_darwin = |name: &str| { |
| 1475 | let s = &s[name.len()..]; |
| 1476 | let mut parts = s.split('.' ); |
| 1477 | |
| 1478 | if s.is_empty() { |
| 1479 | // Not specifying a version is allowed! |
| 1480 | return Ok(None); |
| 1481 | } |
| 1482 | |
| 1483 | let major = if let Some(part) = parts.next() { |
| 1484 | part.parse().map_err(|_| ())? |
| 1485 | } else { |
| 1486 | // If the string was just `.`, with no major version, that's |
| 1487 | // clearly an error. |
| 1488 | return Err(()); |
| 1489 | }; |
| 1490 | let minor = if let Some(part) = parts.next() { |
| 1491 | part.parse().map_err(|_| ())? |
| 1492 | } else { |
| 1493 | // Fall back to 0 if no minor version was set |
| 1494 | 0 |
| 1495 | }; |
| 1496 | let patch = if let Some(part) = parts.next() { |
| 1497 | part.parse().map_err(|_| ())? |
| 1498 | } else { |
| 1499 | // Fall back to 0 if no patch version was set |
| 1500 | 0 |
| 1501 | }; |
| 1502 | |
| 1503 | if parts.next().is_some() { |
| 1504 | // Too many parts |
| 1505 | return Err(()); |
| 1506 | } |
| 1507 | |
| 1508 | Ok(Some(DeploymentTarget { |
| 1509 | major, |
| 1510 | minor, |
| 1511 | patch, |
| 1512 | })) |
| 1513 | }; |
| 1514 | |
| 1515 | // Parse operating system names that contain a version, like `macosx10.7.0`. |
| 1516 | if s.starts_with("darwin" ) { |
| 1517 | return Ok(Darwin(parse_darwin("darwin" )?)); |
| 1518 | } |
| 1519 | if s.starts_with("ios" ) { |
| 1520 | return Ok(IOS(parse_darwin("ios" )?)); |
| 1521 | } |
| 1522 | if s.starts_with("macosx" ) { |
| 1523 | return Ok(MacOSX(parse_darwin("macosx" )?)); |
| 1524 | } |
| 1525 | if s.starts_with("tvos" ) { |
| 1526 | return Ok(TvOS(parse_darwin("tvos" )?)); |
| 1527 | } |
| 1528 | if s.starts_with("visionos" ) { |
| 1529 | return Ok(VisionOS(parse_darwin("visionos" )?)); |
| 1530 | } |
| 1531 | if s.starts_with("watchos" ) { |
| 1532 | return Ok(WatchOS(parse_darwin("watchos" )?)); |
| 1533 | } |
| 1534 | if s.starts_with("xros" ) { |
| 1535 | return Ok(XROS(parse_darwin("xros" )?)); |
| 1536 | } |
| 1537 | |
| 1538 | Ok(match s { |
| 1539 | "unknown" => Unknown, |
| 1540 | "aix" => Aix, |
| 1541 | "amdhsa" => AmdHsa, |
| 1542 | "bitrig" => Bitrig, |
| 1543 | "cloudabi" => Cloudabi, |
| 1544 | "cuda" => Cuda, |
| 1545 | "dragonfly" => Dragonfly, |
| 1546 | "emscripten" => Emscripten, |
| 1547 | "freebsd" => Freebsd, |
| 1548 | "fuchsia" => Fuchsia, |
| 1549 | "haiku" => Haiku, |
| 1550 | "hermit" => Hermit, |
| 1551 | "horizon" => Horizon, |
| 1552 | "hurd" => Hurd, |
| 1553 | "illumos" => Illumos, |
| 1554 | "l4re" => L4re, |
| 1555 | "linux" => Linux, |
| 1556 | "nebulet" => Nebulet, |
| 1557 | "netbsd" => Netbsd, |
| 1558 | "none" => None_, |
| 1559 | "openbsd" => Openbsd, |
| 1560 | "psp" => Psp, |
| 1561 | "redox" => Redox, |
| 1562 | "solaris" => Solaris, |
| 1563 | "solid_asp3" => SolidAsp3, |
| 1564 | "uefi" => Uefi, |
| 1565 | "vxworks" => VxWorks, |
| 1566 | "wasi" => Wasi, |
| 1567 | "wasip1" => WasiP1, |
| 1568 | "wasip2" => WasiP2, |
| 1569 | "windows" => Windows, |
| 1570 | "espidf" => Espidf, |
| 1571 | _ => return Err(()), |
| 1572 | }) |
| 1573 | } |
| 1574 | } |
| 1575 | |
| 1576 | impl fmt::Display for Environment { |
| 1577 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
| 1578 | f.write_str(&self.into_str()) |
| 1579 | } |
| 1580 | } |
| 1581 | |
| 1582 | impl FromStr for Environment { |
| 1583 | type Err = (); |
| 1584 | |
| 1585 | fn from_str(s: &str) -> Result<Self, ()> { |
| 1586 | use Environment::*; |
| 1587 | |
| 1588 | Ok(match s { |
| 1589 | "unknown" => Unknown, |
| 1590 | "amdgiz" => AmdGiz, |
| 1591 | "android" => Android, |
| 1592 | "androideabi" => Androideabi, |
| 1593 | "eabi" => Eabi, |
| 1594 | "eabihf" => Eabihf, |
| 1595 | "gnu" => Gnu, |
| 1596 | "gnuabi64" => Gnuabi64, |
| 1597 | "gnueabi" => Gnueabi, |
| 1598 | "gnueabihf" => Gnueabihf, |
| 1599 | "gnuspe" => Gnuspe, |
| 1600 | "gnux32" => Gnux32, |
| 1601 | "gnu_ilp32" => GnuIlp32, |
| 1602 | "gnullvm" => GnuLlvm, |
| 1603 | "hermitkernel" => HermitKernel, |
| 1604 | "hurdkernel" => HurdKernel, |
| 1605 | "linuxkernel" => LinuxKernel, |
| 1606 | "macabi" => Macabi, |
| 1607 | "musl" => Musl, |
| 1608 | "musleabi" => Musleabi, |
| 1609 | "musleabihf" => Musleabihf, |
| 1610 | "muslabi64" => Muslabi64, |
| 1611 | "msvc" => Msvc, |
| 1612 | "newlib" => Newlib, |
| 1613 | "none" => None, |
| 1614 | "kernel" => Kernel, |
| 1615 | "uclibc" => Uclibc, |
| 1616 | "uclibceabi" => Uclibceabi, |
| 1617 | "uclibceabihf" => Uclibceabihf, |
| 1618 | "sgx" => Sgx, |
| 1619 | "sim" => Sim, |
| 1620 | "softfloat" => Softfloat, |
| 1621 | "spe" => Spe, |
| 1622 | "threads" => Threads, |
| 1623 | "ohos" => Ohos, |
| 1624 | _ => return Err(()), |
| 1625 | }) |
| 1626 | } |
| 1627 | } |
| 1628 | |
| 1629 | impl fmt::Display for BinaryFormat { |
| 1630 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
| 1631 | f.write_str(&self.into_str()) |
| 1632 | } |
| 1633 | } |
| 1634 | |
| 1635 | impl FromStr for BinaryFormat { |
| 1636 | type Err = (); |
| 1637 | |
| 1638 | fn from_str(s: &str) -> Result<Self, ()> { |
| 1639 | use BinaryFormat::*; |
| 1640 | |
| 1641 | Ok(match s { |
| 1642 | "unknown" => Unknown, |
| 1643 | "elf" => Elf, |
| 1644 | "coff" => Coff, |
| 1645 | "macho" => Macho, |
| 1646 | "wasm" => Wasm, |
| 1647 | "xcoff" => Xcoff, |
| 1648 | _ => return Err(()), |
| 1649 | }) |
| 1650 | } |
| 1651 | } |
| 1652 | |
| 1653 | #[cfg (test)] |
| 1654 | mod tests { |
| 1655 | use super::*; |
| 1656 | use alloc::string::ToString; |
| 1657 | |
| 1658 | #[test ] |
| 1659 | fn roundtrip_known_triples() { |
| 1660 | // This list is constructed from: |
| 1661 | // - targets emitted by "rustup target list" |
| 1662 | // - targets emitted by "rustc +nightly --print target-list" |
| 1663 | // - targets contributors have added |
| 1664 | let targets = [ |
| 1665 | "aarch64-apple-darwin" , |
| 1666 | "aarch64-apple-ios" , |
| 1667 | "aarch64-apple-ios-macabi" , |
| 1668 | "aarch64-apple-ios-sim" , |
| 1669 | "aarch64-apple-tvos" , |
| 1670 | "aarch64-apple-tvos-sim" , |
| 1671 | "aarch64-apple-visionos" , |
| 1672 | "aarch64-apple-visionos-sim" , |
| 1673 | "aarch64-apple-watchos" , |
| 1674 | "aarch64-apple-watchos-sim" , |
| 1675 | "aarch64_be-unknown-linux-gnu" , |
| 1676 | "aarch64_be-unknown-linux-gnu_ilp32" , |
| 1677 | "aarch64_be-unknown-netbsd" , |
| 1678 | "aarch64-kmc-solid_asp3" , |
| 1679 | "aarch64-linux-android" , |
| 1680 | //"aarch64-nintendo-switch-freestanding", // TODO |
| 1681 | "aarch64-pc-windows-gnullvm" , |
| 1682 | "aarch64-pc-windows-msvc" , |
| 1683 | "aarch64-unknown-cloudabi" , |
| 1684 | "aarch64-unknown-freebsd" , |
| 1685 | "aarch64-unknown-fuchsia" , |
| 1686 | "aarch64-unknown-hermit" , |
| 1687 | "aarch64-unknown-illumos" , |
| 1688 | "aarch64-unknown-linux-gnu" , |
| 1689 | "aarch64-unknown-linux-gnu_ilp32" , |
| 1690 | "aarch64-unknown-linux-musl" , |
| 1691 | "aarch64-unknown-linux-ohos" , |
| 1692 | "aarch64-unknown-netbsd" , |
| 1693 | "aarch64-unknown-none" , |
| 1694 | "aarch64-unknown-none-softfloat" , |
| 1695 | //"aarch64-unknown-nto-qnx710", // TODO |
| 1696 | "aarch64-unknown-openbsd" , |
| 1697 | "aarch64-unknown-redox" , |
| 1698 | //"aarch64-unknown-teeos", // TODO |
| 1699 | "aarch64-unknown-uefi" , |
| 1700 | "aarch64-uwp-windows-msvc" , |
| 1701 | "aarch64-wrs-vxworks" , |
| 1702 | //"arm64_32-apple-watchos", // TODO |
| 1703 | //"arm64e-apple-darwin", // TODO |
| 1704 | "amdgcn-amd-amdhsa" , |
| 1705 | "amdgcn-amd-amdhsa-amdgiz" , |
| 1706 | //"arm64e-apple-ios", // TODO |
| 1707 | //"arm64ec-pc-windows-msvc", // TODO |
| 1708 | "armeb-unknown-linux-gnueabi" , |
| 1709 | "armebv7r-none-eabi" , |
| 1710 | "armebv7r-none-eabihf" , |
| 1711 | "arm-linux-androideabi" , |
| 1712 | "arm-unknown-linux-gnueabi" , |
| 1713 | "arm-unknown-linux-gnueabihf" , |
| 1714 | "arm-unknown-linux-musleabi" , |
| 1715 | "arm-unknown-linux-musleabihf" , |
| 1716 | "armv4t-none-eabi" , |
| 1717 | "armv4t-unknown-linux-gnueabi" , |
| 1718 | "armv5te-none-eabi" , |
| 1719 | "armv5te-unknown-linux-gnueabi" , |
| 1720 | "armv5te-unknown-linux-musleabi" , |
| 1721 | "armv5te-unknown-linux-uclibceabi" , |
| 1722 | "armv6k-nintendo-3ds" , |
| 1723 | "armv6-unknown-freebsd" , |
| 1724 | "armv6-unknown-netbsd-eabihf" , |
| 1725 | "armv7a-kmc-solid_asp3-eabi" , |
| 1726 | "armv7a-kmc-solid_asp3-eabihf" , |
| 1727 | "armv7a-none-eabi" , |
| 1728 | "armv7a-none-eabihf" , |
| 1729 | "armv7-apple-ios" , |
| 1730 | "armv7k-apple-watchos" , |
| 1731 | "armv7-linux-androideabi" , |
| 1732 | "armv7r-none-eabi" , |
| 1733 | "armv7r-none-eabihf" , |
| 1734 | "armv7s-apple-ios" , |
| 1735 | "armv7-unknown-cloudabi-eabihf" , |
| 1736 | //"armv7-sony-vita-newlibeabihf", // TODO |
| 1737 | "armv7-unknown-freebsd" , |
| 1738 | "armv7-unknown-linux-gnueabi" , |
| 1739 | "armv7-unknown-linux-gnueabihf" , |
| 1740 | "armv7-unknown-linux-musleabi" , |
| 1741 | "armv7-unknown-linux-musleabihf" , |
| 1742 | "armv7-unknown-linux-ohos" , |
| 1743 | "armv7-unknown-linux-uclibceabi" , |
| 1744 | "armv7-unknown-linux-uclibceabihf" , |
| 1745 | "armv7-unknown-netbsd-eabihf" , |
| 1746 | "armv7-wrs-vxworks-eabihf" , |
| 1747 | "asmjs-unknown-emscripten" , |
| 1748 | "armv8r-none-eabihf" , |
| 1749 | //"avr-unknown-gnu-atmega328", // TODO |
| 1750 | "avr-unknown-unknown" , |
| 1751 | "bpfeb-unknown-none" , |
| 1752 | "bpfel-unknown-none" , |
| 1753 | //"csky-unknown-linux-gnuabiv2", // TODO |
| 1754 | //"csky-unknown-linux-gnuabiv2hf", // TODO |
| 1755 | "hexagon-unknown-linux-musl" , |
| 1756 | "hexagon-unknown-none-elf" , |
| 1757 | "i386-apple-ios" , |
| 1758 | //"i586-pc-nto-qnx700", // TODO |
| 1759 | "i586-pc-windows-msvc" , |
| 1760 | "i586-unknown-linux-gnu" , |
| 1761 | "i586-unknown-linux-musl" , |
| 1762 | "i586-unknown-netbsd" , |
| 1763 | "i686-apple-darwin" , |
| 1764 | "i686-linux-android" , |
| 1765 | "i686-apple-macosx10.7.0" , |
| 1766 | "i686-pc-windows-gnu" , |
| 1767 | "i686-pc-windows-gnullvm" , |
| 1768 | "i686-pc-windows-msvc" , |
| 1769 | "i686-unknown-cloudabi" , |
| 1770 | "i686-unknown-dragonfly" , |
| 1771 | "i686-unknown-freebsd" , |
| 1772 | "i686-unknown-haiku" , |
| 1773 | "i686-unknown-hurd-gnu" , |
| 1774 | "i686-unknown-linux-gnu" , |
| 1775 | "i686-unknown-linux-musl" , |
| 1776 | "i686-unknown-netbsd" , |
| 1777 | "i686-unknown-openbsd" , |
| 1778 | "i686-unknown-redox" , |
| 1779 | "i686-unknown-uefi" , |
| 1780 | "i686-uwp-windows-gnu" , |
| 1781 | "i686-uwp-windows-msvc" , |
| 1782 | "i686-win7-windows-msvc" , |
| 1783 | "i686-wrs-vxworks" , |
| 1784 | "loongarch64-unknown-linux-gnu" , |
| 1785 | "loongarch64-unknown-linux-musl" , |
| 1786 | "loongarch64-unknown-none" , |
| 1787 | "loongarch64-unknown-none-softfloat" , |
| 1788 | "m68k-unknown-linux-gnu" , |
| 1789 | "mips64el-unknown-linux-gnuabi64" , |
| 1790 | "mips64el-unknown-linux-muslabi64" , |
| 1791 | "mips64-openwrt-linux-musl" , |
| 1792 | "mips64-unknown-linux-gnuabi64" , |
| 1793 | "mips64-unknown-linux-muslabi64" , |
| 1794 | "mipsel-sony-psp" , |
| 1795 | //"mipsel-sony-psx", // TODO |
| 1796 | "mipsel-unknown-linux-gnu" , |
| 1797 | "mipsel-unknown-linux-musl" , |
| 1798 | "mipsel-unknown-linux-uclibc" , |
| 1799 | "mipsel-unknown-netbsd" , |
| 1800 | "mipsel-unknown-none" , |
| 1801 | "mipsisa32r6el-unknown-linux-gnu" , |
| 1802 | "mipsisa32r6-unknown-linux-gnu" , |
| 1803 | "mipsisa64r6el-unknown-linux-gnuabi64" , |
| 1804 | "mipsisa64r6-unknown-linux-gnuabi64" , |
| 1805 | "mips-unknown-linux-gnu" , |
| 1806 | "mips-unknown-linux-musl" , |
| 1807 | "mips-unknown-linux-uclibc" , |
| 1808 | "msp430-none-elf" , |
| 1809 | "nvptx64-nvidia-cuda" , |
| 1810 | "powerpc64-ibm-aix" , |
| 1811 | "powerpc64le-unknown-freebsd" , |
| 1812 | "powerpc64le-unknown-linux-gnu" , |
| 1813 | "powerpc64le-unknown-linux-musl" , |
| 1814 | "powerpc64-unknown-freebsd" , |
| 1815 | "powerpc64-unknown-linux-gnu" , |
| 1816 | "powerpc64-unknown-linux-musl" , |
| 1817 | "powerpc64-unknown-openbsd" , |
| 1818 | "powerpc64-wrs-vxworks" , |
| 1819 | "powerpc-ibm-aix" , |
| 1820 | "powerpc-unknown-freebsd" , |
| 1821 | "powerpc-unknown-linux-gnu" , |
| 1822 | "powerpc-unknown-linux-gnuspe" , |
| 1823 | "powerpc-unknown-linux-musl" , |
| 1824 | "powerpc-unknown-netbsd" , |
| 1825 | "powerpc-unknown-openbsd" , |
| 1826 | "powerpc-wrs-vxworks" , |
| 1827 | "powerpc-wrs-vxworks-spe" , |
| 1828 | "riscv32gc-unknown-linux-gnu" , |
| 1829 | "riscv32gc-unknown-linux-musl" , |
| 1830 | "riscv32imac-esp-espidf" , |
| 1831 | "riscv32imac-unknown-none-elf" , |
| 1832 | //"riscv32imac-unknown-xous-elf", // TODO |
| 1833 | "riscv32imafc-esp-espidf" , |
| 1834 | "riscv32imafc-unknown-none-elf" , |
| 1835 | "riscv32ima-unknown-none-elf" , |
| 1836 | "riscv32imc-esp-espidf" , |
| 1837 | "riscv32imc-unknown-none-elf" , |
| 1838 | //"riscv32im-risc0-zkvm-elf", // TODO |
| 1839 | "riscv32im-unknown-none-elf" , |
| 1840 | "riscv32i-unknown-none-elf" , |
| 1841 | "riscv64gc-unknown-freebsd" , |
| 1842 | "riscv64gc-unknown-fuchsia" , |
| 1843 | "riscv64gc-unknown-hermit" , |
| 1844 | "riscv64gc-unknown-linux-gnu" , |
| 1845 | "riscv64gc-unknown-linux-musl" , |
| 1846 | "riscv64gc-unknown-netbsd" , |
| 1847 | "riscv64gc-unknown-none-elf" , |
| 1848 | "riscv64gc-unknown-openbsd" , |
| 1849 | "riscv64imac-unknown-none-elf" , |
| 1850 | "riscv64-linux-android" , |
| 1851 | "s390x-unknown-linux-gnu" , |
| 1852 | "s390x-unknown-linux-musl" , |
| 1853 | "sparc64-unknown-linux-gnu" , |
| 1854 | "sparc64-unknown-netbsd" , |
| 1855 | "sparc64-unknown-openbsd" , |
| 1856 | "sparc-unknown-linux-gnu" , |
| 1857 | "sparc-unknown-none-elf" , |
| 1858 | "sparcv9-sun-solaris" , |
| 1859 | "thumbv4t-none-eabi" , |
| 1860 | "thumbv5te-none-eabi" , |
| 1861 | "thumbv6m-none-eabi" , |
| 1862 | "thumbv7a-pc-windows-msvc" , |
| 1863 | "thumbv7a-uwp-windows-msvc" , |
| 1864 | "thumbv7em-none-eabi" , |
| 1865 | "thumbv7em-none-eabihf" , |
| 1866 | "thumbv7m-none-eabi" , |
| 1867 | "thumbv7neon-linux-androideabi" , |
| 1868 | "thumbv7neon-unknown-linux-gnueabihf" , |
| 1869 | "thumbv7neon-unknown-linux-musleabihf" , |
| 1870 | "thumbv8m.base-none-eabi" , |
| 1871 | "thumbv8m.main-none-eabi" , |
| 1872 | "thumbv8m.main-none-eabihf" , |
| 1873 | "wasm32-experimental-emscripten" , |
| 1874 | "wasm32-unknown-emscripten" , |
| 1875 | "wasm32-unknown-unknown" , |
| 1876 | "wasm32-wasi" , |
| 1877 | "wasm32-wasip1" , |
| 1878 | "wasm32-wasip1-threads" , |
| 1879 | "wasm32-wasip2" , |
| 1880 | "wasm64-unknown-unknown" , |
| 1881 | "wasm64-wasi" , |
| 1882 | "x86_64-apple-darwin" , |
| 1883 | "x86_64-apple-darwin23.6.0" , |
| 1884 | "x86_64-apple-ios" , |
| 1885 | "x86_64-apple-ios-macabi" , |
| 1886 | "x86_64-apple-tvos" , |
| 1887 | "x86_64-apple-watchos-sim" , |
| 1888 | "x86_64-fortanix-unknown-sgx" , |
| 1889 | "x86_64h-apple-darwin" , |
| 1890 | "x86_64-linux-android" , |
| 1891 | //"x86_64-pc-nto-qnx710", // TODO |
| 1892 | "x86_64-linux-kernel" , // Changed to x86_64-unknown-none-linuxkernel in 1.53.0 |
| 1893 | "x86_64-apple-macosx" , |
| 1894 | "x86_64-apple-macosx10.7.0" , |
| 1895 | "x86_64-pc-solaris" , |
| 1896 | "x86_64-pc-windows-gnu" , |
| 1897 | "x86_64-pc-windows-gnullvm" , |
| 1898 | "x86_64-pc-windows-msvc" , |
| 1899 | "x86_64-rumprun-netbsd" , // Removed in 1.53.0 |
| 1900 | "x86_64-sun-solaris" , |
| 1901 | "x86_64-unknown-bitrig" , |
| 1902 | "x86_64-unknown-cloudabi" , |
| 1903 | "x86_64-unikraft-linux-musl" , |
| 1904 | "x86_64-unknown-dragonfly" , |
| 1905 | "x86_64-unknown-freebsd" , |
| 1906 | "x86_64-unknown-fuchsia" , |
| 1907 | "x86_64-unknown-haiku" , |
| 1908 | "x86_64-unknown-hermit-kernel" , // Changed to x86_64-unknown-none-hermitkernel in 1.53.0 |
| 1909 | "x86_64-unknown-hermit" , |
| 1910 | "x86_64-unknown-illumos" , |
| 1911 | "x86_64-unknown-l4re-uclibc" , |
| 1912 | "x86_64-unknown-linux-gnu" , |
| 1913 | "x86_64-unknown-linux-gnux32" , |
| 1914 | "x86_64-unknown-linux-musl" , |
| 1915 | "x86_64-unknown-linux-none" , |
| 1916 | "x86_64-unknown-linux-ohos" , |
| 1917 | "x86_64-unknown-netbsd" , |
| 1918 | "x86_64-unknown-none" , |
| 1919 | "x86_64-unknown-none-hermitkernel" , |
| 1920 | "x86_64-unknown-none-linuxkernel" , |
| 1921 | "x86_64-unknown-openbsd" , |
| 1922 | "x86_64-unknown-redox" , |
| 1923 | "x86_64-unknown-uefi" , |
| 1924 | "x86_64-uwp-windows-gnu" , |
| 1925 | "x86_64-uwp-windows-msvc" , |
| 1926 | "x86_64-win7-windows-msvc" , |
| 1927 | "x86_64-wrs-vxworks" , |
| 1928 | "xtensa-esp32-espidf" , |
| 1929 | "clever-unknown-elf" , |
| 1930 | "xtensa-esp32-none-elf" , |
| 1931 | "xtensa-esp32s2-espidf" , |
| 1932 | "xtensa-esp32s2-none-elf" , |
| 1933 | "xtensa-esp32s3-espidf" , |
| 1934 | "xtensa-esp32s3-none-elf" , |
| 1935 | #[cfg (feature = "arch_zkasm" )] |
| 1936 | "zkasm-unknown-unknown" , |
| 1937 | ]; |
| 1938 | |
| 1939 | for target in targets.iter() { |
| 1940 | let t = Triple::from_str(target).expect("can't parse target" ); |
| 1941 | assert_ne!(t.architecture, Architecture::Unknown); |
| 1942 | assert_eq!(t.to_string(), *target, "{:#?}" , t); |
| 1943 | } |
| 1944 | } |
| 1945 | |
| 1946 | #[test ] |
| 1947 | fn default_format_to_elf() { |
| 1948 | let t = Triple::from_str("riscv64" ).expect("can't parse target" ); |
| 1949 | assert_eq!( |
| 1950 | t.architecture, |
| 1951 | Architecture::Riscv64(Riscv64Architecture::Riscv64), |
| 1952 | ); |
| 1953 | assert_eq!(t.vendor, Vendor::Unknown); |
| 1954 | assert_eq!(t.operating_system, OperatingSystem::Unknown); |
| 1955 | assert_eq!(t.environment, Environment::Unknown); |
| 1956 | assert_eq!(t.binary_format, BinaryFormat::Elf); |
| 1957 | } |
| 1958 | |
| 1959 | #[test ] |
| 1960 | fn thumbv7em_none_eabihf() { |
| 1961 | let t = Triple::from_str("thumbv7em-none-eabihf" ).expect("can't parse target" ); |
| 1962 | assert_eq!( |
| 1963 | t.architecture, |
| 1964 | Architecture::Arm(ArmArchitecture::Thumbv7em) |
| 1965 | ); |
| 1966 | assert_eq!(t.vendor, Vendor::Unknown); |
| 1967 | assert_eq!(t.operating_system, OperatingSystem::None_); |
| 1968 | assert_eq!(t.environment, Environment::Eabihf); |
| 1969 | assert_eq!(t.binary_format, BinaryFormat::Elf); |
| 1970 | } |
| 1971 | |
| 1972 | #[test ] |
| 1973 | fn fuchsia_rename() { |
| 1974 | // Fuchsia targets were renamed to add the `unknown`. |
| 1975 | assert_eq!( |
| 1976 | Triple::from_str("aarch64-fuchsia" ), |
| 1977 | Triple::from_str("aarch64-unknown-fuchsia" ) |
| 1978 | ); |
| 1979 | assert_eq!( |
| 1980 | Triple::from_str("x86_64-fuchsia" ), |
| 1981 | Triple::from_str("x86_64-unknown-fuchsia" ) |
| 1982 | ); |
| 1983 | } |
| 1984 | |
| 1985 | #[test ] |
| 1986 | fn custom_vendors() { |
| 1987 | // Test various invalid cases. |
| 1988 | assert!(Triple::from_str("x86_64--linux" ).is_err()); |
| 1989 | assert!(Triple::from_str("x86_64-42-linux" ).is_err()); |
| 1990 | assert!(Triple::from_str("x86_64-__customvendor__-linux" ).is_err()); |
| 1991 | assert!(Triple::from_str("x86_64-^-linux" ).is_err()); |
| 1992 | assert!(Triple::from_str("x86_64- -linux" ).is_err()); |
| 1993 | assert!(Triple::from_str("x86_64-CustomVendor-linux" ).is_err()); |
| 1994 | assert!(Triple::from_str("x86_64-linux-linux" ).is_err()); |
| 1995 | assert!(Triple::from_str("x86_64-x86_64-linux" ).is_err()); |
| 1996 | assert!(Triple::from_str("x86_64-elf-linux" ).is_err()); |
| 1997 | assert!(Triple::from_str("x86_64-gnu-linux" ).is_err()); |
| 1998 | assert!(Triple::from_str("x86_64-linux-customvendor" ).is_err()); |
| 1999 | assert!(Triple::from_str("customvendor" ).is_err()); |
| 2000 | assert!(Triple::from_str("customvendor-x86_64" ).is_err()); |
| 2001 | assert!(Triple::from_str("x86_64-" ).is_err()); |
| 2002 | assert!(Triple::from_str("x86_64--" ).is_err()); |
| 2003 | |
| 2004 | // Test various Unicode things. |
| 2005 | assert!( |
| 2006 | Triple::from_str("x86_64-𝓬𝓾𝓼𝓽𝓸𝓶𝓿𝓮𝓷𝓭𝓸𝓻-linux" ).is_err(), |
| 2007 | "unicode font hazard" |
| 2008 | ); |
| 2009 | assert!( |
| 2010 | Triple::from_str("x86_64-ćúśtőḿvéńdőŕ-linux" ).is_err(), |
| 2011 | "diacritical mark stripping hazard" |
| 2012 | ); |
| 2013 | assert!( |
| 2014 | Triple::from_str("x86_64-customvendοr-linux" ).is_err(), |
| 2015 | "homoglyph hazard" |
| 2016 | ); |
| 2017 | assert!(Triple::from_str("x86_64-customvendor-linux" ).is_ok()); |
| 2018 | assert!( |
| 2019 | Triple::from_str("x86_64-ffi-linux" ).is_err(), |
| 2020 | "normalization hazard" |
| 2021 | ); |
| 2022 | assert!(Triple::from_str("x86_64-ffi-linux" ).is_ok()); |
| 2023 | assert!( |
| 2024 | Triple::from_str("x86_64-customvendor-linux" ).is_err(), |
| 2025 | "zero-width character hazard" |
| 2026 | ); |
| 2027 | assert!( |
| 2028 | Triple::from_str("x86_64-customvendor-linux" ).is_err(), |
| 2029 | "BOM hazard" |
| 2030 | ); |
| 2031 | |
| 2032 | // Test some valid cases. |
| 2033 | let t = Triple::from_str("x86_64-customvendor-linux" ) |
| 2034 | .expect("can't parse target with custom vendor" ); |
| 2035 | assert_eq!(t.architecture, Architecture::X86_64); |
| 2036 | assert_eq!( |
| 2037 | t.vendor, |
| 2038 | Vendor::Custom(CustomVendor::Static("customvendor" )) |
| 2039 | ); |
| 2040 | assert_eq!(t.operating_system, OperatingSystem::Linux); |
| 2041 | assert_eq!(t.environment, Environment::Unknown); |
| 2042 | assert_eq!(t.binary_format, BinaryFormat::Elf); |
| 2043 | assert_eq!(t.to_string(), "x86_64-customvendor-linux" ); |
| 2044 | |
| 2045 | let t = |
| 2046 | Triple::from_str("x86_64-customvendor" ).expect("can't parse target with custom vendor" ); |
| 2047 | assert_eq!(t.architecture, Architecture::X86_64); |
| 2048 | assert_eq!( |
| 2049 | t.vendor, |
| 2050 | Vendor::Custom(CustomVendor::Static("customvendor" )) |
| 2051 | ); |
| 2052 | assert_eq!(t.operating_system, OperatingSystem::Unknown); |
| 2053 | assert_eq!(t.environment, Environment::Unknown); |
| 2054 | assert_eq!(t.binary_format, BinaryFormat::Elf); |
| 2055 | |
| 2056 | assert_eq!( |
| 2057 | Triple::from_str("unknown-foo" ), |
| 2058 | Ok(Triple { |
| 2059 | architecture: Architecture::Unknown, |
| 2060 | vendor: Vendor::Custom(CustomVendor::Static("foo" )), |
| 2061 | operating_system: OperatingSystem::Unknown, |
| 2062 | environment: Environment::Unknown, |
| 2063 | binary_format: BinaryFormat::Unknown, |
| 2064 | }) |
| 2065 | ); |
| 2066 | } |
| 2067 | |
| 2068 | #[test ] |
| 2069 | fn deployment_version_parsing() { |
| 2070 | assert_eq!( |
| 2071 | Triple::from_str("aarch64-apple-macosx" ), |
| 2072 | Ok(Triple { |
| 2073 | architecture: Architecture::Aarch64(Aarch64Architecture::Aarch64), |
| 2074 | vendor: Vendor::Apple, |
| 2075 | operating_system: OperatingSystem::MacOSX(None), |
| 2076 | environment: Environment::Unknown, |
| 2077 | binary_format: BinaryFormat::Macho, |
| 2078 | }) |
| 2079 | ); |
| 2080 | |
| 2081 | assert_eq!( |
| 2082 | Triple::from_str("aarch64-apple-macosx10.14.6" ), |
| 2083 | Ok(Triple { |
| 2084 | architecture: Architecture::Aarch64(Aarch64Architecture::Aarch64), |
| 2085 | vendor: Vendor::Apple, |
| 2086 | operating_system: OperatingSystem::MacOSX(Some(DeploymentTarget { |
| 2087 | major: 10, |
| 2088 | minor: 14, |
| 2089 | patch: 6, |
| 2090 | })), |
| 2091 | environment: Environment::Unknown, |
| 2092 | binary_format: BinaryFormat::Macho, |
| 2093 | }) |
| 2094 | ); |
| 2095 | |
| 2096 | let expected = Triple { |
| 2097 | architecture: Architecture::X86_64, |
| 2098 | vendor: Vendor::Apple, |
| 2099 | operating_system: OperatingSystem::Darwin(Some(DeploymentTarget { |
| 2100 | major: 23, |
| 2101 | minor: 0, |
| 2102 | patch: 0, |
| 2103 | })), |
| 2104 | environment: Environment::Unknown, |
| 2105 | binary_format: BinaryFormat::Macho, |
| 2106 | }; |
| 2107 | assert_eq!( |
| 2108 | Triple::from_str("x86_64-apple-darwin23" ), |
| 2109 | Ok(expected.clone()) |
| 2110 | ); |
| 2111 | assert_eq!( |
| 2112 | Triple::from_str("x86_64-apple-darwin23.0" ), |
| 2113 | Ok(expected.clone()) |
| 2114 | ); |
| 2115 | assert_eq!(Triple::from_str("x86_64-apple-darwin23.0.0" ), Ok(expected)); |
| 2116 | |
| 2117 | assert!(Triple::from_str("x86_64-apple-darwin." ).is_err()); |
| 2118 | assert!(Triple::from_str("x86_64-apple-darwin23.0.0.0" ).is_err()); |
| 2119 | } |
| 2120 | } |
| 2121 | |