pelite/
stringify.rs

1/*!
2Stringify image constants.
3*/
4
5use std::mem;
6use std::str::FromStr;
7
8use crate::image::*;
9
10//----------------------------------------------------------------
11// Define some reflection macros for enums and flags
12
13macro_rules! enum1 {
14	(
15		$(#[$meta:meta])*
16		$Item:ident($item:ident: $ty:ty),
17		$($name:ident => $desc:expr,)*
18	) => {
19		$(#[$meta])*
20		#[derive(Copy, Clone)]
21		pub struct $Item(pub $ty);
22		impl $Item {
23			/// Gets the code identifier name for the value.
24			pub fn to_str(self) -> Option<&'static str> {
25				match self.0 {
26					$($name => Some(stringify!($name)),)*
27					_ => None,
28				}
29			}
30			/// Gets a longer description for the value.
31			pub fn description(self) -> Option<&'static str> {
32				match self.0 {
33					$($name => Some($desc),)*
34					_ => None,
35				}
36			}
37		}
38		impl FromStr for $Item {
39			type Err = ();
40			fn from_str(s: &str) -> Result<$Item, ()> {
41				match s {
42					$(stringify!($name) => Ok($Item($name)),)*
43					_ => Err(()),
44				}
45			}
46		}
47	}
48}
49
50macro_rules! flags {
51	(
52		$(#[$meta:meta])*
53		$Item:ident($item:ident: $ty:ty),
54		$($index:expr, $name:expr => $desc:expr,)*
55	) => {
56		$(#[$meta])*
57		#[derive(Copy, Clone)]
58		pub struct $Item(pub $ty);
59		impl $Item {
60			/// Gets the code identifier for a flag value given the bit index.
61			pub fn flag_str(index: u32) -> Option<&'static str> {
62				match index {
63					$($index => Some(stringify!($name)),)*
64					_ => None,
65				}
66			}
67			/// Gets the description for a flag value given the bit index.
68			pub fn flag_desc(index: u32) -> Option<&'static str> {
69				match index {
70					$($index => Some($desc),)*
71					_ => None,
72				}
73			}
74			pub fn parse_flag(s: &str) -> Option<$ty> {
75				match s {
76					$(stringify!($name) => Some($name),)*
77					_ => None,
78				}
79			}
80			/// Returns an Iterator over set flag bits returning their code identifiers.
81			pub fn to_strs(self) -> impl Clone + Iterator<Item = &'static str> {
82				(0..mem::size_of::<$ty>() as u32 * 8)
83					.filter_map(move |i| {
84						if self.0 & (1 << i) != 0 {
85							Self::flag_str(i)
86						}
87						else {
88							None
89						}
90					})
91			}
92		}
93	};
94}
95
96//----------------------------------------------------------------
97
98enum1! {
99	/// Stringifies the `IMAGE_FILE_MACHINE_*` constants for [`IMAGE_FILE_HEADER::Machine`](../image/struct.IMAGE_FILE_HEADER.html#Machine.v).
100	Machine(machine: u16),
101	IMAGE_FILE_MACHINE_I386 => "i386",
102	IMAGE_FILE_MACHINE_AMD64 => "AMD64",
103	IMAGE_FILE_MACHINE_IA64 => "IA64",
104}
105
106flags! {
107	/// Stringifies the `IMAGE_FILE_*` flag indices for [`IMAGE_FILE_HEADER::Characteristics`](../image/struct.IMAGE_FILE_HEADER.html#Characteristics.v).
108	FileChars(file_chars: u16),
109	/*0001*/ 0, IMAGE_FILE_RELOCS_STRIPPED => "RELOCS_STRIPPED",
110	/*0002*/ 1, IMAGE_FILE_EXECUTABLE_IMAGE => "EXECUTABLE_IMAGE",
111	/*0004*/ 2, IMAGE_FILE_LINE_NUMS_STRIPPED => "LINE_NUMS_STRIPPED",
112	/*0008*/ 3, IMAGE_FILE_LOCAL_SYMS_STRIPPED => "LOCAL_SYMS_STRIPPED",
113	/*0010*/ 4, IMAGE_FILE_AGGRESIVE_WS_TRIM => "AGGRESIVE_WS_TRIM",
114	/*0020*/ 5, IMAGE_FILE_LARGE_ADDRESS_AWARE => "LARGE_ADDRESS_AWARE",
115	/*0040*/ 6, IMAGE_FILE_6 => "Reserved",
116	/*0080*/ 7, IMAGE_FILE_BYTES_REVERSED_LO => "BYTES_REVERSED_LO",
117	/*0100*/ 8, IMAGE_FILE_32BIT_MACHINE => "32BIT_MACHINE",
118	/*0200*/ 9, IMAGE_FILE_DEBUG_STRIPPED => "DEBUG_STRIPPED",
119	/*0400*/10, IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP => "REMOVABLE_RUN_FROM_SWAP",
120	/*0800*/11, IMAGE_FILE_NET_RUN_FROM_SWAP => "NET_RUN_FROM_SWAP",
121	/*1000*/12, IMAGE_FILE_SYSTEM => "SYSTEM",
122	/*2000*/13, IMAGE_FILE_DLL => "DLL",
123	/*4000*/14, IMAGE_FILE_UP_SYSTEM_ONLY => "UP_SYSTEM_ONLY",
124	/*8000*/15, IMAGE_FILE_BYTES_REVERSED_HI => "BYTES_REVERSED_HI",
125}
126
127enum1! {
128	/// Stringifies the optional header's `Magic` value.
129	OptionalMagic(magic: u16),
130	IMAGE_NT_OPTIONAL_HDR32_MAGIC => "PE32",
131	IMAGE_NT_OPTIONAL_HDR64_MAGIC => "PE32+",
132	IMAGE_ROM_OPTIONAL_HDR_MAGIC => "ROM",
133}
134
135enum1! {
136	/// Stringifies the `IMAGE_SUBSYSTEM_*` constants for [`IMAGE_OPTIONAL_HEADER::Subsystem`](../image/struct.IMAGE_OPTIONAL_HEADER64.html#Subsystem.v).
137	Subsystem(subsystem: u16),
138	IMAGE_SUBSYSTEM_UNKNOWN => "Unknown",
139	IMAGE_SUBSYSTEM_NATIVE => "Native",
140	IMAGE_SUBSYSTEM_WINDOWS_GUI => "Windows GUI",
141	IMAGE_SUBSYSTEM_WINDOWS_CUI => "Windows CUI",
142	IMAGE_SUBSYSTEM_OS2_CUI => "OS/2 CUI",
143	IMAGE_SUBSYSTEM_POSIX_CUI => "POSIX CUI",
144	IMAGE_SUBSYSTEM_NATIVE_WINDOWS => "Native Win9x driver",
145	IMAGE_SUBSYSTEM_WINDOWS_CE_GUI => "Windows CE GUI",
146	IMAGE_SUBSYSTEM_EFI_APPLICATION => "Windows EFI Application",
147	IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER => "Windows EFI Boot Service Driver",
148	IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER => "Windows EFI Runtime Driver",
149	IMAGE_SUBSYSTEM_EFI_ROM => "Windows EFI ROM",
150	IMAGE_SUBSYSTEM_XBOX => "XBOX",
151	IMAGE_SUBSYSTEM_WINDOWS_BOOT_APPLICATION => "Windows Boot Application",
152}
153
154flags! {
155	/// Stringifies the `IMAGE_DLLCHARACTERISTICS_*` flag indices for [`IMAGE_OPTIONAL_HEADER::DllCharacteristics`](../image/struct.IMAGE_OPTIONAL_HEADER64.html#DllCharacteristics.v).
156	DllChars(dll_chars: u16),
157	/*0001*/ 0, IMAGE_DLLCHARACTERISTICS_0 => "Reserved",
158	/*0002*/ 1, IMAGE_DLLCHARACTERISTICS_1 => "Reserved",
159	/*0004*/ 2, IMAGE_DLLCHARACTERISTICS_2 => "Reserved",
160	/*0008*/ 3, IMAGE_DLLCHARACTERISTICS_3 => "Reserved",
161	/*0010*/ 4, IMAGE_DLLCHARACTERISTICS_4 => "Reserved",
162	/*0020*/ 5, IMAGE_DLLCHARACTERISTICS_HIGH_ENTROPY_VA => "Image can handle a high entropy virtual address space",
163	/*0040*/ 6, IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE => "Can be relocated at load time",
164	/*0080*/ 7, IMAGE_DLLCHARACTERISTICS_FORCE_INTEGRITY => "Code Integrity checks are enforced",
165	/*0100*/ 8, IMAGE_DLLCHARACTERISTICS_NX_COMPAT => "Image is NX compatible",
166	/*0200*/ 9, IMAGE_DLLCHARACTERISTICS_NO_ISOLATION => "Isolation aware, but do not isolate the image",
167	/*0400*/10, IMAGE_DLLCHARACTERISTICS_NO_SEH => "Does not use SEH",
168	/*0800*/11, IMAGE_DLLCHARACTERISTICS_NO_BIND => "Do not bind the image",
169	/*1000*/12, IMAGE_DLLCHARACTERISTICS_APPCONTAINER => "Image must execute in an AppContainer",
170	/*2000*/13, IMAGE_DLLCHARACTERISTICS_WDM_DRIVER => "A WDM driver",
171	/*4000*/14, IMAGE_DLLCHARACTERISTICS_GUARD_CF => "Image supports Control Flow Guard",
172	/*8000*/15, IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE => "Terminal Server aware",
173}
174
175enum1! {
176	/// Stringifies the `IMAGE_DIRECTORY_ENTRY_*` constants for [`IMAGE_OPTIONAL_HEADER::DataDirectory`](../image/struct.IMAGE_OPTIONAL_HEADER64.html#DataDirectory.v).
177	DirectoryEntry(entry: usize),
178	IMAGE_DIRECTORY_ENTRY_EXPORT => "Export Directory",
179	IMAGE_DIRECTORY_ENTRY_IMPORT => "Import Directory",
180	IMAGE_DIRECTORY_ENTRY_RESOURCE => "Resource Directory",
181	IMAGE_DIRECTORY_ENTRY_EXCEPTION => "Exception Directory",
182	IMAGE_DIRECTORY_ENTRY_SECURITY => "Security Directory",
183	IMAGE_DIRECTORY_ENTRY_BASERELOC => "Base Relocation Table",
184	IMAGE_DIRECTORY_ENTRY_DEBUG => "Debug Directory",
185	IMAGE_DIRECTORY_ENTRY_ARCHITECTURE => "Architecture Specific Data",
186	IMAGE_DIRECTORY_ENTRY_GLOBALPTR => "RVA of GlobalPtr",
187	IMAGE_DIRECTORY_ENTRY_TLS => "TLS Directory",
188	IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG => "Load Configuration Directory",
189	IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT => "Bound Import Directory",
190	IMAGE_DIRECTORY_ENTRY_IAT => "Import Address Table",
191	IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT => "Delay Load Import Descriptors",
192	IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR => "COM Runtime Descriptor",
193}
194
195flags! {
196	/// Stringifies the `IMAGE_SCN_*` flag indices for [`IMAGE_SECTION_HEADER::Characteristics`](../image/struct.IMAGE_SECTION_HEADER.html#Characteristics.v).
197	SectionChars(section_chars: u32),
198	/*00000001*/ 0, IMAGE_SCN_0 => "Reserved",
199	/*00000002*/ 1, IMAGE_SCN_1 => "Reserved",
200	/*00000004*/ 2, IMAGE_SCN_2 => "Reserved",
201	/*00000008*/ 3, IMAGE_SCN_TYPE_NO_PAD => "TYPE_NO_PAD",
202	/*00000010*/ 4, IMAGE_SCN_4 => "Reserved",
203	/*00000020*/ 5, IMAGE_SCN_CNT_CODE => "Contains executable code",
204	/*00000040*/ 6, IMAGE_SCN_CNT_INITIALIZED_DATA => "Contains initialized data",
205	/*00000080*/ 7, IMAGE_SCN_CNT_UNINITIALIZED_DATA => "Contains uninitialized data",
206	/*00000100*/ 8, IMAGE_SCN_LNK_OTHER => "LNK_OTHER",
207	/*00000200*/ 9, IMAGE_SCN_LNK_INFO => "LNK_INFO",
208	/*00000400*/10, IMAGE_SCN_10 => "Reserved",
209	/*00000800*/11, IMAGE_SCN_LNK_REMOVE => "LNK_REMOVE",
210	/*00001000*/12, IMAGE_SCN_LNK_COMDAT => "LNK_COMDAT",
211	/*00002000*/13, IMAGE_SCN_13 => "Reserved",
212	/*00004000*/14, IMAGE_SCN_NO_DEFER_SPEC_EXC => "NO_DEFER_SPEC_EXC",
213	/*00008000*/15, IMAGE_SCN_GPREL => "GPREL",
214	/*00010000*/16, IMAGE_SCN_16 => "Reserved",
215	/*00020000*/17, IMAGE_SCN_MEM_PURGEABLE => "MEM_PURGEABLE",
216	/*00040000*/18, IMAGE_SCN_MEM_LOCKED => "MEM_LOCKED",
217	/*00080000*/19, IMAGE_SCN_MEM_PRELOAD => "MEM_PRELOAD",
218	/*00100000*/20, IMAGE_SCN_ALIGN_1 => "",
219	/*00200000*/21, IMAGE_SCN_ALIGN_2 => "",
220	/*00400000*/22, IMAGE_SCN_ALIGN_4 => "",
221	/*00800000*/23, IMAGE_SCN_ALIGN_8 => "",
222	/*01000000*/24, IMAGE_SCN_LNK_NRELOC_OVFL => "LNK_NRELOC_OVFL",
223	/*02000000*/25, IMAGE_SCN_MEM_DISCARDABLE => "MEM_DISCARDABLE",
224	/*04000000*/26, IMAGE_SCN_MEM_NOT_CACHED => "MEM_NOT_CACHED",
225	/*08000000*/27, IMAGE_SCN_MEM_NOT_PAGED => "MEM_NOT_PAGED",
226	/*10000000*/28, IMAGE_SCN_MEM_SHARED => "MEM_SHARED",
227	/*20000000*/29, IMAGE_SCN_MEM_EXECUTE => "MEM_EXECUTE",
228	/*40000000*/30, IMAGE_SCN_MEM_READ => "MEM_READ",
229	/*80000000*/31, IMAGE_SCN_MEM_WRITE => "MEM_WRITE",
230}
231
232enum1! {
233	/// Stringifies the `RT_*` constants for [`IMAGE_RESOURCE_DIRECTORY_ENTRY::Name`](../image/struct.IMAGE_RESOURCE_DIRECTORY_ENTRY.html#Name.v).
234	ResourceName(name: u16),
235	RT_CURSOR => "RT_CURSOR",
236	RT_BITMAP => "RT_BITMAP",
237	RT_ICON => "RT_ICON",
238	RT_MENU => "RT_MENU",
239	RT_DIALOG => "RT_DIALOG",
240	RT_STRING => "RT_STRING",
241	RT_FONTDIR => "RT_FONTDIR",
242	RT_FONT => "RT_FONT",
243	RT_ACCELERATOR => "RT_ACCELERATOR",
244	RT_RCDATA => "RT_RCDATA",
245	RT_MESSAGETABLE => "RT_MESSAGETABLE",
246	RT_GROUP_CURSOR => "RT_GROUP_CURSOR",
247	RT_GROUP_ICON => "RT_GROUP_ICON",
248	RT_VERSION => "RT_VERSION",
249	RT_DLGINCLUDE => "RT_DLGINCLUDE",
250	RT_PLUGPLAY => "RT_PLUGPLAY",
251	RT_VXD => "RT_VXD",
252	RT_ANICURSOR => "RT_ANICURSOR",
253	RT_ANIICON => "RT_ANIICON",
254	RT_HTML => "RT_HTML",
255	RT_MANIFEST => "RT_MANIFEST",
256}
257
258enum1! {
259	/// Stringifies the `IMAGE_REL_BASED_*` constants for [`IMAGE_BASE_RELOCATION` types](../image/struct.IMAGE_BASE_RELOCATION.html).
260	RelocType(reloc_type: u8),
261	IMAGE_REL_BASED_ABSOLUTE => "ABSOLUTE",
262	IMAGE_REL_BASED_HIGH => "HIGH",
263	IMAGE_REL_BASED_LOW => "LOW",
264	IMAGE_REL_BASED_HIGHLOW => "HIGHLOW",
265	IMAGE_REL_BASED_HIGHADJ => "HIGHADJ",
266	IMAGE_REL_BASED_MACHINE_SPECIFIC_5 => "MACHINE_SPECIFIC_5",
267	IMAGE_REL_BASED_MACHINE_SPECIFIC_7 => "MACHINE_SPECIFIC_7",
268	IMAGE_REL_BASED_MACHINE_SPECIFIC_9 => "MACHINE_SPECIFIC_9",
269	IMAGE_REL_BASED_DIR64 => "DIR64",
270}
271
272enum1! {
273	/// Stringifies the `UWOP_*` constants for [`UNWIND_CODE` operations](../image/struct.UNWIND_CODE.html).
274	UnwindOp(unwind_op: u8),
275	UWOP_PUSH_NONVOL => "push nonvol",
276	UWOP_ALLOC_LARGE => "alloc large",
277	UWOP_ALLOC_SMALL => "alloc small",
278	UWOP_SET_FPREG => "set fpreg",
279	UWOP_SAVE_NONVOL => "save nonvol",
280	UWOP_SAVE_NONVOL_FAR => "save nonvol large",
281	UWOP_SAVE_XMM128 => "save xmm128",
282	UWOP_SAVE_XMM128_FAR => "save xmm128 far",
283	UWOP_PUSH_MACHFRAME => "push machframe",
284}
285
286enum1! {
287	/// Stringifies the `UNW_FLAG_*` constants for [`UNWIND_INFO` flags](..image/struct.UNWIND_INFO.html).
288	UnwindFlag(unwind_flag: u8),
289	UNW_FLAG_NHANDLER => "NHANDLER",
290	UNW_FLAG_EHANDLER => "EHANDLER",
291	UNW_FLAG_UHANDLER => "UHANDLER",
292	UNW_FLAG_FHANDLER => "FHANDLER",
293	UNW_FLAG_CHAININFO => "CHAININFO",
294}
295
296enum1! {
297	/// Stringifies the `IMAGE_DEBUG_TYPE_*` constants for [`IMAGE_DEBUG_DIRECTORY::Type`](../image/struct.IMAGE_DEBUG_DIRECTORY.html#Type.v).
298	DebugType(debug_type: u32),
299	IMAGE_DEBUG_TYPE_UNKNOWN => "Unknown",
300	IMAGE_DEBUG_TYPE_COFF => "COFF",
301	IMAGE_DEBUG_TYPE_CODEVIEW => "CodeView",
302	IMAGE_DEBUG_TYPE_FPO => "FPO",
303	IMAGE_DEBUG_TYPE_MISC => "DBG",
304	IMAGE_DEBUG_TYPE_EXCEPTION => "Exception",
305	IMAGE_DEBUG_TYPE_FIXUP => "Fixup",
306	IMAGE_DEBUG_TYPE_OMAP_TO_SRC => "OMAP to src",
307	IMAGE_DEBUG_TYPE_OMAP_FROM_SRC => "OMAP from src",
308	IMAGE_DEBUG_TYPE_BORLAND => "Borland",
309	IMAGE_DEBUG_TYPE_RESERVED10 => "Reserved10",
310	IMAGE_DEBUG_TYPE_CLSID => "CLSID",
311	IMAGE_DEBUG_TYPE_VC_FEATURE => "VCFeature",
312	IMAGE_DEBUG_TYPE_POGO => "POGO",
313	IMAGE_DEBUG_TYPE_ILTCG => "ILTCG",
314	IMAGE_DEBUG_TYPE_MPX => "MPX",
315	IMAGE_DEBUG_TYPE_REPRO => "Repro",
316}