Skip to main content

goblin/mach/
constants.rs

1//! Miscellaneous constants used inside of and when constructing, Mach-o binaries
2// Convienence constants for return values from dyld_get_sdk_version() and friends.
3pub const DYLD_MACOSX_VERSION_10_4: u32 = 0x000A_0400;
4pub const DYLD_MACOSX_VERSION_10_5: u32 = 0x000A_0500;
5pub const DYLD_MACOSX_VERSION_10_6: u32 = 0x000A_0600;
6pub const DYLD_MACOSX_VERSION_10_7: u32 = 0x000A_0700;
7pub const DYLD_MACOSX_VERSION_10_8: u32 = 0x000A_0800;
8pub const DYLD_MACOSX_VERSION_10_9: u32 = 0x000A_0900;
9pub const DYLD_MACOSX_VERSION_10_10: u32 = 0x000A_0A00;
10pub const DYLD_MACOSX_VERSION_10_11: u32 = 0x000A_0B00;
11pub const DYLD_MACOSX_VERSION_10_12: u32 = 0x000A_0C00;
12pub const DYLD_MACOSX_VERSION_10_13: u32 = 0x000A_0D00;
13
14pub const DYLD_IOS_VERSION_2_0: u32 = 0x0002_0000;
15pub const DYLD_IOS_VERSION_2_1: u32 = 0x0002_0100;
16pub const DYLD_IOS_VERSION_2_2: u32 = 0x0002_0200;
17pub const DYLD_IOS_VERSION_3_0: u32 = 0x0003_0000;
18pub const DYLD_IOS_VERSION_3_1: u32 = 0x0003_0100;
19pub const DYLD_IOS_VERSION_3_2: u32 = 0x0003_0200;
20pub const DYLD_IOS_VERSION_4_0: u32 = 0x0004_0000;
21pub const DYLD_IOS_VERSION_4_1: u32 = 0x0004_0100;
22pub const DYLD_IOS_VERSION_4_2: u32 = 0x0004_0200;
23pub const DYLD_IOS_VERSION_4_3: u32 = 0x0004_0300;
24pub const DYLD_IOS_VERSION_5_0: u32 = 0x0005_0000;
25pub const DYLD_IOS_VERSION_5_1: u32 = 0x0005_0100;
26pub const DYLD_IOS_VERSION_6_0: u32 = 0x0006_0000;
27pub const DYLD_IOS_VERSION_6_1: u32 = 0x0006_0100;
28pub const DYLD_IOS_VERSION_7_0: u32 = 0x0007_0000;
29pub const DYLD_IOS_VERSION_7_1: u32 = 0x0007_0100;
30pub const DYLD_IOS_VERSION_8_0: u32 = 0x0008_0000;
31pub const DYLD_IOS_VERSION_9_0: u32 = 0x0009_0000;
32pub const DYLD_IOS_VERSION_10_0: u32 = 0x000A_0000;
33pub const DYLD_IOS_VERSION_11_0: u32 = 0x000B_0000;
34
35// Segment and Section Constants
36
37// The flags field of a section structure is separated into two parts a section
38// type and section attributes.  The section types are mutually exclusive (it
39// can only have one type) but the section attributes are not (it may have more
40// than one attribute).
41/// 256 section types
42pub const SECTION_TYPE: u32 = 0x0000_00ff;
43///  24 section attributes
44pub const SECTION_ATTRIBUTES: u32 = 0xffff_ff00;
45
46// Constants for the type of a section
47/// regular section
48pub const S_REGULAR: u32 = 0x0;
49/// zero fill on demand section
50pub const S_ZEROFILL: u32 = 0x1;
51/// section with only literal C strings
52pub const S_CSTRING_LITERALS: u32 = 0x2;
53/// section with only 4 byte literals
54pub const S_4BYTE_LITERALS: u32 = 0x3;
55/// section with only 8 byte literals
56pub const S_8BYTE_LITERALS: u32 = 0x4;
57/// section with only pointers to
58pub const S_LITERAL_POINTERS: u32 = 0x5;
59
60// literals
61// For the two types of symbol pointers sections and the symbol stubs section
62// they have indirect symbol table entries.  For each of the entries in the
63// section the indirect symbol table entries, in corresponding order in the
64// indirect symbol table, start at the index stored in the reserved1 field
65// of the section structure.  Since the indirect symbol table entries
66// correspond to the entries in the section the number of indirect symbol table
67// entries is inferred from the size of the section divided by the size of the
68// entries in the section.  For symbol pointers sections the size of the entries
69// in the section is 4 bytes and for symbol stubs sections the byte size of the
70// stubs is stored in the reserved2 field of the section structure.
71/// section with only non-lazy symbol pointers
72pub const S_NON_LAZY_SYMBOL_POINTERS: u32 = 0x6;
73/// section with only lazy symbol pointers
74pub const S_LAZY_SYMBOL_POINTERS: u32 = 0x7;
75/// section with only symbol stubs, byte size of stub in the reserved2 field
76pub const S_SYMBOL_STUBS: u32 = 0x8;
77/// section with only function pointers for initialization
78pub const S_MOD_INIT_FUNC_POINTERS: u32 = 0x9;
79/// section with only function pointers for termination
80pub const S_MOD_TERM_FUNC_POINTERS: u32 = 0xa;
81/// section contains symbols that are to be coalesced
82pub const S_COALESCED: u32 = 0xb;
83/// zero fill on demand section that can be larger than 4 gigabytes)
84pub const S_GB_ZEROFILL: u32 = 0xc;
85/// section with only pairs of function pointers for interposing
86pub const S_INTERPOSING: u32 = 0xd;
87/// section with only 16 byte literals
88pub const S_16BYTE_LITERALS: u32 = 0xe;
89/// section contains DTrace Object Format
90pub const S_DTRACE_DOF: u32 = 0xf;
91/// section with only lazy symbol pointers to lazy loaded dylibs
92pub const S_LAZY_DYLIB_SYMBOL_POINTERS: u32 = 0x10;
93
94// Section types to support thread local variables
95/// template of initial  values for TLVs
96pub const S_THREAD_LOCAL_REGULAR: u32 = 0x11;
97/// template of initial  values for TLVs
98pub const S_THREAD_LOCAL_ZEROFILL: u32 = 0x12;
99/// TLV descriptors
100pub const S_THREAD_LOCAL_VARIABLES: u32 = 0x13;
101/// pointers to TLV  descriptors
102pub const S_THREAD_LOCAL_VARIABLE_POINTERS: u32 = 0x14;
103/// functions to call to initialize TLV values
104pub const S_THREAD_LOCAL_INIT_FUNCTION_POINTERS: u32 = 0x15;
105
106// Constants for the section attributes part of the flags field of a section
107// structure.
108/// User setable attributes
109pub const SECTION_ATTRIBUTES_USR: u32 = 0xff00_0000;
110/// section contains only true machine instructions
111pub const S_ATTR_PURE_INSTRUCTIONS: u32 = 0x8000_0000;
112/// section contains coalesced symbols that are not to be in a ranlib table of contents
113pub const S_ATTR_NO_TOC: u32 = 0x4000_0000;
114/// ok to strip static symbols in this section in files with the MH_DYLDLINK flag
115pub const S_ATTR_STRIP_STATIC_SYMS: u32 = 0x2000_0000;
116/// no dead stripping
117pub const S_ATTR_NO_DEAD_STRIP: u32 = 0x1000_0000;
118/// blocks are live if they reference live blocks
119pub const S_ATTR_LIVE_SUPPORT: u32 = 0x0800_0000;
120/// Used with i386 code stubs written on by dyld
121pub const S_ATTR_SELF_MODIFYING_CODE: u32 = 0x0400_0000;
122
123// If a segment contains any sections marked with S_ATTR_DEBUG then all
124// sections in that segment must have this attribute.  No section other than
125// a section marked with this attribute may reference the contents of this
126// section.  A section with this attribute may contain no symbols and must have
127// a section type S_REGULAR.  The static linker will not copy section contents
128// from sections with this attribute into its output file.  These sections
129// generally contain DWARF debugging info.
130/// debug section
131pub const S_ATTR_DEBUG: u32 = 0x0200_0000;
132/// system setable attributes
133pub const SECTION_ATTRIBUTES_SYS: u32 = 0x00ff_ff00;
134/// section contains some machine instructions
135pub const S_ATTR_SOME_INSTRUCTIONS: u32 = 0x0000_0400;
136/// section has external relocation entries
137pub const S_ATTR_EXT_RELOC: u32 = 0x0000_0200;
138/// section has local relocation entries
139pub const S_ATTR_LOC_RELOC: u32 = 0x0000_0100;
140
141// The names of segments and sections in them are mostly meaningless to the
142// link-editor.  But there are few things to support traditional UNIX
143// executables that require the link-editor and assembler to use some names
144// agreed upon by convention.
145// The initial protection of the "__TEXT" segment has write protection turned
146// off (not writeable).
147// The link-editor will allocate common symbols at the end of the "__common"
148// section in the "__DATA" segment.  It will create the section and segment
149// if needed.
150
151// The currently known segment names and the section names in those segments
152/// the pagezero segment which has no protections and catches NULL references for MH_EXECUTE files
153pub const SEG_PAGEZERO: &str = "__PAGEZERO";
154/// the tradition UNIX text segment
155pub const SEG_TEXT: &str = "__TEXT";
156/// the real text part of the text section no headers, and no padding
157pub const SECT_TEXT: &str = "__text";
158/// the fvmlib initialization section
159pub const SECT_FVMLIB_INIT0: &str = "__fvmlib_init0";
160/// the section following the fvmlib initialization section
161pub const SECT_FVMLIB_INIT1: &str = "__fvmlib_init1";
162/// the tradition UNIX data segment
163pub const SEG_DATA: &str = "__DATA";
164/// the real initialized data section no padding, no bss overlap
165pub const SECT_DATA: &str = "__data";
166/// the real uninitialized data sectionno padding
167pub const SECT_BSS: &str = "__bss";
168/// the section common symbols are allocated in by the link editor
169pub const SECT_COMMON: &str = "__common";
170/// objective-C runtime segment
171pub const SEG_OBJC: &str = "__OBJC";
172/// symbol table
173pub const SECT_OBJC_SYMBOLS: &str = "__symbol_table";
174/// module information
175pub const SECT_OBJC_MODULES: &str = "__module_info";
176/// string table
177pub const SECT_OBJC_STRINGS: &str = "__selector_strs";
178/// string table
179pub const SECT_OBJC_REFS: &str = "__selector_refs";
180/// the icon segment
181pub const SEG_ICON: &str = "__ICON";
182/// the icon headers
183pub const SECT_ICON_HEADER: &str = "__header";
184/// the icons in tiff format
185pub const SECT_ICON_TIFF: &str = "__tiff";
186/// the segment containing all structs created and maintained by the link editor.  Created with -seglinkedit option to ld(1) for MH_EXECUTE and FVMLIB file types only
187pub const SEG_LINKEDIT: &str = "__LINKEDIT";
188/// the unix stack segment
189pub const SEG_UNIXSTACK: &str = "__UNIXSTACK";
190/// the segment for the self (dyld) modifing code stubs that has read, write and execute permissions
191pub const SEG_IMPORT: &str = "__IMPORT";
192
193/// Segment is readable.
194pub const VM_PROT_READ: u32 = 0x1;
195/// Segment is writable.
196pub const VM_PROT_WRITE: u32 = 0x2;
197/// Segment is executable.
198pub const VM_PROT_EXECUTE: u32 = 0x4;
199
200pub mod cputype {
201
202    /// An alias for u32
203    pub type CpuType = u32;
204    /// An alias for u32
205    pub type CpuSubType = u32;
206
207    /// the mask for CPU feature flags
208    pub const CPU_SUBTYPE_MASK: u32 = 0xff00_0000;
209    /// mask for architecture bits
210    pub const CPU_ARCH_MASK: CpuType = 0xff00_0000;
211    /// the mask for 64 bit ABI
212    pub const CPU_ARCH_ABI64: CpuType = 0x0100_0000;
213    /// the mask for ILP32 ABI on 64 bit hardware
214    pub const CPU_ARCH_ABI64_32: CpuType = 0x0200_0000;
215
216    // CPU Types
217    pub const CPU_TYPE_ANY: CpuType = !0;
218    pub const CPU_TYPE_VAX: CpuType = 1;
219    pub const CPU_TYPE_MC680X0: CpuType = 6;
220    pub const CPU_TYPE_X86: CpuType = 7;
221    pub const CPU_TYPE_I386: CpuType = CPU_TYPE_X86;
222    pub const CPU_TYPE_X86_64: CpuType = CPU_TYPE_X86 | CPU_ARCH_ABI64;
223    pub const CPU_TYPE_MIPS: CpuType = 8;
224    pub const CPU_TYPE_MC98000: CpuType = 10;
225    pub const CPU_TYPE_HPPA: CpuType = 11;
226    pub const CPU_TYPE_ARM: CpuType = 12;
227    pub const CPU_TYPE_ARM64: CpuType = CPU_TYPE_ARM | CPU_ARCH_ABI64;
228    pub const CPU_TYPE_ARM64_32: CpuType = CPU_TYPE_ARM | CPU_ARCH_ABI64_32;
229    pub const CPU_TYPE_MC88000: CpuType = 13;
230    pub const CPU_TYPE_SPARC: CpuType = 14;
231    pub const CPU_TYPE_I860: CpuType = 15;
232    pub const CPU_TYPE_ALPHA: CpuType = 16;
233    pub const CPU_TYPE_POWERPC: CpuType = 18;
234    pub const CPU_TYPE_POWERPC64: CpuType = CPU_TYPE_POWERPC | CPU_ARCH_ABI64;
235
236    // CPU Subtypes
237    pub const CPU_SUBTYPE_MULTIPLE: CpuSubType = !0;
238    pub const CPU_SUBTYPE_LITTLE_ENDIAN: CpuSubType = 0;
239    pub const CPU_SUBTYPE_BIG_ENDIAN: CpuSubType = 1;
240    pub const CPU_SUBTYPE_VAX_ALL: CpuSubType = 0;
241    pub const CPU_SUBTYPE_VAX780: CpuSubType = 1;
242    pub const CPU_SUBTYPE_VAX785: CpuSubType = 2;
243    pub const CPU_SUBTYPE_VAX750: CpuSubType = 3;
244    pub const CPU_SUBTYPE_VAX730: CpuSubType = 4;
245    pub const CPU_SUBTYPE_UVAXI: CpuSubType = 5;
246    pub const CPU_SUBTYPE_UVAXII: CpuSubType = 6;
247    pub const CPU_SUBTYPE_VAX8200: CpuSubType = 7;
248    pub const CPU_SUBTYPE_VAX8500: CpuSubType = 8;
249    pub const CPU_SUBTYPE_VAX8600: CpuSubType = 9;
250    pub const CPU_SUBTYPE_VAX8650: CpuSubType = 10;
251    pub const CPU_SUBTYPE_VAX8800: CpuSubType = 11;
252    pub const CPU_SUBTYPE_UVAXIII: CpuSubType = 12;
253    pub const CPU_SUBTYPE_MC680X0_ALL: CpuSubType = 1;
254    pub const CPU_SUBTYPE_MC68030: CpuSubType = 1; /* compat */
255    pub const CPU_SUBTYPE_MC68040: CpuSubType = 2;
256    pub const CPU_SUBTYPE_MC68030_ONLY: CpuSubType = 3;
257
258    macro_rules! CPU_SUBTYPE_INTEL {
259        ($f:expr, $m:expr) => {{ ($f) + (($m) << 4) }};
260    }
261
262    pub const CPU_SUBTYPE_I386_ALL: CpuSubType = CPU_SUBTYPE_INTEL!(3, 0);
263    pub const CPU_SUBTYPE_386: CpuSubType = CPU_SUBTYPE_INTEL!(3, 0);
264    pub const CPU_SUBTYPE_486: CpuSubType = CPU_SUBTYPE_INTEL!(4, 0);
265    pub const CPU_SUBTYPE_486SX: CpuSubType = CPU_SUBTYPE_INTEL!(4, 8); // 8 << 4 = 128
266    pub const CPU_SUBTYPE_586: CpuSubType = CPU_SUBTYPE_INTEL!(5, 0);
267    pub const CPU_SUBTYPE_PENT: CpuSubType = CPU_SUBTYPE_INTEL!(5, 0);
268    pub const CPU_SUBTYPE_PENTPRO: CpuSubType = CPU_SUBTYPE_INTEL!(6, 1);
269    pub const CPU_SUBTYPE_PENTII_M3: CpuSubType = CPU_SUBTYPE_INTEL!(6, 3);
270    pub const CPU_SUBTYPE_PENTII_M5: CpuSubType = CPU_SUBTYPE_INTEL!(6, 5);
271    pub const CPU_SUBTYPE_CELERON: CpuSubType = CPU_SUBTYPE_INTEL!(7, 6);
272    pub const CPU_SUBTYPE_CELERON_MOBILE: CpuSubType = CPU_SUBTYPE_INTEL!(7, 7);
273    pub const CPU_SUBTYPE_PENTIUM_3: CpuSubType = CPU_SUBTYPE_INTEL!(8, 0);
274    pub const CPU_SUBTYPE_PENTIUM_3_M: CpuSubType = CPU_SUBTYPE_INTEL!(8, 1);
275    pub const CPU_SUBTYPE_PENTIUM_3_XEON: CpuSubType = CPU_SUBTYPE_INTEL!(8, 2);
276    pub const CPU_SUBTYPE_PENTIUM_M: CpuSubType = CPU_SUBTYPE_INTEL!(9, 0);
277    pub const CPU_SUBTYPE_PENTIUM_4: CpuSubType = CPU_SUBTYPE_INTEL!(10, 0);
278    pub const CPU_SUBTYPE_PENTIUM_4_M: CpuSubType = CPU_SUBTYPE_INTEL!(10, 1);
279    pub const CPU_SUBTYPE_ITANIUM: CpuSubType = CPU_SUBTYPE_INTEL!(11, 0);
280    pub const CPU_SUBTYPE_ITANIUM_2: CpuSubType = CPU_SUBTYPE_INTEL!(11, 1);
281    pub const CPU_SUBTYPE_XEON: CpuSubType = CPU_SUBTYPE_INTEL!(12, 0);
282    pub const CPU_SUBTYPE_XEON_MP: CpuSubType = CPU_SUBTYPE_INTEL!(12, 1);
283    pub const CPU_SUBTYPE_INTEL_FAMILY_MAX: CpuSubType = 15;
284    pub const CPU_SUBTYPE_INTEL_MODEL_ALL: CpuSubType = 0;
285    pub const CPU_SUBTYPE_X86_ALL: CpuSubType = 3;
286    pub const CPU_SUBTYPE_X86_64_ALL: CpuSubType = 3;
287    pub const CPU_SUBTYPE_X86_ARCH1: CpuSubType = 4;
288    pub const CPU_SUBTYPE_X86_64_H: CpuSubType = 8;
289    pub const CPU_SUBTYPE_MIPS_ALL: CpuSubType = 0;
290    pub const CPU_SUBTYPE_MIPS_R2300: CpuSubType = 1;
291    pub const CPU_SUBTYPE_MIPS_R2600: CpuSubType = 2;
292    pub const CPU_SUBTYPE_MIPS_R2800: CpuSubType = 3;
293    pub const CPU_SUBTYPE_MIPS_R2000A: CpuSubType = 4;
294    pub const CPU_SUBTYPE_MIPS_R2000: CpuSubType = 5;
295    pub const CPU_SUBTYPE_MIPS_R3000A: CpuSubType = 6;
296    pub const CPU_SUBTYPE_MIPS_R3000: CpuSubType = 7;
297    pub const CPU_SUBTYPE_MC98000_ALL: CpuSubType = 0;
298    pub const CPU_SUBTYPE_MC98601: CpuSubType = 1;
299    pub const CPU_SUBTYPE_HPPA_ALL: CpuSubType = 0;
300    pub const CPU_SUBTYPE_HPPA_7100: CpuSubType = 0;
301    pub const CPU_SUBTYPE_HPPA_7100LC: CpuSubType = 1;
302    pub const CPU_SUBTYPE_MC88000_ALL: CpuSubType = 0;
303    pub const CPU_SUBTYPE_MC88100: CpuSubType = 1;
304    pub const CPU_SUBTYPE_MC88110: CpuSubType = 2;
305    pub const CPU_SUBTYPE_SPARC_ALL: CpuSubType = 0;
306    pub const CPU_SUBTYPE_I860_ALL: CpuSubType = 0;
307    pub const CPU_SUBTYPE_I860_860: CpuSubType = 1;
308    pub const CPU_SUBTYPE_POWERPC_ALL: CpuSubType = 0;
309    pub const CPU_SUBTYPE_POWERPC_601: CpuSubType = 1;
310    pub const CPU_SUBTYPE_POWERPC_602: CpuSubType = 2;
311    pub const CPU_SUBTYPE_POWERPC_603: CpuSubType = 3;
312    pub const CPU_SUBTYPE_POWERPC_603E: CpuSubType = 4;
313    pub const CPU_SUBTYPE_POWERPC_603EV: CpuSubType = 5;
314    pub const CPU_SUBTYPE_POWERPC_604: CpuSubType = 6;
315    pub const CPU_SUBTYPE_POWERPC_604E: CpuSubType = 7;
316    pub const CPU_SUBTYPE_POWERPC_620: CpuSubType = 8;
317    pub const CPU_SUBTYPE_POWERPC_750: CpuSubType = 9;
318    pub const CPU_SUBTYPE_POWERPC_7400: CpuSubType = 10;
319    pub const CPU_SUBTYPE_POWERPC_7450: CpuSubType = 11;
320    pub const CPU_SUBTYPE_POWERPC_970: CpuSubType = 100;
321    pub const CPU_SUBTYPE_ARM_ALL: CpuSubType = 0;
322    pub const CPU_SUBTYPE_ARM_V4T: CpuSubType = 5;
323    pub const CPU_SUBTYPE_ARM_V6: CpuSubType = 6;
324    pub const CPU_SUBTYPE_ARM_V5TEJ: CpuSubType = 7;
325    pub const CPU_SUBTYPE_ARM_XSCALE: CpuSubType = 8;
326    pub const CPU_SUBTYPE_ARM_V7: CpuSubType = 9;
327    pub const CPU_SUBTYPE_ARM_V7F: CpuSubType = 10;
328    pub const CPU_SUBTYPE_ARM_V7S: CpuSubType = 11;
329    pub const CPU_SUBTYPE_ARM_V7K: CpuSubType = 12;
330    pub const CPU_SUBTYPE_ARM_V6M: CpuSubType = 14;
331    pub const CPU_SUBTYPE_ARM_V7M: CpuSubType = 15;
332    pub const CPU_SUBTYPE_ARM_V7EM: CpuSubType = 16;
333    pub const CPU_SUBTYPE_ARM_V8: CpuSubType = 13;
334    pub const CPU_SUBTYPE_ARM64_ALL: CpuSubType = 0;
335    pub const CPU_SUBTYPE_ARM64_V8: CpuSubType = 1;
336    pub const CPU_SUBTYPE_ARM64_E: CpuSubType = 2;
337    pub const CPU_SUBTYPE_ARM64_32_ALL: CpuSubType = 0;
338    pub const CPU_SUBTYPE_ARM64_32_V8: CpuSubType = 1;
339
340    macro_rules! cpu_flag_mapping {
341        (
342            $(($name:expr, $cputype:ident, $cpusubtype:ident),)*
343        ) => {
344            fn get_arch_from_flag_no_alias(name: &str) -> Option<(CpuType, CpuSubType)> {
345                match name {
346                    $($name => Some(($cputype, $cpusubtype)),)*
347                    _ => None
348                }
349            }
350
351            /// Get the architecture name from cputype and cpusubtype
352            ///
353            /// When using this method to determine the architecture
354            /// name of an instance of
355            /// [`goblin::mach::header::Header`](/goblin/mach/header/struct.Header.html),
356            /// use the provided method
357            /// [`cputype()`](/goblin/mach/header/struct.Header.html#method.cputype) and
358            /// [`cpusubtype()`](/goblin/mach/header/struct.Header.html#method.cpusubtype)
359            /// instead of corresponding field `cputype` and `cpusubtype`.
360            ///
361            /// For example:
362            ///
363            /// ```rust
364            /// use std::fs::read;
365            /// use goblin::mach::constants::cputype::get_arch_name_from_types;
366            /// use goblin::mach::Mach;
367            ///
368            /// read("path/to/macho").and_then(|buf| {
369            ///     if let Ok(Mach::Binary(a)) = Mach::parse(&buf) {
370            ///         println!("arch name: {}", get_arch_name_from_types(a.header.cputype(), a.header.cpusubtype()).unwrap());
371            ///     }
372            ///     Ok(())
373            /// });
374            /// ```
375            pub fn get_arch_name_from_types(cputype: CpuType, cpusubtype: CpuSubType)
376                -> Option<&'static str> {
377                match (cputype, cpusubtype) {
378                    $(($cputype, $cpusubtype) => Some($name),)*
379                    (_, _) => None
380                }
381            }
382        }
383    }
384
385    /// Get the cputype and cpusubtype from a name
386    pub fn get_arch_from_flag(name: &str) -> Option<(CpuType, CpuSubType)> {
387        get_arch_from_flag_no_alias(name).or_else(|| {
388            // we also handle some common aliases
389            match name {
390                // these are used by apple
391                "pentium" => Some((CPU_TYPE_I386, CPU_SUBTYPE_PENT)),
392                "pentpro" => Some((CPU_TYPE_I386, CPU_SUBTYPE_PENTPRO)),
393                // these are used commonly for consistency
394                "x86" => Some((CPU_TYPE_I386, CPU_SUBTYPE_I386_ALL)),
395                _ => None,
396            }
397        })
398    }
399
400    cpu_flag_mapping! {
401        // generic types
402        ("any", CPU_TYPE_ANY, CPU_SUBTYPE_MULTIPLE),
403        ("little", CPU_TYPE_ANY, CPU_SUBTYPE_LITTLE_ENDIAN),
404        ("big", CPU_TYPE_ANY, CPU_SUBTYPE_BIG_ENDIAN),
405
406        // macho names
407        ("ppc64", CPU_TYPE_POWERPC64, CPU_SUBTYPE_POWERPC_ALL),
408        ("x86_64", CPU_TYPE_X86_64, CPU_SUBTYPE_X86_64_ALL),
409        ("x86_64h", CPU_TYPE_X86_64, CPU_SUBTYPE_X86_64_H),
410        ("arm64", CPU_TYPE_ARM64, CPU_SUBTYPE_ARM64_ALL),
411        ("arm64_32", CPU_TYPE_ARM64_32, CPU_SUBTYPE_ARM64_32_ALL),
412        ("ppc970-64", CPU_TYPE_POWERPC64, CPU_SUBTYPE_POWERPC_970),
413        ("ppc", CPU_TYPE_POWERPC, CPU_SUBTYPE_POWERPC_ALL),
414        ("i386", CPU_TYPE_I386, CPU_SUBTYPE_I386_ALL),
415        ("m68k", CPU_TYPE_MC680X0, CPU_SUBTYPE_MC680X0_ALL),
416        ("hppa", CPU_TYPE_HPPA, CPU_SUBTYPE_HPPA_ALL),
417        ("sparc", CPU_TYPE_SPARC, CPU_SUBTYPE_SPARC_ALL),
418        ("m88k", CPU_TYPE_MC88000, CPU_SUBTYPE_MC88000_ALL),
419        ("i860", CPU_TYPE_I860, CPU_SUBTYPE_I860_ALL),
420        ("arm", CPU_TYPE_ARM, CPU_SUBTYPE_ARM_ALL),
421        ("ppc601", CPU_TYPE_POWERPC, CPU_SUBTYPE_POWERPC_601),
422        ("ppc603", CPU_TYPE_POWERPC, CPU_SUBTYPE_POWERPC_603),
423        ("ppc603e", CPU_TYPE_POWERPC, CPU_SUBTYPE_POWERPC_603E),
424        ("ppc603ev", CPU_TYPE_POWERPC,CPU_SUBTYPE_POWERPC_603EV),
425        ("ppc604", CPU_TYPE_POWERPC, CPU_SUBTYPE_POWERPC_604),
426        ("ppc604e",CPU_TYPE_POWERPC, CPU_SUBTYPE_POWERPC_604E),
427        ("ppc750", CPU_TYPE_POWERPC, CPU_SUBTYPE_POWERPC_750),
428        ("ppc7400", CPU_TYPE_POWERPC, CPU_SUBTYPE_POWERPC_7400),
429        ("ppc7450", CPU_TYPE_POWERPC, CPU_SUBTYPE_POWERPC_7450),
430        ("ppc970", CPU_TYPE_POWERPC, CPU_SUBTYPE_POWERPC_970),
431        ("i486", CPU_TYPE_I386, CPU_SUBTYPE_486),
432        ("i486SX", CPU_TYPE_I386, CPU_SUBTYPE_486SX),
433        ("i586", CPU_TYPE_I386, CPU_SUBTYPE_586),
434        ("i686", CPU_TYPE_I386, CPU_SUBTYPE_PENTPRO),
435        ("pentIIm3", CPU_TYPE_I386, CPU_SUBTYPE_PENTII_M3),
436        ("pentIIm5", CPU_TYPE_I386, CPU_SUBTYPE_PENTII_M5),
437        ("pentium4", CPU_TYPE_I386, CPU_SUBTYPE_PENTIUM_4),
438        ("m68030", CPU_TYPE_MC680X0, CPU_SUBTYPE_MC68030_ONLY),
439        ("m68040", CPU_TYPE_MC680X0, CPU_SUBTYPE_MC68040),
440        ("hppa7100LC", CPU_TYPE_HPPA,  CPU_SUBTYPE_HPPA_7100LC),
441        ("armv4t", CPU_TYPE_ARM, CPU_SUBTYPE_ARM_V4T),
442        ("armv5", CPU_TYPE_ARM, CPU_SUBTYPE_ARM_V5TEJ),
443        ("xscale", CPU_TYPE_ARM, CPU_SUBTYPE_ARM_XSCALE),
444        ("armv6", CPU_TYPE_ARM, CPU_SUBTYPE_ARM_V6),
445        ("armv6m", CPU_TYPE_ARM, CPU_SUBTYPE_ARM_V6M),
446        ("armv7", CPU_TYPE_ARM, CPU_SUBTYPE_ARM_V7),
447        ("armv7f", CPU_TYPE_ARM, CPU_SUBTYPE_ARM_V7F),
448        ("armv7s", CPU_TYPE_ARM, CPU_SUBTYPE_ARM_V7S),
449        ("armv7k", CPU_TYPE_ARM, CPU_SUBTYPE_ARM_V7K),
450        ("armv7m", CPU_TYPE_ARM, CPU_SUBTYPE_ARM_V7M),
451        ("armv7em", CPU_TYPE_ARM, CPU_SUBTYPE_ARM_V7EM),
452        ("arm64v8", CPU_TYPE_ARM64, CPU_SUBTYPE_ARM64_V8),
453        ("arm64e", CPU_TYPE_ARM64, CPU_SUBTYPE_ARM64_E),
454        ("arm64_32_v8", CPU_TYPE_ARM64_32, CPU_SUBTYPE_ARM64_32_V8),
455    }
456}
457
458#[cfg(test)]
459mod tests {
460    #[test]
461    fn test_basic_mapping() {
462        use super::cputype::*;
463
464        assert_eq!(
465            get_arch_from_flag("armv7"),
466            Some((CPU_TYPE_ARM, CPU_SUBTYPE_ARM_V7))
467        );
468        assert_eq!(
469            get_arch_name_from_types(CPU_TYPE_ARM, CPU_SUBTYPE_ARM_V7),
470            Some("armv7")
471        );
472        assert_eq!(
473            get_arch_from_flag("i386"),
474            Some((CPU_TYPE_I386, CPU_SUBTYPE_I386_ALL))
475        );
476        assert_eq!(
477            get_arch_from_flag("x86"),
478            Some((CPU_TYPE_I386, CPU_SUBTYPE_I386_ALL))
479        );
480    }
481}